@avi2dg/checks 0.21.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +66 -40
- package/CONTRIBUTING.md +14 -10
- package/README.md +15 -24
- package/bunfig.toml +1 -1
- package/dist/effect-channel/index.js +122 -0
- package/dist/{index.js → readability/index.js} +8 -120
- package/docs/configs/commit-messages.md +5 -1
- package/docs/configs/dependency-rules.md +5 -2
- package/docs/configs/effect-rules.md +32 -33
- package/docs/configs/native-settings.md +74 -0
- package/docs/configs/typescript-rules.md +4 -0
- package/docs/design.md +26 -27
- package/docs/gates/checks-backtest.md +4 -0
- package/docs/gates/checks-ci-wiring.md +30 -93
- package/docs/gates/checks-comment-gate.md +4 -0
- package/docs/gates/checks-commit-identity.md +23 -27
- package/docs/gates/checks-docs.md +23 -21
- package/docs/gates/checks-flake.md +4 -10
- package/docs/gates/checks-lint-coverage.md +5 -1
- package/docs/gates/checks-lint.md +22 -104
- package/docs/gates/checks-mutation-compare.md +4 -0
- package/docs/gates/checks-quarantine-clock.md +4 -0
- package/docs/gates/checks-repetition.md +27 -41
- package/docs/gates/checks-subsumed-tests.md +4 -0
- package/docs/gates/checks-suppressions-ratchet.md +4 -0
- package/docs/gates/checks-test-layout.md +16 -8
- package/docs/gates/checks-test.md +68 -36
- package/docs/gates/checks-vendor.md +20 -13
- package/oxlintrc.json +1 -1
- package/package.json +10 -21
- package/scripts/ci-wiring.ts +28 -97
- package/scripts/commit-identity.ts +32 -4
- package/scripts/doc-rules.ts +26 -11
- package/scripts/doc-templates.ts +2 -1
- package/scripts/docs.ts +4 -7
- package/scripts/gates.ts +0 -29
- package/scripts/git.ts +24 -1
- package/scripts/lint.ts +15 -34
- package/scripts/range-gate.ts +1 -2
- package/scripts/repetition.ts +51 -40
- package/scripts/shell-command.ts +7 -1
- package/scripts/swc.ts +46 -0
- package/scripts/test-layout.ts +40 -56
- package/scripts/test-skips.ts +180 -0
- package/scripts/test.ts +33 -38
- package/scripts/vendor.ts +55 -11
- package/dist/feature-rules.js +0 -354
- package/docs/configs/quality-file.md +0 -103
- package/docs/gates/checks-feature-owners.md +0 -113
- package/docs/gates/checks-quality.md +0 -111
- package/docs/gates/checks-size-budget.md +0 -107
- package/quality.schema.json +0 -514
- package/scripts/feature-owners.ts +0 -139
- package/scripts/quality-file.ts +0 -353
- package/scripts/quality.ts +0 -363
- package/scripts/size-budget.ts +0 -285
- package/scripts/size-rules.ts +0 -126
package/CHANGELOG.md
CHANGED
|
@@ -2,13 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
Every release of `@avi2dg/checks`, newest first, written by the release from its conventional commits.
|
|
4
4
|
|
|
5
|
+
## 0.23.0
|
|
6
|
+
|
|
7
|
+
Released 2026-09-26.
|
|
8
|
+
|
|
9
|
+
### Breaking changes
|
|
10
|
+
|
|
11
|
+
- move cognitive-complexity into its own readability oxlint plugin [#74](https://github.com/avi2d/checks/pull/74)
|
|
12
|
+
|
|
13
|
+
## 0.22.0
|
|
14
|
+
|
|
15
|
+
Released 2026-09-26.
|
|
16
|
+
|
|
17
|
+
### Breaking changes
|
|
18
|
+
|
|
19
|
+
- replace quality.json with native configs and workflow gates [#72](https://github.com/avi2d/checks/pull/72)
|
|
20
|
+
- declare test skips inline and add live and pixel test tiers [#71](https://github.com/avi2d/checks/pull/71)
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
- create GitHub releases with linked changelogs [#70](https://github.com/avi2d/checks/pull/70)
|
|
25
|
+
|
|
26
|
+
### Fixes
|
|
27
|
+
|
|
28
|
+
- **scripts:** run generated commitlint through bun so the runner needs no node [#69](https://github.com/avi2d/checks/pull/69)
|
|
29
|
+
- **test:** allow npm pack enough time on release runners [#68](https://github.com/avi2d/checks/pull/68)
|
|
30
|
+
|
|
5
31
|
## 0.21.0
|
|
6
32
|
|
|
7
33
|
Released 2026-09-26.
|
|
8
34
|
|
|
9
35
|
### Features
|
|
10
36
|
|
|
11
|
-
- **scripts:** let quality.json set the runs-on of generated workflows
|
|
37
|
+
- **scripts:** let quality.json set the runs-on of generated workflows [#66](https://github.com/avi2d/checks/pull/66)
|
|
12
38
|
|
|
13
39
|
## 0.20.0
|
|
14
40
|
|
|
@@ -16,12 +42,12 @@ Released 2026-09-26.
|
|
|
16
42
|
|
|
17
43
|
### Features
|
|
18
44
|
|
|
19
|
-
- **scripts:** pin node from .node-version in the generated CI workflow
|
|
20
|
-
- **scripts:** add checks-subsumed-tests to report tests another test subsumes in a
|
|
45
|
+
- **scripts:** pin node from .node-version in the generated CI workflow [#64](https://github.com/avi2d/checks/pull/64)
|
|
46
|
+
- **scripts:** add checks-subsumed-tests to report tests another test subsumes in a [#62](https://github.com/avi2d/checks/pull/62)
|
|
21
47
|
|
|
22
48
|
### Fixes
|
|
23
49
|
|
|
24
|
-
- **scripts:** lint a PR title that starts with # in the generated commitlint workflow
|
|
50
|
+
- **scripts:** lint a PR title that starts with # in the generated commitlint workflow [#63](https://github.com/avi2d/checks/pull/63)
|
|
25
51
|
|
|
26
52
|
## 0.19.0
|
|
27
53
|
|
|
@@ -29,9 +55,9 @@ Released 2026-09-26.
|
|
|
29
55
|
|
|
30
56
|
### Features
|
|
31
57
|
|
|
32
|
-
- **scripts:** judge checks-mutation-compare mutant by mutant instead of by score
|
|
33
|
-
- **scripts:** fail a test left in tests/quarantine past 30 days
|
|
34
|
-
- **scripts:** pin shared read-only library clones with checks-vendor
|
|
58
|
+
- **scripts:** judge checks-mutation-compare mutant by mutant instead of by score [#58](https://github.com/avi2d/checks/pull/58)
|
|
59
|
+
- **scripts:** fail a test left in tests/quarantine past 30 days [#59](https://github.com/avi2d/checks/pull/59)
|
|
60
|
+
- **scripts:** pin shared read-only library clones with checks-vendor [#57](https://github.com/avi2d/checks/pull/57)
|
|
35
61
|
|
|
36
62
|
## 0.18.0
|
|
37
63
|
|
|
@@ -39,11 +65,11 @@ Released 2026-09-26.
|
|
|
39
65
|
|
|
40
66
|
### Features
|
|
41
67
|
|
|
42
|
-
- **scripts:** generate commitlint and CI workflows with checks-quality
|
|
68
|
+
- **scripts:** generate commitlint and CI workflows with checks-quality [#54](https://github.com/avi2d/checks/pull/54)
|
|
43
69
|
|
|
44
70
|
### Fixes
|
|
45
71
|
|
|
46
|
-
- **scripts:** make checks-quality refuse a config that drops the kit's extends
|
|
72
|
+
- **scripts:** make checks-quality refuse a config that drops the kit's extends [#55](https://github.com/avi2d/checks/pull/55)
|
|
47
73
|
|
|
48
74
|
## 0.17.0
|
|
49
75
|
|
|
@@ -51,9 +77,9 @@ Released 2026-09-25.
|
|
|
51
77
|
|
|
52
78
|
### Features
|
|
53
79
|
|
|
54
|
-
- **effect-channel:** add a cognitive complexity rule and make it the size budget's
|
|
55
|
-
- **scripts:** export the refused directive names from comment-matchers
|
|
56
|
-
- refuse undeclared package imports and deprecated symbol use
|
|
80
|
+
- **effect-channel:** add a cognitive complexity rule and make it the size budget's [#50](https://github.com/avi2d/checks/pull/50)
|
|
81
|
+
- **scripts:** export the refused directive names from comment-matchers [#49](https://github.com/avi2d/checks/pull/49)
|
|
82
|
+
- refuse undeclared package imports and deprecated symbol use [#48](https://github.com/avi2d/checks/pull/48)
|
|
57
83
|
|
|
58
84
|
## 0.16.0
|
|
59
85
|
|
|
@@ -61,8 +87,8 @@ Released 2026-09-25.
|
|
|
61
87
|
|
|
62
88
|
### Features
|
|
63
89
|
|
|
64
|
-
- **scripts:** add checks-repetition to hold new repetition in production code
|
|
65
|
-
- **scripts:** add the recommended size limits, a tests budget and an overrun ratchet
|
|
90
|
+
- **scripts:** add checks-repetition to hold new repetition in production code [#46](https://github.com/avi2d/checks/pull/46)
|
|
91
|
+
- **scripts:** add the recommended size limits, a tests budget and an overrun ratchet [#45](https://github.com/avi2d/checks/pull/45)
|
|
66
92
|
|
|
67
93
|
## 0.15.0
|
|
68
94
|
|
|
@@ -70,7 +96,7 @@ Released 2026-09-25.
|
|
|
70
96
|
|
|
71
97
|
### Features
|
|
72
98
|
|
|
73
|
-
- **scripts:** hold living docs to prose rules and resolvable references in checks-docs
|
|
99
|
+
- **scripts:** hold living docs to prose rules and resolvable references in checks-docs [#42](https://github.com/avi2d/checks/pull/42)
|
|
74
100
|
|
|
75
101
|
## 0.14.0
|
|
76
102
|
|
|
@@ -78,8 +104,8 @@ Released 2026-09-25.
|
|
|
78
104
|
|
|
79
105
|
### Features
|
|
80
106
|
|
|
81
|
-
- **scripts:** generate README blocks, check CONTRIBUTING.md, and give each bin a page
|
|
82
|
-
- **scripts:** generate CHANGELOG.md from conventional commits and ship it in the package
|
|
107
|
+
- **scripts:** generate README blocks, check CONTRIBUTING.md, and give each bin a page [#39](https://github.com/avi2d/checks/pull/39)
|
|
108
|
+
- **scripts:** generate CHANGELOG.md from conventional commits and ship it in the package [#40](https://github.com/avi2d/checks/pull/40)
|
|
83
109
|
|
|
84
110
|
## 0.13.0
|
|
85
111
|
|
|
@@ -87,7 +113,7 @@ Released 2026-09-25.
|
|
|
87
113
|
|
|
88
114
|
### Features
|
|
89
115
|
|
|
90
|
-
- **scripts:** add checks-docs gate holding doc files to shared templates
|
|
116
|
+
- **scripts:** add checks-docs gate holding doc files to shared templates [#37](https://github.com/avi2d/checks/pull/37)
|
|
91
117
|
|
|
92
118
|
## 0.12.0
|
|
93
119
|
|
|
@@ -95,11 +121,11 @@ Released 2026-09-24.
|
|
|
95
121
|
|
|
96
122
|
### Features
|
|
97
123
|
|
|
98
|
-
- **scripts:** add size budget, feature-owner rules and change-signal gates
|
|
124
|
+
- **scripts:** add size budget, feature-owner rules and change-signal gates [#35](https://github.com/avi2d/checks/pull/35)
|
|
99
125
|
|
|
100
126
|
### Fixes
|
|
101
127
|
|
|
102
|
-
- release 0.12.0 and read local exports in checks-feature-owners
|
|
128
|
+
- release 0.12.0 and read local exports in checks-feature-owners [#36](https://github.com/avi2d/checks/pull/36)
|
|
103
129
|
|
|
104
130
|
## 0.11.0
|
|
105
131
|
|
|
@@ -107,7 +133,7 @@ Released 2026-09-24.
|
|
|
107
133
|
|
|
108
134
|
### Features
|
|
109
135
|
|
|
110
|
-
- **scripts:** add quality.json with schema, loader and checks-quality fragment generator
|
|
136
|
+
- **scripts:** add quality.json with schema, loader and checks-quality fragment generator [#33](https://github.com/avi2d/checks/pull/33)
|
|
111
137
|
|
|
112
138
|
## 0.10.0
|
|
113
139
|
|
|
@@ -115,7 +141,7 @@ Released 2026-09-24.
|
|
|
115
141
|
|
|
116
142
|
### Features
|
|
117
143
|
|
|
118
|
-
- **scripts:** add checks-test skip gate and checks-flake seed recorder
|
|
144
|
+
- **scripts:** add checks-test skip gate and checks-flake seed recorder [#31](https://github.com/avi2d/checks/pull/31)
|
|
119
145
|
|
|
120
146
|
## 0.9.0
|
|
121
147
|
|
|
@@ -123,14 +149,14 @@ Released 2026-09-24.
|
|
|
123
149
|
|
|
124
150
|
### Features
|
|
125
151
|
|
|
126
|
-
- **scripts:** let ciWiring.lintGates select the gates checks-lint runs
|
|
127
|
-
- **oxlintrc:** turn on no-unsafe-type-assertion and no-non-null-assertion
|
|
152
|
+
- **scripts:** let ciWiring.lintGates select the gates checks-lint runs [#29](https://github.com/avi2d/checks/pull/29)
|
|
153
|
+
- **oxlintrc:** turn on no-unsafe-type-assertion and no-non-null-assertion [#26](https://github.com/avi2d/checks/pull/26)
|
|
128
154
|
|
|
129
155
|
### Fixes
|
|
130
156
|
|
|
131
|
-
- **scripts:** split Effect-free comment matchers out for hosts without node_modules
|
|
132
|
-
- **scripts:** judge a repository's first commit against the empty tree in the range gates
|
|
133
|
-
- **lint:** cruise the whole repo; lint-coverage counts skips and exits 2 on a failed walk
|
|
157
|
+
- **scripts:** split Effect-free comment matchers out for hosts without node_modules [#30](https://github.com/avi2d/checks/pull/30)
|
|
158
|
+
- **scripts:** judge a repository's first commit against the empty tree in the range gates [#28](https://github.com/avi2d/checks/pull/28)
|
|
159
|
+
- **lint:** cruise the whole repo; lint-coverage counts skips and exits 2 on a failed walk [#27](https://github.com/avi2d/checks/pull/27)
|
|
134
160
|
|
|
135
161
|
## 0.8.0
|
|
136
162
|
|
|
@@ -138,8 +164,8 @@ Released 2026-09-24.
|
|
|
138
164
|
|
|
139
165
|
### Features
|
|
140
166
|
|
|
141
|
-
- **scripts:** add checks-lint to run every kit lint gate over one resolved range
|
|
142
|
-
- **scripts:** run the bins on Effect and hold scripts/ to Effect-native IO
|
|
167
|
+
- **scripts:** add checks-lint to run every kit lint gate over one resolved range [#25](https://github.com/avi2d/checks/pull/25)
|
|
168
|
+
- **scripts:** run the bins on Effect and hold scripts/ to Effect-native IO [#22](https://github.com/avi2d/checks/pull/22)
|
|
143
169
|
|
|
144
170
|
## 0.6.0
|
|
145
171
|
|
|
@@ -147,7 +173,7 @@ Released 2026-09-24.
|
|
|
147
173
|
|
|
148
174
|
### Features
|
|
149
175
|
|
|
150
|
-
- add checks-suppressions-ratchet to refuse a raised oxlint suppression count
|
|
176
|
+
- add checks-suppressions-ratchet to refuse a raised oxlint suppression count [#21](https://github.com/avi2d/checks/pull/21)
|
|
151
177
|
|
|
152
178
|
## 0.5.0
|
|
153
179
|
|
|
@@ -155,7 +181,7 @@ Released 2026-09-24.
|
|
|
155
181
|
|
|
156
182
|
### Features
|
|
157
183
|
|
|
158
|
-
- **effect-channel:** add opt-in no-throw and no-try-catch rules
|
|
184
|
+
- **effect-channel:** add opt-in no-throw and no-try-catch rules [#20](https://github.com/avi2d/checks/pull/20)
|
|
159
185
|
|
|
160
186
|
## 0.4.0
|
|
161
187
|
|
|
@@ -163,11 +189,11 @@ Released 2026-09-24.
|
|
|
163
189
|
|
|
164
190
|
### Features
|
|
165
191
|
|
|
166
|
-
- add checks-ci-wiring to confirm CI runs each declared gate on pull requests
|
|
192
|
+
- add checks-ci-wiring to confirm CI runs each declared gate on pull requests [#19](https://github.com/avi2d/checks/pull/19)
|
|
167
193
|
|
|
168
194
|
### Fixes
|
|
169
195
|
|
|
170
|
-
- pin the quarantine pathIgnorePatterns in the test-layout bunfig check
|
|
196
|
+
- pin the quarantine pathIgnorePatterns in the test-layout bunfig check [#18](https://github.com/avi2d/checks/pull/18)
|
|
171
197
|
|
|
172
198
|
## 0.3.0
|
|
173
199
|
|
|
@@ -175,8 +201,8 @@ Released 2026-09-23.
|
|
|
175
201
|
|
|
176
202
|
### Features
|
|
177
203
|
|
|
178
|
-
- add checks-mutation-compare no-regression gate for Stryker reports
|
|
179
|
-
- ship a shared Stryker mutation-testing preset
|
|
204
|
+
- add checks-mutation-compare no-regression gate for Stryker reports [#17](https://github.com/avi2d/checks/pull/17)
|
|
205
|
+
- ship a shared Stryker mutation-testing preset [#16](https://github.com/avi2d/checks/pull/16)
|
|
180
206
|
|
|
181
207
|
## 0.2.0
|
|
182
208
|
|
|
@@ -184,11 +210,11 @@ Released 2026-09-23.
|
|
|
184
210
|
|
|
185
211
|
### Features
|
|
186
212
|
|
|
187
|
-
- expose runnable scripts as checks- bins for consumer package scripts
|
|
188
|
-
- rename npm package from @avi2d/checks to @avi2dg/checks
|
|
189
|
-
- add a shared comment gate and backtest command
|
|
190
|
-
- publish @avi2d/checks to the public npm registry
|
|
213
|
+
- expose runnable scripts as checks- bins for consumer package scripts [#15](https://github.com/avi2d/checks/pull/15)
|
|
214
|
+
- rename npm package from @avi2d/checks to @avi2dg/checks [#14](https://github.com/avi2d/checks/pull/14)
|
|
215
|
+
- add a shared comment gate and backtest command [#12](https://github.com/avi2d/checks/pull/12)
|
|
216
|
+
- publish @avi2d/checks to the public npm registry [#11](https://github.com/avi2d/checks/pull/11)
|
|
191
217
|
|
|
192
218
|
### Fixes
|
|
193
219
|
|
|
194
|
-
- count violation lines from file top, drop dead moduleStart
|
|
220
|
+
- count violation lines from file top, drop dead moduleStart [#10](https://github.com/avi2d/checks/pull/10)
|
package/CONTRIBUTING.md
CHANGED
|
@@ -16,7 +16,9 @@ To check a change the way CI does:
|
|
|
16
16
|
1. Run `bun run typecheck`.
|
|
17
17
|
1. Run `bun run test`, which runs the suite through `scripts/test.ts`.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Declare each skip with `skipReason(reason, name)` beside the native Bun test call, as [checks-test](docs/gates/checks-test.md) says.
|
|
20
|
+
|
|
21
|
+
CI runs the commands in `.github/workflows/ci.yml` and lints the pull request title in `.github/workflows/commitlint.yml`.
|
|
20
22
|
|
|
21
23
|
## Regenerate what is committed
|
|
22
24
|
|
|
@@ -24,9 +26,8 @@ Each generated file is committed, and lint, the suite or CI's diff after the bui
|
|
|
24
26
|
|
|
25
27
|
To regenerate after an edit:
|
|
26
28
|
|
|
27
|
-
1. After editing `
|
|
28
|
-
|
|
29
|
-
It rewrites `dist/index.js`, `dist/feature-rules.js`, `quality.schema.json` and `templates/`.
|
|
29
|
+
1. After editing `effect-channel/`, `readability/` or the templates in `scripts/doc-templates.ts`, run `bun run build`.
|
|
30
|
+
It rewrites `dist/` and `templates/`.
|
|
30
31
|
1. After editing anything a generated block names as its source in its opening marker, run `bun run build`, which rewrites every generated block.
|
|
31
32
|
1. Commit what the command rewrote in the same commit as the edit.
|
|
32
33
|
|
|
@@ -49,7 +50,9 @@ To release a version:
|
|
|
49
50
|
```
|
|
50
51
|
|
|
51
52
|
1. Watch the `release` workflow.
|
|
52
|
-
It refuses a tag off `main` or one that disagrees with `package.json
|
|
53
|
+
It refuses a tag off `main` or one that disagrees with `package.json`.
|
|
54
|
+
It reruns the build, the check that the build changed no committed file, lint, typecheck and the suite before it publishes to npm.
|
|
55
|
+
After npm publish succeeds, the workflow creates or updates the GitHub release with the matching `CHANGELOG.md` section.
|
|
53
56
|
|
|
54
57
|
`publishConfig.access` in `package.json` is what makes the scoped package public.
|
|
55
58
|
npm attaches a trusted publisher only to a package that already exists, so a package's first version goes out by hand.
|
|
@@ -65,22 +68,23 @@ To place a change:
|
|
|
65
68
|
| Path | What it holds |
|
|
66
69
|
| --- | --- |
|
|
67
70
|
| `scripts/` | every bin, and the modules they share |
|
|
68
|
-
| `effect-channel/` | the oxlint plugin with the Effect error-channel
|
|
69
|
-
| `
|
|
70
|
-
| `
|
|
71
|
+
| `effect-channel/` | the oxlint plugin with the Effect error-channel rules |
|
|
72
|
+
| `readability/` | the oxlint plugin with the readability rules |
|
|
73
|
+
| `dist/` | the committed oxlint plugin bundles |
|
|
74
|
+
| `presets/` | the Effect rule blocks consumers copy into native configs |
|
|
71
75
|
| `templates/` | one template per kind of doc file, which `bun run build` renders |
|
|
72
76
|
| `CHANGELOG.md` | every release, which `bun run build` writes from the conventional commits |
|
|
73
77
|
| `tests/` | the suite, with the tests that spawn a process under `tests/e2e/` |
|
|
74
78
|
| `docs/gates/` | one reference page per bin |
|
|
75
79
|
| `docs/configs/` | one reference page per shipped config a bin does not own |
|
|
76
80
|
| `docs/design.md` | why the kit is shaped the way it is |
|
|
77
|
-
| the root configs | `oxlintrc.json`, `tsconfig.effect.json`, `bunfig.toml`, `commitlint.config.js`, `dependency-cruiser.config.js`, `stryker.preset.js
|
|
81
|
+
| the root configs | `oxlintrc.json`, `tsconfig.effect.json`, `bunfig.toml`, `commitlint.config.js`, `dependency-cruiser.config.js`, `stryker.preset.js`, which a consuming repository extends or copies |
|
|
78
82
|
|
|
79
83
|
1. Change the page under `docs/` that describes the behaviour in the same commit as the behaviour.
|
|
80
84
|
A new bin gets its page under `docs/gates/`, and the suite fails until it has one.
|
|
81
85
|
|
|
82
86
|
This repository holds itself to the kit, with two exceptions of its own.
|
|
83
|
-
Its `.dependency-cruiser.cjs` redeclares `no-orphans` with
|
|
87
|
+
Its `.dependency-cruiser.cjs` redeclares `no-orphans` with each plugin entry added to its `pathNot`.
|
|
84
88
|
Its `.oxlintrc.json` lifts `effect-channel/no-throw` from `scripts/comment-matchers.ts`, whose synchronous `refused()` a host loads without `node_modules`.
|
|
85
89
|
|
|
86
90
|
## Related topics
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`@avi2dg/checks` is the kit of deterministic checks a TypeScript repository installs to hold its code, tests, commits, CI wiring and docs to one shared standard.
|
|
4
4
|
It ships the lint gates `checks-lint` runs over each pull request, the test runners, and the configs a repository extends for oxlint, tsc, dependency-cruiser, commitlint, bun and Stryker.
|
|
5
|
-
|
|
5
|
+
Each repository owns its workflows and native tool configs, as [Native settings](docs/configs/native-settings.md) maps.
|
|
6
6
|
|
|
7
7
|
## Before you begin
|
|
8
8
|
|
|
@@ -59,30 +59,22 @@ To consume the kit from a repository:
|
|
|
59
59
|
}
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
1. Declare the commands CI runs in `quality.json` at the repository root:
|
|
63
|
-
|
|
64
|
-
```json
|
|
65
|
-
{
|
|
66
|
-
"$schema": "./node_modules/@avi2dg/checks/quality.schema.json",
|
|
67
|
-
"gates": { "ci": ["bun run lint", "bun run typecheck", "bun run test"] }
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
62
|
1. Copy the bunfig preset:
|
|
72
63
|
|
|
73
64
|
```sh
|
|
74
65
|
cp node_modules/@avi2dg/checks/bunfig.toml bunfig.toml
|
|
75
66
|
```
|
|
76
67
|
|
|
77
|
-
1. Add
|
|
68
|
+
1. Add scripts to `package.json`, replacing the build entry with the repository's own build command:
|
|
78
69
|
|
|
79
70
|
```json
|
|
71
|
+
"build": "bun build src/index.ts --outdir dist --target node",
|
|
80
72
|
"lint": "oxlint --type-aware && checks-lint",
|
|
81
73
|
"typecheck": "tsc --noEmit && effect-tsgo diagnostics --project tsconfig.json --format text --strict",
|
|
82
74
|
"test": "checks-test"
|
|
83
75
|
```
|
|
84
76
|
|
|
85
|
-
1. Run the
|
|
77
|
+
1. Run the scripts on every pull request in `.github/workflows/ci.yml`, fetching the whole history the range needs:
|
|
86
78
|
|
|
87
79
|
```yaml
|
|
88
80
|
on:
|
|
@@ -96,17 +88,20 @@ To consume the kit from a repository:
|
|
|
96
88
|
fetch-depth: 0
|
|
97
89
|
- uses: oven-sh/setup-bun@v2
|
|
98
90
|
- run: bun install --frozen-lockfile
|
|
91
|
+
- run: bun run build
|
|
92
|
+
- run: git diff --exit-code
|
|
99
93
|
- run: bun run lint
|
|
100
94
|
- run: bun run typecheck
|
|
101
95
|
- run: bun run test
|
|
102
96
|
```
|
|
103
97
|
|
|
98
|
+
Add a pull request title lint step in another workflow using `./node_modules/.bin/commitlint`.
|
|
104
99
|
`bun run lint` then ends with `checks-lint: <count> gate(s) pass`.
|
|
105
100
|
|
|
106
101
|
## What runs
|
|
107
102
|
|
|
108
103
|
`checks-lint` runs these gates in this order, each over the working tree or over the range it resolves, and names every one that fails.
|
|
109
|
-
|
|
104
|
+
`checks-lint` runs every applicable gate, including the TypeScript gates once the repository tracks TypeScript.
|
|
110
105
|
|
|
111
106
|
<!-- generated gates: bun run build writes it from KIT_GATES in scripts/gates.ts and scripts/doc-blocks.ts -->
|
|
112
107
|
|
|
@@ -119,22 +114,19 @@ A repository leaves out a gate that does not apply to it through `gates.lint`, a
|
|
|
119
114
|
| [`checks-suppressions-ratchet`](docs/gates/checks-suppressions-ratchet.md) | the range | every repository |
|
|
120
115
|
| [`checks-ci-wiring`](docs/gates/checks-ci-wiring.md) | the working tree | every repository |
|
|
121
116
|
| [`checks-docs`](docs/gates/checks-docs.md) | the range | every repository |
|
|
122
|
-
| [`checks-quality`](docs/gates/checks-quality.md) | the working tree | a repository tracking `quality.json` |
|
|
123
|
-
| [`checks-size-budget`](docs/gates/checks-size-budget.md) | the range | a repository tracking `*.ts` or `*.tsx` |
|
|
124
117
|
| [`checks-repetition`](docs/gates/checks-repetition.md) | the range | a repository tracking `*.ts` or `*.tsx` |
|
|
125
|
-
| [`checks-feature-owners`](docs/gates/checks-feature-owners.md) | the range | a repository tracking `*.ts` or `*.tsx` |
|
|
126
118
|
| [`checks-quarantine-clock`](docs/gates/checks-quarantine-clock.md) | the range | every repository |
|
|
127
119
|
|
|
128
120
|
<!-- end generated gates -->
|
|
129
121
|
|
|
130
122
|
These bins run on their own:
|
|
131
123
|
|
|
132
|
-
- [`checks-test`](docs/gates/checks-test.md) runs the suite as `scripts.test` and refuses a skip
|
|
124
|
+
- [`checks-test`](docs/gates/checks-test.md) runs the suite as `scripts.test` and refuses a skip without a reason at its test site.
|
|
133
125
|
- [`checks-flake`](docs/gates/checks-flake.md) runs the suite on a schedule and records the seeds a flaky test fails with.
|
|
134
126
|
- [`checks-mutation-compare`](docs/gates/checks-mutation-compare.md) holds every mutant in a pull request to no regression.
|
|
135
127
|
- [`checks-subsumed-tests`](docs/gates/checks-subsumed-tests.md) lists each test another test subsumes in a mutation run.
|
|
136
128
|
- [`checks-backtest`](docs/gates/checks-backtest.md) reports what the comment check would have refused in recent history.
|
|
137
|
-
- [`checks-vendor`](docs/gates/checks-vendor.md) pins each library `
|
|
129
|
+
- [`checks-vendor`](docs/gates/checks-vendor.md) pins each library its `prepare` arguments name to a shared read-only clone and links it under `repos/`.
|
|
138
130
|
|
|
139
131
|
`checks-lint` has [its own page](docs/gates/checks-lint.md), which says which range it resolves.
|
|
140
132
|
The oxlint base, the dependency-cruiser base and the commitlint config run through their own tools, as the pages under Related topics say.
|
|
@@ -144,13 +136,13 @@ The oxlint base, the dependency-cruiser base and the commitlint config run throu
|
|
|
144
136
|
To move a repository to a newer release of the kit:
|
|
145
137
|
|
|
146
138
|
1. Run the install line again, which moves the kit to its newest release and the peers to the versions it pins.
|
|
147
|
-
1.
|
|
139
|
+
1. Review the Effect overrides in `.oxlintrc.json` and `tsconfig.json` when a release changes their presets.
|
|
148
140
|
1. Copy `node_modules/@avi2dg/checks/bunfig.toml` over `bunfig.toml` again, since `checks-test-layout` compares the copy with the installed preset.
|
|
149
141
|
1. Run `bun run lint`, `bun run typecheck` and `bun run test`.
|
|
150
142
|
|
|
151
143
|
The repository's lockfile pins the kit, so a repository moves only when it runs these steps.
|
|
152
144
|
[CHANGELOG.md](CHANGELOG.md), shipped in the package, lists what each release changed.
|
|
153
|
-
A repository that
|
|
145
|
+
A repository that tracks `quality.json` moves its settings as [Native settings](docs/configs/native-settings.md#consumer-migration) maps.
|
|
154
146
|
|
|
155
147
|
## Where things are
|
|
156
148
|
|
|
@@ -168,18 +160,17 @@ Every path is relative to the installed package, `node_modules/@avi2dg/checks/`.
|
|
|
168
160
|
| `dependency-cruiser.config.js` | the shared dependency-cruiser base |
|
|
169
161
|
| `scripts/` | every bin, which a package script calls by its `checks-` name |
|
|
170
162
|
| `templates/` | one template per kind of doc file, which a new doc file starts from |
|
|
171
|
-
| `presets/` | the Effect rule blocks
|
|
172
|
-
| `quality.schema.json` | the schema of `quality.json`, which its `$schema` line names |
|
|
163
|
+
| `presets/` | the Effect rule blocks a repository copies into its native config |
|
|
173
164
|
| `oxlintrc.json` | the oxlint base config `.oxlintrc.json` extends |
|
|
174
165
|
| `stryker.preset.js` | the Stryker mutation-testing preset |
|
|
175
166
|
| `tsconfig.effect.json` | the tsconfig fragment with the Effect language-service block |
|
|
176
|
-
| `dist/` | the compiled oxlint
|
|
167
|
+
| `dist/` | the compiled oxlint plugins, one per purpose |
|
|
177
168
|
|
|
178
169
|
<!-- end generated shipped -->
|
|
179
170
|
|
|
180
171
|
## Related topics
|
|
181
172
|
|
|
182
|
-
- [
|
|
173
|
+
- [Native settings](docs/configs/native-settings.md)
|
|
183
174
|
- [The Effect rules](docs/configs/effect-rules.md)
|
|
184
175
|
- [The TypeScript rules](docs/configs/typescript-rules.md)
|
|
185
176
|
- [The dependency rules](docs/configs/dependency-rules.md)
|
package/bunfig.toml
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
[test]
|
|
2
|
-
pathIgnorePatterns = ["**/tests/quarantine/**", "repos/**"]
|
|
2
|
+
pathIgnorePatterns = ["**/tests/quarantine/**", "**/tests/live/**", "**/tests/pixel/**", "repos/**"]
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// effect-channel/no-error-channel-escape.ts
|
|
2
|
+
var EFFECT_SOURCES = new Set(["effect", "effect/Effect"]);
|
|
3
|
+
var INSTEAD = {
|
|
4
|
+
drops: "it drops the failure and the success together, so no caller can tell one from the other. Handle the error by tag, or keep it as a value with Effect.result or Effect.exit",
|
|
5
|
+
swallows: "a Cause is the typed error plus defects plus interruption, so this swallows the bugs and the cancellations along with it. Catch the errors you named, with Effect.catchTag or Effect.catchTags",
|
|
6
|
+
blind: "the handler cannot see what it is recovering from, so every error in the channel collapses into one fallback. Name the errors with Effect.catchTag, or take the error and use it"
|
|
7
|
+
};
|
|
8
|
+
var REFUSED = new Map([
|
|
9
|
+
["ignore", INSTEAD.drops],
|
|
10
|
+
["ignoreCause", INSTEAD.drops],
|
|
11
|
+
["catchCause", INSTEAD.swallows],
|
|
12
|
+
["catchCauseIf", INSTEAD.swallows],
|
|
13
|
+
["catchCauseFilter", INSTEAD.swallows]
|
|
14
|
+
]);
|
|
15
|
+
var blindToTheError = (handler) => {
|
|
16
|
+
if (!handler)
|
|
17
|
+
return false;
|
|
18
|
+
if (handler.type !== "ArrowFunctionExpression" && handler.type !== "FunctionExpression")
|
|
19
|
+
return false;
|
|
20
|
+
return handler.params.every((param) => param.type === "Identifier" && /^_+$/.test(param.name));
|
|
21
|
+
};
|
|
22
|
+
var rule = {
|
|
23
|
+
meta: {
|
|
24
|
+
type: "problem",
|
|
25
|
+
docs: { description: "Disallow the combinators that erase Effect's error channel" }
|
|
26
|
+
},
|
|
27
|
+
create(context) {
|
|
28
|
+
const effect = new Set;
|
|
29
|
+
const named = (node) => {
|
|
30
|
+
if (!node || node.type !== "MemberExpression" || node.computed)
|
|
31
|
+
return null;
|
|
32
|
+
if (node.object.type !== "Identifier" || !effect.has(node.object.name))
|
|
33
|
+
return null;
|
|
34
|
+
return node.property.type === "Identifier" ? node.property.name : null;
|
|
35
|
+
};
|
|
36
|
+
const refuse = (node, combinator, instead) => {
|
|
37
|
+
context.report({ node, message: `Effect.${combinator} erases the error channel: ${instead}` });
|
|
38
|
+
};
|
|
39
|
+
return {
|
|
40
|
+
ImportDeclaration(node) {
|
|
41
|
+
if (!EFFECT_SOURCES.has(node.source.value))
|
|
42
|
+
return;
|
|
43
|
+
const module = node.source.value === "effect/Effect";
|
|
44
|
+
for (const specifier of node.specifiers) {
|
|
45
|
+
if (specifier.type === "ImportSpecifier") {
|
|
46
|
+
if (specifier.imported.type === "Identifier" && specifier.imported.name === "Effect")
|
|
47
|
+
effect.add(specifier.local.name);
|
|
48
|
+
} else if (module)
|
|
49
|
+
effect.add(specifier.local.name);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
MemberExpression(node) {
|
|
53
|
+
const combinator = named(node);
|
|
54
|
+
if (combinator === null)
|
|
55
|
+
return;
|
|
56
|
+
const instead = REFUSED.get(combinator);
|
|
57
|
+
if (instead !== undefined)
|
|
58
|
+
refuse(node, combinator, instead);
|
|
59
|
+
},
|
|
60
|
+
CallExpression(node) {
|
|
61
|
+
if (named(node.callee) !== "catch")
|
|
62
|
+
return;
|
|
63
|
+
if (!blindToTheError(node.arguments[node.arguments.length - 1]))
|
|
64
|
+
return;
|
|
65
|
+
refuse(node, "catch", INSTEAD.blind);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
var no_error_channel_escape_default = rule;
|
|
71
|
+
|
|
72
|
+
// effect-channel/no-throw.ts
|
|
73
|
+
var rule2 = {
|
|
74
|
+
meta: {
|
|
75
|
+
type: "problem",
|
|
76
|
+
docs: { description: "Disallow throw, which fails outside Effect's error channel" }
|
|
77
|
+
},
|
|
78
|
+
create(context) {
|
|
79
|
+
return {
|
|
80
|
+
ThrowStatement(node) {
|
|
81
|
+
context.report({
|
|
82
|
+
node,
|
|
83
|
+
message: "throw escapes the error channel: no type records the failure, so no caller has to answer for it. Define the failure with Schema.TaggedError and fail with it through Effect.fail, so it stays in E for Effect.catchTag to handle"
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
var no_throw_default = rule2;
|
|
90
|
+
|
|
91
|
+
// effect-channel/no-try-catch.ts
|
|
92
|
+
var rule3 = {
|
|
93
|
+
meta: {
|
|
94
|
+
type: "problem",
|
|
95
|
+
docs: { description: "Disallow a try statement with a catch clause, which recovers outside Effect's error channel" }
|
|
96
|
+
},
|
|
97
|
+
create(context) {
|
|
98
|
+
return {
|
|
99
|
+
CatchClause(node) {
|
|
100
|
+
context.report({
|
|
101
|
+
node,
|
|
102
|
+
message: "catch recovers outside the error channel: it takes whatever was thrown as unknown, bugs included. Wrap the throwing call in Effect.try or Effect.tryPromise, whose catch maps the cause to a Schema.TaggedError, and recover by tag with Effect.catchTag"
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
var no_try_catch_default = rule3;
|
|
109
|
+
|
|
110
|
+
// effect-channel/index.ts
|
|
111
|
+
var plugin = {
|
|
112
|
+
meta: { name: "effect-channel" },
|
|
113
|
+
rules: {
|
|
114
|
+
"no-error-channel-escape": no_error_channel_escape_default,
|
|
115
|
+
"no-throw": no_throw_default,
|
|
116
|
+
"no-try-catch": no_try_catch_default
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
var effect_channel_default = plugin;
|
|
120
|
+
export {
|
|
121
|
+
effect_channel_default as default
|
|
122
|
+
};
|