@opensip-tools/fitness 1.0.6 → 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.6 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.6 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) 259ms
9
- ✓ src/recipes/__tests__/service.test.ts (28 tests) 759ms
10
- ✓ src/framework/__tests__/registry.test.ts (24 tests) 94ms
11
- ✓ src/framework/__tests__/import-graph.test.ts (20 tests) 957ms
12
- ✓ findStronglyConnectedComponents > handles a deep graph without recursion blowing the stack 681ms
13
- ✓ src/plugins/__tests__/check-package-discovery.test.ts (16 tests) 259ms
14
- ✓ src/recipes/__tests__/check-resolution.test.ts (14 tests) 74ms
15
- ✓ src/__tests__/sarif.test.ts (15 tests) 85ms
16
- ✓ src/plugins/__tests__/lang-domain.test.ts (8 tests) 173ms
17
- ✓ src/framework/__tests__/result-builder.test.ts (25 tests) 98ms
18
- ✓ src/framework/__tests__/scope-resolver.test.ts (8 tests) 276ms
19
- ✓ src/plugins/__tests__/loader.test.ts (10 tests) 6660ms
20
- ✓ loadPlugin > registers Check instances exported as named exports (no array wrapper) 6353ms
21
- ✓ src/framework/__tests__/content-filter.test.ts (10 tests) 50ms
22
- ✓ src/framework/__tests__/define-check.test.ts (17 tests) 45ms
23
- ✓ src/framework/__tests__/file-cache.test.ts (15 tests) 249ms
24
- ✓ src/framework/__tests__/path-matcher.test.ts (12 tests) 251ms
25
- ✓ src/recipes/__tests__/registry.test.ts (15 tests) 60ms
26
- ✓ src/framework/__tests__/content-filter-dispatch.test.ts (6 tests) 67ms
27
- ✓ src/targets/__tests__/loader.test.ts (11 tests) 93ms
28
- ✓ src/framework/__tests__/file-accessor.test.ts (11 tests) 95ms
29
- ✓ src/framework/__tests__/strip-literals.test.ts (17 tests) 19ms
30
- ✓ src/recipes/__tests__/built-in-recipes.test.ts (14 tests) 58ms
31
- ✓ src/framework/__tests__/ast-utilities.test.ts (19 tests) 56ms
32
- ✓ src/targets/__tests__/target-registry.test.ts (11 tests) 20ms
33
- ✓ src/framework/__tests__/execution-context.test.ts (4 tests) 159ms
34
- ✓ src/recipes/__tests__/retry.test.ts (6 tests) 17ms
35
- ✓ src/signalers/__tests__/loader.test.ts (8 tests) 92ms
36
- ✓ src/framework/__tests__/directive-inventory.test.ts (9 tests) 14ms
37
- ✓ src/framework/__tests__/command-executor.test.ts (5 tests) 88ms
38
- ✓ src/targets/__tests__/resolver.test.ts (6 tests) 120ms
39
- ✓ src/framework/__tests__/check-config.test.ts (6 tests) 14ms
40
- ✓ src/framework/__tests__/severity-mapping.test.ts (13 tests) 20ms
41
- ✓ src/framework/__tests__/register-helpers.test.ts (4 tests) 15ms
42
- ✓ src/recipes/__tests__/check-config.test.ts (4 tests) 10ms
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  17:46:32
47
-  Duration  23.94s (transform 5.82s, setup 0ms, collect 22.82s, tests 11.31s, environment 40ms, prepare 11.53s)
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.6 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.6",
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.6",
32
- "@opensip-tools/core": "1.0.6"
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