Skip to content

Commit baa58ae

Browse files
thansetanZhengqbbb
andauthored
fix(cz-git): incorrect maxSubjectLength on custom scope (#173)
Co-authored-by: aku < thansetan@users.noreply.github.com> Co-authored-by: Zhengqbbb <Zhengqbbb@users.noreply.github.com>
1 parent e5d73ed commit baa58ae

6 files changed

Lines changed: 103 additions & 65 deletions

File tree

‎package.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"customizable",
2424
"cz-customizable"
2525
],
26-
"packageManager": "pnpm@9.0.0",
26+
"packageManager": "pnpm@9.1.2",
2727
"scripts": {
2828
"x": "czg",
2929
"build": "pnpm clean && pnpm -r build",
@@ -65,7 +65,7 @@
6565
"node-fetch": "2.6.9",
6666
"ora": "^7.0.1",
6767
"pathe": "^1.1.1",
68-
"pnpm": "9.0.0",
68+
"pnpm": "^9.1.2",
6969
"rimraf": "3.0.2",
7070
"simple-git-hooks": "^2.9.0",
7171
"ts-json-schema-generator": "^1.3.0",

‎packages/cz-git/__tests__/util.test.ts‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, expect, test } from 'vitest'
2-
import { getCurrentScopes, getMaxSubjectLength, isSingleItem } from '../src/shared'
2+
import { getMaxSubjectLength, getScopesList, isSingleItem } from '../src/shared'
33

44
/**
55
* @description: utils Test
@@ -90,17 +90,17 @@ describe('isSingleItem()', () => {
9090
})
9191
})
9292

93-
describe('getCurrentScopes()', () => {
93+
describe('getScopesList()', () => {
9494
test('no scopes should empty', () => {
95-
expect(getCurrentScopes([], {}, 'feat')).toEqual([])
96-
expect(getCurrentScopes([], { test: [{ name: 'unitest' }] }, 'feat')).toEqual([])
95+
expect(getScopesList([], {}, 'feat')).toEqual([])
96+
expect(getScopesList([], { test: [{ name: 'unitest' }] }, 'feat')).toEqual([])
9797
})
9898
test('hit scopeOverrides should return', () => {
9999
const scopeOverrides = { test: [{ name: 'unitest' }] }
100-
expect(getCurrentScopes(['feat'], scopeOverrides, 'test')).toEqual([{ name: 'unitest' }])
100+
expect(getScopesList(['feat'], scopeOverrides, 'test')).toEqual([{ name: 'unitest' }])
101101
})
102102
test('no hit scopeOverrides should return scopes', () => {
103103
const scopeOverrides = { test: [{ name: 'unitest' }] }
104-
expect(getCurrentScopes(['feat', 'fix'], scopeOverrides, 'feat')).toEqual(['feat', 'fix'])
104+
expect(getScopesList(['feat', 'fix'], scopeOverrides, 'feat')).toEqual(['feat', 'fix'])
105105
})
106106
})

‎packages/cz-git/src/generator/message.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import { spawnSync } from 'node:child_process'
77
import { style } from '@cz-git/inquirer'
88
import {
9-
getCurrentScopes,
109
getMaxSubjectLength,
10+
getScopesList,
1111
isSingleItem,
1212
isString,
1313
parseStandardScopes,
@@ -37,7 +37,7 @@ function getSingleParams(answers: Answers, options: CommitizenGitOptions) {
3737
singeIssuePrefix: '',
3838
}
3939
const scopeList = parseStandardScopes(
40-
getCurrentScopes(options.scopes, options.scopeOverrides, answers.type),
40+
getScopesList(options.scopes, options.scopeOverrides, answers.type),
4141
)
4242
if (isSingleItem(options.allowCustomScopes, options.allowEmptyScopes, scopeList))
4343
mapping.singleScope = scopeList[singleIndex].value

‎packages/cz-git/src/generator/question.ts‎

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
import { fuzzyFilter, style } from '@cz-git/inquirer'
88
import type { Answers, CommitizenGitOptions, Option } from '../shared'
99
import {
10-
getCurrentScopes,
10+
getAnswersScope,
11+
getAnswersType,
1112
getMaxSubjectLength,
1213
getProcessSubject,
14+
getScopesList,
1315
isSingleItem,
1416
isString,
1517
log,
1618
parseStandardScopes,
17-
resolveDefaultType,
1819
resolveListItemPinTop,
1920
resovleCustomListTemplate,
2021
useThemeCode,
@@ -53,9 +54,9 @@ export function generateQuestions(options: CommitizenGitOptions, cz: any) {
5354
initialCheckedValue: options.defaultScope, // checkbox mode
5455
source: (answer: Answers, input: string) => {
5556
let scopeSource: Option[] = []
56-
const _answerType = resolveDefaultType(options, answer)
57+
const answerType = getAnswersType(options, answer)
5758
scopeSource = parseStandardScopes(
58-
getCurrentScopes(options.scopes, options.scopeOverrides, _answerType),
59+
getScopesList(options.scopes, options.scopeOverrides, answerType),
5960
)
6061
scopeSource = resovleCustomListTemplate(
6162
scopeSource,
@@ -83,12 +84,12 @@ export function generateQuestions(options: CommitizenGitOptions, cz: any) {
8384
return input.length !== 0 ? true : style.red('[ERROR] scope is required')
8485
},
8586
when: (answer: Answers) => {
86-
const _answerType = resolveDefaultType(options, answer)
87+
const answerType = getAnswersType(options, answer)
8788
return !isSingleItem(
8889
options.allowCustomScopes,
8990
options.allowEmptyScopes,
9091
parseStandardScopes(
91-
getCurrentScopes(options.scopes, options.scopeOverrides, _answerType),
92+
getScopesList(options.scopes, options.scopeOverrides, answerType),
9293
),
9394
)
9495
},
@@ -111,8 +112,8 @@ export function generateQuestions(options: CommitizenGitOptions, cz: any) {
111112
return input.length !== 0 ? true : style.red('[ERROR] scope is required')
112113
},
113114
when: (answers: Answers) => {
114-
return answers.scope === '___CUSTOM___'
115-
|| (isString(options.defaultScope) && (options.defaultScope as string).startsWith('___CUSTOM___:'))
115+
const { isCustomScope, isInputMode } = getAnswersScope(options, answers)
116+
return isCustomScope || isInputMode
116117
},
117118
transformer: (input: string) => useThemeCode(input, options.themeColorCode),
118119
},
@@ -125,12 +126,15 @@ export function generateQuestions(options: CommitizenGitOptions, cz: any) {
125126
const processedSubject = getProcessSubject(subject)
126127
if (processedSubject.length === 0)
127128
return style.red('[ERROR] subject is required')
129+
128130
if (!options.minSubjectLength && !options.maxSubjectLength) {
129131
log('err', 'Error [Subject Length] Option')
130132
return false
131133
}
132-
const _answerType = resolveDefaultType(options, answers)
133-
const maxSubjectLength = getMaxSubjectLength(_answerType, answers.scope, options)
134+
135+
const answerType = getAnswersType(options, answers)
136+
const { answerScope } = getAnswersScope(options, answers)
137+
const maxSubjectLength = getMaxSubjectLength(answerType, answerScope, options)
134138
if (options.minSubjectLength && processedSubject.length < options.minSubjectLength) {
135139
return style.red(
136140
`[ERROR]subject length must be greater than or equal to ${options.minSubjectLength} characters`,
@@ -148,8 +152,9 @@ export function generateQuestions(options: CommitizenGitOptions, cz: any) {
148152
transformer: (subject: string, answers: Answers) => {
149153
const { minSubjectLength, isIgnoreCheckMaxSubjectLength } = options
150154
const subjectLength = subject.length
151-
const _answerType = resolveDefaultType(options, answers)
152-
const maxSubjectLength = getMaxSubjectLength(_answerType, answers.scope, options)
155+
const answerType = getAnswersType(options, answers)
156+
const { answerScope } = getAnswersScope(options, answers)
157+
const maxSubjectLength = getMaxSubjectLength(answerType, answerScope, options)
153158
let tooltip
154159
let isWarning = false
155160
if (typeof minSubjectLength === 'number' && subjectLength < minSubjectLength) {
@@ -160,7 +165,9 @@ export function generateQuestions(options: CommitizenGitOptions, cz: any) {
160165
tooltip = `${subjectLength - maxSubjectLength} chars over the expected`
161166
isWarning = true
162167
}
163-
else { tooltip = `${subjectLength - maxSubjectLength} chars over the limit` }
168+
else {
169+
tooltip = `${subjectLength - maxSubjectLength} chars over the limit`
170+
}
164171
}
165172
else {
166173
tooltip = `${maxSubjectLength - subjectLength} more chars allowed`
@@ -218,11 +225,11 @@ export function generateQuestions(options: CommitizenGitOptions, cz: any) {
218225
message: options.messages?.breaking,
219226
completeValue: options.defaultBody || undefined,
220227
when: (answers: Answers) => {
221-
const _answerType = resolveDefaultType(options, answers)
228+
const answerType = getAnswersType(options, answers)
222229
if (
223230
options.allowBreakingChanges
224-
&& _answerType
225-
&& options.allowBreakingChanges.includes(_answerType)
231+
&& answerType
232+
&& options.allowBreakingChanges.includes(answerType)
226233
)
227234
return true
228235

‎packages/cz-git/src/shared/utils/util.ts‎

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,12 @@ export function isSingleItem(allowCustom = true, allowEmpty = true, list: Array<
6060
}
6161

6262
/**
63-
* @description: resolve AI modify mode and normal answer type and default type
63+
* @description make sure can get answers type
64+
* 1. normal answer type
65+
* 2. resolve AI direct output mode
66+
* 3. output default type
6467
*/
65-
export function resolveDefaultType(options: CommitizenGitOptions, answer: Answers) {
68+
export function getAnswersType(options: CommitizenGitOptions, answer: Answers) {
6669
if (!answer.type && options.useAI)
6770
return options.defaultType
6871

@@ -81,10 +84,16 @@ export function parseStandardScopes(scopes: ScopesType): Option[] {
8184
: { value: scope.value, name: scope.name }
8285
})
8386
}
84-
85-
export function getCurrentScopes(scopes?: any[],
87+
/**
88+
* @description To get a list of scopes
89+
* 1. If have overrides by answerType, return the override list
90+
* 2. If have scopes is empty, return empty array
91+
*/
92+
export function getScopesList(
93+
scopes?: any[],
8694
scopeOverrides?: { [x: string]: any[] },
87-
answerType?: string) {
95+
answerType?: string,
96+
) {
8897
let result = []
8998
if (scopeOverrides && answerType && scopeOverrides[answerType])
9099
result = scopeOverrides[answerType]
@@ -95,20 +104,21 @@ export function getCurrentScopes(scopes?: any[],
95104
return result
96105
}
97106

98-
function filterCustomEmptyByOption(target: {
99-
name: string
100-
value: any
101-
}[],
102-
allowCustom = true,
103-
allowEmpty = true) {
107+
function filterCustomEmptyByOption(
108+
target: {
109+
name: string
110+
value: any
111+
}[],
112+
allowCustom = true,
113+
allowEmpty = true,
114+
) {
104115
target = allowCustom ? target : target.filter(i => i.value !== '___CUSTOM___')
105116
return allowEmpty ? target : target.filter(i => i.value !== false)
106117
}
107118
/**
108-
* @description
109-
* Handle custom list template (types, scopes)
110-
*
111-
* Add separator custom empty
119+
* @description Handle custom list template (types, scopes)
120+
* 1. Add separator, custom, empty
121+
* 2. Sort target, empty and custom position
112122
*/
113123
export function resovleCustomListTemplate(
114124
target: Array<{ name: string; value: string }>,
@@ -163,6 +173,18 @@ export function resovleCustomListTemplate(
163173
)
164174
}
165175

176+
/**
177+
* @description To get the scope of the answer
178+
* 1. If scope is custom mode, return the input custom scope
179+
* 2. If scope is input mode flag, return the input scope
180+
*/
181+
export function getAnswersScope(options: CommitizenGitOptions, answers: Answers) {
182+
const isCustomScope = answers.scope === '___CUSTOM___'
183+
const isInputMode = isString(options.defaultScope) && (options.defaultScope as string).startsWith('___CUSTOM___:')
184+
const answerScope = (isCustomScope || isInputMode) ? answers.customScope : answers.scope
185+
return { isCustomScope, isInputMode, answerScope }
186+
}
187+
166188
/**
167189
* @description: get subject word
168190
*/
@@ -180,7 +202,7 @@ function getEmojiStrLength(options: CommitizenGitOptions, type?: string): number
180202
* @description: get max subject length
181203
*/
182204
export function getMaxSubjectLength(type: Answers['type'],
183-
scope: Answers['scope'],
205+
scope: Answers['scope'] | Answers['customScope'],
184206
options: CommitizenGitOptions) {
185207
let optionMaxLength = Infinity
186208
if (Array.isArray(scope))
@@ -190,6 +212,7 @@ export function getMaxSubjectLength(type: Answers['type'],
190212
const emojiLength = options.useEmoji ? getEmojiStrLength(options, type) : 0
191213
const maxHeaderLength = options?.maxHeaderLength ? options?.maxHeaderLength : Infinity
192214
const maxSubjectLength = options?.maxSubjectLength ? options?.maxSubjectLength : Infinity
215+
193216
if (options?.maxHeaderLength === 0 || options?.maxSubjectLength === 0) {
194217
return 0
195218
}

0 commit comments

Comments
 (0)