Skip to content

Commit 5b5285b

Browse files
committed
feat: implement config validation
1 parent ee0650d commit 5b5285b

File tree

44 files changed

+575
-185
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+575
-185
lines changed

@commitlint/cli/src/cli.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ import resolveGlobal from 'resolve-global';
88
import yargs from 'yargs';
99
import util from 'util';
1010

11-
import {CliFlags, Seed} from './types';
11+
import {CliFlags} from './types';
1212
import {
1313
LintOptions,
1414
LintOutcome,
1515
ParserOptions,
1616
ParserPreset,
1717
QualifiedConfig,
1818
Formatter,
19+
UserConfig,
1920
} from '@commitlint/types';
2021
import {CliError} from './cli-error';
2122

@@ -332,7 +333,7 @@ function getEditValue(flags: CliFlags) {
332333
return edit;
333334
}
334335

335-
function getSeed(flags: CliFlags): Seed {
336+
function getSeed(flags: CliFlags): UserConfig {
336337
const n = (flags.extends || []).filter(
337338
(i): i is string => typeof i === 'string'
338339
);

@commitlint/cli/src/types.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,3 @@ export interface CliFlags {
1818
_: string[];
1919
$0: string;
2020
}
21-
22-
export interface Seed {
23-
extends?: string[];
24-
parserPreset?: string;
25-
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "@commitlint/config-validator",
3+
"version": "11.0.0",
4+
"description": "commitizen prompt using commitlint.config.js",
5+
"main": "./lib/validate.js",
6+
"files": [
7+
"lib/"
8+
],
9+
"scripts": {
10+
"deps": "dep-check",
11+
"pkg": "pkg-check --skip-import"
12+
},
13+
"repository": {
14+
"type": "git",
15+
"url": "https://github.com/conventional-changelog/commitlint.git"
16+
},
17+
"author": "Mario Nebl <[email protected]>",
18+
"license": "MIT",
19+
"bugs": {
20+
"url": "https://github.com/conventional-changelog/commitlint/issues"
21+
},
22+
"homepage": "https://github.com/conventional-changelog/commitlint#readme",
23+
"engines": {
24+
"node": ">=v10"
25+
},
26+
"devDependencies": {
27+
"@commitlint/utils": "^11.0.0"
28+
},
29+
"dependencies": {
30+
"@commitlint/types": "^11.0.0",
31+
"ajv": "^6.12.6"
32+
},
33+
"gitHead": "cb565dfcca3128380b9b3dc274aedbcae34ce5ca"
34+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`validation should fail for defaultIgnoresNotBoolean 1`] = `
4+
"Commitlint configuration in defaultIgnoresNotBoolean.js is invalid:
5+
- Property \\"defaultIgnores\\" has the wrong type - should be boolean.
6+
"
7+
`;
8+
9+
exports[`validation should fail for extendsAsObject 1`] = `
10+
"Commitlint configuration in extendsAsObject.js is invalid:
11+
- Property \\"extends\\" has the wrong type - should be array.
12+
- Property \\"extends\\" has the wrong type - should be string.
13+
- \\"extends\\" should match exactly one schema in oneOf. Value: {\\"test\\":1}.
14+
"
15+
`;
16+
17+
exports[`validation should fail for extendsWithFunction 1`] = `
18+
"Commitlint configuration in extendsWithFunction.js is invalid:
19+
- Property \\"extends[0]\\" has the wrong type - should be string.
20+
- Property \\"extends\\" has the wrong type - should be string.
21+
- \\"extends\\" should match exactly one schema in oneOf. Value: [null].
22+
"
23+
`;
24+
25+
exports[`validation should fail for formatterAsObject 1`] = `
26+
"Commitlint configuration in formatterAsObject.js is invalid:
27+
- Property \\"formatter\\" has the wrong type - should be string.
28+
"
29+
`;
30+
31+
exports[`validation should fail for helpUrlAsArray 1`] = `
32+
"Commitlint configuration in helpUrlAsArray.js is invalid:
33+
- Property \\"helpUrl\\" has the wrong type - should be string.
34+
"
35+
`;
36+
37+
exports[`validation should fail for helpUrlNotString 1`] = `
38+
"Commitlint configuration in helpUrlNotString.js is invalid:
39+
- Property \\"helpUrl\\" has the wrong type - should be string.
40+
"
41+
`;
42+
43+
exports[`validation should fail for ignoresFunction 1`] = `
44+
"Commitlint configuration in ignoresFunction.js is invalid:
45+
- Property \\"ignores\\" has the wrong type - should be array.
46+
"
47+
`;
48+
49+
exports[`validation should fail for ignoresNotFunction 1`] = `
50+
"Commitlint configuration in ignoresNotFunction.js is invalid:
51+
- \\"ignores[0]\\" should be a function. Value: 1.
52+
"
53+
`;
54+
55+
exports[`validation should fail for parserPreset 1`] = `
56+
"Commitlint configuration in parserPreset.js is invalid:
57+
- Property \\"parserPreset\\" has the wrong type - should be string.
58+
- Property \\"parserPreset\\" has the wrong type - should be object.
59+
- \\"parserPreset\\" should match exactly one schema in oneOf. Value: [].
60+
"
61+
`;
62+
63+
exports[`validation should fail for pluginsNotArray 1`] = `
64+
"Commitlint configuration in pluginsNotArray.js is invalid:
65+
- Property \\"plugins\\" has the wrong type - should be array.
66+
"
67+
`;
68+
69+
exports[`validation should fail for rules1 1`] = `
70+
"Commitlint configuration in rules1.js is invalid:
71+
- \\"rules['a'][0]\\" should be equal to one of the allowed values. Value: 3.
72+
- \\"rules['a']\\" should match exactly one schema in oneOf. Value: [3].
73+
"
74+
`;
75+
76+
exports[`validation should fail for rules2 1`] = `
77+
"Commitlint configuration in rules2.js is invalid:
78+
- \\"rules['b']\\" should NOT have more than 3 items. Value: [1,\\"test\\",2,2].
79+
- \\"rules['b']\\" should match exactly one schema in oneOf. Value: [1,\\"test\\",2,2].
80+
"
81+
`;
82+
83+
exports[`validation should fail for rules3 1`] = `
84+
"Commitlint configuration in rules3.js is invalid:
85+
- \\"rules['c']\\" should NOT have fewer than 1 items. Value: [].
86+
- \\"rules['c']\\" should match exactly one schema in oneOf. Value: [].
87+
"
88+
`;
89+
90+
exports[`validation should fail for rules4 1`] = `
91+
"Commitlint configuration in rules4.js is invalid:
92+
- Property \\"rules['d'][0]\\" has the wrong type - should be number.
93+
- \\"rules['d'][0]\\" should be equal to one of the allowed values. Value: [].
94+
- \\"rules['d']\\" should match exactly one schema in oneOf. Value: [[],[],[]].
95+
"
96+
`;
97+
98+
exports[`validation should fail for rules5 1`] = `
99+
"Commitlint configuration in rules5.js is invalid:
100+
- Property \\"rules['e']\\" has the wrong type - should be array.
101+
- \\"rules['e']\\" should match exactly one schema in oneOf. Value: {}.
102+
"
103+
`;
104+
105+
exports[`validation should fail for rulesAsArray 1`] = `
106+
"Commitlint configuration in rulesAsArray.js is invalid:
107+
- Property \\"rules\\" has the wrong type - should be object.
108+
"
109+
`;
110+
111+
exports[`validation should fail for whenConfigIsNotObject 1`] = `
112+
"Commitlint configuration in whenConfigIsNotObject.js is invalid:
113+
- Config has the wrong type - should be object.
114+
"
115+
`;
116+
117+
exports[`validation should fail for whenConfigIsNotObject2 1`] = `
118+
"Commitlint configuration in whenConfigIsNotObject2.js is invalid:
119+
- Config has the wrong type - should be object.
120+
"
121+
`;
122+
123+
exports[`validation should fail for withPluginsAsObject 1`] = `
124+
"Commitlint configuration in withPluginsAsObject.js is invalid:
125+
- Property \\"plugins[0]\\" has the wrong type - should be string.
126+
- \\"plugins[0]\\" should have required property '.rules'. Value: {}.
127+
- \\"plugins[0]\\" should match some schema in anyOf. Value: {}.
128+
"
129+
`;
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema",
3+
"default": {},
4+
"type": "object",
5+
"definitions": {
6+
"rule": {
7+
"oneOf": [
8+
{
9+
"description": "A rule",
10+
"type": "array",
11+
"items": [
12+
{
13+
"description": "Level: 0 disables the rule. For 1 it will be considered a warning, for 2 an error",
14+
"type": "number",
15+
"enum": [0, 1, 2]
16+
},
17+
{
18+
"description": "Applicable: always|never: never inverts the rule",
19+
"type": "string",
20+
"enum": ["always", "never"]
21+
},
22+
{
23+
"description": "Value: the value for this rule"
24+
}
25+
],
26+
"minItems": 1,
27+
"maxItems": 3,
28+
"additionalItems": false
29+
}
30+
]
31+
}
32+
},
33+
"properties": {
34+
"extends": {
35+
"description": "Resolveable ids to commitlint configurations to extend",
36+
"oneOf": [
37+
{
38+
"type": "array",
39+
"items": {"type": "string"}
40+
},
41+
{"type": "string"}
42+
]
43+
},
44+
"parserPreset": {
45+
"description": "Resolveable id to conventional-changelog parser preset to import and use",
46+
"oneOf": [
47+
{"type": "string"},
48+
{
49+
"type": "object",
50+
"properties": {
51+
"name": {"type": "string"},
52+
"path": {"type": "string"},
53+
"parserOpts": {}
54+
},
55+
"additionalProperties": true
56+
}
57+
]
58+
},
59+
"helpUrl": {
60+
"description": "Custom URL to show upon failure",
61+
"type": "string"
62+
},
63+
"formatter": {
64+
"description": "Resolveable id to package, from node_modules, which formats the output",
65+
"type": "string"
66+
},
67+
"rules": {
68+
"description": "Rules to check against",
69+
"type": "object",
70+
"propertyNames": {"type": "string"},
71+
"additionalProperties": {"$ref": "#/definitions/rule"}
72+
},
73+
"plugins": {
74+
"description": "Resolveable ids of commitlint plugins from node_modules",
75+
"type": "array",
76+
"items": {
77+
"anyOf": [
78+
{"type": "string"},
79+
{
80+
"required": ["rules"],
81+
"rules": {}
82+
}
83+
]
84+
}
85+
},
86+
"ignores": {
87+
"type": "array",
88+
"items": {"typeof": "function"},
89+
"description": "Additional commits to ignore, defined by ignore matchers"
90+
},
91+
"defaultIgnores": {
92+
"description": "Whether commitlint uses the default ignore rules",
93+
"type": "boolean"
94+
}
95+
}
96+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import {ErrorObject} from 'ajv';
2+
3+
/**
4+
* Formats an array of schema validation errors.
5+
* @param errors An array of error messages to format.
6+
* @returns Formatted error message
7+
* Based on https://github.com/eslint/eslint/blob/master/lib/shared/config-validator.js#L237-L261
8+
*/
9+
export function formatErrors(errors: ErrorObject[]): string {
10+
return errors
11+
.map((error) => {
12+
if (
13+
error.keyword === 'additionalProperties' &&
14+
'additionalProperty' in error.params
15+
) {
16+
const formattedPropertyPath = error.dataPath.length
17+
? `${error.dataPath.slice(1)}.${error.params.additionalProperty}`
18+
: error.params.additionalProperty;
19+
20+
return `Unexpected top-level property "${formattedPropertyPath}"`;
21+
}
22+
if (error.keyword === 'type') {
23+
const formattedField = error.dataPath.slice(1);
24+
if (!formattedField) {
25+
return `Config has the wrong type - ${error.message}`;
26+
}
27+
return `Property "${formattedField}" has the wrong type - ${error.message}`;
28+
}
29+
const field =
30+
(error.dataPath[0] === '.'
31+
? error.dataPath.slice(1)
32+
: error.dataPath) || 'Config';
33+
if (error.keyword === 'typeof') {
34+
return `"${field}" should be a ${error.schema}. Value: ${JSON.stringify(
35+
error.data
36+
)}`;
37+
}
38+
39+
return `"${field}" ${error.message}. Value: ${JSON.stringify(
40+
error.data
41+
)}`;
42+
})
43+
.map((message) => `\t- ${message}.\n`)
44+
.join('');
45+
}

0 commit comments

Comments
 (0)