@yuu1111/quality-check 0.8.0 → 0.10.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/README.ja.md +32 -34
- package/README.md +34 -59
- package/dist/cli.js +31 -21
- package/package.json +1 -1
- package/src/config.ts +29 -2
- package/src/engines.ts +26 -0
package/README.ja.md
CHANGED
|
@@ -10,6 +10,8 @@ Projectごとのscriptから個別に呼んでいたBiome、型検査、Knip、c
|
|
|
10
10
|
bun add -D @yuu1111/quality-check
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
engineのbinaryは利用Projectの `node_modules/.bin` から実行時に解決する engineを自分のscriptから呼ばないProjectではKnipが `@yuu1111/comment-check` などを未使用依存として報告するため `knip.ts` の `ignoreDependencies` で理由付きに宣言する
|
|
14
|
+
|
|
13
15
|
## Usage
|
|
14
16
|
|
|
15
17
|
`quality.config.ts` で起動するengineとengineごとの起動条件を指定し、scriptから起動する
|
|
@@ -50,27 +52,29 @@ export default defineConfig({
|
|
|
50
52
|
});
|
|
51
53
|
```
|
|
52
54
|
|
|
53
|
-
engine
|
|
55
|
+
engineごとの出力と所要時間、集約summaryを並べて出し、どのengineが失敗したかと実行にかかった合計時間を1回の実行で示す
|
|
54
56
|
|
|
55
57
|
```text
|
|
56
58
|
== biome ==
|
|
57
59
|
Checked 128 files in 260ms. No fixes applied.
|
|
58
|
-
biome: passed (exit 0)
|
|
60
|
+
biome: passed (exit 0, 296ms)
|
|
59
61
|
|
|
60
62
|
== comment-check ==
|
|
61
63
|
src/queue.ts:18:2 placeholder-comment placeholder comment should be resolved or tracked
|
|
62
|
-
comment-check: failed (1 new, 0 resolved, 0 warnings)
|
|
64
|
+
comment-check: failed (1 new, 0 resolved, 0 warnings, 118ms)
|
|
63
65
|
|
|
64
|
-
quality-check: 1 of 3 engines failed
|
|
66
|
+
quality-check: 1 of 3 engines failed (1250ms)
|
|
65
67
|
failed: comment-check
|
|
66
68
|
passed: biome, tsdoc-check
|
|
67
69
|
```
|
|
68
70
|
|
|
71
|
+
終了codeは0が全engine成功、1が失敗したengineあり、2が設定またはengine起動の失敗
|
|
72
|
+
|
|
69
73
|
## Config
|
|
70
74
|
|
|
71
|
-
| Field |
|
|
75
|
+
| Field | 説明 |
|
|
72
76
|
|-------|-------------|
|
|
73
|
-
| `engines` | 起動するengine
|
|
77
|
+
| `engines` | 起動するengine、値は `true` または `false` |
|
|
74
78
|
| `config` | engineごとの起動条件 |
|
|
75
79
|
| `baseline` | baseline fileのpath `false` なら差分判定を行わない |
|
|
76
80
|
|
|
@@ -78,7 +82,7 @@ engineは `biome` → `typecheck` → `knip` → `code-style-check` → `comment
|
|
|
78
82
|
|
|
79
83
|
`engines` は起動の委任だけを表し、起動条件は `config` のengineの下へ置く engineごとの条件は複数行のobjectとして書き、ruleやoptionを足しても他のengineの行が動かないようにする engineが受け取る条件は次のとおり
|
|
80
84
|
|
|
81
|
-
|
|
|
85
|
+
| Engine | Command | 条件 |
|
|
82
86
|
|--------|-----------------|--------------|
|
|
83
87
|
| `biome` | `biome check` | `targets`、`args` 除外pathは `biome.json` が持つ |
|
|
84
88
|
| `typecheck` | `tsc --noEmit` | `args`、`projects` 設定は `tsconfig.json` が持つ |
|
|
@@ -86,43 +90,37 @@ engineは `biome` → `typecheck` → `knip` → `code-style-check` → `comment
|
|
|
86
90
|
| `code-style-check` | `code-style-check --json` | `ignore`、`targets`、`args` |
|
|
87
91
|
| `comment-check` | `comment-check --json` | `ignore`、`targets`、`args`、`enable`(有効にするrule名) |
|
|
88
92
|
| `document-style-check` | `document-style-check lint --json` | `ignore`、`targets`、`args`、`enable`(有効にするrule名) |
|
|
89
|
-
| `tsdoc-check` | `tsdoc-check --json` | `ignore`、`targets`、`args`、`error`(違反として扱うrule名) |
|
|
93
|
+
| `tsdoc-check` | `tsdoc-check --json` | `ignore`、`targets`、`args`、`enable`(有効にするrule名)、`error`(違反として扱うrule名) |
|
|
90
94
|
|
|
91
|
-
`args` はengineの既定引数の後ろへ足す
|
|
95
|
+
`args` はengineの既定引数の後ろへ足す
|
|
96
|
+
設定fileで表せない起動条件や、engineの引数が変わったときの逃げ道として使う
|
|
97
|
+
|
|
98
|
+
engineが受け取らない条件は渡さず、その旨をそのengineのsectionへ出す
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
== biome ==
|
|
102
|
+
biome: ignore skipped (biome.json holds its settings)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`enable` は `comment-check` と `document-style-check` と `tsdoc-check` の `--enable <rule>` になり、他のengineでは拒否される
|
|
106
|
+
このCLIはengineを同梱しないため、opt-in ruleを有効にするProjectは対応するengine packageも同じ変更で更新する
|
|
107
|
+
|
|
108
|
+
`comment-check` はbaseline差分を無効化する未作成のpathを渡して起動する
|
|
109
|
+
新規と解消済みの判定はengineごとではなく統合CLIが1つのbaseline fileで行うため、既存の `comment-baseline.json` がある場合は `--update-baseline` で移す
|
|
110
|
+
|
|
111
|
+
`typecheck` は `projects` に並べたtsconfigごとに `tsc --noEmit -p <path>` を起動する
|
|
112
|
+
省略時はカレントの `tsconfig.json` を1回だけ読む
|
|
92
113
|
|
|
93
114
|
## Options
|
|
94
115
|
|
|
95
|
-
| Option |
|
|
116
|
+
| Option | 説明 |
|
|
96
117
|
|--------|-------------|
|
|
97
118
|
| `--config <path>` | 読み込むconfig file(既定は `quality.config.ts`) |
|
|
98
119
|
| `--baseline <path>` | baseline fileを上書きする |
|
|
99
|
-
| `--ignore <path>` | 除外path
|
|
120
|
+
| `--ignore <path>` | 除外pathを追加する、複数指定できる |
|
|
100
121
|
| `--update-baseline` | 現在の検出でbaselineを置き換える |
|
|
101
122
|
| `--json` | engineごとの結果をJSONで出力する |
|
|
102
123
|
|
|
103
124
|
`--ignore` と位置引数の対象pathは、その条件を受け取るengineへだけ渡す
|
|
104
125
|
|
|
105
|
-
## Notes
|
|
106
|
-
|
|
107
|
-
終了codeは0が全engine成功、1が失敗したengineあり、2が設定またはengine起動の失敗
|
|
108
|
-
|
|
109
126
|
色は標準出力が端末のときだけ付ける `NO_COLOR` で無効にし、`FORCE_COLOR` で強制できる `--json` の出力には付けない
|
|
110
|
-
|
|
111
|
-
色を扱えるengineへは自身の出力の色も許可する Biomeは `--colors=force`、tscは `--pretty` を受け取る
|
|
112
|
-
|
|
113
|
-
engineが受け取らない条件を書いた場合は渡さず、その旨をそのengineのsectionへ出す
|
|
114
|
-
|
|
115
|
-
```text
|
|
116
|
-
== biome ==
|
|
117
|
-
biome: ignore skipped (biome.json holds its settings)
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Biome、型検査、Knipの設定は `biome.json`、`tsconfig.json`、`knip.ts` が持つ このCLIは同じfileからengineの起動と結果の集約だけを行う
|
|
121
|
-
|
|
122
|
-
engineのbinaryは利用Projectの `node_modules/.bin` から実行時に解決する engineを自分のscriptから呼ばないProjectではKnipが `@yuu1111/comment-check` などを未使用依存として報告するため `knip.ts` の `ignoreDependencies` で理由付きに宣言する
|
|
123
|
-
|
|
124
|
-
`comment-check` はbaseline差分を無効化する未作成のpathを渡して起動する 新規と解消済みの判定はengineごとではなく統合CLIが1つのbaseline fileで行うため、既存の `comment-baseline.json` がある場合は `--update-baseline` で移す
|
|
125
|
-
|
|
126
|
-
`enable` は `comment-check` と `document-style-check` のopt-in ruleだけを受け取り、それぞれのcommandの `--enable <rule>` になる 他のengineへ書くとunknown optionとして拒否し、既定のrule集合は変えない このCLIはengineを同梱しないため、opt-in ruleを有効にするProjectは対応するengine packageも同じ変更で更新する
|
|
127
|
-
|
|
128
|
-
`typecheck` は `projects` に並べたtsconfigごとに `tsc --noEmit -p <path>` を起動する 省略時はカレントの `tsconfig.json` を1回だけ読み、`args` はすべての起動へ足す
|
package/README.md
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# @yuu1111/quality-check
|
|
4
4
|
|
|
5
|
-
Runs Biome, the type checker, Knip, code-style-check, comment-check,
|
|
6
|
-
document-style-check, and the TSDoc checker from one CLI instead of one script per project.
|
|
5
|
+
Runs Biome, the type checker, Knip, code-style-check, comment-check, document-style-check, and the TSDoc checker from one CLI instead of one script per project.
|
|
7
6
|
The baseline diff lives here too.
|
|
8
7
|
|
|
9
8
|
## Install
|
|
@@ -12,10 +11,12 @@ The baseline diff lives here too.
|
|
|
12
11
|
bun add -D @yuu1111/quality-check
|
|
13
12
|
```
|
|
14
13
|
|
|
14
|
+
An engine binary is resolved at run time from the project's `node_modules/.bin`.
|
|
15
|
+
A project that never calls an engine from its own scripts therefore sees Knip report `@yuu1111/comment-check` and its siblings as unused dependencies, so it declares them in `ignoreDependencies` with the reason.
|
|
16
|
+
|
|
15
17
|
## Usage
|
|
16
18
|
|
|
17
|
-
Declare the engines to run and the conditions of each engine in
|
|
18
|
-
`quality.config.ts`, then call the CLI from a script:
|
|
19
|
+
Declare the engines to run and the conditions of each engine in `quality.config.ts`, then call the CLI from a script:
|
|
19
20
|
|
|
20
21
|
```json
|
|
21
22
|
{
|
|
@@ -53,23 +54,24 @@ export default defineConfig({
|
|
|
53
54
|
});
|
|
54
55
|
```
|
|
55
56
|
|
|
56
|
-
Each engine prints its own section, and the summary names the engines that
|
|
57
|
-
failed:
|
|
57
|
+
Each engine prints its own section with its own time, and the summary names the engines that failed and the total time the run took:
|
|
58
58
|
|
|
59
59
|
```text
|
|
60
60
|
== biome ==
|
|
61
61
|
Checked 128 files in 260ms. No fixes applied.
|
|
62
|
-
biome: passed (exit 0)
|
|
62
|
+
biome: passed (exit 0, 296ms)
|
|
63
63
|
|
|
64
64
|
== comment-check ==
|
|
65
65
|
src/queue.ts:18:2 placeholder-comment placeholder comment should be resolved or tracked
|
|
66
|
-
comment-check: failed (1 new, 0 resolved, 0 warnings)
|
|
66
|
+
comment-check: failed (1 new, 0 resolved, 0 warnings, 118ms)
|
|
67
67
|
|
|
68
|
-
quality-check: 1 of 3 engines failed
|
|
68
|
+
quality-check: 1 of 3 engines failed (1250ms)
|
|
69
69
|
failed: comment-check
|
|
70
70
|
passed: biome, tsdoc-check
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
Exit code 0 means every engine passed, 1 that at least one failed, and 2 that the configuration or an engine could not start.
|
|
74
|
+
|
|
73
75
|
## Config
|
|
74
76
|
|
|
75
77
|
| Field | Description |
|
|
@@ -78,12 +80,11 @@ quality-check: 1 of 3 engines failed
|
|
|
78
80
|
| `config` | Conditions of each engine |
|
|
79
81
|
| `baseline` | Baseline file path; `false` disables the diff |
|
|
80
82
|
|
|
81
|
-
Engines run in the order `biome`, `typecheck`, `knip`, `code-style-check`,
|
|
82
|
-
`comment-check`, `document-style-check`, `tsdoc-check`.
|
|
83
|
+
Engines run in the order `biome`, `typecheck`, `knip`, `code-style-check`, `comment-check`, `document-style-check`, `tsdoc-check`.
|
|
83
84
|
|
|
84
|
-
`engines` only delegates the start-up, and the conditions belong under the
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
`engines` only delegates the start-up, and the conditions belong under the engine in `config`.
|
|
86
|
+
Write an engine's conditions as a multi-line object, so a new rule or option changes one engine's block alone.
|
|
87
|
+
Each engine runs:
|
|
87
88
|
|
|
88
89
|
| Engine | Command | Conditions |
|
|
89
90
|
|--------|---------|------------|
|
|
@@ -93,10 +94,24 @@ new rule or option changes one engine's block alone. Each engine runs:
|
|
|
93
94
|
| `code-style-check` | `code-style-check --json` | `ignore`, `targets`, `args` |
|
|
94
95
|
| `comment-check` | `comment-check --json` | `ignore`, `targets`, `args`, `enable` (rule names to turn on) |
|
|
95
96
|
| `document-style-check` | `document-style-check lint --json` | `ignore`, `targets`, `args`, `enable` (rule names to turn on) |
|
|
96
|
-
| `tsdoc-check` | `tsdoc-check --json` | `ignore`, `targets`, `args`, `error` (rule names to fail on) |
|
|
97
|
+
| `tsdoc-check` | `tsdoc-check --json` | `ignore`, `targets`, `args`, `enable` (rule names to turn on), `error` (rule names to fail on) |
|
|
98
|
+
|
|
99
|
+
`args` is appended after the engine defaults, for conditions the config cannot express and for the case where an engine changes its arguments.
|
|
100
|
+
|
|
101
|
+
A condition that an engine does not take is not passed on, and the section says so:
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
== biome ==
|
|
105
|
+
biome: ignore skipped (biome.json holds its settings)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`enable` becomes `--enable <rule>` on `comment-check`, `document-style-check`, and `tsdoc-check`, and the other engines reject the field.
|
|
109
|
+
This CLI ships no engine of its own, so a project that turns an opt-in rule on updates the matching engine package in the same change.
|
|
110
|
+
|
|
111
|
+
`comment-check` runs with an unwritten baseline path so that it reports every finding.
|
|
112
|
+
The new-and-resolved diff is done by this CLI from a single baseline file, so an existing `comment-baseline.json` is moved over with `--update-baseline`.
|
|
97
113
|
|
|
98
|
-
`
|
|
99
|
-
express and for the case where an engine changes its arguments.
|
|
114
|
+
`typecheck` starts `tsc --noEmit -p <path>` once per path in `projects`, and falls back to the current `tsconfig.json`.
|
|
100
115
|
|
|
101
116
|
## Options
|
|
102
117
|
|
|
@@ -110,45 +125,5 @@ express and for the case where an engine changes its arguments.
|
|
|
110
125
|
|
|
111
126
|
`--ignore` and the positional targets reach only the engines that take them.
|
|
112
127
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
Exit code 0 means every engine passed, 1 that at least one failed, and 2 that the
|
|
116
|
-
configuration or an engine could not start.
|
|
117
|
-
|
|
118
|
-
Color is added only when stdout is a terminal. `NO_COLOR` turns it off and
|
|
119
|
-
`FORCE_COLOR` turns it on; the `--json` output stays plain.
|
|
120
|
-
|
|
121
|
-
The engines that can color their own output receive the same permission: Biome
|
|
122
|
-
gets `--colors=force` and tsc gets `--pretty`.
|
|
123
|
-
|
|
124
|
-
A condition that an engine does not take is not passed on, and the section says
|
|
125
|
-
so:
|
|
126
|
-
|
|
127
|
-
```text
|
|
128
|
-
== biome ==
|
|
129
|
-
biome: ignore skipped (biome.json holds its settings)
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
Biome, the type checker, and Knip keep their settings in `biome.json`,
|
|
133
|
-
`tsconfig.json`, and `knip.ts`. This CLI starts the engines from one file and
|
|
134
|
-
aggregates the results.
|
|
135
|
-
|
|
136
|
-
An engine binary is resolved at run time from the `node_modules/.bin` of the
|
|
137
|
-
project. A project that never calls an engine from its own scripts therefore
|
|
138
|
-
sees Knip report `@yuu1111/comment-check` and its siblings as unused
|
|
139
|
-
dependencies, so it declares them in `ignoreDependencies` with the reason.
|
|
140
|
-
|
|
141
|
-
`comment-check` runs with an unwritten baseline path so that it reports every
|
|
142
|
-
finding. The new-and-resolved diff is done by this CLI from a single baseline
|
|
143
|
-
file, so an existing `comment-baseline.json` is moved over with
|
|
144
|
-
`--update-baseline`.
|
|
145
|
-
|
|
146
|
-
`enable` names the opt-in rules of `comment-check` and `document-style-check`
|
|
147
|
-
and becomes `--enable <rule>` on each of their commands. The other engines
|
|
148
|
-
reject the field, and the default rule set stays as it is. This CLI ships no
|
|
149
|
-
engine of its own, so a project that turns an opt-in rule on updates the
|
|
150
|
-
matching engine package in the same change.
|
|
151
|
-
|
|
152
|
-
`typecheck` starts `tsc --noEmit -p <path>` once per path in `projects`. Without
|
|
153
|
-
it the current `tsconfig.json` is read once, and `args` are added to every
|
|
154
|
-
start.
|
|
128
|
+
Color is added only when stdout is a terminal.
|
|
129
|
+
`NO_COLOR` turns it off and `FORCE_COLOR` turns it on; the `--json` output stays plain.
|
package/dist/cli.js
CHANGED
|
@@ -223,7 +223,7 @@ var ENGINE_OPTION_KEYS = {
|
|
|
223
223
|
"code-style-check": ["args", "ignore", "targets"],
|
|
224
224
|
"comment-check": ["args", "enable", "ignore", "targets"],
|
|
225
225
|
"document-style-check": ["args", "enable", "ignore", "targets"],
|
|
226
|
-
"tsdoc-check": ["args", "error", "ignore", "targets"]
|
|
226
|
+
"tsdoc-check": ["args", "enable", "error", "ignore", "targets"]
|
|
227
227
|
};
|
|
228
228
|
function readStringArray(value, field) {
|
|
229
229
|
if (value === undefined) {
|
|
@@ -264,7 +264,7 @@ function parseEngines(value, source) {
|
|
|
264
264
|
}
|
|
265
265
|
function parseEngineExtras(value, source, name) {
|
|
266
266
|
const extras = {};
|
|
267
|
-
if (name === "comment-check" || name === "document-style-check") {
|
|
267
|
+
if (name === "comment-check" || name === "document-style-check" || name === "tsdoc-check") {
|
|
268
268
|
const enable = readStringArray(value.enable, `${source}: config.${name}.enable`);
|
|
269
269
|
if (enable !== undefined) {
|
|
270
270
|
extras.enable = enable;
|
|
@@ -517,6 +517,7 @@ function buildEngineCommand(name, executable, context) {
|
|
|
517
517
|
return [
|
|
518
518
|
executable,
|
|
519
519
|
"--json",
|
|
520
|
+
...enableArguments(engineConfig(context.config, "tsdoc-check")),
|
|
520
521
|
...errorArguments,
|
|
521
522
|
...targets,
|
|
522
523
|
...ignoreArguments,
|
|
@@ -555,12 +556,17 @@ function describeCounts(result) {
|
|
|
555
556
|
}
|
|
556
557
|
return `${result.reported.length} new, ${result.resolved} resolved, ${result.warnings.length} warnings`;
|
|
557
558
|
}
|
|
559
|
+
function formatMillis(elapsedMs) {
|
|
560
|
+
return `${Math.round(elapsedMs)}ms`;
|
|
561
|
+
}
|
|
558
562
|
function describeStatus(result, paint) {
|
|
559
563
|
if (result.status === "error") {
|
|
560
|
-
|
|
564
|
+
const status = paint("error", "error");
|
|
565
|
+
return result.durationMs === null ? status : `${status} (${formatMillis(result.durationMs)})`;
|
|
561
566
|
}
|
|
562
567
|
const tone = result.status === "passed" ? "pass" : "error";
|
|
563
|
-
|
|
568
|
+
const elapsed = result.durationMs === null ? "" : `, ${formatMillis(result.durationMs)}`;
|
|
569
|
+
return `${paint(result.status, tone)} (${describeCounts(result)}${elapsed})`;
|
|
564
570
|
}
|
|
565
571
|
function formatEngineSection(result, paint = plainPainter) {
|
|
566
572
|
const lines = [paint(`== ${result.name} ==`, "header")];
|
|
@@ -583,14 +589,15 @@ function formatEngineSection(result, paint = plainPainter) {
|
|
|
583
589
|
return lines.join(`
|
|
584
590
|
`);
|
|
585
591
|
}
|
|
586
|
-
function formatSummary(results, paint = plainPainter) {
|
|
592
|
+
function formatSummary(results, elapsedMs, paint = plainPainter) {
|
|
587
593
|
const failed = results.filter((result) => result.status !== "passed").map((result) => result.name);
|
|
588
594
|
const passed = results.filter((result) => result.status === "passed").map((result) => result.name);
|
|
595
|
+
const elapsed = ` (${formatMillis(elapsedMs)})`;
|
|
589
596
|
if (failed.length === 0) {
|
|
590
|
-
return paint(`quality-check: ${results.length} engines passed`, "pass");
|
|
597
|
+
return paint(`quality-check: ${results.length} engines passed${elapsed}`, "pass");
|
|
591
598
|
}
|
|
592
599
|
const lines = [
|
|
593
|
-
paint(`quality-check: ${failed.length} of ${results.length} engines failed`, "error"),
|
|
600
|
+
paint(`quality-check: ${failed.length} of ${results.length} engines failed${elapsed}`, "error"),
|
|
594
601
|
` ${paint("failed:", "error")} ${failed.join(", ")}`
|
|
595
602
|
];
|
|
596
603
|
if (passed.length > 0) {
|
|
@@ -599,10 +606,12 @@ function formatSummary(results, paint = plainPainter) {
|
|
|
599
606
|
return lines.join(`
|
|
600
607
|
`);
|
|
601
608
|
}
|
|
602
|
-
function toJsonReport(results) {
|
|
609
|
+
function toJsonReport(results, elapsedMs) {
|
|
603
610
|
return {
|
|
611
|
+
elapsedMs: Math.round(elapsedMs),
|
|
604
612
|
engines: results.map((result) => ({
|
|
605
613
|
detected: result.detected.length,
|
|
614
|
+
durationMs: result.durationMs === null ? null : Math.round(result.durationMs),
|
|
606
615
|
exitCode: result.exitCode,
|
|
607
616
|
message: result.message ?? null,
|
|
608
617
|
name: result.name,
|
|
@@ -638,8 +647,8 @@ function parseJson(engine, stdout) {
|
|
|
638
647
|
let value;
|
|
639
648
|
try {
|
|
640
649
|
value = JSON.parse(stdout);
|
|
641
|
-
} catch {
|
|
642
|
-
throw new Error(`${engine} did not print JSON
|
|
650
|
+
} catch (error) {
|
|
651
|
+
throw new Error(`${engine} did not print JSON`, { cause: error });
|
|
643
652
|
}
|
|
644
653
|
if (!isJsonObject(value)) {
|
|
645
654
|
throw new Error(`${engine} printed an unexpected JSON value`);
|
|
@@ -754,25 +763,24 @@ async function runProcessEngine(name, options, executable, context, runner) {
|
|
|
754
763
|
status: exitCode === 0 ? "passed" : "failed"
|
|
755
764
|
};
|
|
756
765
|
}
|
|
757
|
-
async function
|
|
766
|
+
async function runEngine(name, options, context, runner) {
|
|
758
767
|
const executable = (options.resolve ?? resolveExecutable)(name, options.cwd);
|
|
768
|
+
const skipped = skippedEngineOptions(name, options.config.config?.[name]);
|
|
759
769
|
if (executable === null) {
|
|
760
770
|
return {
|
|
761
771
|
...baseResult(name, null, ""),
|
|
772
|
+
durationMs: null,
|
|
762
773
|
message: `${ENGINE_BINS[name]} is not installed`,
|
|
774
|
+
skipped,
|
|
763
775
|
status: "error"
|
|
764
776
|
};
|
|
765
777
|
}
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
}
|
|
769
|
-
return await runProcessEngine(name, options, executable, context, runner);
|
|
770
|
-
}
|
|
771
|
-
async function runEngine(name, options, context, runner) {
|
|
772
|
-
const result = await executeEngine(name, options, context, runner);
|
|
778
|
+
const startedAt = performance.now();
|
|
779
|
+
const result = isFindingEngine(name) ? await runFindingEngine(name, options, executable, context, runner) : await runProcessEngine(name, options, executable, context, runner);
|
|
773
780
|
return {
|
|
774
781
|
...result,
|
|
775
|
-
|
|
782
|
+
durationMs: performance.now() - startedAt,
|
|
783
|
+
skipped
|
|
776
784
|
};
|
|
777
785
|
}
|
|
778
786
|
async function runEngines(options) {
|
|
@@ -837,6 +845,7 @@ async function main(argv) {
|
|
|
837
845
|
}
|
|
838
846
|
const config = await loadConfig(configPath);
|
|
839
847
|
const baselinePath = resolveBaselinePath(options, config, cwd);
|
|
848
|
+
const startedAt = performance.now();
|
|
840
849
|
const results = await runEngines({
|
|
841
850
|
baseline: options.update || baselinePath === null ? null : readBaseline(baselinePath, "quality"),
|
|
842
851
|
color,
|
|
@@ -845,6 +854,7 @@ async function main(argv) {
|
|
|
845
854
|
overrides: { ignore: options.ignores, targets: options.targets },
|
|
846
855
|
rawBaseline: join2(tmpdir(), `quality-check-raw-${process.pid}.json`)
|
|
847
856
|
});
|
|
857
|
+
const elapsedMs = performance.now() - startedAt;
|
|
848
858
|
if (options.update) {
|
|
849
859
|
if (baselinePath === null) {
|
|
850
860
|
console.error("baseline is disabled by the configuration");
|
|
@@ -856,12 +866,12 @@ async function main(argv) {
|
|
|
856
866
|
return 0;
|
|
857
867
|
}
|
|
858
868
|
if (options.json) {
|
|
859
|
-
console.log(JSON.stringify(toJsonReport(results), null, "\t"));
|
|
869
|
+
console.log(JSON.stringify(toJsonReport(results, elapsedMs), null, "\t"));
|
|
860
870
|
} else {
|
|
861
871
|
for (const result of results) {
|
|
862
872
|
console.log(formatEngineSection(result, paint));
|
|
863
873
|
}
|
|
864
|
-
console.log(formatSummary(results, paint));
|
|
874
|
+
console.log(formatSummary(results, elapsedMs, paint));
|
|
865
875
|
}
|
|
866
876
|
return results.some((result) => result.status !== "passed") ? 1 : 0;
|
|
867
877
|
}
|
package/package.json
CHANGED
package/src/config.ts
CHANGED
|
@@ -52,6 +52,8 @@ export interface DocumentStyleCheckOptions extends EngineOptions {
|
|
|
52
52
|
* TSDoc検査へ渡す起動条件
|
|
53
53
|
*/
|
|
54
54
|
export interface TsdocCheckOptions extends EngineOptions {
|
|
55
|
+
/** 既定で無効のopt-in ruleのうち有効にするrule名 */
|
|
56
|
+
enable?: string[];
|
|
55
57
|
/** 違反として扱うrule名 */
|
|
56
58
|
error?: string[];
|
|
57
59
|
}
|
|
@@ -91,6 +93,9 @@ export interface QualityConfig {
|
|
|
91
93
|
|
|
92
94
|
/**
|
|
93
95
|
* 設定fileを型付けするための恒等関数
|
|
96
|
+
*
|
|
97
|
+
* @param config - 型付けする統合検査の設定
|
|
98
|
+
* @returns 引数をそのまま返した統合検査の設定
|
|
94
99
|
*/
|
|
95
100
|
export function defineConfig(config: QualityConfig): QualityConfig {
|
|
96
101
|
return config;
|
|
@@ -128,7 +133,7 @@ const ENGINE_OPTION_KEYS: Record<EngineName, readonly string[]> = {
|
|
|
128
133
|
"code-style-check": ["args", "ignore", "targets"],
|
|
129
134
|
"comment-check": ["args", "enable", "ignore", "targets"],
|
|
130
135
|
"document-style-check": ["args", "enable", "ignore", "targets"],
|
|
131
|
-
"tsdoc-check": ["args", "error", "ignore", "targets"],
|
|
136
|
+
"tsdoc-check": ["args", "enable", "error", "ignore", "targets"],
|
|
132
137
|
};
|
|
133
138
|
|
|
134
139
|
function readStringArray(value: unknown, field: string): string[] | undefined {
|
|
@@ -197,7 +202,11 @@ function parseEngineExtras(
|
|
|
197
202
|
name: EngineName,
|
|
198
203
|
): ParsedEngineOptions {
|
|
199
204
|
const extras: ParsedEngineOptions = {};
|
|
200
|
-
if (
|
|
205
|
+
if (
|
|
206
|
+
name === "comment-check" ||
|
|
207
|
+
name === "document-style-check" ||
|
|
208
|
+
name === "tsdoc-check"
|
|
209
|
+
) {
|
|
201
210
|
const enable = readStringArray(
|
|
202
211
|
value.enable,
|
|
203
212
|
`${source}: config.${name}.enable`,
|
|
@@ -290,6 +299,10 @@ function parseEngineConfig(
|
|
|
290
299
|
|
|
291
300
|
/**
|
|
292
301
|
* 読み込んだ設定を検証して不足分を補う
|
|
302
|
+
*
|
|
303
|
+
* @param value - config fileがexportした検証前の値
|
|
304
|
+
* @param source - errorメッセージへ載せるconfig fileのpath
|
|
305
|
+
* @returns 検証して既定値を補った統合検査の設定
|
|
293
306
|
*/
|
|
294
307
|
export function parseConfig(value: unknown, source: string): QualityConfig {
|
|
295
308
|
if (!isJsonObject(value)) {
|
|
@@ -311,6 +324,9 @@ export function parseConfig(value: unknown, source: string): QualityConfig {
|
|
|
311
324
|
|
|
312
325
|
/**
|
|
313
326
|
* 有効なengineを実行順で返す
|
|
327
|
+
*
|
|
328
|
+
* @param config - engineの有効無効を持つ統合検査の設定
|
|
329
|
+
* @returns 有効なengine名を実行順に並べた配列
|
|
314
330
|
*/
|
|
315
331
|
export function enabledEngines(config: QualityConfig): EngineName[] {
|
|
316
332
|
return ENGINE_NAMES.filter((name) => Boolean(config.engines[name]));
|
|
@@ -318,6 +334,11 @@ export function enabledEngines(config: QualityConfig): EngineName[] {
|
|
|
318
334
|
|
|
319
335
|
/**
|
|
320
336
|
* engineの起動条件を返す 無効なengineにはnullを返す
|
|
337
|
+
*
|
|
338
|
+
* @typeParam K - 起動条件を取り出すengine名の型
|
|
339
|
+
* @param config - engineごとの起動条件を持つ統合検査の設定
|
|
340
|
+
* @param name - 起動条件を取り出すengine名
|
|
341
|
+
* @returns 指定したengineの起動条件 無効なengineならnull
|
|
321
342
|
*/
|
|
322
343
|
export function engineConfig<K extends EngineName>(
|
|
323
344
|
config: QualityConfig,
|
|
@@ -331,6 +352,9 @@ export function engineConfig<K extends EngineName>(
|
|
|
331
352
|
|
|
332
353
|
/**
|
|
333
354
|
* 作業ディレクトリからconfig fileを探す
|
|
355
|
+
*
|
|
356
|
+
* @param cwd - 探索を開始する作業ディレクトリのpath
|
|
357
|
+
* @returns 見つけたconfig fileのpath 見つからなければnull
|
|
334
358
|
*/
|
|
335
359
|
export function findConfigFile(cwd: string): string | null {
|
|
336
360
|
for (const name of DEFAULT_CONFIG_FILES) {
|
|
@@ -344,6 +368,9 @@ export function findConfigFile(cwd: string): string | null {
|
|
|
344
368
|
|
|
345
369
|
/**
|
|
346
370
|
* config fileを読み込んで検証する
|
|
371
|
+
*
|
|
372
|
+
* @param path - 読み込むconfig fileのpath
|
|
373
|
+
* @returns 読み込んで検証した統合検査の設定
|
|
347
374
|
*/
|
|
348
375
|
export async function loadConfig(path: string): Promise<QualityConfig> {
|
|
349
376
|
const module: unknown = await import(pathToFileURL(path).href);
|
package/src/engines.ts
CHANGED
|
@@ -85,6 +85,10 @@ export const ENGINE_LIMITS: Record<
|
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
87
|
* engineが受け取らないため渡さなかった起動条件を返す
|
|
88
|
+
*
|
|
89
|
+
* @param name - 受け取れない起動条件を引くengine名
|
|
90
|
+
* @param options - engineへ渡そうとした起動条件
|
|
91
|
+
* @returns 渡さなかった起動条件とその理由の一覧
|
|
88
92
|
*/
|
|
89
93
|
export function skippedEngineOptions(
|
|
90
94
|
name: EngineName,
|
|
@@ -106,6 +110,9 @@ export function skippedEngineOptions(
|
|
|
106
110
|
|
|
107
111
|
/**
|
|
108
112
|
* 検出をJSONで返すengineか
|
|
113
|
+
*
|
|
114
|
+
* @param name - 判定するengine名
|
|
115
|
+
* @returns 検出をJSONで返すengineならtrue
|
|
109
116
|
*/
|
|
110
117
|
export function isFindingEngine(name: EngineName): boolean {
|
|
111
118
|
return (
|
|
@@ -118,6 +125,10 @@ export function isFindingEngine(name: EngineName): boolean {
|
|
|
118
125
|
|
|
119
126
|
/**
|
|
120
127
|
* node_modules/.binとPATHからengineの実行fileを探す
|
|
128
|
+
*
|
|
129
|
+
* @param name - 実行fileを探すengine名
|
|
130
|
+
* @param cwd - 探索を開始する作業ディレクトリのpath
|
|
131
|
+
* @returns 見つけた実行fileのpath PATHにも無ければnull
|
|
121
132
|
*/
|
|
122
133
|
export function resolveExecutable(
|
|
123
134
|
name: EngineName,
|
|
@@ -193,6 +204,11 @@ function enableArguments(
|
|
|
193
204
|
|
|
194
205
|
/**
|
|
195
206
|
* engineへ渡すコマンドを組み立てる
|
|
207
|
+
*
|
|
208
|
+
* @param name - コマンドを組み立てるengine名
|
|
209
|
+
* @param executable - 起動するengineの実行fileのpath
|
|
210
|
+
* @param context - 設定と上書きを持つ実行条件
|
|
211
|
+
* @returns engineへ渡す引数を並べたコマンド
|
|
196
212
|
*/
|
|
197
213
|
export function buildEngineCommand(
|
|
198
214
|
name: EngineName,
|
|
@@ -258,6 +274,7 @@ export function buildEngineCommand(
|
|
|
258
274
|
return [
|
|
259
275
|
executable,
|
|
260
276
|
"--json",
|
|
277
|
+
...enableArguments(engineConfig(context.config, "tsdoc-check")),
|
|
261
278
|
...errorArguments,
|
|
262
279
|
...targets,
|
|
263
280
|
...ignoreArguments,
|
|
@@ -267,6 +284,11 @@ export function buildEngineCommand(
|
|
|
267
284
|
|
|
268
285
|
/**
|
|
269
286
|
* engineの起動コマンドを順番に返す 型検査だけはprojectsごとに起動する
|
|
287
|
+
*
|
|
288
|
+
* @param name - コマンドを組み立てるengine名
|
|
289
|
+
* @param executable - 起動するengineの実行fileのpath
|
|
290
|
+
* @param context - 設定と上書きを持つ実行条件
|
|
291
|
+
* @returns 起動する順に並べたコマンドの配列
|
|
270
292
|
*/
|
|
271
293
|
export function buildEngineCommands(
|
|
272
294
|
name: EngineName,
|
|
@@ -287,6 +309,10 @@ export function buildEngineCommands(
|
|
|
287
309
|
|
|
288
310
|
/**
|
|
289
311
|
* Bun.spawnでengineを起動する既定のrunner
|
|
312
|
+
*
|
|
313
|
+
* @param command - 実行fileと引数を並べたコマンド
|
|
314
|
+
* @param options - engineを起動する作業ディレクトリを持つ条件
|
|
315
|
+
* @returns 終了codeと標準出力と標準エラーを持つ結果
|
|
290
316
|
*/
|
|
291
317
|
export async function runEngineProcess(
|
|
292
318
|
command: string[],
|