diff --git a/lib/cli.js b/lib/cli.js index c3d7b5d6..a4d545d4 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -9,6 +9,7 @@ const runInteractiveQuestions = require('./runInteractiveQuestions'); const runNonInteractiveMode = require('./runNonInteractiveMode'); const formatCommitMessage = require('./formatCommitMessage'); const getGitDir = require('./util/getGitDir'); +const ObjectBuilder = require('./util/ObjectBuilder'); // eslint-disable-next-line no-process-env const executeCommand = (command, env = process.env) => { @@ -31,11 +32,12 @@ const main = async () => { let state = null; - if (cliOptions.disableEmoji) { - state = createState({disableEmoji: cliOptions.disableEmoji}); - } else { - state = createState(); - } + const configFromFlags = new ObjectBuilder() + .if(cliOptions.disableEmoji).add({disableEmoji: true}) + .if(cliOptions.breaking).add({showBreakingChangeQuestion: true}) + .build(); + + state = createState(configFromFlags); if (cliOptions.dryRun) { // eslint-disable-next-line no-console diff --git a/lib/createState.js b/lib/createState.js index bc21af93..8c2f0c46 100644 --- a/lib/createState.js +++ b/lib/createState.js @@ -4,12 +4,22 @@ const getConfig = require('./getConfig'); const createState = (config = {}) => { let root; + const showBreakingChangeQuestion = config.showBreakingChangeQuestion; + delete config.showBreakingChangeQuestion; + try { root = getGitRootDir(); } catch (error) { throw new Error('Could not find Git root folder.'); } + const userConfig = getConfig(root); + const missingBreakingChangeQuestion = !userConfig.questions.includes('breaking'); + + if (showBreakingChangeQuestion && missingBreakingChangeQuestion) { + userConfig.questions.push('breaking'); + } + const state = { answers: { body: '', @@ -21,7 +31,7 @@ const createState = (config = {}) => { type: '' }, config: { - ...getConfig(root), + ...userConfig, ...config }, root diff --git a/lib/parseArgs.js b/lib/parseArgs.js index 503171c1..0aadc253 100644 --- a/lib/parseArgs.js +++ b/lib/parseArgs.js @@ -26,6 +26,18 @@ const helpScreen = ` --lerna Lerna mono-repo packages this commit affects `; +/** If the value is empty the flag is true and the answer is undefined, + * in any other case the flag is false and the answer is the value. + * + * @param {string} value + * @returns {[boolean, string]} + * */ +const flagAndAnswerValues = (value) => { + const isFlagActive = value === ''; + + return [isFlagActive, isFlagActive ? undefined : value]; +}; + const parseArgs = () => { const { // eslint-disable-next-line no-unused-vars @@ -82,7 +94,10 @@ const parseArgs = () => { process.exit(); } + const [breakingChangeFlag, breakingChangeValue] = flagAndAnswerValues(breaking); + const cliOptions = { + breaking: breakingChangeFlag, disableEmoji, dryRun, format, @@ -94,7 +109,7 @@ const parseArgs = () => { const cliAnswers = { body, - breaking, + breaking: breakingChangeValue, issues, lerna, scope, diff --git a/lib/util/ObjectBuilder.js b/lib/util/ObjectBuilder.js new file mode 100644 index 00000000..244525ca --- /dev/null +++ b/lib/util/ObjectBuilder.js @@ -0,0 +1,40 @@ +class ObjectBuilder { + constructor (initial) { + this.currentObject = initial || {}; + } + + /** + * @param {boolean} condition + * @returns {{ add: ConditionalObjectBuilder["add"] }} + */ + if (condition) { + return { + add: (mappedValues) => { + if (condition) { + return this.add(mappedValues); + } + + return this; + } + }; + } + + /** + * @param {{ [key: string]: value }} mappedValues + * @returns {ConditionalObjectBuilder} + */ + add (mappedValues) { + Object.keys(mappedValues) + .forEach((key) => { + this.currentObject[key] = mappedValues[key]; + }); + + return this; + } + + build () { + return this.currentObject; + } +} + +module.exports = ObjectBuilder;