Skip to content

Commit 7becb37

Browse files
Feature/read msg regex from config (#163)
* feat: make the message RegEx configurable * feat: add configurable merge RegEx * refactor --------- Co-authored-by: insurancer591 <148952341+insurancer591@users.noreply.github.com>
1 parent ea0a9a0 commit 7becb37

File tree

4 files changed

+52
-2
lines changed

4 files changed

+52
-2
lines changed

lib/commands/commandChangelog.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ exports.handler = async function (argv) {
6262
includeInvalidCommits: config.changelog.includeInvalidCommits,
6363
commitTypes: config.changelog.commitTypes,
6464
commitScopes: config.changelog.commitScopes,
65-
commitIgnoreRegex: new RegExp(config.changelog.commitIgnoreRegexPattern, "m")
65+
commitIgnoreRegex: config.changelog.commitIgnoreRegex(),
6666
});
6767

6868
// ------ output -------------------------------------------------

lib/commands/config.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,21 @@ function load(configFile) {
2626
const conventionOverride = configOverride.convention;
2727
conventionConfig.releaseTagGlobPattern = conventionOverride.releaseTagGlobPattern ||
2828
conventionConfig.releaseTagGlobPattern;
29+
30+
conventionConfig.msgRegex = RegExp(conventionOverride.commitMessageRegexPattern) || conventionConfig.msgRegex;
2931
conventionConfig.commitTypes = conventionOverride.commitTypes || conventionConfig.commitTypes;
3032
conventionConfig.featureCommitTypes = conventionOverride.featureCommitTypes || conventionConfig.featureCommitTypes;
3133
conventionConfig.commitScopes = conventionOverride.commitScopes || conventionConfig.commitScopes;
34+
3235
// Legacy support convention.issueRegexPattern
3336
config.changelog.issueRegexPattern = conventionOverride.issueRegexPattern || config.changelog.issueRegexPattern;
3437
}
3538

39+
// check for mandatory capturing groups
40+
if (!hasAllCapturingGroups(config.convention.msgRegex, ['type', 'scope', 'breaking', 'description'])) {
41+
throw new Error(`msgRegex: ${config.convention.msgRegex.source} does not have all mandatory capture groups ('type', 'scope', 'breaking', 'description')`);
42+
}
43+
3644
if (configOverride.changelog) {
3745
const changelogConfig = config.changelog;
3846
const changelogOverride = configOverride.changelog;
@@ -106,7 +114,7 @@ function defaultConfig() {
106114
// match only release version e.g. 1.2.3 ((?:[^-]|$) ignores pre-release versions e.g. 1.2.3-SNAPSHOT)
107115
config.convention.semanticVersionRegex = /(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/;
108116

109-
config.changelog.commitIgnoreRegex = () => RegExp(config.changelog.commitIgnoreRegexPattern || '(?!)');
117+
config.changelog.commitIgnoreRegex = () => RegExp(config.changelog.commitIgnoreRegexPattern || '(?!)',"m");
110118

111119
config.changelog.issueRegex = () => RegExp(
112120
"(?<=(^|\\s))" + (config.changelog.issueRegexPattern || '(?!)') + "(?=(\\s|$))",
@@ -116,9 +124,15 @@ function defaultConfig() {
116124
return config;
117125
}
118126

127+
128+
function hasAllCapturingGroups(exp, groups) {
129+
return groups.every(group => exp.source.includes(`(?<${group}>`));
130+
}
131+
119132
module.exports = {
120133
defaultPath,
121134
templatePath,
122135
load,
123136
defaultConfig,
137+
hasAllCapturingGroups
124138
}

lib/gitCommitConvention.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,13 @@ module.exports = function (convention, commitAnchor = 'HEAD') {
8787
const msgMatch = commit.subject.match(convention.msgRegex);
8888
if (msgMatch) {
8989
conventionalSubject.type = msgMatch.groups.type;
90+
if (!conventionalSubject.type)
91+
throw new Error(`Invalid msgRegex: ${convention.msgRegex}. Capturing group 'type' is empty.`);
9092
conventionalSubject.scope = msgMatch.groups.scope === '' ? undefined : msgMatch.groups.scope;
9193
conventionalSubject.breaking = msgMatch.groups.breaking === '!';
9294
conventionalSubject.description = msgMatch.groups.description;
95+
if (!conventionalSubject.description)
96+
throw new Error(`Invalid msgRegex: ${convention.msgRegex}. Capturing group 'description' is empty.`);
9397
} else {
9498
const msgMergeMatch = getFirstMatch(commit.subject, convention.msgMergeRegexList);
9599
if (msgMergeMatch) {

test/commands/config.test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const config = require("../../lib/commands/config");
2+
3+
4+
test("config - message RegEx", async () => {
5+
// GIVEN
6+
const requiredCaptureGroups = ['type', 'scope', 'breaking', 'description'];
7+
8+
9+
// WHEN
10+
const validMsgRegex = /^(?<type>\w+)(?:\((?<scope>[^()]+)\))?(?<breaking>!)?:\s*(?<description>.+)/i;
11+
const invalidMsgRegex = /(?:\((?<scope>[^()]+)\))?(?<breaking>!)?:\s*(?<description>.+)/i;
12+
13+
// THEN
14+
expect(config.hasAllCapturingGroups(validMsgRegex, requiredCaptureGroups)).toBe(true);
15+
expect(config.hasAllCapturingGroups(invalidMsgRegex, requiredCaptureGroups)).toBe(false);
16+
});
17+
18+
test("config - merge RegEx", async () => {
19+
// GIVEN
20+
const requiredCaptureGroups = ['description'];
21+
22+
23+
// WHEN
24+
const validMsgRegex = /^Merge (?<description>.+)/i;
25+
const invalidMsgRegex = /^Merge (?<type>.+)/i;
26+
27+
// THEN
28+
expect(config.hasAllCapturingGroups(validMsgRegex, requiredCaptureGroups)).toBe(true);
29+
expect(config.hasAllCapturingGroups(invalidMsgRegex, requiredCaptureGroups)).toBe(false);
30+
});
31+
32+

0 commit comments

Comments
 (0)