2017-01-19 19:24:47 -05:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
2017-01-23 16:03:40 -05:00
|
|
|
/**
|
|
|
|
* @license
|
|
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
|
|
* found in the LICENSE file at https://angular.io/license
|
|
|
|
*/
|
|
|
|
|
2017-01-19 19:24:47 -05:00
|
|
|
/**
|
|
|
|
* GIT commit message format enforcement
|
|
|
|
*
|
|
|
|
* Note: this script was originally written by Vojta for AngularJS :-)
|
|
|
|
*/
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
2019-08-06 13:17:17 -04:00
|
|
|
const config = require('./commit-message.json');
|
2019-08-06 13:24:10 -04:00
|
|
|
const FIXUP_PREFIX_RE = /^fixup! /i;
|
|
|
|
const SQUASH_PREFIX_RE = /^squash! /i;
|
2019-08-06 13:17:17 -04:00
|
|
|
const REVERT_PREFIX_RE = /^revert:? /i;
|
|
|
|
|
2019-08-06 13:24:10 -04:00
|
|
|
module.exports = (commitHeader, disallowSquash) => {
|
2019-08-06 13:17:17 -04:00
|
|
|
if (REVERT_PREFIX_RE.test(commitHeader)) {
|
2018-04-20 21:03:41 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-08-06 13:24:10 -04:00
|
|
|
const {header, type, scope, isSquash} = parseCommitHeader(commitHeader);
|
|
|
|
|
|
|
|
if (isSquash && disallowSquash) {
|
|
|
|
error('The commit must be manually squashed into the target commit', commitHeader);
|
|
|
|
return false;
|
|
|
|
}
|
2019-08-06 13:17:17 -04:00
|
|
|
|
|
|
|
if (header.length > config.maxLength) {
|
|
|
|
error(`The commit message header is longer than ${config.maxLength} characters`, commitHeader);
|
2017-01-19 19:24:47 -05:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-08-06 13:17:17 -04:00
|
|
|
if (!type) {
|
|
|
|
const format = '<type>(<scope>): <subject>';
|
2017-01-19 19:24:47 -05:00
|
|
|
error(
|
2019-08-06 13:17:17 -04:00
|
|
|
`The commit message header does not match the format of '${format}' or 'Revert: "${format}"'`,
|
|
|
|
commitHeader);
|
2017-01-19 19:24:47 -05:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-08-06 13:17:17 -04:00
|
|
|
if (!config.types.includes(type)) {
|
|
|
|
error(`'${type}' is not an allowed type.\n => TYPES: ${config.types.join(', ')}`, commitHeader);
|
2017-01-19 19:24:47 -05:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-08-06 13:17:17 -04:00
|
|
|
if (scope && !config.scopes.includes(scope)) {
|
2017-01-19 19:24:47 -05:00
|
|
|
error(
|
2019-08-06 13:17:17 -04:00
|
|
|
`'${scope}' is not an allowed scope.\n => SCOPES: ${config.scopes.join(', ')}`,
|
|
|
|
commitHeader);
|
2017-01-19 19:24:47 -05:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
2019-08-06 13:17:17 -04:00
|
|
|
module.exports.config = config;
|
|
|
|
|
|
|
|
// Helpers
|
|
|
|
function error(errorMessage, commitHeader) {
|
|
|
|
console.error(`INVALID COMMIT MSG: ${commitHeader}\n => ERROR: ${errorMessage}`);
|
2017-01-19 19:24:47 -05:00
|
|
|
}
|
2018-01-09 16:46:19 -05:00
|
|
|
|
2019-08-06 13:17:17 -04:00
|
|
|
function parseCommitHeader(header) {
|
2019-08-06 13:24:10 -04:00
|
|
|
const isFixup = FIXUP_PREFIX_RE.test(header);
|
|
|
|
const isSquash = SQUASH_PREFIX_RE.test(header);
|
|
|
|
header = header.replace(FIXUP_PREFIX_RE, '').replace(SQUASH_PREFIX_RE, '');
|
2019-08-06 13:17:17 -04:00
|
|
|
|
|
|
|
const match = /^(\w+)(?:\(([^)]+)\))?\: (.+)$/.exec(header) || [];
|
|
|
|
|
|
|
|
return {
|
|
|
|
header,
|
|
|
|
type: match[1],
|
|
|
|
scope: match[2],
|
2019-08-06 13:24:10 -04:00
|
|
|
subject: match[3], isFixup, isSquash,
|
2019-08-06 13:17:17 -04:00
|
|
|
};
|
|
|
|
}
|