Skip to content

Commit

Permalink
fix(cz-git): incorrect maxSubjectLength on custom scope (#173)
Browse files Browse the repository at this point in the history
Co-authored-by: aku < [email protected]>
Co-authored-by: Zhengqbbb <[email protected]>
  • Loading branch information
3 people authored May 25, 2024
1 parent e5d73ed commit baa58ae
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 65 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"customizable",
"cz-customizable"
],
"packageManager": "pnpm@9.0.0",
"packageManager": "pnpm@9.1.2",
"scripts": {
"x": "czg",
"build": "pnpm clean && pnpm -r build",
Expand Down Expand Up @@ -65,7 +65,7 @@
"node-fetch": "2.6.9",
"ora": "^7.0.1",
"pathe": "^1.1.1",
"pnpm": "9.0.0",
"pnpm": "^9.1.2",
"rimraf": "3.0.2",
"simple-git-hooks": "^2.9.0",
"ts-json-schema-generator": "^1.3.0",
Expand Down
12 changes: 6 additions & 6 deletions packages/cz-git/__tests__/util.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, test } from 'vitest'
import { getCurrentScopes, getMaxSubjectLength, isSingleItem } from '../src/shared'
import { getMaxSubjectLength, getScopesList, isSingleItem } from '../src/shared'

/**
* @description: utils Test
Expand Down Expand Up @@ -90,17 +90,17 @@ describe('isSingleItem()', () => {
})
})

describe('getCurrentScopes()', () => {
describe('getScopesList()', () => {
test('no scopes should empty', () => {
expect(getCurrentScopes([], {}, 'feat')).toEqual([])
expect(getCurrentScopes([], { test: [{ name: 'unitest' }] }, 'feat')).toEqual([])
expect(getScopesList([], {}, 'feat')).toEqual([])
expect(getScopesList([], { test: [{ name: 'unitest' }] }, 'feat')).toEqual([])
})
test('hit scopeOverrides should return', () => {
const scopeOverrides = { test: [{ name: 'unitest' }] }
expect(getCurrentScopes(['feat'], scopeOverrides, 'test')).toEqual([{ name: 'unitest' }])
expect(getScopesList(['feat'], scopeOverrides, 'test')).toEqual([{ name: 'unitest' }])
})
test('no hit scopeOverrides should return scopes', () => {
const scopeOverrides = { test: [{ name: 'unitest' }] }
expect(getCurrentScopes(['feat', 'fix'], scopeOverrides, 'feat')).toEqual(['feat', 'fix'])
expect(getScopesList(['feat', 'fix'], scopeOverrides, 'feat')).toEqual(['feat', 'fix'])
})
})
4 changes: 2 additions & 2 deletions packages/cz-git/src/generator/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import { spawnSync } from 'node:child_process'
import { style } from '@cz-git/inquirer'
import {
getCurrentScopes,
getMaxSubjectLength,
getScopesList,
isSingleItem,
isString,
parseStandardScopes,
Expand Down Expand Up @@ -37,7 +37,7 @@ function getSingleParams(answers: Answers, options: CommitizenGitOptions) {
singeIssuePrefix: '',
}
const scopeList = parseStandardScopes(
getCurrentScopes(options.scopes, options.scopeOverrides, answers.type),
getScopesList(options.scopes, options.scopeOverrides, answers.type),
)
if (isSingleItem(options.allowCustomScopes, options.allowEmptyScopes, scopeList))
mapping.singleScope = scopeList[singleIndex].value
Expand Down
39 changes: 23 additions & 16 deletions packages/cz-git/src/generator/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
import { fuzzyFilter, style } from '@cz-git/inquirer'
import type { Answers, CommitizenGitOptions, Option } from '../shared'
import {
getCurrentScopes,
getAnswersScope,
getAnswersType,
getMaxSubjectLength,
getProcessSubject,
getScopesList,
isSingleItem,
isString,
log,
parseStandardScopes,
resolveDefaultType,
resolveListItemPinTop,
resovleCustomListTemplate,
useThemeCode,
Expand Down Expand Up @@ -53,9 +54,9 @@ export function generateQuestions(options: CommitizenGitOptions, cz: any) {
initialCheckedValue: options.defaultScope, // checkbox mode
source: (answer: Answers, input: string) => {
let scopeSource: Option[] = []
const _answerType = resolveDefaultType(options, answer)
const answerType = getAnswersType(options, answer)
scopeSource = parseStandardScopes(
getCurrentScopes(options.scopes, options.scopeOverrides, _answerType),
getScopesList(options.scopes, options.scopeOverrides, answerType),
)
scopeSource = resovleCustomListTemplate(
scopeSource,
Expand Down Expand Up @@ -83,12 +84,12 @@ export function generateQuestions(options: CommitizenGitOptions, cz: any) {
return input.length !== 0 ? true : style.red('[ERROR] scope is required')
},
when: (answer: Answers) => {
const _answerType = resolveDefaultType(options, answer)
const answerType = getAnswersType(options, answer)
return !isSingleItem(
options.allowCustomScopes,
options.allowEmptyScopes,
parseStandardScopes(
getCurrentScopes(options.scopes, options.scopeOverrides, _answerType),
getScopesList(options.scopes, options.scopeOverrides, answerType),
),
)
},
Expand All @@ -111,8 +112,8 @@ export function generateQuestions(options: CommitizenGitOptions, cz: any) {
return input.length !== 0 ? true : style.red('[ERROR] scope is required')
},
when: (answers: Answers) => {
return answers.scope === '___CUSTOM___'
|| (isString(options.defaultScope) && (options.defaultScope as string).startsWith('___CUSTOM___:'))
const { isCustomScope, isInputMode } = getAnswersScope(options, answers)
return isCustomScope || isInputMode
},
transformer: (input: string) => useThemeCode(input, options.themeColorCode),
},
Expand All @@ -125,12 +126,15 @@ export function generateQuestions(options: CommitizenGitOptions, cz: any) {
const processedSubject = getProcessSubject(subject)
if (processedSubject.length === 0)
return style.red('[ERROR] subject is required')

if (!options.minSubjectLength && !options.maxSubjectLength) {
log('err', 'Error [Subject Length] Option')
return false
}
const _answerType = resolveDefaultType(options, answers)
const maxSubjectLength = getMaxSubjectLength(_answerType, answers.scope, options)

const answerType = getAnswersType(options, answers)
const { answerScope } = getAnswersScope(options, answers)
const maxSubjectLength = getMaxSubjectLength(answerType, answerScope, options)
if (options.minSubjectLength && processedSubject.length < options.minSubjectLength) {
return style.red(
`[ERROR]subject length must be greater than or equal to ${options.minSubjectLength} characters`,
Expand All @@ -148,8 +152,9 @@ export function generateQuestions(options: CommitizenGitOptions, cz: any) {
transformer: (subject: string, answers: Answers) => {
const { minSubjectLength, isIgnoreCheckMaxSubjectLength } = options
const subjectLength = subject.length
const _answerType = resolveDefaultType(options, answers)
const maxSubjectLength = getMaxSubjectLength(_answerType, answers.scope, options)
const answerType = getAnswersType(options, answers)
const { answerScope } = getAnswersScope(options, answers)
const maxSubjectLength = getMaxSubjectLength(answerType, answerScope, options)
let tooltip
let isWarning = false
if (typeof minSubjectLength === 'number' && subjectLength < minSubjectLength) {
Expand All @@ -160,7 +165,9 @@ export function generateQuestions(options: CommitizenGitOptions, cz: any) {
tooltip = `${subjectLength - maxSubjectLength} chars over the expected`
isWarning = true
}
else { tooltip = `${subjectLength - maxSubjectLength} chars over the limit` }
else {
tooltip = `${subjectLength - maxSubjectLength} chars over the limit`
}
}
else {
tooltip = `${maxSubjectLength - subjectLength} more chars allowed`
Expand Down Expand Up @@ -218,11 +225,11 @@ export function generateQuestions(options: CommitizenGitOptions, cz: any) {
message: options.messages?.breaking,
completeValue: options.defaultBody || undefined,
when: (answers: Answers) => {
const _answerType = resolveDefaultType(options, answers)
const answerType = getAnswersType(options, answers)
if (
options.allowBreakingChanges
&& _answerType
&& options.allowBreakingChanges.includes(_answerType)
&& answerType
&& options.allowBreakingChanges.includes(answerType)
)
return true

Expand Down
55 changes: 39 additions & 16 deletions packages/cz-git/src/shared/utils/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,12 @@ export function isSingleItem(allowCustom = true, allowEmpty = true, list: Array<
}

/**
* @description: resolve AI modify mode and normal answer type and default type
* @description make sure can get answers type
* 1. normal answer type
* 2. resolve AI direct output mode
* 3. output default type
*/
export function resolveDefaultType(options: CommitizenGitOptions, answer: Answers) {
export function getAnswersType(options: CommitizenGitOptions, answer: Answers) {
if (!answer.type && options.useAI)
return options.defaultType

Expand All @@ -81,10 +84,16 @@ export function parseStandardScopes(scopes: ScopesType): Option[] {
: { value: scope.value, name: scope.name }
})
}

export function getCurrentScopes(scopes?: any[],
/**
* @description To get a list of scopes
* 1. If have overrides by answerType, return the override list
* 2. If have scopes is empty, return empty array
*/
export function getScopesList(
scopes?: any[],
scopeOverrides?: { [x: string]: any[] },
answerType?: string) {
answerType?: string,
) {
let result = []
if (scopeOverrides && answerType && scopeOverrides[answerType])
result = scopeOverrides[answerType]
Expand All @@ -95,20 +104,21 @@ export function getCurrentScopes(scopes?: any[],
return result
}

function filterCustomEmptyByOption(target: {
name: string
value: any
}[],
allowCustom = true,
allowEmpty = true) {
function filterCustomEmptyByOption(
target: {
name: string
value: any
}[],
allowCustom = true,
allowEmpty = true,
) {
target = allowCustom ? target : target.filter(i => i.value !== '___CUSTOM___')
return allowEmpty ? target : target.filter(i => i.value !== false)
}
/**
* @description
* Handle custom list template (types, scopes)
*
* Add separator custom empty
* @description Handle custom list template (types, scopes)
* 1. Add separator, custom, empty
* 2. Sort target, empty and custom position
*/
export function resovleCustomListTemplate(
target: Array<{ name: string; value: string }>,
Expand Down Expand Up @@ -163,6 +173,18 @@ export function resovleCustomListTemplate(
)
}

/**
* @description To get the scope of the answer
* 1. If scope is custom mode, return the input custom scope
* 2. If scope is input mode flag, return the input scope
*/
export function getAnswersScope(options: CommitizenGitOptions, answers: Answers) {
const isCustomScope = answers.scope === '___CUSTOM___'
const isInputMode = isString(options.defaultScope) && (options.defaultScope as string).startsWith('___CUSTOM___:')
const answerScope = (isCustomScope || isInputMode) ? answers.customScope : answers.scope
return { isCustomScope, isInputMode, answerScope }
}

/**
* @description: get subject word
*/
Expand All @@ -180,7 +202,7 @@ function getEmojiStrLength(options: CommitizenGitOptions, type?: string): number
* @description: get max subject length
*/
export function getMaxSubjectLength(type: Answers['type'],
scope: Answers['scope'],
scope: Answers['scope'] | Answers['customScope'],
options: CommitizenGitOptions) {
let optionMaxLength = Infinity
if (Array.isArray(scope))
Expand All @@ -190,6 +212,7 @@ export function getMaxSubjectLength(type: Answers['type'],
const emojiLength = options.useEmoji ? getEmojiStrLength(options, type) : 0
const maxHeaderLength = options?.maxHeaderLength ? options?.maxHeaderLength : Infinity
const maxSubjectLength = options?.maxSubjectLength ? options?.maxSubjectLength : Infinity

if (options?.maxHeaderLength === 0 || options?.maxSubjectLength === 0) {
return 0
}
Expand Down
Loading

0 comments on commit baa58ae

Please sign in to comment.