@nielspeter/eess 0.2.1 → 0.4.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.md +3 -3
- package/dist/assertion-advice.d.ts +26 -0
- package/dist/assertion-advice.d.ts.map +1 -0
- package/dist/assertion-advice.js +29 -0
- package/dist/assertion-advice.js.map +1 -0
- package/dist/baseline.d.ts +69 -4
- package/dist/baseline.d.ts.map +1 -1
- package/dist/baseline.js +119 -13
- package/dist/baseline.js.map +1 -1
- package/dist/cache-registry.d.ts +14 -0
- package/dist/cache-registry.d.ts.map +1 -0
- package/dist/cache-registry.js +37 -0
- package/dist/cache-registry.js.map +1 -0
- package/dist/cardinality.d.ts +35 -0
- package/dist/cardinality.d.ts.map +1 -0
- package/dist/cardinality.js +65 -0
- package/dist/cardinality.js.map +1 -0
- package/dist/check-options.d.ts +14 -0
- package/dist/check-options.d.ts.map +1 -1
- package/dist/comment-suppression.d.ts +60 -0
- package/dist/comment-suppression.d.ts.map +1 -0
- package/dist/comment-suppression.js +89 -0
- package/dist/comment-suppression.js.map +1 -0
- package/dist/condition.d.ts +6 -0
- package/dist/condition.d.ts.map +1 -1
- package/dist/correspondence-core.d.ts +35 -0
- package/dist/correspondence-core.d.ts.map +1 -0
- package/dist/correspondence-core.js +38 -0
- package/dist/correspondence-core.js.map +1 -0
- package/dist/correspondence.d.ts +27 -5
- package/dist/correspondence.d.ts.map +1 -1
- package/dist/correspondence.js +39 -5
- package/dist/correspondence.js.map +1 -1
- package/dist/dedupe-config-findings.d.ts +56 -0
- package/dist/dedupe-config-findings.d.ts.map +1 -0
- package/dist/dedupe-config-findings.js +74 -0
- package/dist/dedupe-config-findings.js.map +1 -0
- package/dist/define.d.ts +44 -2
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +45 -4
- package/dist/define.js.map +1 -1
- package/dist/diff-aware.d.ts +8 -0
- package/dist/diff-aware.d.ts.map +1 -1
- package/dist/diff-aware.js +11 -2
- package/dist/diff-aware.js.map +1 -1
- package/dist/diff-disclosure.d.ts +72 -0
- package/dist/diff-disclosure.d.ts.map +1 -0
- package/dist/diff-disclosure.js +110 -0
- package/dist/diff-disclosure.js.map +1 -0
- package/dist/disk-set.d.ts +27 -0
- package/dist/disk-set.d.ts.map +1 -0
- package/dist/disk-set.js +12 -0
- package/dist/disk-set.js.map +1 -0
- package/dist/edge-coverage.d.ts +96 -0
- package/dist/edge-coverage.d.ts.map +1 -0
- package/dist/edge-coverage.js +108 -0
- package/dist/edge-coverage.js.map +1 -0
- package/dist/errors.d.ts +25 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +32 -0
- package/dist/errors.js.map +1 -1
- package/dist/execute-rule.d.ts +11 -5
- package/dist/execute-rule.d.ts.map +1 -1
- package/dist/execute-rule.js +87 -19
- package/dist/execute-rule.js.map +1 -1
- package/dist/format-github.d.ts.map +1 -1
- package/dist/format-github.js +37 -5
- package/dist/format-github.js.map +1 -1
- package/dist/format-json.d.ts +83 -1
- package/dist/format-json.d.ts.map +1 -1
- package/dist/format-json.js +70 -9
- package/dist/format-json.js.map +1 -1
- package/dist/format.d.ts +4 -2
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +40 -8
- package/dist/format.js.map +1 -1
- package/dist/glob-site.d.ts +232 -0
- package/dist/glob-site.d.ts.map +1 -0
- package/dist/glob-site.js +156 -0
- package/dist/glob-site.js.map +1 -0
- package/dist/identity-root.d.ts +55 -0
- package/dist/identity-root.d.ts.map +1 -0
- package/dist/identity-root.js +170 -0
- package/dist/identity-root.js.map +1 -0
- package/dist/index.d.ts +41 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -3
- package/dist/index.js.map +1 -1
- package/dist/owns-empty-discovery.d.ts +5 -0
- package/dist/owns-empty-discovery.d.ts.map +1 -0
- package/dist/owns-empty-discovery.js +77 -0
- package/dist/owns-empty-discovery.js.map +1 -0
- package/dist/path-universe.d.ts +44 -0
- package/dist/path-universe.d.ts.map +1 -0
- package/dist/path-universe.js +21 -0
- package/dist/path-universe.js.map +1 -0
- package/dist/predicate.d.ts +33 -0
- package/dist/predicate.d.ts.map +1 -1
- package/dist/preset-dispatch.d.ts +19 -0
- package/dist/preset-dispatch.d.ts.map +1 -1
- package/dist/preset-dispatch.js +43 -3
- package/dist/preset-dispatch.js.map +1 -1
- package/dist/project-relative.d.ts +25 -0
- package/dist/project-relative.d.ts.map +1 -0
- package/dist/project-relative.js +54 -0
- package/dist/project-relative.js.map +1 -0
- package/dist/report.d.ts +11 -5
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +17 -0
- package/dist/report.js.map +1 -1
- package/dist/rule-builder-like.d.ts +11 -0
- package/dist/rule-builder-like.d.ts.map +1 -0
- package/dist/rule-builder-like.js +2 -0
- package/dist/rule-builder-like.js.map +1 -0
- package/dist/rule-builder.d.ts +109 -84
- package/dist/rule-builder.d.ts.map +1 -1
- package/dist/rule-builder.js +202 -158
- package/dist/rule-builder.js.map +1 -1
- package/dist/rule-description.d.ts +33 -1
- package/dist/rule-description.d.ts.map +1 -1
- package/dist/rule-description.js +17 -1
- package/dist/rule-description.js.map +1 -1
- package/dist/rule-metadata.d.ts +20 -3
- package/dist/rule-metadata.d.ts.map +1 -1
- package/dist/selection-memo.d.ts +47 -0
- package/dist/selection-memo.d.ts.map +1 -0
- package/dist/selection-memo.js +68 -0
- package/dist/selection-memo.js.map +1 -0
- package/dist/shallow-clone.d.ts +20 -0
- package/dist/shallow-clone.d.ts.map +1 -0
- package/dist/shallow-clone.js +27 -0
- package/dist/shallow-clone.js.map +1 -0
- package/dist/stderr.d.ts +16 -0
- package/dist/stderr.d.ts.map +1 -0
- package/dist/stderr.js +73 -0
- package/dist/stderr.js.map +1 -0
- package/dist/terminal-builder.d.ts +209 -9
- package/dist/terminal-builder.d.ts.map +1 -1
- package/dist/terminal-builder.js +264 -20
- package/dist/terminal-builder.js.map +1 -1
- package/dist/type-guards.d.ts +38 -0
- package/dist/type-guards.d.ts.map +1 -0
- package/dist/type-guards.js +42 -0
- package/dist/type-guards.js.map +1 -0
- package/dist/unsuppressable.d.ts +54 -0
- package/dist/unsuppressable.d.ts.map +1 -0
- package/dist/unsuppressable.js +76 -0
- package/dist/unsuppressable.js.map +1 -0
- package/dist/vacuity-findings.d.ts +55 -0
- package/dist/vacuity-findings.d.ts.map +1 -0
- package/dist/vacuity-findings.js +124 -0
- package/dist/vacuity-findings.js.map +1 -0
- package/dist/violation.d.ts +152 -4
- package/dist/violation.d.ts.map +1 -1
- package/dist/violation.js +262 -1
- package/dist/violation.js.map +1 -1
- package/package.json +1 -1
package/dist/errors.js
CHANGED
|
@@ -18,4 +18,36 @@ export class ArchRuleError extends Error {
|
|
|
18
18
|
return this.#violations;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Is this an `ArchRuleError` — including one thrown by a DIFFERENT copy of this
|
|
23
|
+
* module?
|
|
24
|
+
*
|
|
25
|
+
* `instanceof` is an identity check, and a rule file does not necessarily load
|
|
26
|
+
* through the same module registry as the CLI that loads it. `load-rules.ts`
|
|
27
|
+
* uses jiti (bug 0074: a `.ts` rule file must load inside a `"type": "commonjs"`
|
|
28
|
+
* consumer project), and jiti keeps its own registry — so the `ArchRuleError`
|
|
29
|
+
* a self-executing rule file throws is a different class object from this one
|
|
30
|
+
* and `instanceof` is FALSE for an error that is, in every way that matters,
|
|
31
|
+
* an ArchRuleError.
|
|
32
|
+
*
|
|
33
|
+
* Measured: that made `check.ts` skip `ruleFileTruncated()`, so a rule file
|
|
34
|
+
* whose first rule threw reported the finding and said nothing about the rules
|
|
35
|
+
* after it that never ran — a silent gap in a red run, which is bug 0029
|
|
36
|
+
* reopened by the loader. The same hazard exists for any consumer with two
|
|
37
|
+
* copies of eess-ts on disk (a nested `node_modules`), where the loader is
|
|
38
|
+
* irrelevant.
|
|
39
|
+
*
|
|
40
|
+
* Structural, therefore: the `name` this class stamps in its constructor plus
|
|
41
|
+
* the `violations` array that is its whole reason to exist. Both are part of the
|
|
42
|
+
* documented public shape (`ArchViolation[]` on a thrown error), so matching on
|
|
43
|
+
* them is matching on the contract rather than on a coincidence.
|
|
44
|
+
*/
|
|
45
|
+
export function isArchRuleError(error) {
|
|
46
|
+
if (error instanceof ArchRuleError)
|
|
47
|
+
return true;
|
|
48
|
+
return (error instanceof Error &&
|
|
49
|
+
error.name === 'ArchRuleError' &&
|
|
50
|
+
'violations' in error &&
|
|
51
|
+
Array.isArray(error.violations));
|
|
52
|
+
}
|
|
21
53
|
//# sourceMappingURL=errors.js.map
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,WAAW,CAAiB;IAErC,YAAY,UAA2B,EAAE,MAAe;QACtD,MAAM,OAAO,GAAG,yBAAyB,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAA;QAClH,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAC/C,KAAK,CAAC,GAAG,OAAO,GAAG,UAAU,EAAE,CAAC,CAAA;QAChC,IAAI,CAAC,IAAI,GAAG,eAAe,CAAA;QAC3B,IAAI,CAAC,WAAW,GAAG,UAAU,CAAA;IAC/B,CAAC;IAED,4DAA4D;IAC5D,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,WAAW,CAAA;IACzB,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,WAAW,CAAiB;IAErC,YAAY,UAA2B,EAAE,MAAe;QACtD,MAAM,OAAO,GAAG,yBAAyB,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAA;QAClH,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAC/C,KAAK,CAAC,GAAG,OAAO,GAAG,UAAU,EAAE,CAAC,CAAA;QAChC,IAAI,CAAC,IAAI,GAAG,eAAe,CAAA;QAC3B,IAAI,CAAC,WAAW,GAAG,UAAU,CAAA;IAC/B,CAAC;IAED,4DAA4D;IAC5D,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,WAAW,CAAA;IACzB,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,KAAK,YAAY,aAAa;QAAE,OAAO,IAAI,CAAA;IAC/C,OAAO,CACL,KAAK,YAAY,KAAK;QACtB,KAAK,CAAC,IAAI,KAAK,eAAe;QAC9B,YAAY,IAAI,KAAK;QACrB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAChC,CAAA;AACH,CAAC"}
|
package/dist/execute-rule.d.ts
CHANGED
|
@@ -6,18 +6,23 @@ import type { RuleMetadata } from './rule-metadata.js';
|
|
|
6
6
|
* Shared across all builder types (RuleBuilder, SliceRuleBuilder,
|
|
7
7
|
* SchemaRuleBuilder, ResolverRuleBuilder, PairFinalBuilder, SmellBuilder).
|
|
8
8
|
*/
|
|
9
|
-
|
|
9
|
+
interface ExecuteRuleContext {
|
|
10
10
|
reason?: string;
|
|
11
11
|
metadata?: RuleMetadata;
|
|
12
12
|
exclusions?: (string | RegExp)[];
|
|
13
13
|
silentIndices?: Set<number>;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
* and diff filtering to a set of violations, then execute the
|
|
18
|
-
* terminal action (throw or warn).
|
|
16
|
+
* Stamp rule metadata onto violations and apply the rule's exclusions.
|
|
19
17
|
*
|
|
20
|
-
* Extracted to eliminate terminal-method duplication across builders.
|
|
18
|
+
* Extracted to eliminate terminal-method duplication across builders. Baseline
|
|
19
|
+
* and diff filtering are NOT done here — `executeCheck`/`executeWarn` apply
|
|
20
|
+
* those after calling this — and neither is the terminal action.
|
|
21
|
+
*
|
|
22
|
+
* **Mutates the violations it is given** and returns a filtered array of the
|
|
23
|
+
* same objects. Every in-repo producer builds fresh violations per call, so this
|
|
24
|
+
* is safe today; a caller that hands one array to two rules would see the first
|
|
25
|
+
* rule's metadata stick. Stated because this is exported API.
|
|
21
26
|
*/
|
|
22
27
|
export declare function applyFilters(violations: ArchViolation[], ctx: ExecuteRuleContext): ArchViolation[];
|
|
23
28
|
/**
|
|
@@ -28,4 +33,5 @@ export declare function executeCheck(violations: ArchViolation[], ctx: ExecuteRu
|
|
|
28
33
|
* Execute the terminal "warn" action: apply options, format, log to stderr.
|
|
29
34
|
*/
|
|
30
35
|
export declare function executeWarn(violations: ArchViolation[], ctx: ExecuteRuleContext, options?: CheckOptions): void;
|
|
36
|
+
export {};
|
|
31
37
|
//# sourceMappingURL=execute-rule.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-rule.d.ts","sourceRoot":"","sources":["../src/execute-rule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"execute-rule.d.ts","sourceRoot":"","sources":["../src/execute-rule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAWtD;;;;GAIG;AACH,UAAU,kBAAkB;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,UAAU,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;IAChC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,aAAa,EAAE,EAC3B,GAAG,EAAE,kBAAkB,GACtB,aAAa,EAAE,CA8GjB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,aAAa,EAAE,EAC3B,GAAG,EAAE,kBAAkB,EACvB,OAAO,CAAC,EAAE,YAAY,GACrB,IAAI,CAkBN;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,aAAa,EAAE,EAC3B,GAAG,EAAE,kBAAkB,EACvB,OAAO,CAAC,EAAE,YAAY,GACrB,IAAI,CA8BN"}
|
package/dist/execute-rule.js
CHANGED
|
@@ -1,24 +1,38 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
+
import { severityFor } from './violation.js';
|
|
2
3
|
import { ArchRuleError } from './errors.js';
|
|
3
4
|
import { formatViolations } from './format.js';
|
|
4
5
|
import { formatViolationsJson } from './format-json.js';
|
|
5
6
|
import { formatViolationsGitHub } from './format-github.js';
|
|
6
7
|
import { reportViolations } from './report.js';
|
|
7
8
|
import { parseExclusionComments, isExcludedByComment } from './exclusion-comments.js';
|
|
9
|
+
import { writeStderr } from './stderr.js';
|
|
10
|
+
import { activeNotice } from './diff-disclosure.js';
|
|
11
|
+
import { recordCommentSuppression } from './comment-suppression.js';
|
|
8
12
|
/**
|
|
9
|
-
*
|
|
10
|
-
* and diff filtering to a set of violations, then execute the
|
|
11
|
-
* terminal action (throw or warn).
|
|
13
|
+
* Stamp rule metadata onto violations and apply the rule's exclusions.
|
|
12
14
|
*
|
|
13
|
-
* Extracted to eliminate terminal-method duplication across builders.
|
|
15
|
+
* Extracted to eliminate terminal-method duplication across builders. Baseline
|
|
16
|
+
* and diff filtering are NOT done here — `executeCheck`/`executeWarn` apply
|
|
17
|
+
* those after calling this — and neither is the terminal action.
|
|
18
|
+
*
|
|
19
|
+
* **Mutates the violations it is given** and returns a filtered array of the
|
|
20
|
+
* same objects. Every in-repo producer builds fresh violations per call, so this
|
|
21
|
+
* is safe today; a caller that hands one array to two rules would see the first
|
|
22
|
+
* rule's metadata stick. Stated because this is exported API.
|
|
14
23
|
*/
|
|
15
24
|
export function applyFilters(violations, ctx) {
|
|
16
25
|
let result = violations;
|
|
17
|
-
// Apply .excluding() chain exclusions
|
|
26
|
+
// Apply .excluding() chain exclusions — never against a bypassFilters
|
|
27
|
+
// (ADR-010 configuration) finding: it reports the rule's own instrument is
|
|
28
|
+
// broken, not a fault in what was examined, so an exclusion aimed at the
|
|
29
|
+
// latter cannot correctly suppress the former.
|
|
18
30
|
const exclusions = ctx.exclusions ?? [];
|
|
19
31
|
if (exclusions.length > 0) {
|
|
20
32
|
const matchedPatterns = new Set();
|
|
21
33
|
result = result.filter((v) => {
|
|
34
|
+
if (v.bypassFilters === true)
|
|
35
|
+
return true;
|
|
22
36
|
// Match against element, file, or message — so that custom conditions
|
|
23
37
|
// using createViolation() can be excluded by file path or message content,
|
|
24
38
|
// not just by element name (which may be a generic AST node kind).
|
|
@@ -36,29 +50,60 @@ export function applyFilters(violations, ctx) {
|
|
|
36
50
|
const silentIndices = ctx.silentIndices ?? new Set();
|
|
37
51
|
exclusions.forEach((pattern, index) => {
|
|
38
52
|
if (!matchedPatterns.has(index) && !silentIndices.has(index)) {
|
|
39
|
-
|
|
53
|
+
writeStderr(`[eess] Unused exclusion '${String(pattern)}' in rule '${ruleId}'. ` +
|
|
40
54
|
`It matched zero violations — it may be stale after a rename.`);
|
|
41
55
|
}
|
|
42
56
|
});
|
|
43
57
|
}
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
58
|
+
// Stamp rule-level metadata onto every violation that doesn't carry its own.
|
|
59
|
+
//
|
|
60
|
+
// `id`, `because`, `suggestion` and `docs` are properties of the RULE, so this
|
|
61
|
+
// is their single source of truth; a condition that already set one is left
|
|
62
|
+
// untouched. That guard is load-bearing, not decorative: `TsconfigBuilder`
|
|
63
|
+
// computes a per-key `suggestion` ("required X, actual Y") that must survive a
|
|
64
|
+
// rule-level generic one, and `spec.rules.ts` builds a per-row remedy the same
|
|
65
|
+
// way. It is tested directly in `packages/core/tests/execute-rule.test.ts`,
|
|
66
|
+
// because inverting it passed the whole suite and every gate.
|
|
67
|
+
//
|
|
68
|
+
// Most builders already carried these: `RuleBuilder`, the pair/slice/schema/
|
|
69
|
+
// resolver builders and the ts dialect's `createViolation` all thread them
|
|
70
|
+
// through `ConditionContext`. (An earlier version of this comment named the
|
|
71
|
+
// pair builders as affected — measured false: dropping the stamp reddens only
|
|
72
|
+
// the correspondence tests.) The ones that construct violations directly and
|
|
73
|
+
// had no such path are `correspondence()` and `TsconfigBuilder`, which lost:
|
|
74
|
+
//
|
|
75
|
+
// - `.because()` reached the terminal renderer only via the report-level
|
|
76
|
+
// `reason` that `.check()` passes separately, so the `.violations()` path
|
|
77
|
+
// — ADR-008's caller-owns-emission route — dropped it entirely, in every
|
|
78
|
+
// format (bug 0122). Two gates had already hand-written the same
|
|
79
|
+
// workaround, which is the signal it belongs here.
|
|
80
|
+
// - `.rule({ suggestion })` type-checked, ran, and could never render a
|
|
81
|
+
// `Fix:` line for a two-sided rule (bug 0113).
|
|
82
|
+
//
|
|
83
|
+
// Done before the exclusion-comment scan below, and outside its `metadata.id`
|
|
84
|
+
// guard: `.because()` is usable without `.rule({ id })`.
|
|
85
|
+
if (result.length > 0) {
|
|
51
86
|
for (const v of result) {
|
|
52
|
-
if (v.ruleId === undefined)
|
|
53
|
-
v.ruleId =
|
|
87
|
+
if (v.ruleId === undefined && ctx.metadata?.id !== undefined)
|
|
88
|
+
v.ruleId = ctx.metadata.id;
|
|
89
|
+
if (v.because === undefined && ctx.reason !== undefined)
|
|
90
|
+
v.because = ctx.reason;
|
|
91
|
+
if (v.suggestion === undefined && ctx.metadata?.suggestion !== undefined)
|
|
92
|
+
v.suggestion = ctx.metadata.suggestion;
|
|
93
|
+
if (v.docs === undefined && ctx.metadata?.docs !== undefined)
|
|
94
|
+
v.docs = ctx.metadata.docs;
|
|
54
95
|
}
|
|
96
|
+
}
|
|
97
|
+
// Scan source files for inline exclusion comments (when rule has an ID).
|
|
98
|
+
// Matching is on ruleId, which the block above has just guaranteed is present.
|
|
99
|
+
if (ctx.metadata?.id && result.length > 0) {
|
|
55
100
|
const filePaths = new Set(result.map((v) => v.file));
|
|
56
101
|
const allComments = [...filePaths].flatMap((filePath) => {
|
|
57
102
|
try {
|
|
58
103
|
const sourceText = fs.readFileSync(filePath, 'utf-8');
|
|
59
104
|
const parseResult = parseExclusionComments(sourceText, filePath);
|
|
60
105
|
for (const warning of parseResult.warnings) {
|
|
61
|
-
|
|
106
|
+
writeStderr(`[eess] ${warning.message}`);
|
|
62
107
|
}
|
|
63
108
|
return parseResult.exclusions;
|
|
64
109
|
}
|
|
@@ -71,7 +116,15 @@ export function applyFilters(violations, ctx) {
|
|
|
71
116
|
}
|
|
72
117
|
});
|
|
73
118
|
if (allComments.length > 0) {
|
|
74
|
-
|
|
119
|
+
const ruleId = ctx.metadata.id;
|
|
120
|
+
result = result.filter((v) => {
|
|
121
|
+
if (v.bypassFilters === true)
|
|
122
|
+
return true;
|
|
123
|
+
const excluded = isExcludedByComment(v, allComments);
|
|
124
|
+
if (excluded)
|
|
125
|
+
recordCommentSuppression(ruleId, v.file);
|
|
126
|
+
return !excluded;
|
|
127
|
+
});
|
|
75
128
|
}
|
|
76
129
|
}
|
|
77
130
|
return result;
|
|
@@ -85,7 +138,11 @@ export function executeCheck(violations, ctx, options) {
|
|
|
85
138
|
filtered = options.baseline.filterNew(filtered);
|
|
86
139
|
}
|
|
87
140
|
if (options?.diff) {
|
|
141
|
+
const before = filtered.length;
|
|
88
142
|
filtered = options.diff.filterToChanged(filtered);
|
|
143
|
+
const notice = activeNotice(before - filtered.length);
|
|
144
|
+
if (notice !== undefined)
|
|
145
|
+
writeStderr(`${notice}\n`);
|
|
89
146
|
}
|
|
90
147
|
if (filtered.length > 0) {
|
|
91
148
|
// One emitter for both paths (plan 0070) — text/json/github, then throw.
|
|
@@ -102,18 +159,29 @@ export function executeWarn(violations, ctx, options) {
|
|
|
102
159
|
filtered = options.baseline.filterNew(filtered);
|
|
103
160
|
}
|
|
104
161
|
if (options?.diff) {
|
|
162
|
+
const before = filtered.length;
|
|
105
163
|
filtered = options.diff.filterToChanged(filtered);
|
|
164
|
+
const notice = activeNotice(before - filtered.length);
|
|
165
|
+
if (notice !== undefined)
|
|
166
|
+
writeStderr(`${notice}\n`);
|
|
106
167
|
}
|
|
107
168
|
if (filtered.length > 0) {
|
|
108
169
|
if (options?.format === 'json') {
|
|
109
|
-
|
|
170
|
+
writeStderr(formatViolationsJson(filtered, ctx.reason));
|
|
110
171
|
}
|
|
111
172
|
else if (options?.format === 'github') {
|
|
112
173
|
process.stdout.write(formatViolationsGitHub(filtered, 'warning') + '\n');
|
|
113
174
|
}
|
|
114
175
|
else {
|
|
115
|
-
|
|
176
|
+
writeStderr(formatViolations(filtered, ctx.reason));
|
|
116
177
|
}
|
|
117
178
|
}
|
|
179
|
+
// `bypassFilters` outranks `.warn()` (see `severityFor`) — a config finding
|
|
180
|
+
// whose own text promises "not by .warn()" must still fail the build even
|
|
181
|
+
// though the rest of this rule's findings are legitimately warn-only.
|
|
182
|
+
const escalated = filtered.filter((v) => severityFor(v, 'warn') === 'error');
|
|
183
|
+
if (escalated.length > 0) {
|
|
184
|
+
throw new ArchRuleError(escalated, ctx.reason);
|
|
185
|
+
}
|
|
118
186
|
}
|
|
119
187
|
//# sourceMappingURL=execute-rule.js.map
|
package/dist/execute-rule.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-rule.js","sourceRoot":"","sources":["../src/execute-rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"execute-rule.js","sourceRoot":"","sources":["../src/execute-rule.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-github.d.ts","sourceRoot":"","sources":["../src/format-github.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"format-github.d.ts","sourceRoot":"","sources":["../src/format-github.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAGnD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,aAAa,EAAE,EAC3B,QAAQ,GAAE,OAAO,GAAG,SAAmB,GACtC,MAAM,CAuCR;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD"}
|
package/dist/format-github.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import { remedyRepeatsMessage } from './violation.js';
|
|
2
3
|
/**
|
|
3
4
|
* Format violations as GitHub Actions annotation commands.
|
|
4
5
|
*
|
|
@@ -20,17 +21,38 @@ export function formatViolationsGitHub(violations, severity = 'error') {
|
|
|
20
21
|
const cwd = process.cwd();
|
|
21
22
|
return violations
|
|
22
23
|
.map((v) => {
|
|
23
|
-
|
|
24
|
+
// Escaped as a PROPERTY: the runner splits the property list on commas,
|
|
25
|
+
// and a path containing one truncates the annotation onto a file that
|
|
26
|
+
// does not exist (measured). Same treatment as `title` two lines down.
|
|
27
|
+
const relativePath = escapeGitHubProperty(path.relative(cwd, v.file));
|
|
24
28
|
const title = v.ruleId
|
|
25
29
|
? `Architecture Violation: ${v.ruleId}`
|
|
26
30
|
: `Architecture Violation: ${v.rule}`;
|
|
27
31
|
let message = v.because ? `${v.message} (${v.because})` : v.message;
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
// The annotation body opens with `message`, so a remedy identical to it is
|
|
33
|
+
// already there — see `remedyRepeatsMessage`.
|
|
34
|
+
//
|
|
35
|
+
// `join` rather than a bare `'. '`: this format is the one that
|
|
36
|
+
// concatenates the parts into a single line, and a message already ending
|
|
37
|
+
// in punctuation got a second period — `…(reading 'config').. Fix: …`,
|
|
38
|
+
// measured on the real CLI once a producer wrote a well-punctuated
|
|
39
|
+
// message. The rich and plain formats put `Fix:` on its own line and never
|
|
40
|
+
// had the problem.
|
|
41
|
+
const join = (text) => (/[.!?]$/.test(text) ? ' ' : '. ');
|
|
42
|
+
if (v.suggestion && !remedyRepeatsMessage(v))
|
|
43
|
+
message += `${join(message)}Fix: ${v.suggestion}`;
|
|
30
44
|
if (v.docs)
|
|
31
|
-
message +=
|
|
45
|
+
message += `${join(message)}Docs: ${v.docs}`;
|
|
32
46
|
// GitHub annotation format: ::level file=path,line=N,title=T::message
|
|
33
|
-
|
|
47
|
+
//
|
|
48
|
+
// A configuration finding has no source location (file '', line 0), and
|
|
49
|
+
// `::error file=,line=0` is not a valid annotation — GitHub drops or
|
|
50
|
+
// misplaces it. Emit a run-level annotation instead, which renders on
|
|
51
|
+
// the workflow summary (plan 0070).
|
|
52
|
+
if (v.file === '') {
|
|
53
|
+
return `::${severity} title=${escapeGitHubProperty(title)}::${escapeGitHub(message)}`;
|
|
54
|
+
}
|
|
55
|
+
return `::${severity} file=${relativePath},line=${String(v.line)},title=${escapeGitHubProperty(title)}::${escapeGitHub(message)}`;
|
|
34
56
|
})
|
|
35
57
|
.join('\n');
|
|
36
58
|
}
|
|
@@ -41,4 +63,14 @@ export function formatViolationsGitHub(violations, severity = 'error') {
|
|
|
41
63
|
export function escapeGitHub(text) {
|
|
42
64
|
return text.replace(/%/g, '%25').replace(/\r/g, '%0D').replace(/\n/g, '%0A');
|
|
43
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Property values (e.g. `title=`) additionally need `,` and `:` escaped —
|
|
68
|
+
* the workflow-command parser splits the property list on commas, and rule
|
|
69
|
+
* descriptions legitimately contain both (`{a,b}` globs, prose). The
|
|
70
|
+
* run-level annotation for locationless findings made `title` the sole
|
|
71
|
+
* identity carrier, which is what surfaced this.
|
|
72
|
+
*/
|
|
73
|
+
function escapeGitHubProperty(text) {
|
|
74
|
+
return escapeGitHub(text).replace(/,/g, '%2C').replace(/:/g, '%3A');
|
|
75
|
+
}
|
|
44
76
|
//# sourceMappingURL=format-github.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-github.js","sourceRoot":"","sources":["../src/format-github.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"format-github.js","sourceRoot":"","sources":["../src/format-github.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAErD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,sBAAsB,CACpC,UAA2B,EAC3B,WAAgC,OAAO;IAEvC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IAEzB,OAAO,UAAU;SACd,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,wEAAwE;QACxE,sEAAsE;QACtE,uEAAuE;QACvE,MAAM,YAAY,GAAG,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;QACrE,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM;YACpB,CAAC,CAAC,2BAA2B,CAAC,CAAC,MAAM,EAAE;YACvC,CAAC,CAAC,2BAA2B,CAAC,CAAC,IAAI,EAAE,CAAA;QACvC,IAAI,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;QACnE,2EAA2E;QAC3E,8CAA8C;QAC9C,EAAE;QACF,gEAAgE;QAChE,0EAA0E;QAC1E,uEAAuE;QACvE,mEAAmE;QACnE,2EAA2E;QAC3E,mBAAmB;QACnB,MAAM,IAAI,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACzE,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC;YAC1C,OAAO,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,UAAU,EAAE,CAAA;QACnD,IAAI,CAAC,CAAC,IAAI;YAAE,OAAO,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAA;QAExD,sEAAsE;QACtE,EAAE;QACF,wEAAwE;QACxE,qEAAqE;QACrE,sEAAsE;QACtE,oCAAoC;QACpC,IAAI,CAAC,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC;YAClB,OAAO,KAAK,QAAQ,UAAU,oBAAoB,CAAC,KAAK,CAAC,KAAK,YAAY,CAAC,OAAO,CAAC,EAAE,CAAA;QACvF,CAAC;QACD,OAAO,KAAK,QAAQ,SAAS,YAAY,SAAS,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,oBAAoB,CAAC,KAAK,CAAC,KAAK,YAAY,CAAC,OAAO,CAAC,EAAE,CAAA;IACnI,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAA;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AAC9E,CAAC;AAED;;;;;;GAMG;AACH,SAAS,oBAAoB,CAAC,IAAY;IACxC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AACrE,CAAC"}
|
package/dist/format-json.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ArchViolation } from './violation.js';
|
|
2
|
+
import type { EdgeCoverage } from './edge-coverage.js';
|
|
2
3
|
/**
|
|
3
4
|
* Format violations as a JSON string.
|
|
4
5
|
*
|
|
@@ -8,5 +9,86 @@ import type { ArchViolation } from './violation.js';
|
|
|
8
9
|
* const violations = collectViolations(rule1, rule2)
|
|
9
10
|
* console.log(formatViolationsJson(violations))
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
|
+
/**
|
|
13
|
+
* The `check --format json` document, as a type.
|
|
14
|
+
*
|
|
15
|
+
* Exported because it is a **contract**, and an unexported contract is one a
|
|
16
|
+
* consumer can only discover by breaking. Without it a TypeScript consumer gets
|
|
17
|
+
* a runtime failure where they could have had a red build — and our own tests
|
|
18
|
+
* had to hand-roll the shape and cast through `unknown`, which is the kind of
|
|
19
|
+
* ADR-005 exemption that should not be needed against our own output.
|
|
20
|
+
*
|
|
21
|
+
* Changing these types is changing the agent contract. Treat a field removal or
|
|
22
|
+
* a narrowed union as breaking.
|
|
23
|
+
*/
|
|
24
|
+
export interface ArchJsonViolation {
|
|
25
|
+
readonly rule: string;
|
|
26
|
+
readonly ruleId: string | null;
|
|
27
|
+
readonly severity: 'error' | 'warn';
|
|
28
|
+
readonly element: string;
|
|
29
|
+
/**
|
|
30
|
+
* The source file, or `null` when the finding has no location.
|
|
31
|
+
*
|
|
32
|
+
* For `kind: 'configuration'` this is the **rule file** that declared the
|
|
33
|
+
* rule — not the code under test — because the CLI attributes findings to
|
|
34
|
+
* their origin before rendering. It is `null` only for findings produced
|
|
35
|
+
* after that step. Never use it to detect a configuration finding; use `kind`.
|
|
36
|
+
*/
|
|
37
|
+
readonly file: string | null;
|
|
38
|
+
/** `null` when there is no location; `1` on an attributed file means the file, not a position. */
|
|
39
|
+
readonly line: number | null;
|
|
40
|
+
/**
|
|
41
|
+
* What kind of finding this is, and therefore what to do about it.
|
|
42
|
+
*
|
|
43
|
+
* `'violation'` — the code is wrong. `'configuration'` — the **rule**
|
|
44
|
+
* enforces nothing, so editing the code cannot clear it.
|
|
45
|
+
*
|
|
46
|
+
* A consumer should treat an **unrecognised** value as `'violation'`: that
|
|
47
|
+
* keeps widening this union non-breaking, and configuration findings today
|
|
48
|
+
* already span four distinct remedies (a rule that matched nothing, a rule
|
|
49
|
+
* file that could not be evaluated, rules after a failure that never ran, and
|
|
50
|
+
* a stale baseline) which may earn their own names later.
|
|
51
|
+
*/
|
|
52
|
+
readonly kind: 'violation' | 'configuration';
|
|
53
|
+
readonly message: string;
|
|
54
|
+
readonly because: string | null;
|
|
55
|
+
readonly suggestion: string | null;
|
|
56
|
+
readonly docs: string | null;
|
|
57
|
+
readonly codeFrame: string | null;
|
|
58
|
+
readonly measured: number | null;
|
|
59
|
+
}
|
|
60
|
+
/** One finding removed by an inline `// eess-exclude` comment. */
|
|
61
|
+
export interface ArchJsonSuppression {
|
|
62
|
+
readonly ruleId: string;
|
|
63
|
+
readonly file: string;
|
|
64
|
+
}
|
|
65
|
+
/** An allowlist rule that had subjects but tested no edges. */
|
|
66
|
+
export interface ArchJsonUntestedAllowlist {
|
|
67
|
+
readonly rule: string;
|
|
68
|
+
readonly subjects: number;
|
|
69
|
+
readonly edges: number;
|
|
70
|
+
}
|
|
71
|
+
/** The whole document emitted by `check --format json`. */
|
|
72
|
+
export interface ArchJsonReport {
|
|
73
|
+
readonly summary: {
|
|
74
|
+
readonly total: number;
|
|
75
|
+
readonly errors: number;
|
|
76
|
+
readonly warnings: number;
|
|
77
|
+
readonly reason: string | null;
|
|
78
|
+
};
|
|
79
|
+
readonly untestedAllowlists: readonly ArchJsonUntestedAllowlist[];
|
|
80
|
+
readonly commentSuppressed: readonly ArchJsonSuppression[];
|
|
81
|
+
readonly violations: readonly ArchJsonViolation[];
|
|
82
|
+
}
|
|
83
|
+
export declare function formatViolationsJson(violations: ArchViolation[], reason?: string,
|
|
84
|
+
/**
|
|
85
|
+
* Allowlist rules that tested no edges (bug 0015).
|
|
86
|
+
*
|
|
87
|
+
* **Passed in, not read from module state.** The first cut called
|
|
88
|
+
* `untestedRules()` here, which made a documented pure formatter impure: a
|
|
89
|
+
* per-rule JSON document in a vitest suite named rules from every earlier
|
|
90
|
+
* rule in the process, because nothing resets between them. Same input,
|
|
91
|
+
* different output depending on history.
|
|
92
|
+
*/
|
|
93
|
+
untested?: readonly EdgeCoverage[]): string;
|
|
12
94
|
//# sourceMappingURL=format-json.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-json.d.ts","sourceRoot":"","sources":["../src/format-json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"format-json.d.ts","sourceRoot":"","sources":["../src/format-json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAGtD;;;;;;;;GAQG;AACH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAA;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,kGAAkG;IAClG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,eAAe,CAAA;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC;AAED,kEAAkE;AAClE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,+DAA+D;AAC/D,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,2DAA2D;AAC3D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;QACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;QACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;KAC/B,CAAA;IACD,QAAQ,CAAC,kBAAkB,EAAE,SAAS,yBAAyB,EAAE,CAAA;IACjE,QAAQ,CAAC,iBAAiB,EAAE,SAAS,mBAAmB,EAAE,CAAA;IAC1D,QAAQ,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAClD;AAED,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,aAAa,EAAE,EAC3B,MAAM,CAAC,EAAE,MAAM;AACf;;;;;;;;GAQG;AACH,QAAQ,GAAE,SAAS,YAAY,EAAO,GACrC,MAAM,CA8ER"}
|
package/dist/format-json.js
CHANGED
|
@@ -1,28 +1,89 @@
|
|
|
1
|
+
import { commentSuppressions } from './comment-suppression.js';
|
|
2
|
+
export function formatViolationsJson(violations, reason,
|
|
1
3
|
/**
|
|
2
|
-
*
|
|
4
|
+
* Allowlist rules that tested no edges (bug 0015).
|
|
3
5
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* **Passed in, not read from module state.** The first cut called
|
|
7
|
+
* `untestedRules()` here, which made a documented pure formatter impure: a
|
|
8
|
+
* per-rule JSON document in a vitest suite named rules from every earlier
|
|
9
|
+
* rule in the process, because nothing resets between them. Same input,
|
|
10
|
+
* different output depending on history.
|
|
9
11
|
*/
|
|
10
|
-
|
|
12
|
+
untested = []) {
|
|
13
|
+
const errors = violations.filter((v) => (v.severity ?? 'error') === 'error').length;
|
|
11
14
|
const output = {
|
|
12
15
|
summary: {
|
|
13
16
|
total: violations.length,
|
|
17
|
+
errors,
|
|
18
|
+
warnings: violations.length - errors,
|
|
14
19
|
reason: reason ?? null,
|
|
15
20
|
},
|
|
21
|
+
// Bug 0015: an allowlist constrains edges, so a subject with none passes
|
|
22
|
+
// whatever the allowlist says. Reported rather than failed — for the `only*`
|
|
23
|
+
// family zero edges is maximal compliance, and only the reader can tell a
|
|
24
|
+
// dependency-free module from a rule that certified nothing. Always present
|
|
25
|
+
// (an empty array, not omitted) so a consumer can distinguish "none" from
|
|
26
|
+
// "this version does not report it".
|
|
27
|
+
untestedAllowlists: untested.map((c) => ({
|
|
28
|
+
rule: c.rule,
|
|
29
|
+
subjects: c.subjects,
|
|
30
|
+
edges: c.edges,
|
|
31
|
+
})),
|
|
32
|
+
// What inline `// eess-exclude` comments removed from this report.
|
|
33
|
+
// Structural rather than prose, for the same reason `untestedAllowlists` is:
|
|
34
|
+
// the agent reading this document needs identities it can act on, not a
|
|
35
|
+
// sentence to grep. Always present — an empty array, not omitted — so a
|
|
36
|
+
// consumer can tell "nothing was suppressed" from "this version does not
|
|
37
|
+
// report it".
|
|
38
|
+
//
|
|
39
|
+
// Every other filter in the pipeline discloses itself; this one did not,
|
|
40
|
+
// which after bug 0041 made it the widest silent filter we ship.
|
|
41
|
+
commentSuppressed: commentSuppressions().map((c) => ({
|
|
42
|
+
ruleId: c.ruleId,
|
|
43
|
+
file: c.file,
|
|
44
|
+
})),
|
|
16
45
|
violations: violations.map((v) => ({
|
|
17
46
|
rule: v.rule,
|
|
18
47
|
ruleId: v.ruleId ?? null,
|
|
48
|
+
severity: v.severity ?? 'error',
|
|
19
49
|
element: v.element,
|
|
20
|
-
|
|
21
|
-
|
|
50
|
+
// `null`, not `''`/`1`, when there is no source location. A configuration
|
|
51
|
+
// finding reports that a RULE enforces nothing; it has no line, and saying
|
|
52
|
+
// `"file": "", "line": 1` states one that looks real (bug 0047). A human
|
|
53
|
+
// skims past it; an agent may open it or anchor an edit to it.
|
|
54
|
+
//
|
|
55
|
+
// `null` rather than omission, and consistent with the rest of this
|
|
56
|
+
// document — `ruleId`, `because`, `suggestion`, `docs` and `measured` all
|
|
57
|
+
// null when absent, so a consumer already handles the idiom here.
|
|
58
|
+
file: v.file === '' ? null : v.file,
|
|
59
|
+
line: v.file === '' ? null : v.line,
|
|
60
|
+
// What kind of finding this is, which drives what the reader should DO:
|
|
61
|
+
// `'violation'` — the code is wrong, edit the named file;
|
|
62
|
+
// `'configuration'` — the RULE enforces nothing, so editing the code
|
|
63
|
+
// cannot clear it. This distinction was absent from the payload entirely,
|
|
64
|
+
// so an agent could not tell them apart by any field.
|
|
65
|
+
//
|
|
66
|
+
// A string rather than a boolean, decided deliberately. There are twelve
|
|
67
|
+
// configuration-finding producers with materially different causes — an
|
|
68
|
+
// empty selector, a dead glob, a rule with no condition, a preset that
|
|
69
|
+
// discovered nothing — and someone will want to distinguish them. A
|
|
70
|
+
// boolean leaves nowhere to put that; adding a second overlapping field
|
|
71
|
+
// later is worse than one field with room in it. This is the agent
|
|
72
|
+
// contract, so the cost of the wrong shape is permanent.
|
|
73
|
+
//
|
|
74
|
+
// Not named after `bypassFilters`: the consumer cares what the finding
|
|
75
|
+
// IS, not which of our filters it happens to survive.
|
|
76
|
+
kind: v.bypassFilters === true ? 'configuration' : 'violation',
|
|
22
77
|
message: v.message,
|
|
23
78
|
because: v.because ?? null,
|
|
24
79
|
suggestion: v.suggestion ?? null,
|
|
25
80
|
docs: v.docs ?? null,
|
|
81
|
+
codeFrame: v.codeFrame ?? null,
|
|
82
|
+
// Bug 0012's measurement, on the wire. Without it the ratchet is
|
|
83
|
+
// machine-readable only inside the baseline file, and a dashboard wanting
|
|
84
|
+
// the number has to regex it back out of the message — which is the
|
|
85
|
+
// fragility bug 0012 was filed about.
|
|
86
|
+
measured: v.measured ?? null,
|
|
26
87
|
})),
|
|
27
88
|
};
|
|
28
89
|
return JSON.stringify(output, null, 2);
|
package/dist/format-json.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format-json.js","sourceRoot":"","sources":["../src/format-json.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"format-json.js","sourceRoot":"","sources":["../src/format-json.ts"],"names":[],"mappings":"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"}
|
package/dist/format.d.ts
CHANGED
|
@@ -18,8 +18,10 @@ export declare function formatViolations(violations: ArchViolation[], reason?: s
|
|
|
18
18
|
/**
|
|
19
19
|
* Format violations into a plain-text string (no ANSI codes).
|
|
20
20
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
21
|
+
* Public export, for callers that aggregate violations themselves and need
|
|
22
|
+
* output free of ANSI codes — serialized, logged to a file, or embedded in
|
|
23
|
+
* another tool's report. `ArchRuleError.message` is a one-line summary and does
|
|
24
|
+
* not use this; the run's detail is written by `writeReport`.
|
|
23
25
|
*/
|
|
24
26
|
export declare function formatViolationsPlain(violations: ArchViolation[], reason?: string): string;
|
|
25
27
|
//# sourceMappingURL=format.d.ts.map
|
package/dist/format.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAKnD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAoDD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,aAAa,EAAE,EAC3B,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,aAAa,GACtB,MAAM,CAYR;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,aAAa,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CA2B1F"}
|