@opensip-tools/fitness 1.0.7 → 1.0.8

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.
@@ -1,4 +1,4 @@
1
1
 
2
- > @opensip-tools/fitness@1.0.7 build /home/runner/work/opensip-tools/opensip-tools/packages/fitness/engine
2
+ > @opensip-tools/fitness@1.0.8 build /home/runner/work/opensip-tools/opensip-tools/packages/fitness/engine
3
3
  > tsc
4
4
 
@@ -1,48 +1,49 @@
1
1
 
2
- > @opensip-tools/fitness@1.0.7 test /home/runner/work/opensip-tools/opensip-tools/packages/fitness/engine
2
+ > @opensip-tools/fitness@1.0.8 test /home/runner/work/opensip-tools/opensip-tools/packages/fitness/engine
3
3
  > vitest run --passWithNoTests
4
4
 
5
5
 
6
6
   RUN  v2.1.9 /home/runner/work/opensip-tools/opensip-tools/packages/fitness/engine
7
7
 
8
- ✓ src/__tests__/gate.test.ts (28 tests) 203ms
9
- ✓ src/framework/__tests__/registry.test.ts (24 tests) 140ms
10
- ✓ src/recipes/__tests__/service.test.ts (28 tests) 1111ms
11
- ✓ src/framework/__tests__/import-graph.test.ts (20 tests) 689ms
12
- ✓ findStronglyConnectedComponents > handles a deep graph without recursion blowing the stack 467ms
13
- ✓ src/plugins/__tests__/check-package-discovery.test.ts (16 tests) 213ms
14
- ✓ src/recipes/__tests__/check-resolution.test.ts (14 tests) 106ms
15
- ✓ src/__tests__/sarif.test.ts (15 tests) 71ms
16
- ✓ src/plugins/__tests__/lang-domain.test.ts (8 tests) 231ms
17
- ✓ src/framework/__tests__/result-builder.test.ts (25 tests) 118ms
18
- ✓ src/framework/__tests__/scope-resolver.test.ts (8 tests) 249ms
19
- ✓ src/plugins/__tests__/loader.test.ts (10 tests) 5899ms
20
- ✓ loadPlugin > registers Check instances exported as named exports (no array wrapper) 5739ms
21
- ✓ src/framework/__tests__/define-check.test.ts (17 tests) 52ms
22
- ✓ src/framework/__tests__/content-filter.test.ts (10 tests) 13ms
23
- ✓ src/framework/__tests__/file-cache.test.ts (15 tests) 247ms
24
- ✓ src/framework/__tests__/path-matcher.test.ts (12 tests) 137ms
25
- ✓ src/framework/__tests__/content-filter-dispatch.test.ts (6 tests) 60ms
26
- ✓ src/recipes/__tests__/registry.test.ts (15 tests) 34ms
27
- ✓ src/targets/__tests__/loader.test.ts (11 tests) 112ms
28
- ✓ src/framework/__tests__/file-accessor.test.ts (11 tests) 117ms
29
- ✓ src/framework/__tests__/strip-literals.test.ts (17 tests) 28ms
30
- ✓ src/framework/__tests__/ast-utilities.test.ts (19 tests) 143ms
31
- ✓ src/recipes/__tests__/built-in-recipes.test.ts (14 tests) 54ms
32
- ✓ src/targets/__tests__/target-registry.test.ts (11 tests) 18ms
33
- ✓ src/signalers/__tests__/loader.test.ts (8 tests) 63ms
34
- ✓ src/framework/__tests__/execution-context.test.ts (4 tests) 175ms
35
- ✓ src/recipes/__tests__/retry.test.ts (6 tests) 22ms
36
- ✓ src/framework/__tests__/directive-inventory.test.ts (9 tests) 28ms
37
- ✓ src/framework/__tests__/command-executor.test.ts (5 tests) 78ms
38
- ✓ src/targets/__tests__/resolver.test.ts (6 tests) 54ms
39
- ✓ src/framework/__tests__/check-config.test.ts (6 tests) 22ms
40
- ✓ src/framework/__tests__/severity-mapping.test.ts (13 tests) 14ms
41
- ✓ src/framework/__tests__/register-helpers.test.ts (4 tests) 23ms
42
- ✓ src/recipes/__tests__/check-config.test.ts (4 tests) 11ms
8
+ ✓ src/__tests__/gate.test.ts (28 tests) 258ms
9
+ ✓ src/recipes/__tests__/service.test.ts (28 tests) 672ms
10
+ ✓ src/framework/__tests__/registry.test.ts (24 tests) 73ms
11
+ ✓ src/framework/__tests__/import-graph.test.ts (20 tests) 778ms
12
+ ✓ findStronglyConnectedComponents > handles a deep graph without recursion blowing the stack 533ms
13
+ ✓ src/plugins/__tests__/check-package-discovery.test.ts (16 tests) 244ms
14
+ ✓ src/recipes/__tests__/check-resolution.test.ts (14 tests) 155ms
15
+ ✓ src/__tests__/sarif.test.ts (15 tests) 70ms
16
+ ✓ src/plugins/__tests__/lang-domain.test.ts (8 tests) 142ms
17
+ ✓ src/framework/__tests__/result-builder.test.ts (25 tests) 114ms
18
+ ✓ src/framework/__tests__/scope-resolver.test.ts (8 tests) 265ms
19
+ ✓ src/plugins/__tests__/loader.test.ts (10 tests) 6800ms
20
+ ✓ loadPlugin > registers Check instances exported as named exports (no array wrapper) 6459ms
21
+ ✓ src/framework/__tests__/content-filter.test.ts (10 tests) 74ms
22
+ ✓ src/framework/__tests__/define-check.test.ts (17 tests) 62ms
23
+ ✓ src/framework/__tests__/file-cache.test.ts (15 tests) 137ms
24
+ ✓ src/framework/__tests__/path-matcher.test.ts (12 tests) 194ms
25
+ ✓ src/framework/__tests__/content-filter-dispatch.test.ts (6 tests) 93ms
26
+ ✓ src/recipes/__tests__/registry.test.ts (15 tests) 20ms
27
+ ✓ src/targets/__tests__/loader.test.ts (11 tests) 94ms
28
+ ✓ src/framework/__tests__/file-accessor.test.ts (11 tests) 106ms
29
+ ✓ src/framework/__tests__/strip-literals.test.ts (17 tests) 26ms
30
+ ✓ src/framework/__tests__/ast-utilities.test.ts (19 tests) 96ms
31
+ ✓ src/recipes/__tests__/built-in-recipes.test.ts (14 tests) 62ms
32
+ ✓ src/targets/__tests__/target-registry.test.ts (11 tests) 43ms
33
+ ✓ src/framework/__tests__/execution-context.test.ts (4 tests) 118ms
34
+ ✓ src/signalers/__tests__/loader.test.ts (8 tests) 109ms
35
+ ✓ src/recipes/__tests__/retry.test.ts (6 tests) 20ms
36
+ ✓ src/framework/__tests__/directive-parsing.test.ts (8 tests) 8ms
37
+ ✓ src/targets/__tests__/resolver.test.ts (6 tests) 67ms
38
+ ✓ src/framework/__tests__/command-executor.test.ts (5 tests) 106ms
39
+ ✓ src/framework/__tests__/directive-inventory.test.ts (9 tests) 8ms
40
+ ✓ src/framework/__tests__/check-config.test.ts (6 tests) 16ms
41
+ ✓ src/framework/__tests__/severity-mapping.test.ts (13 tests) 17ms
42
+ ✓ src/framework/__tests__/register-helpers.test.ts (4 tests) 17ms
43
+ ✓ src/recipes/__tests__/check-config.test.ts (4 tests) 12ms
43
44
 
44
-  Test Files  33 passed (33)
45
-  Tests  419 passed (419)
46
-  Start at  20:35:32
47
-  Duration  22.43s (transform 5.92s, setup 0ms, collect 22.40s, tests 10.53s, environment 31ms, prepare 10.76s)
45
+  Test Files  34 passed (34)
46
+  Tests  427 passed (427)
47
+  Start at  21:42:26
48
+  Duration  24.97s (transform 7.13s, setup 0ms, collect 24.18s, tests 11.07s, environment 62ms, prepare 13.30s)
48
49
 
@@ -1,4 +1,4 @@
1
1
 
2
- > @opensip-tools/fitness@1.0.7 typecheck /home/runner/work/opensip-tools/opensip-tools/packages/fitness/engine
2
+ > @opensip-tools/fitness@1.0.8 typecheck /home/runner/work/opensip-tools/opensip-tools/packages/fitness/engine
3
3
  > tsc --noEmit
4
4
 
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @fileoverview Regression tests for the comment-prefix support added
3
+ * to `extractCheckIdFromDirective` in 1.0.8 (Markdown + HTML + shell/
4
+ * YAML).
5
+ *
6
+ * Prior to 1.0.8 the parser only recognised `//` and `/*` openers, so
7
+ * pragmas inside Markdown documents (`<!-- @fitness-ignore-file ... -->`)
8
+ * or YAML/shell files (`# @fitness-ignore-file ...`) silently
9
+ * failed — the directive was extracted as null and the file was
10
+ * scanned despite the author's intent.
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=directive-parsing.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directive-parsing.test.d.ts","sourceRoot":"","sources":["../../../src/framework/__tests__/directive-parsing.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @fileoverview Regression tests for the comment-prefix support added
3
+ * to `extractCheckIdFromDirective` in 1.0.8 (Markdown + HTML + shell/
4
+ * YAML).
5
+ *
6
+ * Prior to 1.0.8 the parser only recognised `//` and `/*` openers, so
7
+ * pragmas inside Markdown documents (`<!-- @fitness-ignore-file ... -->`)
8
+ * or YAML/shell files (`# @fitness-ignore-file ...`) silently
9
+ * failed — the directive was extracted as null and the file was
10
+ * scanned despite the author's intent.
11
+ */
12
+ import { describe, expect, it } from 'vitest';
13
+ import { parseFileIgnoreDirective } from '../directive-parsing.js';
14
+ describe('parseFileIgnoreDirective — comment-prefix support', () => {
15
+ it('recognises `//` (TypeScript / JavaScript / C-family)', () => {
16
+ const content = '// @fitness-ignore-file file-length-limit -- justified\nrest of file';
17
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(true);
18
+ });
19
+ it('recognises `/*` (block comment in JS-family)', () => {
20
+ const content = '/* @fitness-ignore-file file-length-limit -- justified */\nrest of file';
21
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(true);
22
+ });
23
+ it('recognises `<!--` (Markdown + HTML)', () => {
24
+ const content = '<!-- @fitness-ignore-file file-length-limit -- doc-set catalogue grows by design -->\n# Heading';
25
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(true);
26
+ });
27
+ it('recognises `#` (shell / YAML / Python)', () => {
28
+ const content = '# @fitness-ignore-file file-length-limit -- config grows by design\nkey: value';
29
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(true);
30
+ });
31
+ it('does not recognise an unsupported prefix', () => {
32
+ const content = '; @fitness-ignore-file file-length-limit -- ini-style comments not supported\n[section]';
33
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(false);
34
+ });
35
+ it('requires the directive to actually appear after the comment opener', () => {
36
+ const content = '<!-- not a directive line -->\nrest';
37
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(false);
38
+ });
39
+ it('matches only the specific check id requested', () => {
40
+ const content = '<!-- @fitness-ignore-file other-check -- ... -->\nrest';
41
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(false);
42
+ });
43
+ it('only scans the first 50 lines', () => {
44
+ const filler = Array.from({ length: 60 }, () => 'x').join('\n');
45
+ const content = `${filler}\n<!-- @fitness-ignore-file file-length-limit -- too late -->`;
46
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(false);
47
+ });
48
+ });
49
+ //# sourceMappingURL=directive-parsing.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directive-parsing.test.js","sourceRoot":"","sources":["../../../src/framework/__tests__/directive-parsing.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAElE,QAAQ,CAAC,mDAAmD,EAAE,GAAG,EAAE;IACjE,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,OAAO,GAAG,sEAAsE,CAAA;QACtF,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,OAAO,GAAG,yEAAyE,CAAA;QACzF,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,OAAO,GAAG,iGAAiG,CAAA;QACjH,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,OAAO,GAAG,gFAAgF,CAAA;QAChG,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,OAAO,GAAG,yFAAyF,CAAA;QACzG,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC5E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,OAAO,GAAG,qCAAqC,CAAA;QACrD,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC5E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,OAAO,GAAG,wDAAwD,CAAA;QACxE,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC5E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/D,MAAM,OAAO,GAAG,GAAG,MAAM,+DAA+D,CAAA;QACxF,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC5E,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"directive-parsing.d.ts","sourceRoot":"","sources":["../../src/framework/directive-parsing.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AAsFH;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAClC,OAAO,CAYT;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAClC,GAAG,CAAC,MAAM,CAAC,CAyBb"}
1
+ {"version":3,"file":"directive-parsing.d.ts","sourceRoot":"","sources":["../../src/framework/directive-parsing.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AA6GH;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAClC,OAAO,CAYT;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAClC,GAAG,CAAC,MAAM,CAAC,CAyBb"}
@@ -47,15 +47,37 @@ function isCheckIdChar(char) {
47
47
  const isSpecialChar = code === 95 || code === 45 || code === 47;
48
48
  return isLowerCase || isUpperCase || isDigit || isSpecialChar;
49
49
  }
50
+ /**
51
+ * Comment-opener prefixes the directive parser recognizes. `//` and
52
+ * `/*` cover the TypeScript / JavaScript / C-family languages; `<!--`
53
+ * covers Markdown and HTML so doc files (READMEs, arch docs, the
54
+ * metric taxonomy) can carry `@fitness-ignore-file <slug>` pragmas
55
+ * the same way source code does. `#` covers shell / YAML / Python so
56
+ * config files and scripts use the same surface.
57
+ *
58
+ * Tuple shape: `[opener, length]`. Length is encoded once here so the
59
+ * scanner doesn't repeat it per opener — `<!--` is 4 chars, the
60
+ * others are 2/1.
61
+ */
62
+ const COMMENT_OPENERS = [
63
+ ['//', 2],
64
+ ['/*', 2],
65
+ ['<!--', 4],
66
+ ['#', 1],
67
+ ];
50
68
  function extractCheckIdFromDirective(line, directiveKeyword) {
51
- // Both `//` and `/*` are 2-char prefixes; sliceLen is fixed.
52
- const sliceLen = 2;
53
- let commentIndex = line.indexOf('//');
54
- if (commentIndex === -1) {
55
- commentIndex = line.indexOf('/*');
56
- if (commentIndex === -1)
57
- return null;
69
+ let commentIndex = -1;
70
+ let sliceLen = 0;
71
+ for (const [opener, length] of COMMENT_OPENERS) {
72
+ const idx = line.indexOf(opener);
73
+ if (idx !== -1) {
74
+ commentIndex = idx;
75
+ sliceLen = length;
76
+ break;
77
+ }
58
78
  }
79
+ if (commentIndex === -1)
80
+ return null;
59
81
  const afterComment = line.slice(commentIndex + sliceLen).trimStart();
60
82
  if (!afterComment.startsWith(directiveKeyword))
61
83
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"directive-parsing.js","sourceRoot":"","sources":["../../src/framework/directive-parsing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"directive-parsing.js","sourceRoot":"","sources":["../../src/framework/directive-parsing.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opensip-tools/fitness",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "license": "MIT",
5
5
  "description": "Fitness checks engine for OpenSIP Tools",
6
6
  "repository": {
@@ -28,8 +28,8 @@
28
28
  "minimatch": "^10.0.0",
29
29
  "typescript": "~5.7.0",
30
30
  "zod": "^3.24.0",
31
- "@opensip-tools/contracts": "1.0.7",
32
- "@opensip-tools/core": "1.0.7"
31
+ "@opensip-tools/core": "1.0.8",
32
+ "@opensip-tools/contracts": "1.0.8"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/js-yaml": "^4.0.0",
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @fileoverview Regression tests for the comment-prefix support added
3
+ * to `extractCheckIdFromDirective` in 1.0.8 (Markdown + HTML + shell/
4
+ * YAML).
5
+ *
6
+ * Prior to 1.0.8 the parser only recognised `//` and `/*` openers, so
7
+ * pragmas inside Markdown documents (`<!-- @fitness-ignore-file ... -->`)
8
+ * or YAML/shell files (`# @fitness-ignore-file ...`) silently
9
+ * failed — the directive was extracted as null and the file was
10
+ * scanned despite the author's intent.
11
+ */
12
+
13
+ import { describe, expect, it } from 'vitest'
14
+
15
+ import { parseFileIgnoreDirective } from '../directive-parsing.js'
16
+
17
+ describe('parseFileIgnoreDirective — comment-prefix support', () => {
18
+ it('recognises `//` (TypeScript / JavaScript / C-family)', () => {
19
+ const content = '// @fitness-ignore-file file-length-limit -- justified\nrest of file'
20
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(true)
21
+ })
22
+
23
+ it('recognises `/*` (block comment in JS-family)', () => {
24
+ const content = '/* @fitness-ignore-file file-length-limit -- justified */\nrest of file'
25
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(true)
26
+ })
27
+
28
+ it('recognises `<!--` (Markdown + HTML)', () => {
29
+ const content = '<!-- @fitness-ignore-file file-length-limit -- doc-set catalogue grows by design -->\n# Heading'
30
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(true)
31
+ })
32
+
33
+ it('recognises `#` (shell / YAML / Python)', () => {
34
+ const content = '# @fitness-ignore-file file-length-limit -- config grows by design\nkey: value'
35
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(true)
36
+ })
37
+
38
+ it('does not recognise an unsupported prefix', () => {
39
+ const content = '; @fitness-ignore-file file-length-limit -- ini-style comments not supported\n[section]'
40
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(false)
41
+ })
42
+
43
+ it('requires the directive to actually appear after the comment opener', () => {
44
+ const content = '<!-- not a directive line -->\nrest'
45
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(false)
46
+ })
47
+
48
+ it('matches only the specific check id requested', () => {
49
+ const content = '<!-- @fitness-ignore-file other-check -- ... -->\nrest'
50
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(false)
51
+ })
52
+
53
+ it('only scans the first 50 lines', () => {
54
+ const filler = Array.from({ length: 60 }, () => 'x').join('\n')
55
+ const content = `${filler}\n<!-- @fitness-ignore-file file-length-limit -- too late -->`
56
+ expect(parseFileIgnoreDirective(content, 'file-length-limit')).toBe(false)
57
+ })
58
+ })
@@ -56,14 +56,37 @@ function isCheckIdChar(char: string): boolean {
56
56
  return isLowerCase || isUpperCase || isDigit || isSpecialChar
57
57
  }
58
58
 
59
+ /**
60
+ * Comment-opener prefixes the directive parser recognizes. `//` and
61
+ * `/*` cover the TypeScript / JavaScript / C-family languages; `<!--`
62
+ * covers Markdown and HTML so doc files (READMEs, arch docs, the
63
+ * metric taxonomy) can carry `@fitness-ignore-file <slug>` pragmas
64
+ * the same way source code does. `#` covers shell / YAML / Python so
65
+ * config files and scripts use the same surface.
66
+ *
67
+ * Tuple shape: `[opener, length]`. Length is encoded once here so the
68
+ * scanner doesn't repeat it per opener — `<!--` is 4 chars, the
69
+ * others are 2/1.
70
+ */
71
+ const COMMENT_OPENERS: readonly (readonly [string, number])[] = [
72
+ ['//', 2],
73
+ ['/*', 2],
74
+ ['<!--', 4],
75
+ ['#', 1],
76
+ ]
77
+
59
78
  function extractCheckIdFromDirective(line: string, directiveKeyword: string): string | null {
60
- // Both `//` and `/*` are 2-char prefixes; sliceLen is fixed.
61
- const sliceLen = 2
62
- let commentIndex = line.indexOf('//')
63
- if (commentIndex === -1) {
64
- commentIndex = line.indexOf('/*')
65
- if (commentIndex === -1) return null
79
+ let commentIndex = -1
80
+ let sliceLen = 0
81
+ for (const [opener, length] of COMMENT_OPENERS) {
82
+ const idx = line.indexOf(opener)
83
+ if (idx !== -1) {
84
+ commentIndex = idx
85
+ sliceLen = length
86
+ break
87
+ }
66
88
  }
89
+ if (commentIndex === -1) return null
67
90
 
68
91
  const afterComment = line.slice(commentIndex + sliceLen).trimStart()
69
92
  if (!afterComment.startsWith(directiveKeyword)) return null