@yuu1111/quality-check 0.2.0 → 0.3.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 CHANGED
@@ -12,7 +12,7 @@ bun add -D @yuu1111/quality-check
12
12
 
13
13
  ## Usage
14
14
 
15
- `quality.config.ts` engineと除外pathを指定し、scriptから起動する
15
+ `quality.config.ts` で起動するengineとengineごとの起動条件を指定し、scriptから起動する
16
16
 
17
17
  ```json
18
18
  {
@@ -26,14 +26,17 @@ bun add -D @yuu1111/quality-check
26
26
  import { defineConfig } from "@yuu1111/quality-check";
27
27
 
28
28
  export default defineConfig({
29
- engines: {
30
- biome: true,
31
- knip: true,
32
- "comment-check": true,
33
- "document-style-check": true,
34
- "tsdoc-check": { args: ["--error", "missing-doc"] },
35
- },
36
- ignore: ["FFXIVReplayAnalyzer"],
29
+ engines: {
30
+ biome: true,
31
+ knip: true,
32
+ "comment-check": true,
33
+ "document-style-check": true,
34
+ "tsdoc-check": true,
35
+ },
36
+ config: {
37
+ "comment-check": { ignore: ["FFXIVReplayAnalyzer"] },
38
+ "tsdoc-check": { error: ["missing-doc"] },
39
+ },
37
40
  });
38
41
  ```
39
42
 
@@ -57,13 +60,23 @@ quality-check: 1 of 3 engines failed
57
60
 
58
61
  | Field | Description |
59
62
  |-------|-------------|
60
- | `engines` | 起動するengine 値は `true` または `{ args }` |
61
- | `ignore` | file走査engineが検査から外すpath |
63
+ | `engines` | 起動するengine 値は `true` または `false` |
64
+ | `config` | engineごとの起動条件 |
62
65
  | `baseline` | baseline fileのpath `false` なら差分判定を行わない |
63
- | `targets` | file走査engineへ渡す対象path |
64
66
 
65
67
  engineは `biome` → `knip` → `comment-check` → `document-style-check` → `tsdoc-check` の順に実行する
66
- `args` はengineの既定引数の後ろへ足すため、`tsdoc-check` の `--error` のようなengine固有の指定はここへ置く
68
+
69
+ `engines` は起動の委任だけを表し、起動条件は `config` のengineの下へ置く engineが受け取る条件は次のとおり
70
+
71
+ | engine | 受け取る条件 |
72
+ |--------|--------------|
73
+ | `biome` | `targets`、`args` 除外pathは `biome.json` が持つ |
74
+ | `knip` | `args` 設定は `knip.ts` が持つ |
75
+ | `comment-check` | `ignore`、`targets`、`args` |
76
+ | `document-style-check` | `ignore`、`targets`、`args` |
77
+ | `tsdoc-check` | `ignore`、`targets`、`args`、`error`(違反として扱うrule名) |
78
+
79
+ `args` はengineの既定引数の後ろへ足す 設定fileで表せない起動条件や、engineの引数が変わったときの逃げ道として使う
67
80
 
68
81
  ## Options
69
82
 
@@ -75,11 +88,20 @@ engineは `biome` → `knip` → `comment-check` → `document-style-check` →
75
88
  | `--update-baseline` | 現在の検出でbaselineを置き換える |
76
89
  | `--json` | engineごとの結果をJSONで出力する |
77
90
 
91
+ `--ignore` と位置引数の対象pathは、その条件を受け取るengineへだけ渡す
92
+
78
93
  ## Notes
79
94
 
80
95
  終了codeは0が全engine成功、1が失敗したengineあり、2が設定またはengine起動の失敗
81
96
 
82
- BiomeとKnipは除外pathを自分のconfig(`biome.json`、`knip.ts`)で持つ `ignore` はfile走査engineへ `--ignore` として渡し、BiomeとKnipには渡さない
97
+ engineが受け取らない条件を書いた場合は渡さず、その旨をそのengineのsectionへ出す
98
+
99
+ ```text
100
+ == biome ==
101
+ biome: ignore skipped (biome.json holds its settings)
102
+ ```
103
+
104
+ BiomeとKnipの除外pathは `biome.json` と `knip.ts` が持つ このCLIは同じfileからengineの起動と結果の集約だけを行う
83
105
 
84
106
  `comment-check` はbaseline差分を無効化する未作成のpathを渡して起動する 新規と解消済みの判定はengineごとではなく統合CLIが1つのbaseline fileで行うため、既存の `comment-baseline.json` がある場合は `--update-baseline` で移す
85
107
 
package/README.md CHANGED
@@ -13,8 +13,8 @@ bun add -D @yuu1111/quality-check
13
13
 
14
14
  ## Usage
15
15
 
16
- Declare the engines and the excluded paths in `quality.config.ts`, then call the
17
- CLI from a script:
16
+ Declare the engines to run and the conditions of each engine in
17
+ `quality.config.ts`, then call the CLI from a script:
18
18
 
19
19
  ```json
20
20
  {
@@ -28,14 +28,17 @@ CLI from a script:
28
28
  import { defineConfig } from "@yuu1111/quality-check";
29
29
 
30
30
  export default defineConfig({
31
- engines: {
32
- biome: true,
33
- knip: true,
34
- "comment-check": true,
35
- "document-style-check": true,
36
- "tsdoc-check": { args: ["--error", "missing-doc"] },
37
- },
38
- ignore: ["FFXIVReplayAnalyzer"],
31
+ engines: {
32
+ biome: true,
33
+ knip: true,
34
+ "comment-check": true,
35
+ "document-style-check": true,
36
+ "tsdoc-check": true,
37
+ },
38
+ config: {
39
+ "comment-check": { ignore: ["FFXIVReplayAnalyzer"] },
40
+ "tsdoc-check": { error: ["missing-doc"] },
41
+ },
39
42
  });
40
43
  ```
41
44
 
@@ -60,14 +63,26 @@ quality-check: 1 of 3 engines failed
60
63
 
61
64
  | Field | Description |
62
65
  |-------|-------------|
63
- | `engines` | Engines to run, as `true` or `{ args }` |
64
- | `ignore` | Paths that the file-scanning engines leave out |
66
+ | `engines` | Engines to run, as `true` or `false` |
67
+ | `config` | Conditions of each engine |
65
68
  | `baseline` | Baseline file path; `false` disables the diff |
66
- | `targets` | Targets passed to the file-scanning engines |
67
69
 
68
- Engines run in the order `biome`, `knip`, `comment-check`, `document-style-check`, `tsdoc-check`.
69
- `args` is appended after the engine defaults, so engine-specific flags such as
70
- `--error` for `tsdoc-check` belong there.
70
+ Engines run in the order `biome`, `knip`, `comment-check`,
71
+ `document-style-check`, `tsdoc-check`.
72
+
73
+ `engines` only delegates the start-up, and the conditions belong under the
74
+ engine in `config`. Each engine takes:
75
+
76
+ | Engine | Conditions |
77
+ |--------|------------|
78
+ | `biome` | `targets`, `args`; `biome.json` holds the excluded paths |
79
+ | `knip` | `args`; `knip.ts` holds the settings |
80
+ | `comment-check` | `ignore`, `targets`, `args` |
81
+ | `document-style-check` | `ignore`, `targets`, `args` |
82
+ | `tsdoc-check` | `ignore`, `targets`, `args`, `error` (rule names to fail on) |
83
+
84
+ `args` is appended after the engine defaults, for conditions the config cannot
85
+ express and for the case where an engine changes its arguments.
71
86
 
72
87
  ## Options
73
88
 
@@ -79,14 +94,23 @@ Engines run in the order `biome`, `knip`, `comment-check`, `document-style-check
79
94
  | `--update-baseline` | Replace the baseline with the current findings |
80
95
  | `--json` | Print the per-engine results as JSON |
81
96
 
97
+ `--ignore` and the positional targets reach only the engines that take them.
98
+
82
99
  ## Notes
83
100
 
84
101
  Exit code 0 means every engine passed, 1 that at least one failed, and 2 that the
85
102
  configuration or an engine could not start.
86
103
 
87
- Biome and Knip keep their excluded paths in their own config (`biome.json`,
88
- `knip.ts`). `ignore` reaches the file-scanning engines as `--ignore` and is not
89
- passed to Biome or Knip.
104
+ A condition that an engine does not take is not passed on, and the section says
105
+ so:
106
+
107
+ ```text
108
+ == biome ==
109
+ biome: ignore skipped (biome.json holds its settings)
110
+ ```
111
+
112
+ Biome and Knip keep their excluded paths in `biome.json` and `knip.ts`. This
113
+ CLI starts the engines from one file and aggregates the results.
90
114
 
91
115
  `comment-check` runs with an unwritten baseline path so that it reports every
92
116
  finding. The new-and-resolved diff is done by this CLI from a single baseline
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuu1111/quality-check",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Integrated quality check runner",
5
5
  "license": "MIT",
6
6
  "repository": {
package/src/cli.ts CHANGED
@@ -98,13 +98,6 @@ function parseArguments(argv: string[]): Options {
98
98
  return options;
99
99
  }
100
100
 
101
- function mergeIgnores(config: QualityConfig, ignores: string[]): QualityConfig {
102
- if (ignores.length === 0) {
103
- return config;
104
- }
105
- return { ...config, ignore: [...(config.ignore ?? []), ...ignores] };
106
- }
107
-
108
101
  function resolveBaselinePath(
109
102
  options: Options,
110
103
  config: QualityConfig,
@@ -138,7 +131,7 @@ async function main(argv: string[]): Promise<number> {
138
131
  console.error(`quality.config.ts not found in ${cwd}`);
139
132
  return 2;
140
133
  }
141
- const config = mergeIgnores(await loadConfig(configPath), options.ignores);
134
+ const config = await loadConfig(configPath);
142
135
  const baselinePath = resolveBaselinePath(options, config, cwd);
143
136
  const results = await runEngines({
144
137
  baseline:
@@ -147,9 +140,8 @@ async function main(argv: string[]): Promise<number> {
147
140
  : readBaseline(baselinePath),
148
141
  config,
149
142
  cwd,
143
+ overrides: { ignore: options.ignores, targets: options.targets },
150
144
  rawBaseline: join(tmpdir(), `quality-check-raw-${process.pid}.json`),
151
- targets:
152
- options.targets.length > 0 ? options.targets : (config.targets ?? ["."]),
153
145
  });
154
146
  if (options.update) {
155
147
  if (baselinePath === null) {
package/src/config.ts CHANGED
@@ -19,25 +19,46 @@ export const ENGINE_NAMES = [
19
19
  export type EngineName = (typeof ENGINE_NAMES)[number];
20
20
 
21
21
  /**
22
- * engineのbinへ追加で渡す起動設定
22
+ * engineへ渡す起動条件
23
23
  */
24
24
  export interface EngineOptions {
25
+ /** 検査から外すpath engineが受け取れないときはreportへ出す */
26
+ ignore?: string[];
27
+ /** 検査する対象path engineが受け取れないときはreportへ出す */
28
+ targets?: string[];
25
29
  /** engineの既定引数の後ろへ足す引数 */
26
30
  args?: string[];
27
31
  }
28
32
 
33
+ /**
34
+ * TSDoc検査へ渡す起動条件
35
+ */
36
+ export interface TsdocCheckOptions extends EngineOptions {
37
+ /** 違反として扱うrule名 */
38
+ error?: string[];
39
+ }
40
+
41
+ /**
42
+ * engine名ごとの起動条件
43
+ */
44
+ export interface EngineConfigMap {
45
+ biome: EngineOptions;
46
+ knip: EngineOptions;
47
+ "comment-check": EngineOptions;
48
+ "document-style-check": EngineOptions;
49
+ "tsdoc-check": TsdocCheckOptions;
50
+ }
51
+
29
52
  /**
30
53
  * quality.config.tsが受け付ける統合検査の設定
31
54
  */
32
55
  export interface QualityConfig {
33
56
  /** 起動するengine 値がfalseまたは未指定のengineは起動しない */
34
- engines: Partial<Record<EngineName, boolean | EngineOptions>>;
35
- /** file走査engineが検査から外すpath */
36
- ignore?: string[];
57
+ engines: Partial<Record<EngineName, boolean>>;
58
+ /** engineごとの起動条件 省略したengineは既定値で起動する */
59
+ config?: Partial<EngineConfigMap>;
37
60
  /** baseline fileのpath falseなら差分判定を行わない */
38
61
  baseline?: string | false;
39
- /** file走査engineへ渡す対象path */
40
- targets?: string[];
41
62
  }
42
63
 
43
64
  /**
@@ -72,6 +93,14 @@ function isEngineName(value: string): value is EngineName {
72
93
  return (ENGINE_NAMES as readonly string[]).includes(value);
73
94
  }
74
95
 
96
+ const ENGINE_OPTION_KEYS: Record<EngineName, readonly string[]> = {
97
+ biome: ["args", "ignore", "targets"],
98
+ knip: ["args", "ignore", "targets"],
99
+ "comment-check": ["args", "ignore", "targets"],
100
+ "document-style-check": ["args", "ignore", "targets"],
101
+ "tsdoc-check": ["args", "error", "ignore", "targets"],
102
+ };
103
+
75
104
  function readStringArray(value: unknown, field: string): string[] | undefined {
76
105
  if (value === undefined) {
77
106
  return undefined;
@@ -98,27 +127,96 @@ function readBaseline(
98
127
  throw new Error(`${source}: baseline must be a path string or false`);
99
128
  }
100
129
 
101
- function parseEngineOptions(
130
+ function parseEngines(
102
131
  value: unknown,
103
132
  source: string,
104
- name: EngineName,
105
- ): boolean | EngineOptions {
106
- if (typeof value === "boolean") {
107
- return value;
108
- }
133
+ ): Partial<Record<EngineName, boolean>> {
109
134
  if (!isJsonObject(value)) {
110
- throw new Error(
111
- `${source}: engines.${name} must be a boolean or an object`,
112
- );
135
+ throw new Error(`${source} must export an engines object`);
113
136
  }
114
- const unknown = Object.keys(value).filter((key) => key !== "args");
137
+ const engines: Partial<Record<EngineName, boolean>> = {};
138
+ for (const [name, enabled] of Object.entries(value)) {
139
+ if (!isEngineName(name)) {
140
+ throw new Error(`${source}: unknown engine: ${name}`);
141
+ }
142
+ if (typeof enabled !== "boolean") {
143
+ throw new Error(
144
+ `${source}: engines.${name} must be a boolean 起動条件はconfigへ置く`,
145
+ );
146
+ }
147
+ engines[name] = enabled;
148
+ }
149
+ if (ENGINE_NAMES.every((name) => !engines[name])) {
150
+ throw new Error(`${source} must enable at least one engine`);
151
+ }
152
+ return engines;
153
+ }
154
+
155
+ function parseEngineOptions(
156
+ value: JsonObject,
157
+ source: string,
158
+ name: EngineName,
159
+ ): TsdocCheckOptions {
160
+ const unknown = Object.keys(value).filter(
161
+ (key) => !ENGINE_OPTION_KEYS[name].includes(key),
162
+ );
115
163
  if (unknown.length > 0) {
116
164
  throw new Error(
117
- `${source}: engines.${name} has an unknown option: ${unknown[0]}`,
165
+ `${source}: config.${name} has an unknown option: ${unknown[0]}`,
166
+ );
167
+ }
168
+ const options: TsdocCheckOptions = {};
169
+ const ignore = readStringArray(
170
+ value.ignore,
171
+ `${source}: config.${name}.ignore`,
172
+ );
173
+ if (ignore !== undefined) {
174
+ options.ignore = ignore;
175
+ }
176
+ const targets = readStringArray(
177
+ value.targets,
178
+ `${source}: config.${name}.targets`,
179
+ );
180
+ if (targets !== undefined) {
181
+ options.targets = targets;
182
+ }
183
+ const args = readStringArray(value.args, `${source}: config.${name}.args`);
184
+ if (args !== undefined) {
185
+ options.args = args;
186
+ }
187
+ if (name === "tsdoc-check") {
188
+ const error = readStringArray(
189
+ value.error,
190
+ `${source}: config.${name}.error`,
118
191
  );
192
+ if (error !== undefined) {
193
+ options.error = error;
194
+ }
195
+ }
196
+ return options;
197
+ }
198
+
199
+ function parseEngineConfig(
200
+ value: unknown,
201
+ source: string,
202
+ ): Partial<EngineConfigMap> | undefined {
203
+ if (value === undefined) {
204
+ return undefined;
205
+ }
206
+ if (!isJsonObject(value)) {
207
+ throw new Error(`${source}: config must be an object`);
208
+ }
209
+ const config: Partial<EngineConfigMap> = {};
210
+ for (const [name, options] of Object.entries(value)) {
211
+ if (!isEngineName(name)) {
212
+ throw new Error(`${source}: unknown engine in config: ${name}`);
213
+ }
214
+ if (!isJsonObject(options)) {
215
+ throw new Error(`${source}: config.${name} must be an object`);
216
+ }
217
+ config[name] = parseEngineOptions(options, source, name);
119
218
  }
120
- const args = readStringArray(value.args, `${source}: engines.${name}.args`);
121
- return args === undefined ? {} : { args };
219
+ return config;
122
220
  }
123
221
 
124
222
  /**
@@ -128,32 +226,17 @@ export function parseConfig(value: unknown, source: string): QualityConfig {
128
226
  if (!isJsonObject(value)) {
129
227
  throw new Error(`${source} must export a config object`);
130
228
  }
131
- if (!isJsonObject(value.engines)) {
132
- throw new Error(`${source} must export an engines object`);
133
- }
134
- const engines: Partial<Record<EngineName, boolean | EngineOptions>> = {};
135
- for (const [name, options] of Object.entries(value.engines)) {
136
- if (!isEngineName(name)) {
137
- throw new Error(`${source}: unknown engine: ${name}`);
138
- }
139
- engines[name] = parseEngineOptions(options, source, name);
229
+ const config: QualityConfig = {
230
+ engines: parseEngines(value.engines, source),
231
+ };
232
+ const engineConfig = parseEngineConfig(value.config, source);
233
+ if (engineConfig !== undefined) {
234
+ config.config = engineConfig;
140
235
  }
141
- if (ENGINE_NAMES.every((name) => !engines[name])) {
142
- throw new Error(`${source} must enable at least one engine`);
143
- }
144
- const config: QualityConfig = { engines };
145
236
  const baseline = readBaseline(value.baseline, source);
146
237
  if (baseline !== undefined) {
147
238
  config.baseline = baseline;
148
239
  }
149
- const ignore = readStringArray(value.ignore, `${source}: ignore`);
150
- if (ignore !== undefined) {
151
- config.ignore = ignore;
152
- }
153
- const targets = readStringArray(value.targets, `${source}: targets`);
154
- if (targets !== undefined) {
155
- config.targets = targets;
156
- }
157
240
  return config;
158
241
  }
159
242
 
@@ -165,17 +248,16 @@ export function enabledEngines(config: QualityConfig): EngineName[] {
165
248
  }
166
249
 
167
250
  /**
168
- * engineの起動設定を返す 無効なengineにはnullを返す
251
+ * engineの起動条件を返す 無効なengineにはnullを返す
169
252
  */
170
- export function engineOptions(
253
+ export function engineConfig<K extends EngineName>(
171
254
  config: QualityConfig,
172
- name: EngineName,
173
- ): EngineOptions | null {
174
- const value = config.engines[name];
175
- if (!value) {
255
+ name: K,
256
+ ): EngineConfigMap[K] | null {
257
+ if (!config.engines[name]) {
176
258
  return null;
177
259
  }
178
- return value === true ? {} : value;
260
+ return config.config?.[name] ?? ({} as EngineConfigMap[K]);
179
261
  }
180
262
 
181
263
  /**
package/src/engines.ts CHANGED
@@ -1,6 +1,11 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
- import { type EngineName, engineOptions, type QualityConfig } from "./config";
3
+ import {
4
+ type EngineName,
5
+ type EngineOptions,
6
+ engineConfig,
7
+ type QualityConfig,
8
+ } from "./config";
4
9
 
5
10
  /**
6
11
  * 子プロセスとして起動したengineの生の結果
@@ -33,15 +38,61 @@ export const ENGINE_BINS: Record<EngineName, string> = {
33
38
  const WINDOWS_SHIMS = [".exe", ".cmd", ".bat", ""];
34
39
  const POSIX_SHIMS = [""];
35
40
 
41
+ /**
42
+ * コマンドラインから渡された起動条件の上書き
43
+ */
44
+ export interface RunOverrides {
45
+ ignore: string[];
46
+ targets: string[];
47
+ }
48
+
36
49
  /**
37
50
  * engineのコマンドを組み立てるための実行条件
38
51
  */
39
52
  export interface EngineCommandContext {
40
53
  config: QualityConfig;
41
- ignores: string[];
54
+ /** 対応するengineへだけ足す上書き */
55
+ overrides: RunOverrides;
42
56
  /** comment-checkのbaseline差分を無効化するために渡す未作成のpath */
43
57
  rawBaseline: string;
44
- targets: string[];
58
+ }
59
+
60
+ /**
61
+ * engineが受け取らない起動条件と、その設定の持ち主
62
+ */
63
+ export const ENGINE_LIMITS: Record<
64
+ EngineName,
65
+ Partial<Record<"ignore" | "targets", string>>
66
+ > = {
67
+ biome: { ignore: "biome.json holds its settings" },
68
+ knip: {
69
+ ignore: "knip.ts holds its settings",
70
+ targets: "knip analyzes the whole project",
71
+ },
72
+ "comment-check": {},
73
+ "document-style-check": {},
74
+ "tsdoc-check": {},
75
+ };
76
+
77
+ /**
78
+ * engineが受け取らないため渡さなかった起動条件を返す
79
+ */
80
+ export function skippedEngineOptions(
81
+ name: EngineName,
82
+ options: EngineOptions | undefined,
83
+ ): string[] {
84
+ if (options === undefined) {
85
+ return [];
86
+ }
87
+ const limits = ENGINE_LIMITS[name];
88
+ const skipped: string[] = [];
89
+ for (const key of ["ignore", "targets"] as const) {
90
+ const reason = limits[key];
91
+ if (reason !== undefined && options[key] !== undefined) {
92
+ skipped.push(`${key} skipped (${reason})`);
93
+ }
94
+ }
95
+ return skipped;
45
96
  }
46
97
 
47
98
  /**
@@ -95,24 +146,34 @@ export function buildEngineCommand(
95
146
  executable: string,
96
147
  context: EngineCommandContext,
97
148
  ): string[] {
98
- const extra = engineOptions(context.config, name)?.args ?? [];
149
+ const options: EngineOptions = engineConfig(context.config, name) ?? {};
150
+ const limits = ENGINE_LIMITS[name];
151
+ const extra = options.args ?? [];
152
+ const ignores =
153
+ limits.ignore === undefined
154
+ ? [...(options.ignore ?? []), ...context.overrides.ignore]
155
+ : [];
156
+ const requested =
157
+ context.overrides.targets.length > 0
158
+ ? context.overrides.targets
159
+ : (options.targets ?? ["."]);
160
+ const targets = limits.targets === undefined ? requested : [];
161
+ const ignoreArguments = ignores.flatMap((ignore) => ["--ignore", ignore]);
162
+ const rules = engineConfig(context.config, "tsdoc-check")?.error ?? [];
163
+ const errorArguments = rules.flatMap((rule) => ["--error", rule]);
99
164
  if (name === "biome") {
100
- return [executable, "check", ...context.targets, ...extra];
165
+ return [executable, "check", ...targets, ...extra];
101
166
  }
102
167
  if (name === "knip") {
103
168
  return [executable, ...extra];
104
169
  }
105
- const ignoreArguments = context.ignores.flatMap((ignore) => [
106
- "--ignore",
107
- ignore,
108
- ]);
109
170
  if (name === "comment-check") {
110
171
  return [
111
172
  executable,
112
173
  "--json",
113
174
  "--baseline",
114
175
  context.rawBaseline,
115
- ...context.targets,
176
+ ...targets,
116
177
  ...ignoreArguments,
117
178
  ...extra,
118
179
  ];
@@ -122,7 +183,7 @@ export function buildEngineCommand(
122
183
  executable,
123
184
  "lint",
124
185
  "--json",
125
- ...context.targets,
186
+ ...targets,
126
187
  ...ignoreArguments,
127
188
  ...extra,
128
189
  ];
@@ -130,7 +191,8 @@ export function buildEngineCommand(
130
191
  return [
131
192
  executable,
132
193
  "--json",
133
- ...context.targets,
194
+ ...errorArguments,
195
+ ...targets,
134
196
  ...ignoreArguments,
135
197
  ...extra,
136
198
  ];
package/src/report.ts CHANGED
@@ -25,6 +25,9 @@ function describeStatus(result: EngineResult): string {
25
25
  */
26
26
  export function formatEngineSection(result: EngineResult): string {
27
27
  const lines = [`== ${result.name} ==`];
28
+ for (const skipped of result.skipped) {
29
+ lines.push(`${result.name}: ${skipped}`);
30
+ }
28
31
  if (result.output !== "" && !isFindingEngine(result.name)) {
29
32
  lines.push(result.output);
30
33
  }
@@ -73,6 +76,7 @@ export function toJsonReport(results: EngineResult[]): unknown {
73
76
  name: result.name,
74
77
  reported: result.reported,
75
78
  resolved: result.resolved,
79
+ skipped: result.skipped,
76
80
  status: result.status,
77
81
  warnings: result.warnings,
78
82
  })),
package/src/run.ts CHANGED
@@ -7,8 +7,10 @@ import {
7
7
  type EngineProcessResult,
8
8
  type EngineRunner,
9
9
  isFindingEngine,
10
+ type RunOverrides,
10
11
  resolveExecutable,
11
12
  runEngineProcess,
13
+ skippedEngineOptions,
12
14
  } from "./engines";
13
15
  import { type NormalizedFinding, parseFindings } from "./findings";
14
16
 
@@ -30,6 +32,8 @@ export interface EngineResult {
30
32
  /** baseline適用後に残った阻害する検出 */
31
33
  reported: NormalizedFinding[];
32
34
  resolved: number;
35
+ /** engineが受け取らなかった起動条件 */
36
+ skipped: string[];
33
37
  status: EngineStatus;
34
38
  warnings: NormalizedFinding[];
35
39
  }
@@ -42,8 +46,8 @@ export interface RunOptions {
42
46
  baseline: BaselineFile | null;
43
47
  config: QualityConfig;
44
48
  cwd: string;
45
- /** file走査engineへ渡す対象path */
46
- targets: string[];
49
+ /** コマンドラインから渡された起動条件の上書き */
50
+ overrides: RunOverrides;
47
51
  /** comment-checkのbaseline差分を無効化する未作成のpath */
48
52
  rawBaseline: string;
49
53
  /** engineの実行fileを解決する関数 テストでは差し替える */
@@ -63,6 +67,7 @@ function baseResult(
63
67
  output,
64
68
  reported: [],
65
69
  resolved: 0,
70
+ skipped: [],
66
71
  warnings: [],
67
72
  };
68
73
  }
@@ -144,7 +149,7 @@ async function runProcessEngine(
144
149
  };
145
150
  }
146
151
 
147
- async function runEngine(
152
+ async function executeEngine(
148
153
  name: EngineName,
149
154
  options: RunOptions,
150
155
  context: EngineCommandContext,
@@ -164,6 +169,19 @@ async function runEngine(
164
169
  return await runProcessEngine(name, options, executable, context, runner);
165
170
  }
166
171
 
172
+ async function runEngine(
173
+ name: EngineName,
174
+ options: RunOptions,
175
+ context: EngineCommandContext,
176
+ runner: EngineRunner,
177
+ ): Promise<EngineResult> {
178
+ const result = await executeEngine(name, options, context, runner);
179
+ return {
180
+ ...result,
181
+ skipped: skippedEngineOptions(name, options.config.config?.[name]),
182
+ };
183
+ }
184
+
167
185
  /**
168
186
  * 設定で有効なengineを順に起動する
169
187
  */
@@ -171,9 +189,8 @@ export async function runEngines(options: RunOptions): Promise<EngineResult[]> {
171
189
  const runner = options.runner ?? runEngineProcess;
172
190
  const context: EngineCommandContext = {
173
191
  config: options.config,
174
- ignores: options.config.ignore ?? [],
192
+ overrides: options.overrides,
175
193
  rawBaseline: options.rawBaseline,
176
- targets: options.targets,
177
194
  };
178
195
  const results: EngineResult[] = [];
179
196
  for (const name of enabledEngines(options.config)) {