Skip to content

Commit 8bfb303

Browse files
authored
Merge branch 'master' into feat/validate-configs
2 parents 0c1b6f0 + 8ee0e9e commit 8bfb303

File tree

10 files changed

+203
-80
lines changed

10 files changed

+203
-80
lines changed

@commitlint/config-patternplate/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Additionally these rules apply:
1919

2020
### Problems
2121

22-
The following rules are considered problems for `@commitlint/config-patterplate` and will yield a non-zero exit code when not met.
22+
The following rules are considered problems for `@commitlint/config-patternplate` and will yield a non-zero exit code when not met.
2323

2424
#### scope-enum
2525

@commitlint/load/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
"@commitlint/test": "^12.0.0",
3838
"@commitlint/utils": "^12.0.0",
3939
"@types/lodash": "4.14.168",
40-
"execa": "^5.0.0"
40+
"execa": "^5.0.0",
41+
"conventional-changelog-atom": "^2.0.8"
4142
},
4243
"dependencies": {
4344
"@commitlint/execute-rule": "^12.0.0",

@commitlint/load/src/load.test.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ jest.mock('@scope/commitlint-plugin-example', () => scopedPlugin, {
77
});
88

99
import path from 'path';
10-
import execa from 'execa';
1110
import resolveFrom from 'resolve-from';
1211
import {fix, git, npm} from '@commitlint/test';
1312

@@ -417,10 +416,9 @@ test('recursive resolves parser preset from conventional atom', async () => {
417416
const cwd = await gitBootstrap(
418417
'fixtures/recursive-parser-preset-conventional-atom'
419418
);
420-
// the package file is nested in 2 folders, `npm.bootstrap` cant do that
421-
await execa('npm', ['install'], {
422-
cwd: path.resolve(cwd, 'first-extended', 'second-extended'),
423-
});
419+
await npm.installModules(
420+
path.resolve(cwd, 'first-extended', 'second-extended')
421+
);
424422

425423
const actual = await load({}, {cwd});
426424

@@ -430,7 +428,7 @@ test('recursive resolves parser preset from conventional atom', async () => {
430428
expect((actual.parserPreset!.parserOpts as any).headerPattern).toEqual(
431429
/^(:.*?:) (.*)$/
432430
);
433-
}, 10000);
431+
});
434432

435433
test('resolves parser preset from conventional commits without factory support', async () => {
436434
const cwd = await npmBootstrap(

@commitlint/load/src/utils/load-plugin.test.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import loadPlugin from './load-plugin';
2+
import {AsyncRule, Plugin, Rule, SyncRule} from '@commitlint/types';
23

34
jest.mock('commitlint-plugin-example', () => ({example: true}), {
45
virtual: true,
@@ -8,6 +9,39 @@ jest.mock('@scope/commitlint-plugin-example', () => ({scope: true}), {
89
virtual: true,
910
});
1011

12+
jest.mock(
13+
'commitlint-plugin-rule',
14+
(): Plugin => {
15+
const rule: Rule<number> = (_parsed, when, _value) => {
16+
return [when === 'never'];
17+
};
18+
return {rules: {rule}};
19+
},
20+
{virtual: true}
21+
);
22+
23+
jest.mock(
24+
'commitlint-plugin-sync-rule',
25+
(): Plugin => {
26+
const syncRule: SyncRule<number> = (_parsed, when, _value) => {
27+
return [when === 'never'];
28+
};
29+
return {rules: {syncRule}};
30+
},
31+
{virtual: true}
32+
);
33+
34+
jest.mock(
35+
'commitlint-plugin-async-rule',
36+
(): Plugin => {
37+
const asyncRule: AsyncRule<number> = (_parsed, when, _value) => {
38+
return new Promise(() => [when === 'never']);
39+
};
40+
return {rules: {asyncRule}};
41+
},
42+
{virtual: true}
43+
);
44+
1145
test('should load a plugin when referenced by short name', () => {
1246
const plugins = loadPlugin({}, 'example');
1347
expect(plugins['example']).toBe(require('commitlint-plugin-example'));
@@ -18,6 +52,21 @@ test('should load a plugin when referenced by long name', () => {
1852
expect(plugins['example']).toBe(require('commitlint-plugin-example'));
1953
});
2054

55+
test('should load a plugin with a rule', () => {
56+
const plugins = loadPlugin({}, 'commitlint-plugin-rule');
57+
expect(plugins['rule']).toBe(require('commitlint-plugin-rule'));
58+
});
59+
60+
test('should load a plugin with a sync rule', () => {
61+
const plugins = loadPlugin({}, 'commitlint-plugin-sync-rule');
62+
expect(plugins['sync-rule']).toBe(require('commitlint-plugin-sync-rule'));
63+
});
64+
65+
test('should load a plugin with an async rule', () => {
66+
const plugins = loadPlugin({}, 'commitlint-plugin-async-rule');
67+
expect(plugins['async-rule']).toBe(require('commitlint-plugin-async-rule'));
68+
});
69+
2170
test('should throw an error when a plugin has whitespace', () => {
2271
expect(() => loadPlugin({}, 'whitespace ')).toThrow(
2372
"Whitespace found in plugin name 'whitespace '"

@commitlint/rules/src/index.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import path from 'path';
2+
import fs from 'fs';
23
import globby from 'globby';
34
import rules from '.';
45

@@ -13,6 +14,19 @@ test('rules export functions', () => {
1314
expect(actual.every((rule) => typeof rule === 'function')).toBe(true);
1415
});
1516

17+
test('all rules are present in documentation', () => {
18+
const file = fs.readFileSync(
19+
path.join(__dirname, '../../../docs/reference-rules.md'),
20+
'utf-8'
21+
);
22+
const results = file
23+
.split(/(\n|\r)/)
24+
.filter((s) => s.startsWith('####') && !s.includes('`deprecated`'))
25+
.map((s) => s.replace('#### ', ''));
26+
27+
expect(Object.keys(rules)).toEqual(expect.arrayContaining(results));
28+
});
29+
1630
async function glob(pattern: string | string[]) {
1731
const files = await globby(pattern, {
1832
ignore: ['**/index.ts', '**/*.test.ts'],

@commitlint/types/src/load.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1-
import {Rule, RulesConfig, RuleConfigQuality} from './rules';
1+
import {
2+
Rule,
3+
RulesConfig,
4+
RuleConfigQuality,
5+
AsyncRule,
6+
SyncRule,
7+
} from './rules';
28

39
export type PluginRecords = Record<string, Plugin>;
410

511
export interface Plugin {
612
rules: {
7-
[ruleName: string]: Rule<unknown>;
13+
[ruleName: string]: Rule | AsyncRule | SyncRule;
814
};
915
}
1016

@packages/test/src/npm.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import resolvePkg from 'resolve-pkg';
44

55
import * as git from './git';
66

7-
export async function bootstrap(fixture: string, directory?: string) {
8-
const cwd = await git.bootstrap(fixture, directory);
7+
export async function installModules(cwd: string) {
98
const manifestPath = path.join(cwd, 'package.json');
109
const targetModulesPath = path.join(cwd, 'node_modules');
1110

@@ -36,7 +35,11 @@ export async function bootstrap(fixture: string, directory?: string) {
3635
})
3736
);
3837
}
38+
}
3939

40+
export async function bootstrap(fixture: string, directory?: string) {
41+
const cwd = await git.bootstrap(fixture, directory);
42+
await installModules(cwd);
4043
return cwd;
4144
}
4245

docs/reference-configuration.md

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,39 +8,57 @@ The file is expected
88
- export a configuration object
99
- adhere to the schema outlined below
1010

11-
```ts
12-
type Config = {
11+
## Configuration object example
12+
13+
### JavaScript
14+
15+
```js
16+
const Configuration = {
1317
/*
14-
* Resolveable ids to commitlint configurations to extend
18+
* Resolve and load @commitlint/config-conventional from node_modules.
19+
* Referenced packages must be installed
1520
*/
16-
extends?: string[];
21+
extends: ['@commitlint/config-conventional'],
1722
/*
18-
* Resolveable id to conventional-changelog parser preset to import and use
23+
* Resolve and load conventional-changelog-atom from node_modules.
24+
* Referenced packages must be installed
1925
*/
20-
parserPreset?: string;
26+
parserPreset: 'conventional-changelog-atom',
2127
/*
22-
* Resolveable id to package, from node_modules, which formats the output.
28+
* Resolve and load @commitlint/format from node_modules.
29+
* Referenced package must be installed
2330
*/
24-
formatter: string;
31+
formatter: '@commitlint/format',
2532
/*
26-
* Rules to check against
33+
* Any rules defined here will override rules from @commitlint/config-conventional
2734
*/
28-
rules?: {[name: string]: Rule};
35+
rules: {
36+
'type-enum': [2, 'always', ['foo']],
37+
},
2938
/*
3039
* Functions that return true if commitlint should ignore the given message.
3140
*/
32-
ignores?: ((message: string) => boolean)[];
41+
ignores: [(commit) => commit === ''],
3342
/*
3443
* Whether commitlint uses the default ignore rules.
3544
*/
36-
defaultIgnores?: boolean;
45+
defaultIgnores: true,
3746
/*
3847
* Custom URL to show upon failure
3948
*/
40-
helpUrl?: string;
49+
helpUrl:
50+
'https://github.com/conventional-changelog/commitlint/#what-is-commitlint',
4151
};
4252

43-
const Configuration: Config = {
53+
module.exports = Configuration;
54+
```
55+
56+
### TypeScript
57+
58+
```ts
59+
import type {UserConfig} from '@commitlint/types';
60+
61+
const Configuration: UserConfig = {
4462
/*
4563
* Resolve and load @commitlint/config-conventional from node_modules.
4664
* Referenced packages must be installed

docs/reference-rules.md

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ Rule configurations are either of type `array` residing on a key with the rule's
5757
- **condition**: `body` begins with blank line
5858
- **rule**: `always`
5959

60+
#### body-empty
61+
62+
- **condition**: `body` is empty
63+
- **rule**: `never`
64+
6065
#### body-max-length
6166

6267
- **condition**: `body` has `value` or less characters
@@ -87,11 +92,41 @@ Infinity
8792
0
8893
```
8994

95+
#### body-case
96+
97+
- **condition**: `header` is in case `value`
98+
- **rule**: `always`
99+
- **value**
100+
101+
```
102+
'lower-case'
103+
```
104+
105+
- **possible values**
106+
107+
```
108+
[
109+
'lower-case', // default
110+
'upper-case', // UPPERCASE
111+
'camel-case', // camelCase
112+
'kebab-case', // kebab-case
113+
'pascal-case', // PascalCase
114+
'sentence-case', // Sentence case
115+
'snake-case', // snake_case
116+
'start-case' // Start Case
117+
]
118+
```
119+
90120
#### footer-leading-blank
91121

92122
- **condition**: `footer` begins with blank line
93123
- **rule**: `always`
94124

125+
#### footer-empty
126+
127+
- **condition**: `footer` is empty
128+
- **rule**: `never`
129+
95130
#### footer-max-length
96131

97132
- **condition**: `footer` has `value` or less characters
@@ -129,7 +164,7 @@ Infinity
129164
- **value**
130165

131166
```
132-
'lowerCase'
167+
'lower-case'
133168
```
134169

135170
- **possible values**
@@ -198,7 +233,7 @@ Infinity
198233
- **value**
199234

200235
```
201-
'lowerCase'
236+
'lower-case'
202237
```
203238

204239
- **possible values**
@@ -248,7 +283,7 @@ Infinity
248283
- **value**
249284

250285
```
251-
'lowerCase'
286+
'lower-case'
252287
```
253288

254289
- **possible values**

0 commit comments

Comments
 (0)