Skip to content

Commit ca3ae8b

Browse files
authored
feat(config-pnpm-scopes): implement config-pnpm-scopes (#3427)
shareable config enforcing pnpm workspaces names as scopes
1 parent 8f70b59 commit ca3ae8b

16 files changed

+2503
-59
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "basic",
3+
"version": "1.0.0",
4+
"private": true,
5+
"devDependencies": {}
6+
}
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+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
packages:
2+
- 'packages/*'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "empty",
3+
"version": "1.0.0",
4+
"private": true,
5+
"devDependencies": {}
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
packages:
2+
- 'packages/*'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "basic",
3+
"version": "1.0.0",
4+
"private": true,
5+
"devDependencies": {}
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "@scope/a",
3+
"version": "1.0.0"
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "@scope/b",
3+
"version": "1.0.0"
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
packages:
2+
- 'packages/*'
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const {findWorkspacePackages} = require('@pnpm/find-workspace-packages');
2+
3+
module.exports = {
4+
utils: {getProjects},
5+
rules: {
6+
'scope-enum': (ctx) =>
7+
getProjects(ctx).then((packages) => [2, 'always', packages]),
8+
},
9+
};
10+
11+
function getProjects(context) {
12+
const ctx = context || {};
13+
const cwd = ctx.cwd || process.cwd();
14+
15+
return findWorkspacePackages(cwd).then((projects) => {
16+
return projects.reduce((projects, project) => {
17+
const name = project.manifest.name;
18+
19+
if (name && project.dir !== cwd) {
20+
projects.push(name.charAt(0) === '@' ? name.split('/')[1] : name);
21+
}
22+
23+
return projects;
24+
}, []);
25+
});
26+
}
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 pnpm 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 pnpm 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 pnpm 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+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2022 - present Dan Onoshko
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,50 @@
1+
{
2+
"name": "@commitlint/config-pnpm-scopes",
3+
"version": "17.2.0",
4+
"description": "Shareable commitlint config enforcing pnpm workspaces 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-pnpm-scopes"
16+
},
17+
"keywords": [
18+
"conventional-changelog",
19+
"commitlint",
20+
"commitlint-config",
21+
"pnpm"
22+
],
23+
"author": "Dan Onoshko <danon0404@gmail.com>",
24+
"license": "MIT",
25+
"bugs": {
26+
"url": "https://github.com/conventional-changelog/commitlint/issues"
27+
},
28+
"homepage": "https://commitlint.js.org/",
29+
"peerDependencies": {
30+
"@pnpm/find-workspace-packages": "^5.0.0",
31+
"@pnpm/logger": "^5.0.0"
32+
},
33+
"peerDependenciesMeta": {
34+
"@pnpm/find-workspace-packages": {
35+
"optional": true
36+
},
37+
"@pnpm/logger": {
38+
"optional": true
39+
}
40+
},
41+
"engines": {
42+
"node": ">=v14"
43+
},
44+
"devDependencies": {
45+
"@commitlint/test": "^17.2.0",
46+
"@commitlint/utils": "^17.0.0",
47+
"@pnpm/find-workspace-packages": "^5.0.0",
48+
"@pnpm/logger": "^5.0.0"
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
> Lint your pnpm workspaces project commits
2+
3+
# @commitlint/config-pnpm-scopes
4+
5+
Shareable `commitlint` config enforcing pnpm workspaces 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-pnpm-scopes @commitlint/cli
12+
echo "module.exports = {extends: ['@commitlint/config-pnpm-scopes']};" > commitlint.config.js
13+
```
14+
15+
## Examples
16+
17+
```
18+
❯ cat commitlint.config.js
19+
{
20+
extends: ['@commitlint/config-pnpm-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.

0 commit comments

Comments
Β (0)