diff --git a/README.md b/README.md index c579ca7..2fd4ba3 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ Here are the options you can set in your `.cz-config.js`: * **ticketNumberPrefix**: {string, default 'ISSUES CLOSED:'}: Set custom prefix for footer ticker number. * **breakingPrefix**: {string, default 'BREAKING CHANGE:'}: Set a custom prefix for the breaking change block in commit messages. * **footerPrefix**: {string, default 'ISSUES CLOSED:'}: Set a custom prefix for the footer block in commit messages. Set to empty string to remove prefix. +* **breaklineChar**: {string, default '|'}: It gets replaced with \n to create the breakline in your commit message. This is supported for fields `body` and `footer` at the moment. ## Related tools - (https://github.com/commitizen/cz-cli) diff --git a/buildCommit.js b/buildCommit.js index 2c8193e..d1288db 100644 --- a/buildCommit.js +++ b/buildCommit.js @@ -3,8 +3,9 @@ const wrap = require('word-wrap'); const defaultSubjectSeparator = ': '; const defaultMaxLineWidth = 100; +const defaultBreaklineChar = '|'; -function addTicketNumber(ticketNumber, config) { +const addTicketNumber = (ticketNumber, config) => { if (!ticketNumber) { return ''; } @@ -12,35 +13,54 @@ function addTicketNumber(ticketNumber, config) { return `${config.ticketNumberPrefix + ticketNumber.trim()} `; } return `${ticketNumber.trim()} `; -} +}; -function addScope(scope, config) { +const addScope = (scope, config) => { const separator = _.get(config, 'subjectSeparator', defaultSubjectSeparator); if (!scope) return separator; // it could be type === WIP. So there is no scope return `(${scope.trim()})${separator}`; -} +}; -function addSubject(subject) { - return _.trim(subject); -} +const addSubject = subject => _.trim(subject); -function addType(type, config) { +const addType = (type, config) => { const prefix = _.get(config, 'typePrefix', ''); const suffix = _.get(config, 'typeSuffix', ''); return _.trim(`${prefix}${type}${suffix}`); -} +}; -function addFooter(footer, config) { +const addBreaklinesIfNeeded = (value, breaklineChar = defaultBreaklineChar) => + value + .split(breaklineChar) + .join('\n') + .valueOf(); + +const addFooter = (footer, config) => { if (config && config.footerPrefix === '') return `\n\n${footer}`; const footerPrefix = config && config.footerPrefix ? config.footerPrefix : 'ISSUES CLOSED:'; - return `\n\n${footerPrefix} ${footer}`; -} -module.exports = function buildCommit(answers, config) { + return `\n\n${footerPrefix} ${addBreaklinesIfNeeded(footer, config.breaklineChar)}`; +}; + +const escapeSpecialChars = result => { + // eslint-disable-next-line no-useless-escape + const specialChars = ['`']; + + let newResult = result; + // eslint-disable-next-line array-callback-return + specialChars.map(item => { + // If user types "feat: `string`", the commit preview should show "feat: `\string\`". + // Don't worry. The git log will be "feat: `string`" + newResult = result.replace(new RegExp(item, 'g'), '\\`'); + }); + return newResult; +}; + +module.exports = (answers, config) => { const wrapOptions = { trim: true, newline: '\n', @@ -48,20 +68,6 @@ module.exports = function buildCommit(answers, config) { width: defaultMaxLineWidth, }; - function escapeSpecialChars(result) { - // eslint-disable-next-line no-useless-escape - const specialChars = ['`']; - - let newResult = result; - // eslint-disable-next-line array-callback-return - specialChars.map(item => { - // If user types "feat: `string`", the commit preview should show "feat: `\string\`". - // Don't worry. The git log will be "feat: `string`" - newResult = result.replace(new RegExp(item, 'g'), '\\`'); - }); - return newResult; - } - // Hard limit this line // eslint-disable-next-line max-len const head = ( @@ -73,7 +79,7 @@ module.exports = function buildCommit(answers, config) { // Wrap these lines at 100 characters let body = wrap(answers.body, wrapOptions) || ''; - body = body.split('|').join('\n'); + body = addBreaklinesIfNeeded(body, config.breaklineChar); const breaking = wrap(answers.breaking, wrapOptions); const footer = wrap(answers.footer, wrapOptions); diff --git a/cz-config-EXAMPLE.js b/cz-config-EXAMPLE.js index 8844f1b..7b5fb33 100644 --- a/cz-config-EXAMPLE.js +++ b/cz-config-EXAMPLE.js @@ -65,4 +65,6 @@ module.exports = { // limit subject length subjectLimit: 100, + // breaklineChar: '|', // It is supported for fields body and footer. + // footerPrefix : 'ISSUES CLOSED:', // default value }; diff --git a/index.js b/index.js index 8244d38..6dbc847 100755 --- a/index.js +++ b/index.js @@ -14,7 +14,7 @@ const log = require('./logger'); const buildCommit = require('./buildCommit'); /* istanbul ignore next */ -function readConfigFile() { +const readConfigFile = () => { // First try to find the .cz-config.js config file const czConfig = findConfig.require(CZ_CONFIG_NAME, { home: false }); @@ -43,7 +43,7 @@ function readConfigFile() { 'Unable to find a configuration file. Please refer to documentation to learn how to ser up: https://github.com/leonardoanalista/cz-customizable#steps "' ); return null; -} +}; module.exports = { prompter(cz, commit) { diff --git a/questions.js b/questions.js index f21e6d4..f6f540e 100644 --- a/questions.js +++ b/questions.js @@ -3,7 +3,7 @@ const log = require('./logger'); const isNotWip = answers => answers.type.toLowerCase() !== 'wip'; -function isValidateTicketNo(value, config) { +const isValidateTicketNo = (value, config) => { if (!value) { return !config.isTicketNumberRequired; } @@ -15,7 +15,7 @@ function isValidateTicketNo(value, config) { return false; } return true; -} +}; module.exports = { getQuestions(config, cz) { diff --git a/spec/buildCommitSpec.js b/spec/buildCommitSpec.js index 84b542e..fc21ebd 100644 --- a/spec/buildCommitSpec.js +++ b/spec/buildCommitSpec.js @@ -62,4 +62,40 @@ describe('buildCommit()', () => { expect(buildCommit(answersNoScope, options)).toEqual('[feat] this is a new feature'); }); }); + + describe('pipe replaced with new line', () => { + // I know it looks weird on tests but this proves to have the correct breakline inserted. + const expecteMessage = `feat: this is a new feature\n +body with new line now +body line2 + +ISSUES CLOSED: footer with new line +line 2`; + + it('should add breakline for body and footer', () => { + const answersNoScope = { + type: 'feat', + subject: 'this is a new feature', + body: 'body with new line now|body line2', + footer: 'footer with new line|line 2', + }; + const options = {}; + + expect(buildCommit(answersNoScope, options)).toEqual(expecteMessage); + }); + + it('should override breakline character with option breaklineChar', () => { + const answersNoScope = { + type: 'feat', + subject: 'this is a new feature', + body: 'body with new line now@@@body line2', + footer: 'footer with new line@@@line 2', + }; + const options = { + breaklineChar: '@@@', + }; + + expect(buildCommit(answersNoScope, options)).toEqual(expecteMessage); + }); + }); });