George Kalpakas 364284b0dc fix(dev-infra): ignore comments when validating commit messages (#38438)
When creating a commit with the git cli, git pre-populates the editor
used to enter the commit message with some comments (i.e. lines starting
with `#`). These comments contain helpful instructions or information
regarding the changes that are part of the commit. As happens with all
commit message comments, they are removed by git and do not end up in
the final commit message.

However, the file that is passed to the `commit-msg` to be validated
still contains these comments. This may affect the outcome of the commit
message validation. In such cases, the author will not realize that the
commit message is not in the desired format until the linting checks
fail on CI (which validates the final commit messages and is not
affected by this issue), usually several minutes later.

Possible ways in which the commit message validation outcome can be
affected:
- The minimum body length check may pass incorrectly, even if there is
  no actual body, because the comments are counted as part of the body.
- The maximum line length check may fail incorrectly due to a very long
  line in the comments.

This commit fixes the problem by removing comment lines before
validating a commit message.

Fixes #37865

PR Close #38438
2020-08-21 12:17:14 -07:00

106 lines
3.6 KiB
TypeScript

/**
* @license
* Copyright Google LLC 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
*/
import {parseCommitMessage, ParsedCommitMessage} from './parse';
const commitValues = {
prefix: '',
type: 'fix',
scope: 'changed-area',
summary: 'This is a short summary of the change',
body: 'This is a longer description of the change Closes #1',
};
function buildCommitMessage(params = {}) {
const {prefix, type, scope, summary, body} = {...commitValues, ...params};
return `${prefix}${type}${scope ? '(' + scope + ')' : ''}: ${summary}\n\n${body}`;
}
describe('commit message parsing:', () => {
it('parses the scope', () => {
const message = buildCommitMessage();
expect(parseCommitMessage(message).scope).toBe(commitValues.scope);
});
it('parses the type', () => {
const message = buildCommitMessage();
expect(parseCommitMessage(message).type).toBe(commitValues.type);
});
it('parses the header', () => {
const message = buildCommitMessage();
expect(parseCommitMessage(message).header)
.toBe(`${commitValues.type}(${commitValues.scope}): ${commitValues.summary}`);
});
it('parses the body', () => {
const message = buildCommitMessage();
expect(parseCommitMessage(message).body).toBe(commitValues.body);
});
it('parses the body without Github linking', () => {
const body = 'This has linking\nCloses #1';
const message = buildCommitMessage({body});
expect(parseCommitMessage(message).bodyWithoutLinking).toBe('This has linking\n');
});
it('parses the subject', () => {
const message = buildCommitMessage();
expect(parseCommitMessage(message).subject).toBe(commitValues.summary);
});
it('identifies if a commit is a fixup', () => {
const message1 = buildCommitMessage();
expect(parseCommitMessage(message1).isFixup).toBe(false);
const message2 = buildCommitMessage({prefix: 'fixup! '});
expect(parseCommitMessage(message2).isFixup).toBe(true);
});
it('identifies if a commit is a revert', () => {
const message1 = buildCommitMessage();
expect(parseCommitMessage(message1).isRevert).toBe(false);
const message2 = buildCommitMessage({prefix: 'revert: '});
expect(parseCommitMessage(message2).isRevert).toBe(true);
const message3 = buildCommitMessage({prefix: 'revert '});
expect(parseCommitMessage(message3).isRevert).toBe(true);
});
it('identifies if a commit is a squash', () => {
const message1 = buildCommitMessage();
expect(parseCommitMessage(message1).isSquash).toBe(false);
const message2 = buildCommitMessage({prefix: 'squash! '});
expect(parseCommitMessage(message2).isSquash).toBe(true);
});
it('ignores comment lines', () => {
const message = buildCommitMessage({
prefix: '# This is a comment line before the header.\n' +
'## This is another comment line before the headers.\n',
body: '# This is a comment line befor the body.\n' +
'This is line 1 of the actual body.\n' +
'## This is another comment line inside the body.\n' +
'This is line 2 of the actual body (and it also contains a # but it not a comment).\n' +
'### This is yet another comment line after the body.\n',
});
const parsedMessage = parseCommitMessage(message);
expect(parsedMessage.header)
.toBe(`${commitValues.type}(${commitValues.scope}): ${commitValues.summary}`);
expect(parsedMessage.body)
.toBe(
'This is line 1 of the actual body.\n' +
'This is line 2 of the actual body (and it also contains a # but it not a comment).\n');
});
});