diff --git a/src/prompt/LimitedInput.js b/src/LimitedInput.js similarity index 100% rename from src/prompt/LimitedInput.js rename to src/LimitedInput.js diff --git a/src/createPrompter.js b/src/createPrompter.js new file mode 100644 index 00000000..8e580012 --- /dev/null +++ b/src/createPrompter.js @@ -0,0 +1,83 @@ +const fs = require('fs'); +const inquirer = require('inquirer'); +const wrap = require('word-wrap'); +const appRoot = require('app-root-path'); +const { + createPackagesQuestion, + createQuestions +} = require('./questions'); +const LimitedInput = require('./LimitedInput'); +const { + getAllPackages, + getChangedPackages +} = require('./lernaUtils'); + +const MAX_LINE_WIDTH = 72; + +inquirer.registerPrompt('limitedInput', LimitedInput); + +const IS_LERNA_PROJECT = fs.existsSync(appRoot.resolve('lerna.json')); + +const makeAffectsLine = function (answers) { + const selectedPackages = answers.packages; + + if (selectedPackages && selectedPackages.length) { + return `\naffects: ${selectedPackages.join(', ')}`; + } + + return ''; +}; + +module.exports = (config) => { + const prompter = { + prompter (cz, commit) { + let promptQuestions = createQuestions(config); + + if (IS_LERNA_PROJECT) { + const allPackages = getAllPackages().map((pkg) => pkg.name); + const changedPackages = getChangedPackages(); + + promptQuestions = promptQuestions.concat(createPackagesQuestion(allPackages, changedPackages)); + } + + return inquirer.prompt(promptQuestions) + .then((answers) => { + const wrapOptions = { + indent: '', + trim: true, + width: MAX_LINE_WIDTH + }; + + const emoji = config.types[answers.type].emoji; + const emojiPrefix = emoji ? emoji + ' ' : ''; + const head = answers.type + ': ' + emojiPrefix + answers.subject; + const affectsLine = makeAffectsLine(answers); + + // Wrap these lines at MAX_LINE_WIDTH character + const body = wrap(answers.body + affectsLine, wrapOptions); + const breaking = wrap(answers.breaking, wrapOptions); + const footer = wrap(answers.footer, wrapOptions); + + let msg; + + msg = head; + + if (body) { + msg += '\n\n' + body; + } + + if (breaking) { + msg += '\n\nBREAKING CHANGE: ' + breaking; + } + + if (footer) { + msg += '\n\nIssues: ' + footer; + } + + return commit(msg); + }); + } + }; + + return prompter; +}; diff --git a/src/index.js b/src/index.js index cdb8bec2..fb18ce48 100644 --- a/src/index.js +++ b/src/index.js @@ -1,80 +1,4 @@ -const fs = require('fs'); -const inquirer = require('inquirer'); -const wrap = require('word-wrap'); -const appRoot = require('app-root-path'); -const defaults = require('./defaults'); -const { - makePackagesQuestion, - questions -} = require('./prompt/questions'); -const LimitedInput = require('./prompt/LimitedInput'); -const { - getAllPackages, - getChangedPackages -} = require('./lernaUtils'); +const createPrompter = require('./createPrompter'); +const config = require('./defaults'); -const MAX_LINE_WIDTH = 72; - -inquirer.registerPrompt('limitedInput', LimitedInput); - -const IS_LERNA_PROJECT = fs.existsSync(appRoot.resolve('lerna.json')); - -const makeAffectsLine = function (answers) { - const selectedPackages = answers.packages; - - if (selectedPackages && selectedPackages.length) { - return `\naffects: ${selectedPackages.join(', ')}`; - } - - return ''; -}; - -module.exports = { - prompter (cz, commit) { - let promptQuestions = questions; - - if (IS_LERNA_PROJECT) { - const allPackages = getAllPackages().map((pkg) => pkg.name); - const changedPackages = getChangedPackages(); - - promptQuestions = promptQuestions.concat(makePackagesQuestion(allPackages, changedPackages)); - } - - return inquirer.prompt(promptQuestions) - .then((answers) => { - const wrapOptions = { - indent: '', - trim: true, - width: MAX_LINE_WIDTH - }; - - const emoji = defaults.types[answers.type].emoji; - const emojiPrefix = emoji ? emoji + ' ' : ''; - const head = answers.type + ': ' + emojiPrefix + answers.subject; - const affectsLine = makeAffectsLine(answers); - - // Wrap these lines at MAX_LINE_WIDTH character - const body = wrap(answers.body + affectsLine, wrapOptions); - const breaking = wrap(answers.breaking, wrapOptions); - const footer = wrap(answers.footer, wrapOptions); - - let msg; - - msg = head; - - if (body) { - msg += '\n\n' + body; - } - - if (breaking) { - msg += '\n\nBREAKING CHANGE: ' + breaking; - } - - if (footer) { - msg += '\n\nIssues: ' + footer; - } - - return commit(msg); - }); - } -}; +module.exports = createPrompter(config); diff --git a/src/prompt/questions.js b/src/prompt/questions.js deleted file mode 100644 index 66d25120..00000000 --- a/src/prompt/questions.js +++ /dev/null @@ -1,68 +0,0 @@ -const pad = require('pad-right'); -const defaults = require('../defaults'); - -const MAX_SUBJECT_LENGTH = defaults.maxMessageLength; -const MIN_SUBJECT_LENGTH = defaults.minMessageLength; -const MIN_SUBJECT_LENGTH_ERROR_MESSAGE = `The subject must have at least ${MIN_SUBJECT_LENGTH} characters`; - -const typeToListItem = ({description, emoji, value}) => ({ - name: (emoji || '❔') + ' ' + pad(value + ':', 12, ' ') + description, - value -}); - -const questions = [ - { - choices: defaults.list.map((type) => typeToListItem(defaults.types[type])), - message: 'Select the type of change that you\'re committing:', - name: 'type', - type: 'list' - }, - { - filter: (input) => { - let subject; - - subject = input.trim(); - while (subject.endsWith('.')) { - subject = subject.substr(0, subject.length - 1).trim(); - } - - return subject; - }, - leadingLabel: (answers) => `${answers.type}:`, - - // Minus 3 chars are for emoji + space. - maxLength: MAX_SUBJECT_LENGTH - 3, - message: 'Write a short, imperative mood description of the change:', - name: 'subject', - type: 'limitedInput', - validate: (input) => input.length >= MIN_SUBJECT_LENGTH || MIN_SUBJECT_LENGTH_ERROR_MESSAGE - }, - { - message: 'Provide a longer description of the change:\n', - name: 'body', - type: 'input' - }, - { - message: 'List any breaking changes:\n BREAKING CHANGE:', - name: 'breaking', - type: 'input' - }, - { - message: 'Reference any task that this commit closes:\n Issues:', - name: 'footer', - type: 'input' - } -]; - -const makePackagesQuestion = (allPackages, changedPackages) => ({ - choices: allPackages, - default: changedPackages, - message: `The packages that this commit has affected (${changedPackages.length} detected)\n`, - name: 'packages', - type: 'checkbox' -}); - -module.exports = { - makePackagesQuestion, - questions -}; diff --git a/src/questions.js b/src/questions.js new file mode 100644 index 00000000..290d8a15 --- /dev/null +++ b/src/questions.js @@ -0,0 +1,68 @@ +const pad = require('pad-right'); + +const typeToListItem = ({description, emoji, value}) => ({ + name: (emoji || '❔') + ' ' + pad(value + ':', 12, ' ') + description, + value +}); + +const createQuestions = (config) => { + const MIN_SUBJECT_LENGTH_ERROR_MESSAGE = `The subject must have at least ${config.minMessageLength} characters`; + const questions = [ + { + choices: config.list.map((type) => typeToListItem(config.types[type])), + message: 'Select the type of change that you\'re committing:', + name: 'type', + type: 'list' + }, + { + filter: (input) => { + let subject; + + subject = input.trim(); + while (subject.endsWith('.')) { + subject = subject.substr(0, subject.length - 1).trim(); + } + + return subject; + }, + leadingLabel: (answers) => `${answers.type}:`, + + // Minus 3 chars are for emoji + space. + maxLength: config.maxMessageLength - 3, + message: 'Write a short, imperative mood description of the change:', + name: 'subject', + type: 'limitedInput', + validate: (input) => input.length >= config.minMessageLength || MIN_SUBJECT_LENGTH_ERROR_MESSAGE + }, + { + message: 'Provide a longer description of the change:\n', + name: 'body', + type: 'input' + }, + { + message: 'List any breaking changes:\n BREAKING CHANGE:', + name: 'breaking', + type: 'input' + }, + { + message: 'Reference any task that this commit closes:\n Issues:', + name: 'footer', + type: 'input' + } + ]; + + return questions; +}; + +const createPackagesQuestion = (allPackages, changedPackages) => ({ + choices: allPackages, + default: changedPackages, + message: `The packages that this commit has affected (${changedPackages.length} detected)\n`, + name: 'packages', + type: 'checkbox' +}); + +module.exports = { + createPackagesQuestion, + createQuestions +};