Skip to content

Commit befa677

Browse files
authored
feat(config-rush-scopes): add config for rush monorepo (#2878)
* feat(config-rush-scopes): add config for rush monorepo * fix(config-rush-scopes): support older NodeJS
1 parent 2af2f23 commit befa677

File tree

14 files changed

+1557
-0
lines changed

14 files changed

+1557
-0
lines changed

@commitlint/config-rush-scopes/CHANGELOG.md

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "a",
3+
"version": "1.0.0"
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "b",
3+
"version": "1.0.0"
4+
}

@commitlint/config-rush-scopes/fixtures/basic/rush.json

+441
Large diffs are not rendered by default.

@commitlint/config-rush-scopes/fixtures/empty/rush.json

+433
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "@packages/a",
3+
"version": "1.0.0"
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "@packages/b",
3+
"version": "1.0.0"
4+
}

@commitlint/config-rush-scopes/fixtures/scoped/rush.json

+441
Large diffs are not rendered by default.
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const Path = require('path');
2+
const util = require('util');
3+
const fs = require('fs');
4+
const jsonc = require('jsonc');
5+
6+
const readFilePromisifed = util.promisify(fs.readFile);
7+
8+
module.exports = {
9+
utils: {getPackages},
10+
rules: {
11+
'scope-enum': (ctx) =>
12+
getPackages(ctx).then((packages) => [2, 'always', packages]),
13+
},
14+
};
15+
16+
function getPackages(context) {
17+
return Promise.resolve()
18+
.then(() => {
19+
const ctx = context || {};
20+
const cwd = ctx.cwd || process.cwd();
21+
22+
return readFilePromisifed(Path.join(cwd, 'rush.json'), {encoding: 'utf8'})
23+
.then((content) => jsonc.parse(content))
24+
.then(({projects}) => projects)
25+
.catch(() => []);
26+
})
27+
.then((packages) => {
28+
return packages
29+
.map((pkg) => pkg.packageName)
30+
.filter(Boolean)
31+
.map((name) => (name.charAt(0) === '@' ? name.split('/')[1] : name));
32+
});
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import {npm} from '@commitlint/test';
2+
import config from '.';
3+
4+
test('exports rules key', () => {
5+
expect(config).toHaveProperty('rules');
6+
});
7+
8+
test('rules hold object', () => {
9+
expect(config).toMatchObject({
10+
rules: expect.any(Object),
11+
});
12+
});
13+
14+
test('rules contain scope-enum', () => {
15+
expect(config).toMatchObject({
16+
rules: {
17+
'scope-enum': expect.anything(),
18+
},
19+
});
20+
});
21+
22+
test('scope-enum is function', () => {
23+
expect(config).toMatchObject({
24+
rules: {
25+
'scope-enum': expect.any(Function),
26+
},
27+
});
28+
});
29+
30+
test('scope-enum does not throw for missing context', async () => {
31+
const {'scope-enum': fn} = config.rules;
32+
await expect(fn()).resolves.toBeTruthy();
33+
});
34+
35+
test('scope-enum has expected severity', async () => {
36+
const {'scope-enum': fn} = config.rules;
37+
const [severity] = await fn();
38+
expect(severity).toBe(2);
39+
});
40+
41+
test('scope-enum has expected modifier', async () => {
42+
const {'scope-enum': fn} = config.rules;
43+
const [, modifier] = await fn();
44+
expect(modifier).toBe('always');
45+
});
46+
47+
test('returns empty value for empty rush repository', async () => {
48+
const {'scope-enum': fn} = config.rules;
49+
const cwd = await npm.bootstrap('fixtures/empty', __dirname);
50+
const [, , value] = await fn({cwd});
51+
expect(value).toEqual([]);
52+
});
53+
54+
test('returns expected value for basic rush repository', async () => {
55+
const {'scope-enum': fn} = config.rules;
56+
const cwd = await npm.bootstrap('fixtures/basic', __dirname);
57+
58+
const [, , value] = await fn({cwd});
59+
expect(value).toEqual(['a', 'b']);
60+
});
61+
62+
test('returns expected value for scoped lerna repository', async () => {
63+
const {'scope-enum': fn} = config.rules;
64+
const cwd = await npm.bootstrap('fixtures/scoped', __dirname);
65+
66+
const [, , value] = await fn({cwd});
67+
68+
expect(value).toEqual(['a', 'b']);
69+
});
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2016 - present Mario Nebl
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "@commitlint/config-rush-scopes",
3+
"version": "15.0.0",
4+
"description": "Shareable commitlint config enforcing rush package and workspace names as scopes",
5+
"files": [
6+
"index.js"
7+
],
8+
"scripts": {
9+
"deps": "dep-check",
10+
"pkg": "pkg-check"
11+
},
12+
"repository": {
13+
"type": "git",
14+
"url": "https://github.com/conventional-changelog/commitlint.git",
15+
"directory": "@commitlint/config-rush-scopes"
16+
},
17+
"keywords": [
18+
"conventional-changelog",
19+
"commitlint",
20+
"commitlint-config",
21+
"rush"
22+
],
23+
"author": {
24+
"name": "Alexander Vyzhanov",
25+
"email": "[email protected]"
26+
},
27+
"license": "MIT",
28+
"bugs": {
29+
"url": "https://github.com/conventional-changelog/commitlint/issues"
30+
},
31+
"homepage": "https://commitlint.js.org/",
32+
"engines": {
33+
"node": ">=v12"
34+
},
35+
"dependencies": {
36+
"jsonc": "^2.0.0"
37+
},
38+
"devDependencies": {
39+
"@commitlint/test": "^15.0.0",
40+
"@commitlint/utils": "^15.0.0"
41+
}
42+
}
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
> Lint your rush project commits
2+
3+
# @commitlint/config-rush-scopes
4+
5+
Shareable `commitlint` config enforcing rush package and workspace names as scopes.
6+
Use with [@commitlint/cli](../cli) and [@commitlint/prompt-cli](../prompt-cli).
7+
8+
## Getting started
9+
10+
```
11+
npm install --save-dev @commitlint/config-rush-scopes @commitlint/cli
12+
echo "module.exports = {extends: ['@commitlint/config-rush-scopes']};" > commitlint.config.js
13+
```
14+
15+
## Examples
16+
17+
```
18+
❯ cat commitlint.config.js
19+
{
20+
extends: ['@commitlint/config-rush-scopes']
21+
}
22+
23+
❯ tree packages
24+
25+
packages
26+
├── api
27+
├── app
28+
└── web
29+
30+
❯ echo "build(api): change something in api's build" | commitlint
31+
⧗ input: build(api): change something in api's build
32+
✔ found 0 problems, 0 warnings
33+
34+
❯ echo "test(foo): this won't pass" | commitlint
35+
⧗ input: test(foo): this won't pass
36+
✖ scope must be one of [api, app, web] [scope-enum]
37+
✖ found 1 problems, 0 warnings
38+
39+
❯ echo "ci: do some general maintenance" | commitlint
40+
⧗ input: ci: do some general maintenance
41+
✔ found 0 problems, 0 warnings
42+
```
43+
44+
Consult [docs/rules](https://conventional-changelog.github.io/commitlint/#/reference-rules) for a list of available rules.

yarn.lock

+17
Original file line numberDiff line numberDiff line change
@@ -4325,6 +4325,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
43254325
resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
43264326
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
43274327

4328+
fast-safe-stringify@^2.0.6:
4329+
version "2.1.1"
4330+
resolved "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884"
4331+
integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==
4332+
43284333
fastq@^1.6.0:
43294334
version "1.13.0"
43304335
resolved "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c"
@@ -6063,6 +6068,18 @@ json5@^1.0.1:
60636068
dependencies:
60646069
minimist "^1.2.0"
60656070

6071+
jsonc@^2.0.0:
6072+
version "2.0.0"
6073+
resolved "https://registry.npmjs.org/jsonc/-/jsonc-2.0.0.tgz#9e2a25100d164a9bb864c57517563717fa882551"
6074+
integrity sha512-B281bLCT2TRMQa+AQUQY5AGcqSOXBOKaYGP4wDzoA/+QswUfN8sODektbPEs9Baq7LGKun5jQbNFpzwGuVYKhw==
6075+
dependencies:
6076+
fast-safe-stringify "^2.0.6"
6077+
graceful-fs "^4.1.15"
6078+
mkdirp "^0.5.1"
6079+
parse-json "^4.0.0"
6080+
strip-bom "^4.0.0"
6081+
strip-json-comments "^3.0.1"
6082+
60666083
jsonfile@^4.0.0:
60676084
version "4.0.0"
60686085
resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"

0 commit comments

Comments
 (0)