From 3a4b4d05177d70f618bedbd8d755cc652d883909 Mon Sep 17 00:00:00 2001 From: Leonardo Correa Date: Thu, 4 Apr 2019 14:19:39 +1100 Subject: [PATCH] feat: add options subjectSeparator typePrefix and typeSuffix (#77) --- README.md | 6 +++- buildCommit.js | 43 +++++++++++++++++---------- package-lock.json | 4 ++- package.json | 1 + spec/buildCommitSpec.js | 65 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 101 insertions(+), 18 deletions(-) create mode 100644 spec/buildCommitSpec.js diff --git a/README.md b/README.md index 2f3bded..e3d6933 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,11 @@ Hopefully this will help you to have consistent commit messages and have a fully Here are the options you can set in your `.cz-config.js`: +* **subjectLimit**: {number, default 100}: This is the commit first line. Example: `feat: this is a new feature` or `feat(scopePayments): this is a new feature` +* **subjectSeparator**: {string, default ': '}: This is the subject separator. Example: `feat: this is a new feature` +* **typePrefix**: {string, default ''}: This is the commit type prefix. Example: config: `{ typePrefix: '[' }`, result: `[feat: this is a new feature` +* **typeSuffix**: {string, default ''}: This is the commit type suffix. Example: config: `{ typePrefix: '[', typeSuffix: ']', subjectSeparator: ' ' }`, result: `[feat] this is a new feature` + * **scopes**: {Array of Strings}: Specify the scopes for your particular project. Eg.: for some banking system: ["acccounts", "payments"]. For another travelling application: ["bookings", "search", "profile"] * **scopeOverrides**: {Object where key contains a Array of String}: Use this when you want to override scopes for a specific commit type. Example bellow specify scopes when type is `fix`: ``` @@ -78,7 +83,6 @@ Here are the options you can set in your `.cz-config.js`: ] } ``` -* **subjectLimit**: {number, default 100}: This is the commit first line. * **allowCustomScopes**: {boolean, default false}: adds the option `custom` to scope selection so you can still type a scope if you need. * **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']. diff --git a/buildCommit.js b/buildCommit.js index 0669035..24cb618 100644 --- a/buildCommit.js +++ b/buildCommit.js @@ -1,5 +1,9 @@ +const _ = require('lodash'); const wrap = require('word-wrap'); +const defaultSubjectSeparator = ': '; +const defaultMaxLineWidth = 100; + function addTicketNumber(ticketNumber, config) { if (!ticketNumber) { return ''; @@ -10,26 +14,33 @@ function addTicketNumber(ticketNumber, config) { return `${ticketNumber.trim()} `; } -module.exports = function buildCommit(answers, config) { - const maxLineWidth = 100; +function 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); +} + +function addType(type, config) { + const prefix = _.get(config, 'typePrefix', ''); + const suffix = _.get(config, 'typeSuffix', ''); + return _.trim(`${prefix}${type}${suffix}`); +} + +module.exports = function buildCommit(answers, config) { const wrapOptions = { trim: true, newline: '\n', indent: '', - width: maxLineWidth, + width: defaultMaxLineWidth, }; - function addScope(scope) { - if (!scope) return ': '; // it could be type === WIP. So there is no scope - - return `(${scope.trim()}): `; - } - - function addSubject(subject) { - return subject.trim(); - } - function escapeSpecialChars(result) { // eslint-disable-next-line no-useless-escape const specialChars = ['`']; @@ -47,11 +58,11 @@ module.exports = function buildCommit(answers, config) { // Hard limit this line // eslint-disable-next-line max-len const head = ( - answers.type + - addScope(answers.scope) + + addType(answers.type, config) + + addScope(answers.scope, config) + addTicketNumber(answers.ticketNumber, config) + addSubject(answers.subject) - ).slice(0, maxLineWidth); + ).slice(0, defaultMaxLineWidth); // Wrap these lines at 100 characters let body = wrap(answers.body, wrapOptions) || ''; diff --git a/package-lock.json b/package-lock.json index ed96cbc..3fe78a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1427,6 +1427,7 @@ "resolved": "http://registry.npmjs.org/boom/-/boom-0.4.2.tgz", "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", "dev": true, + "optional": true, "requires": { "hoek": "0.9.x" } @@ -3550,7 +3551,8 @@ "version": "0.9.1", "resolved": "http://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=", - "dev": true + "dev": true, + "optional": true }, "home-or-tmp": { "version": "3.0.0", diff --git a/package.json b/package.json index 174b1be..9b740be 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "editor": "1.0.0", "find-config": "^1.0.0", "inquirer": "^6.2.2", + "lodash": "^4.17.11", "temp": "^0.9.0", "word-wrap": "^1.2.3" }, diff --git a/spec/buildCommitSpec.js b/spec/buildCommitSpec.js new file mode 100644 index 0000000..84b542e --- /dev/null +++ b/spec/buildCommitSpec.js @@ -0,0 +1,65 @@ +const buildCommit = require('../buildCommit'); + +describe('buildCommit()', () => { + const answers = { + type: 'feat', + scope: 'app', + subject: 'this is a new feature', + }; + + it('subject with default subject separator', () => { + const options = {}; + expect(buildCommit(answers, options)).toEqual('feat(app): this is a new feature'); + }); + + it('subject with custom subject separator option', () => { + const options = { + subjectSeparator: ' - ', + }; + expect(buildCommit(answers, options)).toEqual('feat(app) - this is a new feature'); + }); + + it('subject 1 empty character separator', () => { + const options = { + subjectSeparator: ' ', + }; + expect(buildCommit(answers, options)).toEqual('feat(app) this is a new feature'); + }); + + describe('without scope', () => { + it('subject without scope', () => { + const answersNoScope = { + type: 'feat', + subject: 'this is a new feature', + }; + const options = {}; + expect(buildCommit(answersNoScope, options)).toEqual('feat: this is a new feature'); + }); + + it('subject without scope', () => { + const answersNoScope = { + type: 'feat', + subject: 'this is a new feature', + }; + const options = { + subjectSeparator: ' - ', + }; + expect(buildCommit(answersNoScope, options)).toEqual('feat - this is a new feature'); + }); + }); + + describe('type prefix and type suffix', () => { + it('subject with both', () => { + const answersNoScope = { + type: 'feat', + subject: 'this is a new feature', + }; + const options = { + typePrefix: '[', + typeSuffix: ']', + subjectSeparator: ' ', + }; + expect(buildCommit(answersNoScope, options)).toEqual('[feat] this is a new feature'); + }); + }); +});