refactor: clean up `validate-commit-message` script (#32023)
This sets the ground for adding stricter rules for fixup commits in a follow-up PR. PR Close #32023
This commit is contained in:
parent
ddd02044ea
commit
2b289250d8
|
@ -16,55 +16,62 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const fs = require('fs');
|
const config = require('./commit-message.json');
|
||||||
const path = require('path');
|
const FIXUP_SQUASH_PREFIX_RE = /^(?:fixup|squash)! /i;
|
||||||
const configPath = path.resolve(__dirname, './commit-message.json');
|
const REVERT_PREFIX_RE = /^revert:? /i;
|
||||||
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
||||||
const PATTERN = /^(\w+)(?:\(([^)]+)\))?\: (.+)$/;
|
|
||||||
const FIXUP_SQUASH = /^(fixup|squash)\! /i;
|
|
||||||
const REVERT = /^revert:? /i;
|
|
||||||
|
|
||||||
module.exports = function(commitSubject) {
|
module.exports = commitHeader => {
|
||||||
const subject = commitSubject.replace(FIXUP_SQUASH, '');
|
if (REVERT_PREFIX_RE.test(commitHeader)) {
|
||||||
|
|
||||||
if (subject.match(REVERT)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subject.length > config['maxLength']) {
|
const {header, type, scope} = parseCommitHeader(commitHeader);
|
||||||
error(`The commit message is longer than ${config['maxLength']} characters`, commitSubject);
|
|
||||||
|
if (header.length > config.maxLength) {
|
||||||
|
error(`The commit message header is longer than ${config.maxLength} characters`, commitHeader);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const match = PATTERN.exec(subject);
|
if (!type) {
|
||||||
if (!match) {
|
const format = '<type>(<scope>): <subject>';
|
||||||
error(
|
error(
|
||||||
`The commit message does not match the format of '<type>(<scope>): <subject>' OR 'Revert: "type(<scope>): <subject>"'`,
|
`The commit message header does not match the format of '${format}' or 'Revert: "${format}"'`,
|
||||||
commitSubject);
|
commitHeader);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const type = match[1];
|
if (!config.types.includes(type)) {
|
||||||
if (config['types'].indexOf(type) === -1) {
|
error(`'${type}' is not an allowed type.\n => TYPES: ${config.types.join(', ')}`, commitHeader);
|
||||||
error(
|
|
||||||
`${type} is not an allowed type.\n => TYPES: ${config['types'].join(', ')}`, commitSubject);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const scope = match[2];
|
if (scope && !config.scopes.includes(scope)) {
|
||||||
|
|
||||||
if (scope && !config['scopes'].includes(scope)) {
|
|
||||||
error(
|
error(
|
||||||
`"${scope}" is not an allowed scope.\n => SCOPES: ${config['scopes'].join(', ')}`,
|
`'${scope}' is not an allowed scope.\n => SCOPES: ${config.scopes.join(', ')}`,
|
||||||
commitSubject);
|
commitHeader);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
function error(errorMessage, commitMessage) {
|
module.exports.config = config;
|
||||||
console.error(`INVALID COMMIT MSG: "${commitMessage}"\n => ERROR: ${errorMessage}`);
|
|
||||||
|
// Helpers
|
||||||
|
function error(errorMessage, commitHeader) {
|
||||||
|
console.error(`INVALID COMMIT MSG: ${commitHeader}\n => ERROR: ${errorMessage}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.config = config;
|
function parseCommitHeader(header) {
|
||||||
|
const isFixupOrSquash = FIXUP_SQUASH_PREFIX_RE.test(header);
|
||||||
|
header = header.replace(FIXUP_SQUASH_PREFIX_RE, '');
|
||||||
|
|
||||||
|
const match = /^(\w+)(?:\(([^)]+)\))?\: (.+)$/.exec(header) || [];
|
||||||
|
|
||||||
|
return {
|
||||||
|
header,
|
||||||
|
type: match[1],
|
||||||
|
scope: match[2],
|
||||||
|
subject: match[3], isFixupOrSquash,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ describe('validate-commit-message.js', () => {
|
||||||
|
|
||||||
expect(validateMessage(msg)).toBe(INVALID);
|
expect(validateMessage(msg)).toBe(INVALID);
|
||||||
expect(errors).toEqual([
|
expect(errors).toEqual([
|
||||||
`INVALID COMMIT MSG: "${msg}"\n => ERROR: The commit message is longer than 120 characters`
|
`INVALID COMMIT MSG: ${msg}\n => ERROR: The commit message header is longer than 120 characters`
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ describe('validate-commit-message.js', () => {
|
||||||
|
|
||||||
expect(validateMessage(msg)).toBe(INVALID);
|
expect(validateMessage(msg)).toBe(INVALID);
|
||||||
expect(errors).toEqual([
|
expect(errors).toEqual([
|
||||||
`INVALID COMMIT MSG: "${msg}"\n => ERROR: The commit message does not match the format of '<type>(<scope>): <subject>' OR 'Revert: "type(<scope>): <subject>"'`,
|
`INVALID COMMIT MSG: ${msg}\n => ERROR: The commit message header does not match the format of '<type>(<scope>): <subject>' or 'Revert: "<type>(<scope>): <subject>"'`,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -76,13 +76,13 @@ describe('validate-commit-message.js', () => {
|
||||||
|
|
||||||
expect(validateMessage(msg)).toBe(INVALID);
|
expect(validateMessage(msg)).toBe(INVALID);
|
||||||
expect(errors).toEqual([
|
expect(errors).toEqual([
|
||||||
`INVALID COMMIT MSG: "${msg}"\n => ERROR: weird is not an allowed type.\n => TYPES: ${TYPES}`,
|
`INVALID COMMIT MSG: ${msg}\n => ERROR: 'weird' is not an allowed type.\n => TYPES: ${TYPES}`,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail when scope is invalid', () => {
|
it('should fail when scope is invalid', () => {
|
||||||
const errorMessageFor = (scope, header) =>
|
const errorMessageFor = (scope, header) =>
|
||||||
`INVALID COMMIT MSG: "${header}"\n => ERROR: "${scope}" is not an allowed scope.\n => SCOPES: ${SCOPES}`;
|
`INVALID COMMIT MSG: ${header}\n => ERROR: '${scope}' is not an allowed scope.\n => SCOPES: ${SCOPES}`;
|
||||||
|
|
||||||
expect(validateMessage('fix(Compiler): something')).toBe(INVALID);
|
expect(validateMessage('fix(Compiler): something')).toBe(INVALID);
|
||||||
expect(validateMessage('feat(bah): something')).toBe(INVALID);
|
expect(validateMessage('feat(bah): something')).toBe(INVALID);
|
||||||
|
@ -112,7 +112,7 @@ describe('validate-commit-message.js', () => {
|
||||||
|
|
||||||
expect(validateMessage(msg)).toBe(INVALID);
|
expect(validateMessage(msg)).toBe(INVALID);
|
||||||
expect(errors).toEqual([
|
expect(errors).toEqual([
|
||||||
`INVALID COMMIT MSG: "${msg}"\n => ERROR: WIP is not an allowed type.\n => TYPES: ${TYPES}`,
|
`INVALID COMMIT MSG: ${msg}\n => ERROR: 'WIP' is not an allowed type.\n => TYPES: ${TYPES}`,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ describe('validate-commit-message.js', () => {
|
||||||
|
|
||||||
expect(validateMessage(msg)).toBe(INVALID);
|
expect(validateMessage(msg)).toBe(INVALID);
|
||||||
expect(errors).toEqual([
|
expect(errors).toEqual([
|
||||||
`INVALID COMMIT MSG: "${msg}"\n => ERROR: revert is not an allowed type.\n => TYPES: ${TYPES}`,
|
`INVALID COMMIT MSG: ${msg}\n => ERROR: 'revert' is not an allowed type.\n => TYPES: ${TYPES}`,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue