Skip to content

Commit

Permalink
feat: config based is-ignored overrides (#595)
Browse files Browse the repository at this point in the history
* feat: config based is-ignored overrides

* style: apply formatting

* refactor: simplify configurable is-ignored
  • Loading branch information
SimeonC authored and marionebl committed Apr 26, 2019
1 parent f7e4e68 commit 2434d71
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 8 deletions.
25 changes: 22 additions & 3 deletions @commitlint/is-ignored/src/index.js
@@ -1,6 +1,6 @@
import semver from 'semver';

const WILDCARDS = [
export const WILDCARDS = [
c =>
c.match(
/^((Merge pull request)|(Merge (.*?) into (.*?)|(Merge branch (.*?)))(?:\r?\n)*$)/m
Expand All @@ -21,6 +21,25 @@ const WILDCARDS = [
c => c.match(/^Auto-merged (.*?) into (.*)/)
];

export default function isIgnored(commit = '') {
return WILDCARDS.some(w => w(commit));
export default function isIgnored(commit = '', opts = {}) {
const ignores = typeof opts.ignores === 'undefined' ? [] : opts.ignores;

if (!Array.isArray(ignores)) {
throw new Error(
`ignores must be of type array, received ${ignores} of type ${typeof ignores}`
);
}

const invalids = ignores.filter(c => typeof c !== 'function');

if (invalids.length > 0) {
throw new Error(
`ignores must be array of type function, received items of type: ${invalids
.map(i => typeof i)
.join(', ')}`
);
}

const base = opts.defaults === false ? [] : WILDCARDS;
return [...base, ...ignores].some(w => w(commit));
}
34 changes: 34 additions & 0 deletions @commitlint/is-ignored/src/index.test.js
Expand Up @@ -117,3 +117,37 @@ test('should return true for automatic merge commits', t => {
test('should return false for commits containing, but not starting, with merge branch', t => {
t.false(isIgnored('foo bar Merge branch xxx'));
});

test('should return false for ignored message if defaults is false', t => {
t.false(
isIgnored('Auto-merged develop into master', {
defaults: false
})
);
});

test('should return false for ignored message if custom ignores and defaults is false', t => {
t.false(
isIgnored('Auto-merged develop into master', {
defaults: false
})
);
});

test('should throw error if ignores is not an array', t => {
const ignoredString = 'this should be ignored';
t.throws(() => {
isIgnored(ignoredString, {
ignores: 'throws error'
});
});
});

test('should return true for custom ignores as function', t => {
const ignoredString = 'this should be ignored';
t.true(
isIgnored(ignoredString, {
ignores: [c => c === ignoredString]
})
);
});
4 changes: 3 additions & 1 deletion @commitlint/lint/src/index.js
Expand Up @@ -15,7 +15,9 @@ const buildCommitMesage = ({header, body, footer}) => {

export default async (message, rules = {}, opts = {}) => {
// Found a wildcard match, skip
if (isIgnored(message)) {
if (
isIgnored(message, {defaults: opts.defaultIgnores, ignores: opts.ignores})
) {
return {
valid: true,
errors: [],
Expand Down
28 changes: 28 additions & 0 deletions @commitlint/lint/src/index.test.js
Expand Up @@ -38,6 +38,34 @@ test('positive on ignored message and broken rule', async t => {
t.is(actual.input, 'Revert "some bogus commit"');
});

test('negative on ignored message, disabled ignored messages and broken rule', async t => {
const actual = await lint(
'Revert "some bogus commit"',
{
'type-empty': [2, 'never']
},
{
defaultIgnores: false
}
);
t.false(actual.valid);
});

test('positive on custom ignored message and broken rule', async t => {
const ignoredMessage = 'some ignored custom message';
const actual = await lint(
ignoredMessage,
{
'type-empty': [2, 'never']
},
{
ignores: [c => c === ignoredMessage]
}
);
t.true(actual.valid);
t.is(actual.input, ignoredMessage);
});

test('positive on stub message and opts', async t => {
const actual = await lint(
'foo-bar',
Expand Down
15 changes: 12 additions & 3 deletions @commitlint/load/src/index.js
Expand Up @@ -8,7 +8,16 @@ import loadPlugin from './utils/loadPlugin';

const w = (a, b) => (Array.isArray(b) ? b : undefined);
const valid = input =>
pick(input, 'extends', 'plugins', 'rules', 'parserPreset', 'formatter');
pick(
input,
'extends',
'rules',
'plugins',
'parserPreset',
'formatter',
'ignores',
'defaultIgnores'
);

export default async (seed = {}, options = {cwd: process.cwd()}) => {
const loaded = await loadConfig(options.cwd, options.file);
Expand All @@ -17,8 +26,8 @@ export default async (seed = {}, options = {cwd: process.cwd()}) => {
// Merge passed config with file based options
const config = valid(merge(loaded.config, seed));
const opts = merge(
{extends: [], plugins: [], rules: {}, formatter: '@commitlint/format'},
pick(config, 'extends', 'plugins')
{extends: [], rules: {}, formatter: '@commitlint/format'},
pick(config, 'extends', 'plugins', 'ignores', 'defaultIgnores')
);

// Resolve parserPreset key
Expand Down
23 changes: 22 additions & 1 deletion docs/reference-configuration.md
Expand Up @@ -26,6 +26,14 @@ type Config = {
* Rules to check against
*/
rules?: {[name: string]: Rule};
/*
* Custom list of Messages to Ignore, string values will be compiled as RegExp
*/
ignoredMessages?: Array<string | RegExp | string => boolean>;
/*
* If this is true we will not use any of the default is-ignored rules
*/
disableDefaultIgnoredMessages?: boolean;
}

const Configuration: Config = {
Expand All @@ -49,7 +57,20 @@ const Configuration: Config = {
*/
rules: {
'type-enum': [2, 'always', ['foo']]
}
},
/*
* These RegExp and functions are used to ignore messages that shouldn't be linted
*/
ignoredMessages: [
'^Entire Message to Ignore$',
/^(ci|github):/,
(commit) => commit === ''
],
/*
* If this is true then the default ignores like `Merge commit` are not ignored
* and will cause commitlint to fail
*/
disableDefaultIgnoredMessages: true
};

module.exports = Configuration;
Expand Down

0 comments on commit 2434d71

Please sign in to comment.