@yuu1111/comment-check 2.0.0 → 2.1.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 +10 -0
- package/README.md +14 -0
- package/dist/cli.js +54 -13
- package/dist/scan.js +42 -9
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -24,6 +24,12 @@ src/queue.ts:18:2 undocumented-directive TypeScript directive needs a descriptio
|
|
|
24
24
|
Checked 42 files: 1 new, 0 resolved, 3 baselined
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
日本語の文末の `。` も止めるProjectはopt-inのruleを指定する
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
comment-check --enable japanese-period .
|
|
31
|
+
```
|
|
32
|
+
|
|
27
33
|
## Rules
|
|
28
34
|
|
|
29
35
|
| Rule | 検出対象 |
|
|
@@ -32,12 +38,14 @@ Checked 42 files: 1 new, 0 resolved, 3 baselined
|
|
|
32
38
|
| `undocumented-directive` | 説明の無い `@ts-ignore` と `@ts-expect-error` |
|
|
33
39
|
| `placeholder-comment` | `TODO`、`FIXME`、`XXX`、`HACK` |
|
|
34
40
|
| `separator-comment` | 記号だけで作った装飾comment |
|
|
41
|
+
| `japanese-period` | 日本語の文を終える `。` を含むcomment(opt-in) |
|
|
35
42
|
|
|
36
43
|
## Options
|
|
37
44
|
|
|
38
45
|
| Option | Description |
|
|
39
46
|
|--------|-------------|
|
|
40
47
|
| `--baseline <path>` | 読み書きするbaseline file(既定は `comment-baseline.json`) |
|
|
48
|
+
| `--enable <rule>` | opt-in ruleを実行する 複数指定できる 未知の名前は設定error |
|
|
41
49
|
| `--ignore <path>` | 検査から外すpath 複数指定できる |
|
|
42
50
|
| `--update-baseline` | baselineを現在の検出で置き換える |
|
|
43
51
|
| `--json` | 新規と解消済みの検出をJSONで出力する |
|
|
@@ -47,3 +55,5 @@ Checked 42 files: 1 new, 0 resolved, 3 baselined
|
|
|
47
55
|
生成物のディレクトリなどProjectが持つpathは `--ignore` で検査から外す 例えば `--ignore src/generated`
|
|
48
56
|
|
|
49
57
|
baselineはrule、file、comment本文をキーにするため、行が動いてもそのcommentを新規とは報告しない Biomeは `biome-ignore` の理由と未使用の抑制を既に扱うため、このcheckerはBiomeが読まないcommentの細部だけを担当する
|
|
58
|
+
|
|
59
|
+
`japanese-period` は `--enable` で指定するまで動かないため、既存Projectの検出結果は変わらない 最初の `。` の位置を行と桁で報告し、句点が複数あっても1 commentにつき1件にまとめ、comment本文は書き換えない
|
package/README.md
CHANGED
|
@@ -25,6 +25,13 @@ src/queue.ts:18:2 undocumented-directive TypeScript directive needs a descriptio
|
|
|
25
25
|
Checked 42 files: 1 new, 0 resolved, 3 baselined
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
A project that also keeps Japanese sentences free of a trailing `。` names the
|
|
29
|
+
opt-in rule:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
comment-check --enable japanese-period .
|
|
33
|
+
```
|
|
34
|
+
|
|
28
35
|
## Rules
|
|
29
36
|
|
|
30
37
|
| Rule | Detects |
|
|
@@ -33,12 +40,14 @@ Checked 42 files: 1 new, 0 resolved, 3 baselined
|
|
|
33
40
|
| `undocumented-directive` | `@ts-ignore` or `@ts-expect-error` without a description |
|
|
34
41
|
| `placeholder-comment` | `TODO`, `FIXME`, `XXX`, `HACK` |
|
|
35
42
|
| `separator-comment` | decorative comments made only of punctuation |
|
|
43
|
+
| `japanese-period` | a Japanese sentence in a comment that ends with `。` (opt-in) |
|
|
36
44
|
|
|
37
45
|
## Options
|
|
38
46
|
|
|
39
47
|
| Option | Description |
|
|
40
48
|
|--------|-------------|
|
|
41
49
|
| `--baseline <path>` | Baseline file to read or write (default `comment-baseline.json`) |
|
|
50
|
+
| `--enable <rule>` | Run an opt-in rule, repeatable; an unknown name is a configuration error |
|
|
42
51
|
| `--ignore <path>` | Path to leave out, repeatable |
|
|
43
52
|
| `--update-baseline` | Replace the baseline with the current findings |
|
|
44
53
|
| `--json` | Print new and resolved findings as JSON |
|
|
@@ -52,3 +61,8 @@ The baseline keys on the rule, the file, and the comment text, so moving a line
|
|
|
52
61
|
does not report the comment as new. Biome already requires a reason on
|
|
53
62
|
`biome-ignore` and reports unused suppressions, so this checker only covers the
|
|
54
63
|
comment trivia that Biome does not read.
|
|
64
|
+
|
|
65
|
+
`japanese-period` stays off until `--enable` names it, so an existing project
|
|
66
|
+
keeps the findings it had. The rule reports the first `。` of a comment at its
|
|
67
|
+
own line and column, reports one finding per comment however many periods it
|
|
68
|
+
holds, and never rewrites the comment.
|
package/dist/cli.js
CHANGED
|
@@ -286,9 +286,27 @@ function extractComments(source) {
|
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
// src/rules.ts
|
|
289
|
+
var OPT_IN_RULE_IDS = ["japanese-period"];
|
|
289
290
|
var PLACEHOLDER_PATTERN = /\b(TODO|FIXME|XXX|HACK)\b/;
|
|
290
291
|
var SEPARATOR_PATTERN = /^[-=*_#~+./\\|]{4,}$/;
|
|
291
292
|
var DIRECTIVE_PATTERN = /^@ts-(?:ignore|expect-error)\b([\s\S]*)$/;
|
|
293
|
+
var JAPANESE_PERIOD = "\u3002";
|
|
294
|
+
function parseEnabledRules(values) {
|
|
295
|
+
const enabled = [];
|
|
296
|
+
for (const value of values) {
|
|
297
|
+
if (!OPT_IN_RULE_IDS.includes(value)) {
|
|
298
|
+
throw new Error(`unknown rule: ${value}`);
|
|
299
|
+
}
|
|
300
|
+
const rule = value;
|
|
301
|
+
if (!enabled.includes(rule)) {
|
|
302
|
+
enabled.push(rule);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return enabled;
|
|
306
|
+
}
|
|
307
|
+
function findJapanesePeriod(text) {
|
|
308
|
+
return text.indexOf(JAPANESE_PERIOD);
|
|
309
|
+
}
|
|
292
310
|
function normalizeComment(body) {
|
|
293
311
|
return body.split(`
|
|
294
312
|
`).map((line) => line.replace(/^\s*\*+\s?/, "")).join(" ").replace(/\s+/g, " ").trim();
|
|
@@ -337,31 +355,46 @@ function positionAt(source, offset) {
|
|
|
337
355
|
}
|
|
338
356
|
return { line, column: offset - lineStart + 1 };
|
|
339
357
|
}
|
|
340
|
-
function scanSource(source, file) {
|
|
358
|
+
function scanSource(source, file, enabled = []) {
|
|
341
359
|
const findings = [];
|
|
342
360
|
for (const comment of extractComments(source)) {
|
|
361
|
+
const text = normalizeComment(comment.text);
|
|
343
362
|
const rule = classifyComment(comment.text);
|
|
344
|
-
if (rule
|
|
363
|
+
if (rule !== null) {
|
|
364
|
+
const position2 = positionAt(source, comment.start);
|
|
365
|
+
findings.push({
|
|
366
|
+
column: position2.column,
|
|
367
|
+
file,
|
|
368
|
+
line: position2.line,
|
|
369
|
+
rule,
|
|
370
|
+
text
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
if (!enabled.includes("japanese-period")) {
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
const offset = findJapanesePeriod(comment.text);
|
|
377
|
+
if (offset < 0) {
|
|
345
378
|
continue;
|
|
346
379
|
}
|
|
347
|
-
const position = positionAt(source, comment.start);
|
|
380
|
+
const position = positionAt(source, comment.start + 2 + offset);
|
|
348
381
|
findings.push({
|
|
349
382
|
column: position.column,
|
|
350
383
|
file,
|
|
351
384
|
line: position.line,
|
|
352
|
-
rule,
|
|
353
|
-
text
|
|
385
|
+
rule: "japanese-period",
|
|
386
|
+
text
|
|
354
387
|
});
|
|
355
388
|
}
|
|
356
389
|
return findings;
|
|
357
390
|
}
|
|
358
|
-
function scanFile(file, cwd = process.cwd()) {
|
|
359
|
-
return scanSource(readFileSync(file, "utf8"), normalizePath(relative2(cwd, file)));
|
|
391
|
+
function scanFile(file, cwd = process.cwd(), enabled = []) {
|
|
392
|
+
return scanSource(readFileSync(file, "utf8"), normalizePath(relative2(cwd, file)), enabled);
|
|
360
393
|
}
|
|
361
|
-
function scanFiles(files, cwd = process.cwd()) {
|
|
394
|
+
function scanFiles(files, cwd = process.cwd(), enabled = []) {
|
|
362
395
|
const findings = [];
|
|
363
396
|
for (const file of files) {
|
|
364
|
-
findings.push(...scanFile(file, cwd));
|
|
397
|
+
findings.push(...scanFile(file, cwd, enabled));
|
|
365
398
|
}
|
|
366
399
|
return findings.sort(compareFindings);
|
|
367
400
|
}
|
|
@@ -531,18 +564,20 @@ function runCli(main) {
|
|
|
531
564
|
var DEFAULT_BASELINE = "comment-baseline.json";
|
|
532
565
|
var RULE_MESSAGES = {
|
|
533
566
|
"broad-suppression": "file-wide suppression hides too much",
|
|
567
|
+
"japanese-period": "a Japanese sentence in a comment does not end with a period",
|
|
534
568
|
"placeholder-comment": "placeholder comment should be resolved or tracked",
|
|
535
569
|
"separator-comment": "decorative separator comment adds no information",
|
|
536
570
|
"undocumented-directive": "TypeScript directive needs a description"
|
|
537
571
|
};
|
|
538
|
-
var USAGE = "Usage: comment-check [--baseline <path>] [--ignore <path>] [--update-baseline] [--json] [path...]";
|
|
572
|
+
var USAGE = "Usage: comment-check [--baseline <path>] [--enable <rule>] [--ignore <path>] [--update-baseline] [--json] [path...]";
|
|
539
573
|
function parseArguments(argv) {
|
|
540
574
|
const parsed = parseArgv(argv, {
|
|
541
575
|
flags: ["json", "update-baseline"],
|
|
542
|
-
values: ["baseline", "ignore"]
|
|
576
|
+
values: ["baseline", "enable", "ignore"]
|
|
543
577
|
});
|
|
544
578
|
return {
|
|
545
579
|
baselinePath: parsed.values.get("baseline")?.at(-1) ?? DEFAULT_BASELINE,
|
|
580
|
+
enabled: parseEnabledRules(parsed.values.get("enable") ?? []),
|
|
546
581
|
ignores: (parsed.values.get("ignore") ?? []).map(normalizePath),
|
|
547
582
|
json: parsed.flags.has("json"),
|
|
548
583
|
targets: parsed.targets.length > 0 ? parsed.targets : ["."],
|
|
@@ -564,7 +599,7 @@ function main(argv) {
|
|
|
564
599
|
extensions: SUPPORTED_EXTENSIONS,
|
|
565
600
|
ignores: options.ignores
|
|
566
601
|
});
|
|
567
|
-
const findings = scanFiles(files);
|
|
602
|
+
const findings = scanFiles(files, process.cwd(), options.enabled);
|
|
568
603
|
if (options.update) {
|
|
569
604
|
const baseline2 = createBaseline(findings);
|
|
570
605
|
writeBaseline(options.baselinePath, baseline2);
|
|
@@ -583,4 +618,10 @@ function main(argv) {
|
|
|
583
618
|
}
|
|
584
619
|
return comparison.added.length > 0 ? 1 : 0;
|
|
585
620
|
}
|
|
586
|
-
|
|
621
|
+
if (import.meta.main) {
|
|
622
|
+
runCli(main);
|
|
623
|
+
}
|
|
624
|
+
export {
|
|
625
|
+
parseArguments,
|
|
626
|
+
main
|
|
627
|
+
};
|
package/dist/scan.js
CHANGED
|
@@ -284,9 +284,27 @@ function extractComments(source) {
|
|
|
284
284
|
}
|
|
285
285
|
|
|
286
286
|
// src/rules.ts
|
|
287
|
+
var OPT_IN_RULE_IDS = ["japanese-period"];
|
|
287
288
|
var PLACEHOLDER_PATTERN = /\b(TODO|FIXME|XXX|HACK)\b/;
|
|
288
289
|
var SEPARATOR_PATTERN = /^[-=*_#~+./\\|]{4,}$/;
|
|
289
290
|
var DIRECTIVE_PATTERN = /^@ts-(?:ignore|expect-error)\b([\s\S]*)$/;
|
|
291
|
+
var JAPANESE_PERIOD = "\u3002";
|
|
292
|
+
function parseEnabledRules(values) {
|
|
293
|
+
const enabled = [];
|
|
294
|
+
for (const value of values) {
|
|
295
|
+
if (!OPT_IN_RULE_IDS.includes(value)) {
|
|
296
|
+
throw new Error(`unknown rule: ${value}`);
|
|
297
|
+
}
|
|
298
|
+
const rule = value;
|
|
299
|
+
if (!enabled.includes(rule)) {
|
|
300
|
+
enabled.push(rule);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return enabled;
|
|
304
|
+
}
|
|
305
|
+
function findJapanesePeriod(text) {
|
|
306
|
+
return text.indexOf(JAPANESE_PERIOD);
|
|
307
|
+
}
|
|
290
308
|
function normalizeComment(body) {
|
|
291
309
|
return body.split(`
|
|
292
310
|
`).map((line) => line.replace(/^\s*\*+\s?/, "")).join(" ").replace(/\s+/g, " ").trim();
|
|
@@ -335,31 +353,46 @@ function positionAt(source, offset) {
|
|
|
335
353
|
}
|
|
336
354
|
return { line, column: offset - lineStart + 1 };
|
|
337
355
|
}
|
|
338
|
-
function scanSource(source, file) {
|
|
356
|
+
function scanSource(source, file, enabled = []) {
|
|
339
357
|
const findings = [];
|
|
340
358
|
for (const comment of extractComments(source)) {
|
|
359
|
+
const text = normalizeComment(comment.text);
|
|
341
360
|
const rule = classifyComment(comment.text);
|
|
342
|
-
if (rule
|
|
361
|
+
if (rule !== null) {
|
|
362
|
+
const position2 = positionAt(source, comment.start);
|
|
363
|
+
findings.push({
|
|
364
|
+
column: position2.column,
|
|
365
|
+
file,
|
|
366
|
+
line: position2.line,
|
|
367
|
+
rule,
|
|
368
|
+
text
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
if (!enabled.includes("japanese-period")) {
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
const offset = findJapanesePeriod(comment.text);
|
|
375
|
+
if (offset < 0) {
|
|
343
376
|
continue;
|
|
344
377
|
}
|
|
345
|
-
const position = positionAt(source, comment.start);
|
|
378
|
+
const position = positionAt(source, comment.start + 2 + offset);
|
|
346
379
|
findings.push({
|
|
347
380
|
column: position.column,
|
|
348
381
|
file,
|
|
349
382
|
line: position.line,
|
|
350
|
-
rule,
|
|
351
|
-
text
|
|
383
|
+
rule: "japanese-period",
|
|
384
|
+
text
|
|
352
385
|
});
|
|
353
386
|
}
|
|
354
387
|
return findings;
|
|
355
388
|
}
|
|
356
|
-
function scanFile(file, cwd = process.cwd()) {
|
|
357
|
-
return scanSource(readFileSync(file, "utf8"), normalizePath(relative2(cwd, file)));
|
|
389
|
+
function scanFile(file, cwd = process.cwd(), enabled = []) {
|
|
390
|
+
return scanSource(readFileSync(file, "utf8"), normalizePath(relative2(cwd, file)), enabled);
|
|
358
391
|
}
|
|
359
|
-
function scanFiles(files, cwd = process.cwd()) {
|
|
392
|
+
function scanFiles(files, cwd = process.cwd(), enabled = []) {
|
|
360
393
|
const findings = [];
|
|
361
394
|
for (const file of files) {
|
|
362
|
-
findings.push(...scanFile(file, cwd));
|
|
395
|
+
findings.push(...scanFile(file, cwd, enabled));
|
|
363
396
|
}
|
|
364
397
|
return findings.sort(compareFindings);
|
|
365
398
|
}
|