From e4c0affa0f2fcab2e4fefec54c44a0a5ef5eaadb Mon Sep 17 00:00:00 2001 From: XPoet Date: Wed, 3 Aug 2022 16:39:58 +0800 Subject: [PATCH] fix: fixed invalid custom scopes --- .cz-config.js | 4 ++++ README.md | 3 +++ index.d.ts | 3 +++ lib/build-commit.js | 19 ++++++++++------- lib/questions.js | 52 ++++++++++++++++++++++++++------------------- 5 files changed, 51 insertions(+), 30 deletions(-) diff --git a/.cz-config.js b/.cz-config.js index 64014b1..8d68805 100644 --- a/.cz-config.js +++ b/.cz-config.js @@ -59,6 +59,10 @@ module.exports = { }, allowCustomScopes: true, + customScopesName: 'customScopes', + allowEmptyScopes: true, + emptyScopesName: 'emptyScopes', + allowBreakingChanges: ['feat', 'fix'], // skip any questions you want skipQuestions: ['body'], diff --git a/README.md b/README.md index 8e1d3db..43db38e 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,9 @@ Here are the options you can set in your `.cz-config.js`: } ``` * **allowCustomScopes**: {boolean, default false}: adds the option `custom` to scope selection so you can still type a scope if you need. +* **allowEmptyScopes**: {boolean, default false}: allow non-selection or not to fill in the scopes. +* **customScopesName**: {string, default 'custom scopes'}: custom scopes label in terminal scopes list. +* **emptyScopesName**: {string, default 'empty scopes'}: empty scopes label in terminal scopes list. * **allowBreakingChanges**: {Array of Strings: default none}. List of commit types you would like to the question `breaking change` prompted. Eg.: ['feat', 'fix']. * **skipQuestions**: {Array of Strings: default none}. List of questions you want to skip. Eg.: ['body', 'footer']. * **skipEmptyScopes**: {boolean, default false}: If a chosen type has no scopes declared, skip the scope question diff --git a/index.d.ts b/index.d.ts index c302607..56ed3b2 100644 --- a/index.d.ts +++ b/index.d.ts @@ -18,6 +18,9 @@ declare module "cz-customizable" { confirmCommit?: string, }; allowCustomScopes?: boolean; + customScopesName?: string; + allowEmptyScopes?: boolean; + emptyScopesName?: string; allowBreakingChanges?: string[]; skipQuestions?: string[]; appendBranchNameToCommitMessage?: boolean; diff --git a/lib/build-commit.js b/lib/build-commit.js index 84650f4..b9ac875 100644 --- a/lib/build-commit.js +++ b/lib/build-commit.js @@ -17,15 +17,21 @@ const addTicketNumber = (ticketNumber, config) => { return `${ticketNumber.trim()} `; }; -const addScope = (scope, config) => { +const addScope = (scope, customScope, config) => { const separator = _.get(config, 'subjectSeparator', defaultSubjectSeparator); - if (!scope) return separator; // it could be type === WIP. So there is no scope + if (customScope) { + scope = customScope; + } + + if (!scope || scope === 'empty') { + return separator; + } return `(${scope.trim()})${separator}`; }; -const addSubject = subject => _.trim(subject); +const addSubject = (subject) => _.trim(subject); const addType = (type, config) => { const prefix = _.get(config, 'typePrefix', ''); @@ -35,10 +41,7 @@ const addType = (type, config) => { }; const addBreaklinesIfNeeded = (value, breaklineChar = defaultBreaklineChar) => - value - .split(breaklineChar) - .join('\n') - .valueOf(); + value.split(breaklineChar).join('\n').valueOf(); const addFooter = (footer, config) => { if (config && config.footerPrefix === '') return `\n\n${footer}`; @@ -74,7 +77,7 @@ module.exports = (answers, config) => { // eslint-disable-next-line max-len const head = addType(answers.type, config) + - addScope(answers.scope, config) + + addScope(answers.scope, answers.customScope, config) + addTicketNumber(answers.ticketNumber, config) + addSubject(answers.subject.slice(0, config.subjectLimit)); diff --git a/lib/questions.js b/lib/questions.js index 5f4464b..8f129a2 100644 --- a/lib/questions.js +++ b/lib/questions.js @@ -3,7 +3,7 @@ const _ = require('lodash'); const buildCommit = require('./build-commit'); const log = require('./logger'); -const isNotWip = answers => answers.type.toLowerCase() !== 'wip'; +const isNotWip = (answers) => answers.type.toLowerCase() !== 'wip'; const isValidateTicketNo = (value, config) => { if (!value) { @@ -13,13 +13,10 @@ const isValidateTicketNo = (value, config) => { return true; } const reg = new RegExp(config.ticketNumberRegExp); - if (value.replace(reg, '') !== '') { - return false; - } - return true; + return value.replace(reg, '') === ''; }; -const getPreparedCommit = context => { +const getPreparedCommit = (context) => { let message = null; if (fs.existsSync('./.git/COMMIT_EDITMSG')) { let preparedCommit = fs.readFileSync('./.git/COMMIT_EDITMSG', 'utf-8'); @@ -81,39 +78,52 @@ module.exports = { message: messages.scope, choices(answers) { let scopes = []; + if (scopeOverrides[answers.type]) { scopes = scopes.concat(scopeOverrides[answers.type]); } else { scopes = scopes.concat(config.scopes); } + if (config.allowCustomScopes || scopes.length === 0) { scopes = scopes.concat([ new cz.Separator(), - { name: 'empty', value: false }, - { name: 'custom', value: 'custom' }, + { value: 'custom', name: config.customScopesName || 'custom scopes' }, ]); } + + if (config.allowEmptyScopes || scopes.length === 0) { + if (!config.allowCustomScopes) { + scopes = scopes.concat([new cz.Separator()]); + } + scopes = scopes.concat([{ value: 'empty', name: config.emptyScopesName || 'empty scopes' }]); + } + + if (config.allowCustomScopes || config.allowEmptyScopes) { + scopes = scopes.concat([new cz.Separator()]); + } + return scopes; }, when(answers) { let hasScope = false; + if (scopeOverrides[answers.type]) { - hasScope = !!(scopeOverrides[answers.type].length > 0); + hasScope = scopeOverrides[answers.type].length > 0; } else { - hasScope = !!(config.scopes && config.scopes.length > 0); + hasScope = config.scopes && config.scopes.length > 0; } + if (!hasScope) { - // TODO: Fix when possible - // eslint-disable-next-line no-param-reassign answers.scope = skipEmptyScopes ? '' : 'custom'; - return false; } - return isNotWip(answers); + + return hasScope && isNotWip(answers); }, }, { type: 'input', - name: 'scope', + name: 'customScope', message: messages.customScope, when(answers) { return answers.scope === 'custom'; @@ -160,13 +170,11 @@ module.exports = { message: messages.breaking, when(answers) { // eslint-disable-next-line max-len - if ( + return !!( config.askForBreakingChangeFirst || (config.allowBreakingChanges && config.allowBreakingChanges.indexOf(answers.type.toLowerCase()) >= 0) - ) { - return true; - } - return false; // no breaking changes allowed unless specifed + ); + // no breaking changes allowed unless specifed }, }, { @@ -192,10 +200,10 @@ module.exports = { }, ]; - questions = questions.filter(item => !skipQuestions.includes(item.name)); + questions = questions.filter((item) => !skipQuestions.includes(item.name)); if (config.askForBreakingChangeFirst) { - const isBreaking = oneQuestion => oneQuestion.name === 'breaking'; + const isBreaking = (oneQuestion) => oneQuestion.name === 'breaking'; const breakingQuestion = _.filter(questions, isBreaking); const questionWithoutBreaking = _.reject(questions, isBreaking);