@nielspeter/eess 0.2.2 → 0.5.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 +97 -4
- 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-generator.d.ts +9 -0
- package/dist/baseline-generator.d.ts.map +1 -1
- package/dist/baseline-generator.js +9 -0
- package/dist/baseline-generator.js.map +1 -1
- 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 +80 -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/cli-config.d.ts +59 -0
- package/dist/cli-config.d.ts.map +1 -0
- package/dist/cli-config.js +84 -0
- package/dist/cli-config.js.map +1 -0
- package/dist/collect-result.d.ts +94 -0
- package/dist/collect-result.d.ts.map +1 -0
- package/dist/collect-result.js +142 -0
- package/dist/collect-result.js.map +1 -0
- package/dist/combinators.d.ts +14 -0
- package/dist/combinators.d.ts.map +1 -1
- package/dist/combinators.js +53 -16
- package/dist/combinators.js.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 +43 -0
- package/dist/condition.d.ts.map +1 -1
- package/dist/condition.js +48 -1
- package/dist/condition.js.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 +57 -5
- package/dist/correspondence.d.ts.map +1 -1
- package/dist/correspondence.js +74 -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 +101 -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 -1
- package/dist/diff-aware.d.ts.map +1 -1
- package/dist/diff-aware.js +39 -9
- 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/emitter-findings.d.ts +167 -0
- package/dist/emitter-findings.d.ts.map +1 -0
- package/dist/emitter-findings.js +237 -0
- package/dist/emitter-findings.js.map +1 -0
- package/dist/errors.d.ts +73 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +93 -0
- package/dist/errors.js.map +1 -1
- package/dist/exclusion-comments.d.ts +36 -1
- package/dist/exclusion-comments.d.ts.map +1 -1
- package/dist/exclusion-comments.js +185 -37
- package/dist/exclusion-comments.js.map +1 -1
- package/dist/execute-rule.d.ts +11 -1
- package/dist/execute-rule.d.ts.map +1 -1
- package/dist/execute-rule.js +220 -11
- package/dist/execute-rule.js.map +1 -1
- package/dist/file-walk.d.ts +22 -0
- package/dist/file-walk.d.ts.map +1 -0
- package/dist/file-walk.js +51 -0
- package/dist/file-walk.js.map +1 -0
- 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 +96 -1
- package/dist/format-json.d.ts.map +1 -1
- package/dist/format-json.js +94 -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 +41 -19
- 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 +18 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -10
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +55 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +92 -0
- package/dist/internal.js.map +1 -0
- package/dist/mask-non-comment.d.ts +49 -0
- package/dist/mask-non-comment.d.ts.map +1 -0
- package/dist/mask-non-comment.js +261 -0
- package/dist/mask-non-comment.js.map +1 -0
- 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 +85 -0
- package/dist/owns-empty-discovery.js.map +1 -0
- package/dist/path-suffix.d.ts +57 -0
- package/dist/path-suffix.d.ts.map +1 -0
- package/dist/path-suffix.js +73 -0
- package/dist/path-suffix.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 +45 -0
- package/dist/predicate.d.ts.map +1 -1
- package/dist/predicate.js +20 -1
- package/dist/predicate.js.map +1 -1
- package/dist/preset-dispatch.d.ts +6 -15
- package/dist/preset-dispatch.d.ts.map +1 -1
- package/dist/preset-dispatch.js +35 -17
- 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 +42 -12
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +190 -14
- package/dist/report.js.map +1 -1
- package/dist/rule-builder-like.d.ts +17 -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 +124 -84
- package/dist/rule-builder.d.ts.map +1 -1
- package/dist/rule-builder.js +230 -181
- package/dist/rule-builder.js.map +1 -1
- package/dist/rule-description.d.ts +83 -1
- package/dist/rule-description.d.ts.map +1 -1
- package/dist/rule-description.js +75 -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 +45 -0
- package/dist/selection-memo.d.ts.map +1 -0
- package/dist/selection-memo.js +66 -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/silent-exclusion.d.ts +12 -0
- package/dist/silent-exclusion.d.ts.map +1 -1
- package/dist/silent-exclusion.js +22 -0
- package/dist/silent-exclusion.js.map +1 -1
- 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 +224 -10
- package/dist/terminal-builder.d.ts.map +1 -1
- package/dist/terminal-builder.js +336 -46
- 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 +49 -0
- package/dist/vacuity-findings.d.ts.map +1 -0
- package/dist/vacuity-findings.js +94 -0
- package/dist/vacuity-findings.js.map +1 -0
- package/dist/violation.d.ts +173 -4
- package/dist/violation.d.ts.map +1 -1
- package/dist/violation.js +262 -1
- package/dist/violation.js.map +1 -1
- package/dist/watch.d.ts +71 -0
- package/dist/watch.d.ts.map +1 -0
- package/dist/watch.js +129 -0
- package/dist/watch.js.map +1 -0
- package/package.json +6 -1
package/dist/rule-builder.js
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { assertionAdviceFor } from './assertion-advice.js';
|
|
2
|
+
import { collectResult } from './collect-result.js';
|
|
3
|
+
import { selectMatching, matchingElements } from './correspondence.js';
|
|
4
|
+
import { recordPredicate } from './predicate.js';
|
|
5
|
+
import { countDeclaredGlobs, stampGlobs } from './glob-site.js';
|
|
6
|
+
import { TerminalBuilder, assertionLessViolation } from './terminal-builder.js';
|
|
7
|
+
import { assertsCardinality as conditionAssertsCardinality } from './cardinality.js';
|
|
8
|
+
import { ruleDescriptionOf, ruleDescriptionFrom } from './rule-description.js';
|
|
9
|
+
import { conditionContextFrom } from './condition.js';
|
|
10
|
+
/**
|
|
11
|
+
* A declared glob's own label in a dead-glob finding — the predicate/
|
|
12
|
+
* condition's description, disambiguated with the literal glob only when
|
|
13
|
+
* more than one site shares the description (a variadic predicate like
|
|
14
|
+
* `importFrom(...globs)` already spells every glob into its own
|
|
15
|
+
* description, so a substring test would collapse the one case this exists
|
|
16
|
+
* to separate — keyed on the site COUNT instead).
|
|
17
|
+
*/
|
|
18
|
+
function describeOrigin(description, glob, siteCount) {
|
|
19
|
+
return siteCount > 1 ? `${description} ("${glob.glob}")` : description;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The actual walk `RuleBuilder.globs()` delegates to — a free function
|
|
23
|
+
* rather than a method body, to keep the class itself under this repo's own
|
|
24
|
+
* 300-line class-length gate (`arch.internal.rules.ts`).
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* The globs a rule declares, stamped with where each came from.
|
|
28
|
+
*
|
|
29
|
+
* Exported (as family plumbing) so `eess-ts` can call it instead of keeping its
|
|
30
|
+
* own copy — they were 94% similar, and the difference was not cosmetic: only
|
|
31
|
+
* the eess-ts copy honoured `originLabel`. The kernel's `Predicate` has carried
|
|
32
|
+
* that field all along and this function ignored it, so a preset's label was
|
|
33
|
+
* dropped for `eess-md`, `eess-mermaid` and `eess-gherkin`. Found by unifying.
|
|
34
|
+
*/
|
|
35
|
+
export function declaredGlobsOf(
|
|
36
|
+
// `readonly`, widened so a caller holding a frozen declaration can pass it
|
|
37
|
+
// without a copy. Strictly more permissive; the body only iterates.
|
|
38
|
+
predicates, conditions) {
|
|
39
|
+
const trees = [];
|
|
40
|
+
for (const predicate of predicates) {
|
|
41
|
+
if (predicate.globs) {
|
|
42
|
+
const count = countDeclaredGlobs(predicate.globs);
|
|
43
|
+
trees.push(stampGlobs(predicate.globs, 'selector', (g) =>
|
|
44
|
+
// A preset's `originLabel` names the option the user wrote rather
|
|
45
|
+
// than the calls it expanded into. Used VERBATIM, skipping
|
|
46
|
+
// `describeOrigin`: that appends `("glob")` to disambiguate a
|
|
47
|
+
// predicate holding several sites, and a label already names exactly
|
|
48
|
+
// one option and one glob — left in, the finding read
|
|
49
|
+
// `shared: "**/x/**" ("**/x/**")`.
|
|
50
|
+
predicate.originLabel ?? describeOrigin(predicate.description, g, count)));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
for (const condition of conditions) {
|
|
54
|
+
if (condition.globs) {
|
|
55
|
+
const count = countDeclaredGlobs(condition.globs);
|
|
56
|
+
trees.push(stampGlobs(condition.globs, 'condition', (g) => describeOrigin(condition.description, g, count)));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return trees;
|
|
60
|
+
}
|
|
3
61
|
/**
|
|
4
62
|
* Abstract base class for all rule builders.
|
|
5
63
|
*
|
|
@@ -9,29 +67,46 @@ import { executeCheck, executeWarn, applyFilters } from './execute-rule.js';
|
|
|
9
67
|
* 3. Add condition methods that call `addCondition()`
|
|
10
68
|
*
|
|
11
69
|
* The builder accumulates predicates and conditions. Nothing executes
|
|
12
|
-
* until a terminal method (`.check()`, `.warn()`, `.severity()`) is called
|
|
70
|
+
* until a terminal method (`.check()`, `.warn()`, `.severity()`) is called —
|
|
71
|
+
* inherited from {@link TerminalBuilder} (plan 0088 Phase 4), which also
|
|
72
|
+
* supplies `because`/`rule`/`excluding`/`violations`/`expectEmpty`/
|
|
73
|
+
* `expectNonEmpty` and the ADR-010 evidence gate. `RuleBuilder` keeps its own
|
|
74
|
+
* `<T, P>` two-param generic — `P` is the dialect's project type, kept
|
|
75
|
+
* separate from `TerminalBuilder` (which has no project concept, since
|
|
76
|
+
* `correspondence()`, `SmellBuilder`, and the graphql builders don't share a
|
|
77
|
+
* uniform notion of "one project") — every builder across all five dialects
|
|
78
|
+
* depends on this exact two-param signature, so it is not replaced by the
|
|
79
|
+
* fold, only extended.
|
|
13
80
|
*/
|
|
14
|
-
export class RuleBuilder {
|
|
81
|
+
export class RuleBuilder extends TerminalBuilder {
|
|
15
82
|
project;
|
|
16
83
|
_predicates = [];
|
|
17
84
|
_conditions = [];
|
|
18
|
-
_reason;
|
|
19
|
-
_metadata;
|
|
20
|
-
_exclusions = [];
|
|
21
|
-
_silentIndices = new Set();
|
|
22
85
|
_phase = 'predicate';
|
|
86
|
+
/** Whether `.should()` was ever reached — bug 0155 state 3/4 vs state 1. */
|
|
87
|
+
_reachedShould = false;
|
|
88
|
+
/**
|
|
89
|
+
* Descriptions of predicate-only methods used AFTER `.should()` — bug 0155
|
|
90
|
+
* state 2. A dual-use method dispatches to a condition in that phase and
|
|
91
|
+
* never lands here, so anything recorded is genuinely a filter written where
|
|
92
|
+
* an assertion was meant.
|
|
93
|
+
*/
|
|
94
|
+
_misplaced = [];
|
|
23
95
|
constructor(project) {
|
|
96
|
+
super();
|
|
24
97
|
this.project = project;
|
|
25
98
|
}
|
|
26
99
|
// --- Chain methods (grammar transitions) ---
|
|
27
100
|
/**
|
|
28
|
-
* Begin the predicate phase. Returns
|
|
101
|
+
* Begin the predicate phase. Returns a COPY — a held selection is never
|
|
102
|
+
* edited by narrowing it (see `TerminalBuilder.copy()`).
|
|
29
103
|
* Purely a readability marker — `.that().haveNameMatching(...)` reads like English.
|
|
30
104
|
* Explicitly resets phase to 'predicate' — defensive against `.should().that()` misuse.
|
|
31
105
|
*/
|
|
32
106
|
that() {
|
|
33
|
-
|
|
34
|
-
|
|
107
|
+
const next = this.copy();
|
|
108
|
+
next._phase = 'predicate';
|
|
109
|
+
return next;
|
|
35
110
|
}
|
|
36
111
|
/**
|
|
37
112
|
* Add another predicate (AND). Returns `this` for chaining.
|
|
@@ -48,6 +123,7 @@ export class RuleBuilder {
|
|
|
48
123
|
should() {
|
|
49
124
|
const fork = this.fork();
|
|
50
125
|
fork._phase = 'condition';
|
|
126
|
+
fork._reachedShould = true;
|
|
51
127
|
return fork;
|
|
52
128
|
}
|
|
53
129
|
/**
|
|
@@ -72,70 +148,11 @@ export class RuleBuilder {
|
|
|
72
148
|
}
|
|
73
149
|
return this.addCondition(custom);
|
|
74
150
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
this._reason = reason;
|
|
81
|
-
return this;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Attach rich metadata to the rule.
|
|
85
|
-
* Provides educational context in violation output: why, how to fix, docs link.
|
|
86
|
-
*
|
|
87
|
-
* If `metadata.because` is set, it also sets the reason (same as `.because()`).
|
|
88
|
-
*/
|
|
89
|
-
rule(metadata) {
|
|
90
|
-
this._metadata = metadata;
|
|
91
|
-
if (metadata.because) {
|
|
92
|
-
this._reason = metadata.because;
|
|
93
|
-
}
|
|
94
|
-
return this;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Exclude specific violations from reporting by matching against
|
|
98
|
-
* the violation's `element`, `file`, or `message` fields.
|
|
99
|
-
*
|
|
100
|
-
* Matched violations are silently suppressed. Use for permanent,
|
|
101
|
-
* intentional exceptions — not for temporary violations (use baseline for those).
|
|
102
|
-
*
|
|
103
|
-
* Patterns are matched against all three fields. Prefer anchored regexes
|
|
104
|
-
* or full string matches over short substrings, especially for `message`
|
|
105
|
-
* matching, to avoid accidentally suppressing unrelated violations whose
|
|
106
|
-
* messages happen to contain the same text.
|
|
107
|
-
*
|
|
108
|
-
* Emits a warning if an exclusion matches zero violations — so renamed
|
|
109
|
-
* or deleted exceptions don't silently stay in the rule.
|
|
110
|
-
*
|
|
111
|
-
* For narrowing a rule's scope at the predicate phase (so the rule never
|
|
112
|
-
* evaluates the excluded element), use `satisfy(not(<predicate>))` instead.
|
|
113
|
-
* See the "Excluding a file from a rule's scope" recipe in docs/recipes.md.
|
|
114
|
-
*
|
|
115
|
-
* @example
|
|
116
|
-
* // Exclude by element name (fully qualified)
|
|
117
|
-
* .excluding('Asset.getImageUrl')
|
|
118
|
-
*
|
|
119
|
-
* @example
|
|
120
|
-
* // Exclude by file path (regex anchored to suffix)
|
|
121
|
-
* .excluding(/repositories\/index\.ts$/)
|
|
122
|
-
*
|
|
123
|
-
* @example
|
|
124
|
-
* // Multiple exclusions, mixed forms
|
|
125
|
-
* .excluding('Asset.getImageUrl', /\/legacy\//, /generated/)
|
|
126
|
-
*/
|
|
127
|
-
excluding(...patterns) {
|
|
128
|
-
for (const p of patterns) {
|
|
129
|
-
if (isSilent(p)) {
|
|
130
|
-
this._exclusions.push(p.pattern);
|
|
131
|
-
this._silentIndices.add(this._exclusions.length - 1);
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
this._exclusions.push(p);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
return this;
|
|
138
|
-
}
|
|
151
|
+
// `because`, `rule`, `excluding`, `violations`, `check`, `warn`, `severity`,
|
|
152
|
+
// `expectEmpty`, `expectNonEmpty` are inherited from `TerminalBuilder`
|
|
153
|
+
// (plan 0088 Phase 4) — this class used to duplicate all of them, and the
|
|
154
|
+
// two copies had already drifted (the exact hazard `ts-archunit`'s own
|
|
155
|
+
// `RuleBuilder`/`TerminalBuilder` merge commit documents).
|
|
139
156
|
// --- Terminal methods ---
|
|
140
157
|
/**
|
|
141
158
|
* Return the predicate-filtered elements as a labelled `Selection<T>` for
|
|
@@ -146,114 +163,141 @@ export class RuleBuilder {
|
|
|
146
163
|
* @param opts.identify - map an element to its message metadata (name/file/line)
|
|
147
164
|
*/
|
|
148
165
|
select(opts) {
|
|
149
|
-
|
|
150
|
-
return { elements: filtered, label: opts.label, identify: opts.identify };
|
|
166
|
+
return selectMatching(this.getElements(), this._predicates, opts);
|
|
151
167
|
}
|
|
152
168
|
/**
|
|
153
169
|
* Return a structured description of this rule without executing it.
|
|
154
170
|
* Used by the `explain` CLI subcommand.
|
|
155
171
|
*/
|
|
156
172
|
describeRule() {
|
|
157
|
-
return {
|
|
158
|
-
rule: this.buildRuleDescription(),
|
|
159
|
-
id: this._metadata?.id,
|
|
160
|
-
because: this._reason,
|
|
161
|
-
suggestion: this._metadata?.suggestion,
|
|
162
|
-
docs: this._metadata?.docs,
|
|
163
|
-
imperative: this._metadata?.imperative,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Execute the rule and return violations after exclusion filtering.
|
|
168
|
-
* Does not throw — use for programmatic access (presets, aggregation).
|
|
169
|
-
*/
|
|
170
|
-
violations() {
|
|
171
|
-
const raw = this.evaluate();
|
|
172
|
-
return applyFilters(raw, {
|
|
173
|
-
reason: this._reason,
|
|
173
|
+
return ruleDescriptionFrom({
|
|
174
174
|
metadata: this._metadata,
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
reason: this._reason,
|
|
176
|
+
rule: this.buildRuleDescription(),
|
|
177
177
|
});
|
|
178
178
|
}
|
|
179
179
|
/**
|
|
180
|
-
*
|
|
181
|
-
*
|
|
180
|
+
* ADR-010: is this rule's assertion satisfied by an empty selection, as a
|
|
181
|
+
* property of what its conditions assert (`.notExist()`) rather than a
|
|
182
|
+
* caller's `.expectEmpty()` declaration?
|
|
183
|
+
*
|
|
184
|
+
* `.every()`, not `.some()` — `.andShould()` ANDs, so a rule reading
|
|
185
|
+
* `.should().notExist().andShould().beExported()` still asserts something
|
|
186
|
+
* about subjects that exist, and exempting it on the strength of the one
|
|
187
|
+
* cardinality condition would silence the other. An empty condition list is
|
|
188
|
+
* NOT exempt: `[].every()` is vacuously `true`, and a rule with zero
|
|
189
|
+
* conditions is the assertion-less case `collectViolations()` now reports as
|
|
190
|
+
* a configuration finding (bug 0155; it used to be an unreachable stderr
|
|
191
|
+
* warning, which this comment named until that fix landed) — this override
|
|
192
|
+
* must not paper over it by also declaring it cardinality-satisfied.
|
|
182
193
|
*
|
|
183
|
-
*
|
|
194
|
+
* **Load-bearing:** for a DEAD selector this early return is the only thing
|
|
195
|
+
* between an assertion-less rule and a silent pass (the gate runs after the
|
|
196
|
+
* zero-examined branch). Pinned in `assertion-less-rules.test.ts`.
|
|
184
197
|
*/
|
|
185
|
-
check(options) {
|
|
186
|
-
const violations = this.evaluate();
|
|
187
|
-
executeCheck(violations, {
|
|
188
|
-
reason: this._reason,
|
|
189
|
-
metadata: this._metadata,
|
|
190
|
-
exclusions: this._exclusions,
|
|
191
|
-
silentIndices: this._silentIndices,
|
|
192
|
-
}, options);
|
|
193
|
-
}
|
|
194
198
|
/**
|
|
195
|
-
*
|
|
196
|
-
* Use for rules that should warn but not fail CI.
|
|
199
|
+
* Does this rule assert anything at all? — bug 0155.
|
|
197
200
|
*
|
|
198
|
-
*
|
|
201
|
+
* Conditions alone are not enough: a predicate-only method written *after*
|
|
202
|
+
* `.should()` silently shrank the set the conditions run over, possibly to
|
|
203
|
+
* empty, in which case they hold vacuously. That rule asserts nothing
|
|
204
|
+
* meaningful even though `_conditions` is non-empty.
|
|
199
205
|
*/
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
206
|
+
assertsSomething() {
|
|
207
|
+
return this._conditions.length > 0 && this._misplaced.length === 0;
|
|
208
|
+
}
|
|
209
|
+
assertionAdvice() {
|
|
210
|
+
return assertionAdviceFor({
|
|
211
|
+
reachedShould: this._reachedShould,
|
|
212
|
+
misplaced: this._misplaced,
|
|
213
|
+
conditionCount: this._conditions.length,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
assertsCardinality() {
|
|
217
|
+
if (this._conditions.length === 0)
|
|
218
|
+
return false;
|
|
219
|
+
return this._conditions.every((condition) => conditionAssertsCardinality(condition));
|
|
208
220
|
}
|
|
209
221
|
/**
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
222
|
+
* ADR-010 part 3: did this rule's own underlying source (the project, a
|
|
223
|
+
* diagram, an SDL string — whatever `P` loads) produce nothing at all,
|
|
224
|
+
* before `getElements()`'s own domain-specific extraction or any
|
|
225
|
+
* predicate ran? Default `false` — the kernel has no way to know, since
|
|
226
|
+
* `P` is opaque here. A dialect's concrete builder, which knows `P`'s real
|
|
227
|
+
* shape (e.g. `ArchProject`), overrides this to check its own project's
|
|
228
|
+
* file count directly — never `getElements().length`, which conflates "the
|
|
229
|
+
* source is empty" with "this domain legitimately has nothing in a
|
|
230
|
+
* healthy project" (e.g. zero JSX elements in a backend-only codebase).
|
|
213
231
|
*/
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
232
|
+
sourceEmpty() {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
/** Declared globs, position derived from `_phase`. Pure — no `P` needed. */
|
|
236
|
+
globs() {
|
|
237
|
+
return declaredGlobsOf(this._predicates, this._conditions);
|
|
238
|
+
}
|
|
239
|
+
/** This rule's own project, for `diagnose()`/`doctor` outside `.check()`. */
|
|
240
|
+
getProject() {
|
|
241
|
+
return this.project;
|
|
242
|
+
}
|
|
243
|
+
/** A `globs()` tree diagnosably dead, when zero examined — same shape as `sourceEmpty()`. */
|
|
244
|
+
deadGlobDiagnosis() {
|
|
245
|
+
return undefined;
|
|
221
246
|
}
|
|
222
247
|
// --- Protected: for subclasses ---
|
|
223
248
|
/**
|
|
224
249
|
* Register a predicate. Called by concrete builder methods like
|
|
225
|
-
* `.haveNameMatching()`, `.extend()`, etc.
|
|
250
|
+
* `.haveNameMatching()`, `.extend()`, etc. Returns a COPY — see `copy()`.
|
|
226
251
|
*/
|
|
227
252
|
addPredicate(predicate) {
|
|
228
|
-
this.
|
|
229
|
-
|
|
253
|
+
const next = this.copy();
|
|
254
|
+
recordPredicate(predicate, next._predicates, next._misplaced, next._phase);
|
|
255
|
+
return next;
|
|
230
256
|
}
|
|
231
257
|
/**
|
|
232
258
|
* Register a condition. Called by concrete builder methods like
|
|
233
|
-
* `.notContain()`, `.notExist()`, etc.
|
|
259
|
+
* `.notContain()`, `.notExist()`, etc. Returns a COPY — see `copy()`.
|
|
234
260
|
*/
|
|
235
261
|
addCondition(condition) {
|
|
236
|
-
this.
|
|
237
|
-
|
|
262
|
+
const next = this.copy();
|
|
263
|
+
next._conditions.push(condition);
|
|
264
|
+
return next;
|
|
238
265
|
}
|
|
239
266
|
/**
|
|
240
|
-
*
|
|
241
|
-
*
|
|
267
|
+
* An independent copy, carrying **both** predicates and conditions.
|
|
268
|
+
* Extends `TerminalBuilder.copy()` with the fields this class adds.
|
|
242
269
|
*
|
|
243
|
-
* Subclasses with additional
|
|
270
|
+
* Subclasses with additional mutable-reference fields of their own (arrays,
|
|
271
|
+
* sets, maps a chain method pushes onto) MUST override this and call
|
|
272
|
+
* `super.copy()` first, the same reason `TerminalBuilder.copy()`'s own
|
|
273
|
+
* docstring gives — `Object.assign` shallow-copies a field, it does not
|
|
274
|
+
* give it independent identity.
|
|
275
|
+
*/
|
|
276
|
+
copy() {
|
|
277
|
+
const clone = super.copy();
|
|
278
|
+
clone._predicates = [...this._predicates];
|
|
279
|
+
clone._conditions = [...this._conditions];
|
|
280
|
+
clone._misplaced = [...this._misplaced];
|
|
281
|
+
return clone;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* A fork of this builder, carrying BOTH lists. Used by `.should()` to support
|
|
285
|
+
* named selections without mutation.
|
|
286
|
+
*
|
|
287
|
+
* **Nothing here clears the conditions** (bug 0156). It used to, and a second
|
|
288
|
+
* `.should()` therefore silently discarded the first assertion — a rule that
|
|
289
|
+
* asserted something turned into one that asserted less, by a chain method.
|
|
290
|
+
* `.should().X().should().Y()` now accumulates exactly as `.andShould()` does.
|
|
291
|
+
*
|
|
292
|
+
* Ported from `packages/ts/src/core/rule-builder.ts`, where the engine copy
|
|
293
|
+
* landed the fix and left the kernel behind. Found by the architect review of
|
|
294
|
+
* PR #72: `eess-md`, `eess-mermaid` and `eess-gherkin` all extend THIS class,
|
|
295
|
+
* so they carried the defect — and `check:corpus`, `check:ledger` and
|
|
296
|
+
* `check:diagram` are md/mermaid gates, meaning this repo's own corpus
|
|
297
|
+
* enforcement ran on the broken copy.
|
|
244
298
|
*/
|
|
245
299
|
fork() {
|
|
246
|
-
|
|
247
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
248
|
-
const proto = Object.getPrototypeOf(this);
|
|
249
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
250
|
-
const fork = Object.create(proto);
|
|
251
|
-
Object.assign(fork, this);
|
|
252
|
-
fork._predicates = [...this._predicates];
|
|
253
|
-
fork._conditions = [];
|
|
254
|
-
fork._exclusions = [...this._exclusions];
|
|
255
|
-
fork._silentIndices = new Set(this._silentIndices);
|
|
256
|
-
fork._metadata = this._metadata ? { ...this._metadata } : undefined;
|
|
300
|
+
const fork = this.copy();
|
|
257
301
|
fork._reason = fork._metadata?.because ?? this._reason;
|
|
258
302
|
return fork;
|
|
259
303
|
}
|
|
@@ -262,38 +306,45 @@ export class RuleBuilder {
|
|
|
262
306
|
* Build the rule description from predicates and conditions.
|
|
263
307
|
*/
|
|
264
308
|
buildRuleDescription() {
|
|
265
|
-
|
|
266
|
-
const conditionDesc = this._conditions.map((c) => c.description).join(' and ');
|
|
267
|
-
const parts = [];
|
|
268
|
-
if (predicateDesc)
|
|
269
|
-
parts.push(`that ${predicateDesc}`);
|
|
270
|
-
if (conditionDesc)
|
|
271
|
-
parts.push(`should ${conditionDesc}`);
|
|
272
|
-
return parts.join(' ');
|
|
309
|
+
return ruleDescriptionOf(this._predicates, this._conditions);
|
|
273
310
|
}
|
|
274
311
|
/**
|
|
275
|
-
* Execute the full pipeline: filter elements with predicates,
|
|
276
|
-
*
|
|
312
|
+
* Execute the full pipeline: filter elements with predicates, evaluate
|
|
313
|
+
* conditions, return violations plus the ADR-010 evidence — the
|
|
314
|
+
* post-predicate subject count, whatever it is. `TerminalBuilder.check()` /
|
|
315
|
+
* `.warn()` / `.violations()` decide what a zero count means (a
|
|
316
|
+
* configuration finding, unless `.expectEmpty()` was declared); this method
|
|
317
|
+
* only reports the count, never interprets it.
|
|
318
|
+
*
|
|
319
|
+
* `sourceEmpty` (ADR-010 part 3) is deliberately not `allElements.length
|
|
320
|
+
* === 0` — a domain's own `getElements()` legitimately returning nothing in
|
|
321
|
+
* a healthy, fully-loaded project (e.g. zero JSX elements in a
|
|
322
|
+
* backend-only codebase) is not brokenness, and conflating the two broke
|
|
323
|
+
* `.notExist()`'s cardinality exemption for exactly that case. Subclasses
|
|
324
|
+
* that can answer "did my underlying source load anything at all" override
|
|
325
|
+
* `sourceEmpty()`; the default assumes it did.
|
|
277
326
|
*/
|
|
278
|
-
|
|
279
|
-
// Step 1: Get all elements from the concrete builder
|
|
327
|
+
collectViolations() {
|
|
280
328
|
const allElements = this.getElements();
|
|
281
|
-
|
|
282
|
-
const
|
|
283
|
-
// Step 3: If no elements match predicates, no violations
|
|
329
|
+
const filtered = matchingElements(allElements, this._predicates);
|
|
330
|
+
const examined = filtered.length;
|
|
284
331
|
if (filtered.length === 0) {
|
|
285
|
-
|
|
332
|
+
const sourceEmpty = this.sourceEmpty();
|
|
333
|
+
// Skip the diagnosis (a real filesystem walk, in a dialect's
|
|
334
|
+
// override) when the project itself is already known empty — nothing
|
|
335
|
+
// useful to say about one glob's fate against zero loaded files, and
|
|
336
|
+
// `sourceEmpty` outranks it in `evidencedViolations()` regardless.
|
|
337
|
+
const deadGlob = sourceEmpty ? undefined : this.deadGlobDiagnosis();
|
|
338
|
+
return collectResult([], { examined, sourceEmpty, deadGlob });
|
|
286
339
|
}
|
|
287
|
-
//
|
|
288
|
-
//
|
|
289
|
-
//
|
|
290
|
-
|
|
340
|
+
// Bug 0155 — gate-first, before the conditions run. See
|
|
341
|
+
// `assertionLessViolation` for why this is a finding and not a warning,
|
|
342
|
+
// and why there is no `_phase` term.
|
|
343
|
+
// `_expectEmpty === undefined`: a declared emptiness expectation is an
|
|
344
|
+
// assertion too — see `assertionLessViolation`.
|
|
345
|
+
if (!this.assertsSomething() && this._expectEmpty === undefined) {
|
|
291
346
|
const ruleId = this._metadata?.id ?? (this.buildRuleDescription() || 'unnamed');
|
|
292
|
-
|
|
293
|
-
`Did you use a predicate-only method after .should()? ` +
|
|
294
|
-
`Predicate-only methods (e.g. areExported, areAsync) filter elements; ` +
|
|
295
|
-
`use a condition method or .satisfy() after .should().`);
|
|
296
|
-
return [];
|
|
347
|
+
return collectResult([assertionLessViolation(ruleId, this.assertionAdvice())], { examined });
|
|
297
348
|
}
|
|
298
349
|
// Step 4: Build context for conditions
|
|
299
350
|
const context = this.buildConditionContext();
|
|
@@ -302,7 +353,7 @@ export class RuleBuilder {
|
|
|
302
353
|
for (const condition of this._conditions) {
|
|
303
354
|
violations.push(...condition.evaluate(filtered, context));
|
|
304
355
|
}
|
|
305
|
-
return violations;
|
|
356
|
+
return collectResult(violations, { examined });
|
|
306
357
|
}
|
|
307
358
|
/**
|
|
308
359
|
* Build the `ConditionContext` passed to each condition.
|
|
@@ -312,13 +363,11 @@ export class RuleBuilder {
|
|
|
312
363
|
* Call `super.buildConditionContext()` and spread the result.
|
|
313
364
|
*/
|
|
314
365
|
buildConditionContext() {
|
|
315
|
-
return {
|
|
366
|
+
return conditionContextFrom({
|
|
367
|
+
metadata: this._metadata,
|
|
368
|
+
reason: this._reason,
|
|
316
369
|
rule: this.buildRuleDescription(),
|
|
317
|
-
|
|
318
|
-
ruleId: this._metadata?.id,
|
|
319
|
-
suggestion: this._metadata?.suggestion,
|
|
320
|
-
docs: this._metadata?.docs,
|
|
321
|
-
};
|
|
370
|
+
});
|
|
322
371
|
}
|
|
323
372
|
}
|
|
324
373
|
//# sourceMappingURL=rule-builder.js.map
|
package/dist/rule-builder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-builder.js","sourceRoot":"","sources":["../src/rule-builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rule-builder.js","sourceRoot":"","sources":["../src/rule-builder.ts"],"names":[],"mappings":"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"}
|