@intentius/chant 0.18.26 → 0.18.27
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/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/handlers/components.d.ts +0 -16
- package/dist/cli/handlers/components.d.ts.map +1 -1
- package/dist/cli/handlers/graph.d.ts +3 -1
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +4 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/graph-dot.d.ts.map +1 -1
- package/dist/graph-ir.d.ts +5 -0
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/graph-mermaid.d.ts.map +1 -1
- package/dist/lexicon.d.ts +36 -0
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/status.d.ts +12 -0
- package/dist/lifecycle/status.d.ts.map +1 -1
- package/dist/lint/config.d.ts +12 -0
- package/dist/lint/config.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/cli/commands/lint.test.ts +89 -0
- package/src/cli/commands/lint.ts +58 -18
- package/src/cli/handlers/components.ts +65 -2
- package/src/cli/handlers/graph.test.ts +79 -0
- package/src/cli/handlers/graph.ts +65 -1
- package/src/components/cli-support.ts +12 -1
- package/src/graph-dot.ts +6 -5
- package/src/graph-ir.ts +5 -0
- package/src/graph-mermaid.ts +8 -6
- package/src/lexicon.ts +35 -0
- package/src/lifecycle/status.test.ts +32 -0
- package/src/lifecycle/status.ts +27 -0
- package/src/lint/config.test.ts +29 -1
- package/src/lint/config.ts +23 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/lint.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/lint.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAW,MAAM,iBAAiB,CAAC;AAkBzE;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAW5D;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAmBhC;AAgDD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,oBAAoB;IACpB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,qCAAqC;IACrC,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAyPD;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CA6I3E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAIxD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,GACtC,MAAM,IAAI,CAiCZ"}
|
|
@@ -17,22 +17,6 @@ import type { CommandContext } from "../registry.js";
|
|
|
17
17
|
* timestamp from the environment/CLI at record time."
|
|
18
18
|
*/
|
|
19
19
|
export declare function runComponentsReleaseRecord(ctx: CommandContext): Promise<number>;
|
|
20
|
-
/**
|
|
21
|
-
* chant components status [env] [--live] [--json] [--compare-to <env>]
|
|
22
|
-
*
|
|
23
|
-
* Answers "what's built" and "what's deployed where," joined by digest.
|
|
24
|
-
* Without `--live`, reports the release ledger alone (recorded vs unrecorded
|
|
25
|
-
* is meaningless without live evidence, so every recorded row reports
|
|
26
|
-
* `unknown` reconciliation — still useful as a pure ledger read). With
|
|
27
|
-
* `--live`, joins against `lifecycle diff --live` + ownership (reusing
|
|
28
|
-
* `buildChangeSet`, the same classification `lifecycle plan` already
|
|
29
|
-
* trusts) to flag unrecorded deploys and drift.
|
|
30
|
-
*
|
|
31
|
-
* Omitting `<env>` reports every environment that has release records.
|
|
32
|
-
* `--compare-to <env>` answers the single-query cross-environment question
|
|
33
|
-
* the epic names explicitly: "which build is in `<env>`, and is it the one
|
|
34
|
-
* tested in `<compare-to>`."
|
|
35
|
-
*/
|
|
36
20
|
export declare function runComponentsStatus(ctx: CommandContext): Promise<number>;
|
|
37
21
|
/** Fallback for `chant components` with no/unknown subcommand. */
|
|
38
22
|
export declare function runComponentsUnknown(ctx: CommandContext): Promise<number>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/components.ts"],"names":[],"mappings":"AA6CA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/components.ts"],"names":[],"mappings":"AA6CA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAuErF;AA2GD,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAqN9E;AAED,kEAAkE;AAClE,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAM/E"}
|
|
@@ -5,7 +5,9 @@ import type { CommandContext } from "../registry.js";
|
|
|
5
5
|
* cross-lexicon references; `--components` (#560) renders the same
|
|
6
6
|
* order/waves shape for discovered `Component` declarations, from their
|
|
7
7
|
* `dependsOn`; `--format ir|mermaid` emits the lint-gated entity-graph IR (or
|
|
8
|
-
* a Mermaid flowchart of it) for diagrams (#493/#496).
|
|
8
|
+
* a Mermaid flowchart of it) for diagrams (#493/#496). `--components` with a
|
|
9
|
+
* `--format` projects the component DAG itself into that format (nodes =
|
|
10
|
+
* components, wave groups, `dependsOn` edges) — the graph behold renders.
|
|
9
11
|
*/
|
|
10
12
|
export declare function runGraph(ctx: CommandContext): Promise<number>;
|
|
11
13
|
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/graph.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/graph.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD;;;;;;;;;GASG;AACH,wBAAsB,QAAQ,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBnE"}
|
|
@@ -66,6 +66,10 @@ export interface ComponentGraphResult {
|
|
|
66
66
|
from: string;
|
|
67
67
|
to: string;
|
|
68
68
|
}>;
|
|
69
|
+
/** Component name → its declaring `*.component.ts` file (relative to `path`),
|
|
70
|
+
* so a renderer can deep-link a component node to source (`chant graph
|
|
71
|
+
* --components --format ir` sets `sourceLoc` from this). */
|
|
72
|
+
files?: Record<string, string>;
|
|
69
73
|
error?: string;
|
|
70
74
|
}
|
|
71
75
|
/** Compute the components' dependency graph under `path`, for `chant graph --components`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-support.d.ts","sourceRoot":"","sources":["../../src/components/cli-support.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAQL,KAAK,eAAe,EAEpB,KAAK,eAAe,EACrB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAuC,KAAK,wBAAwB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cli-support.d.ts","sourceRoot":"","sources":["../../src/components/cli-support.ts"],"names":[],"mappings":"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"}
|
package/dist/graph-dot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-dot.d.ts","sourceRoot":"","sources":["../src/graph-dot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,YAAY,CAAC;AAE1D;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"graph-dot.d.ts","sourceRoot":"","sources":["../src/graph-dot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,YAAY,CAAC;AAE1D;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,CA4BzC"}
|
package/dist/graph-ir.d.ts
CHANGED
|
@@ -82,6 +82,11 @@ export interface IRGroups {
|
|
|
82
82
|
* so a boundary-box renderer recurses it. Populated by `chant graph --live`
|
|
83
83
|
* from the reference resolver's containment output; absent for source IR. */
|
|
84
84
|
byContainer?: Record<string, string[]>;
|
|
85
|
+
/** Component-graph deploy wave (`chant graph --components --format ir`):
|
|
86
|
+
* `wave-N → component node ids` that deploy in parallel in that wave. A
|
|
87
|
+
* wave-laned renderer reads this the way `byStack` drives boundary boxes.
|
|
88
|
+
* Present only for the component-DAG projection; absent for entity IR. */
|
|
89
|
+
byWave?: Record<string, string[]>;
|
|
85
90
|
}
|
|
86
91
|
/** A cross-stack export this stack publishes (a `stackOutput`/`output`): its
|
|
87
92
|
* name (the matching key another stack imports by) and the node that produces it. */
|
package/dist/graph-ir.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-ir.d.ts","sourceRoot":"","sources":["../src/graph-ir.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,UAAU,EAAgB,MAAM,cAAc,CAAC;AAI7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElD;;;;;;;;GAQG;AAEH,iFAAiF;AACjF,MAAM,WAAW,SAAS;IACxB,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,iCAAiC;AACjC,MAAM,WAAW,MAAM;IACrB,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,mCAAmC;IACnC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACjC;AAED,qEAAqE;AACrE,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,yCAAyC;IACzC,IAAI,EAAE,KAAK,CAAC;IACZ,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qFAAqF;AACrF,MAAM,WAAW,QAAQ;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC;;iFAE6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACnC;;;;iFAI6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"graph-ir.d.ts","sourceRoot":"","sources":["../src/graph-ir.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-mermaid.d.ts","sourceRoot":"","sources":["../src/graph-mermaid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,YAAY,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"graph-mermaid.d.ts","sourceRoot":"","sources":["../src/graph-mermaid.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,YAAY,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,CAkC7C"}
|
package/dist/lexicon.d.ts
CHANGED
|
@@ -211,6 +211,24 @@ export interface ComponentPipelineResult {
|
|
|
211
211
|
/** Every generated job, in emit order. */
|
|
212
212
|
jobs: ComponentPipelineJob[];
|
|
213
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Live status of a single deploy unit (a CloudFormation stack, a K8s release, …)
|
|
216
|
+
* addressed by its deployed name — the per-component presence signal
|
|
217
|
+
* `chant components status --live` needs (#57). A component's deploy step carries
|
|
218
|
+
* the exact unit name it targets (e.g. a `cfn-deploy` step's `stack`), which is
|
|
219
|
+
* the identity in a multi-stack component project where `describeResources`
|
|
220
|
+
* (entity-keyed, single-stack-per-env) can't see the component's own stack.
|
|
221
|
+
*/
|
|
222
|
+
export interface StackStatusObservation {
|
|
223
|
+
/** The deploy-unit name queried (the stack name). */
|
|
224
|
+
stack: string;
|
|
225
|
+
/** False when the unit does not exist yet — the pre-first-apply state. */
|
|
226
|
+
present: boolean;
|
|
227
|
+
/** Provider-native status string, e.g. CloudFormation "CREATE_COMPLETE". */
|
|
228
|
+
status?: string;
|
|
229
|
+
/** True when `status` is a terminal *success* state (deployed and healthy). */
|
|
230
|
+
healthy?: boolean;
|
|
231
|
+
}
|
|
214
232
|
export interface LexiconPlugin {
|
|
215
233
|
/** Human-readable name (e.g. "aws", "gcp") */
|
|
216
234
|
readonly name: string;
|
|
@@ -344,6 +362,24 @@ export interface LexiconPlugin {
|
|
|
344
362
|
*/
|
|
345
363
|
owned?: boolean;
|
|
346
364
|
}): Promise<Record<string, ResourceMetadata>>;
|
|
365
|
+
/**
|
|
366
|
+
* Report the live status of one deploy unit by its deployed name. Opt-in.
|
|
367
|
+
*
|
|
368
|
+
* Complements {@link describeResources}: that observes a stack's *entities*
|
|
369
|
+
* keyed by chant entity name (and assumes one stack per environment), which
|
|
370
|
+
* can't see a multi-stack component project where each component owns its own
|
|
371
|
+
* stack. `chant components status --live` resolves a component's deploy-step
|
|
372
|
+
* target (e.g. a `cfn-deploy` step's `stack`) and calls this to learn whether
|
|
373
|
+
* that unit is present and healthy — a component-level presence signal.
|
|
374
|
+
*
|
|
375
|
+
* Returns `null` when the lexicon cannot determine status (e.g. the provider
|
|
376
|
+
* CLI failed for a reason other than "does not exist"); a genuinely absent
|
|
377
|
+
* unit returns `{ present: false }`.
|
|
378
|
+
*/
|
|
379
|
+
describeStackStatus?(options: {
|
|
380
|
+
environment: string;
|
|
381
|
+
stack: string;
|
|
382
|
+
}): Promise<StackStatusObservation | null>;
|
|
347
383
|
/**
|
|
348
384
|
* Reference catalog for live edge reconstruction (#778). Declares how this
|
|
349
385
|
* lexicon's observed resources reference each other — an identity map (which
|
package/dist/lexicon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lexicon.d.ts","sourceRoot":"","sources":["../src/lexicon.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"lexicon.d.ts","sourceRoot":"","sources":["../src/lexicon.ts"],"names":[],"mappings":"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"}
|
|
@@ -81,6 +81,18 @@ export interface LiveComponentEvidence {
|
|
|
81
81
|
/** Ownership verdict, when known. */
|
|
82
82
|
ownership?: "owned" | "foreign" | "unknown";
|
|
83
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Overlay per-component stack-presence evidence onto change-set evidence.
|
|
86
|
+
*
|
|
87
|
+
* The change-set axis (`liveEvidenceFromChangeSet`) is entity-keyed and, for
|
|
88
|
+
* AWS, single-stack-per-env — it can't see a multi-stack component project where
|
|
89
|
+
* each component owns its own stack (#57). `supplement` carries the direct
|
|
90
|
+
* per-component stack observation (from a lexicon's `describeStackStatus`), which
|
|
91
|
+
* is authoritative for **presence** (`live`) and **ownership**; the change-set's
|
|
92
|
+
* `action` is kept, since drift is still assessed from the diff. A component in
|
|
93
|
+
* only one map passes through unchanged.
|
|
94
|
+
*/
|
|
95
|
+
export declare function mergeLiveEvidence(base: Map<string, LiveComponentEvidence> | undefined, supplement: Map<string, LiveComponentEvidence>): Map<string, LiveComponentEvidence>;
|
|
84
96
|
/**
|
|
85
97
|
* Component -> live entity/resource name(s) it owns (#598). Mirrors
|
|
86
98
|
* `Component.liveNames` (../components/component.ts) without importing it —
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lifecycle/status.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lifecycle/status.ts"],"names":[],"mappings":"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"}
|
package/dist/lint/config.d.ts
CHANGED
|
@@ -75,6 +75,18 @@ export declare function parseRuleConfig(value: RuleConfig): ParsedRuleConfig;
|
|
|
75
75
|
* Default configuration with all rules enabled at strict preset severities
|
|
76
76
|
*/
|
|
77
77
|
export declare const DEFAULT_CONFIG: LintConfig;
|
|
78
|
+
/**
|
|
79
|
+
* Walk up from `startDir` to the nearest ancestor holding a chant project
|
|
80
|
+
* config (`chant.config.ts` or `chant.config.json`). Returns that directory, or
|
|
81
|
+
* `startDir` unchanged when none is found before the filesystem root.
|
|
82
|
+
*
|
|
83
|
+
* Linting a subpath (`chant graph src --format ir`, `chant lint src/lib`) must
|
|
84
|
+
* still see the project-root config: its `lint.overrides` globs are written
|
|
85
|
+
* project-root-relative (`src/lib/**`), and a rule set scoped only to the lint
|
|
86
|
+
* arg would silently drop them. Config discovery therefore anchors on the
|
|
87
|
+
* project root, not the path being linted.
|
|
88
|
+
*/
|
|
89
|
+
export declare function findProjectRoot(startDir: string): string;
|
|
78
90
|
/**
|
|
79
91
|
* Load lint configuration from a directory.
|
|
80
92
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lint/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAmBnD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAS3B,CAAC;AAkGH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,gDAAgD;IAChD,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC;IAC3B,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,gBAAgB,CAsBnE;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,UAG5B,CAAC;AA0HF;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAoClD;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAkBpG"}
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lint/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAmBnD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAS3B,CAAC;AAkGH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,gDAAgD;IAChD,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC;IAC3B,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,gBAAgB,CAsBnE;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,UAG5B,CAAC;AA0HF;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUxD;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAoClD;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAkBpG"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant",
|
|
3
|
-
"version": "0.18.
|
|
4
|
-
"description": "Declarative infrastructure-as-code toolkit
|
|
3
|
+
"version": "0.18.27",
|
|
4
|
+
"description": "Declarative infrastructure-as-code toolkit \u2014 TypeScript on Node.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://intentius.io/chant",
|
|
7
7
|
"repository": {
|
|
@@ -3,6 +3,7 @@ import { lintCommand, isLintRule, loadPluginRules, type LintOptions } from "./li
|
|
|
3
3
|
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
|
+
import { execFileSync } from "node:child_process";
|
|
6
7
|
|
|
7
8
|
describe("lintCommand", () => {
|
|
8
9
|
let testDir: string;
|
|
@@ -330,3 +331,91 @@ describe("plugin integration", () => {
|
|
|
330
331
|
expect(pluginDiags.length).toBe(1);
|
|
331
332
|
});
|
|
332
333
|
});
|
|
334
|
+
|
|
335
|
+
describe("lintCommand — project-root config resolution (scoped lint)", () => {
|
|
336
|
+
let testDir: string;
|
|
337
|
+
|
|
338
|
+
beforeEach(async () => {
|
|
339
|
+
testDir = join(tmpdir(), `chant-lint-scope-${Date.now()}-${Math.random()}`);
|
|
340
|
+
await mkdir(join(testDir, "src", "lib"), { recursive: true });
|
|
341
|
+
process.env.NO_COLOR = "1";
|
|
342
|
+
// Root config disables EVL003 for src/lib/** — a project-root-relative glob.
|
|
343
|
+
await writeFile(
|
|
344
|
+
join(testDir, "chant.config.json"),
|
|
345
|
+
JSON.stringify({ overrides: [{ files: ["src/lib/**"], rules: { EVL003: "off" } }] }),
|
|
346
|
+
);
|
|
347
|
+
// A runtime helper with dynamic property access — EVL003 fires unless overridden.
|
|
348
|
+
await writeFile(
|
|
349
|
+
join(testDir, "src", "lib", "naming.ts"),
|
|
350
|
+
`const table = { a: 1 };\nexport function pick(k: string) { return table[k]; }\n`,
|
|
351
|
+
);
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
afterEach(async () => {
|
|
355
|
+
await rm(testDir, { recursive: true, force: true });
|
|
356
|
+
delete process.env.NO_COLOR;
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
test("linting the project root applies the src/lib/** override", async () => {
|
|
360
|
+
const result = await lintCommand({ path: testDir, format: "stylish" });
|
|
361
|
+
expect(result.diagnostics.filter((d) => d.ruleId === "EVL003")).toHaveLength(0);
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
test("linting a subpath still finds the root config and applies the override", async () => {
|
|
365
|
+
// Regression: overrides are project-root-relative, so a scoped lint must
|
|
366
|
+
// anchor config discovery + glob matching on the root, not the path arg.
|
|
367
|
+
const result = await lintCommand({ path: join(testDir, "src"), format: "stylish" });
|
|
368
|
+
expect(result.diagnostics.filter((d) => d.ruleId === "EVL003")).toHaveLength(0);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
test("a file outside the override glob still reports EVL003 under a scoped lint", async () => {
|
|
372
|
+
await mkdir(join(testDir, "src", "runtime"), { recursive: true });
|
|
373
|
+
await writeFile(
|
|
374
|
+
join(testDir, "src", "runtime", "other.ts"),
|
|
375
|
+
`const t = { a: 1 };\nexport function g(k: string) { return t[k]; }\n`,
|
|
376
|
+
);
|
|
377
|
+
const result = await lintCommand({ path: join(testDir, "src"), format: "stylish" });
|
|
378
|
+
const evl003 = result.diagnostics.filter((d) => d.ruleId === "EVL003");
|
|
379
|
+
expect(evl003).toHaveLength(1);
|
|
380
|
+
expect(evl003[0].file).toContain(join("src", "runtime", "other.ts"));
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
describe("lintCommand — git-ignored files are not linted", () => {
|
|
385
|
+
let testDir: string;
|
|
386
|
+
|
|
387
|
+
beforeEach(async () => {
|
|
388
|
+
testDir = join(tmpdir(), `chant-lint-gitignore-${Date.now()}-${Math.random()}`);
|
|
389
|
+
await mkdir(join(testDir, "vendor"), { recursive: true });
|
|
390
|
+
process.env.NO_COLOR = "1";
|
|
391
|
+
execFileSync("git", ["init", "-q"], { cwd: testDir });
|
|
392
|
+
await writeFile(join(testDir, ".gitignore"), "vendor/\n");
|
|
393
|
+
// Vendored code full of a pattern EVL003 forbids — but it's not our source.
|
|
394
|
+
await writeFile(
|
|
395
|
+
join(testDir, "vendor", "app.ts"),
|
|
396
|
+
`const t = { a: 1 };\nexport function g(k: string) { return t[k]; }\n`,
|
|
397
|
+
);
|
|
398
|
+
// A clean authored file at the root.
|
|
399
|
+
await writeFile(join(testDir, "index.ts"), `export const x = 1;\n`);
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
afterEach(async () => {
|
|
403
|
+
await rm(testDir, { recursive: true, force: true });
|
|
404
|
+
delete process.env.NO_COLOR;
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
test("skips gitignored vendor/ so its EVL violations don't gate the project", async () => {
|
|
408
|
+
const result = await lintCommand({ path: testDir, format: "stylish" });
|
|
409
|
+
expect(result.diagnostics.filter((d) => d.file.includes("vendor"))).toHaveLength(0);
|
|
410
|
+
expect(result.success).toBe(true);
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
test("still lints a non-ignored file with the same violation", async () => {
|
|
414
|
+
await writeFile(
|
|
415
|
+
join(testDir, "authored.ts"),
|
|
416
|
+
`const t = { a: 1 };\nexport function g(k: string) { return t[k]; }\n`,
|
|
417
|
+
);
|
|
418
|
+
const result = await lintCommand({ path: testDir, format: "stylish" });
|
|
419
|
+
expect(result.diagnostics.some((d) => d.file.includes("authored.ts") && d.ruleId === "EVL003")).toBe(true);
|
|
420
|
+
});
|
|
421
|
+
});
|
package/src/cli/commands/lint.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { resolve, join } from "path";
|
|
1
|
+
import { resolve, join, relative } from "path";
|
|
2
2
|
import { readFileSync, writeFileSync, readdirSync, statSync } from "fs";
|
|
3
|
+
import { execFileSync } from "child_process";
|
|
3
4
|
import { runLint, parseDisableComments } from "../../lint/engine";
|
|
4
5
|
import type { LintRule, LintDiagnostic, LintFix } from "../../lint/rule";
|
|
5
6
|
import { loadPlugins, resolveProjectLexicons } from "../plugins";
|
|
@@ -16,7 +17,7 @@ import { formatError, formatInfo } from "../format";
|
|
|
16
17
|
import { GENERATED_MARKER } from "../../discovery/files";
|
|
17
18
|
|
|
18
19
|
// Import config loader
|
|
19
|
-
import { loadConfig, resolveRulesForFile, parseRuleConfig } from "../../lint/config";
|
|
20
|
+
import { loadConfig, resolveRulesForFile, parseRuleConfig, findProjectRoot } from "../../lint/config";
|
|
20
21
|
import type { RuleConfig } from "../../lint/rule";
|
|
21
22
|
|
|
22
23
|
/**
|
|
@@ -140,7 +141,36 @@ export interface LintResult {
|
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
/**
|
|
143
|
-
*
|
|
144
|
+
* Drop paths git ignores. Vendored trees (`vendor/`), build output (`dist/`),
|
|
145
|
+
* and anything else in `.gitignore` are not authored chant source — linting
|
|
146
|
+
* them surfaces EVL/COR errors in code the project never wrote, which then
|
|
147
|
+
* gates `chant graph --format ir` on files outside the graph. Delegates to
|
|
148
|
+
* `git check-ignore` for exact gitignore semantics (nesting, negation) in one
|
|
149
|
+
* batched call; a non-git tree (or absent git) filters nothing.
|
|
150
|
+
*/
|
|
151
|
+
function filterGitIgnored(files: string[], cwd: string): string[] {
|
|
152
|
+
if (files.length === 0) return files;
|
|
153
|
+
try {
|
|
154
|
+
const out = execFileSync("git", ["check-ignore", "--stdin"], {
|
|
155
|
+
cwd,
|
|
156
|
+
input: files.join("\n"),
|
|
157
|
+
encoding: "utf-8",
|
|
158
|
+
// stdin piped (input), stdout captured, stderr silenced so a non-git tree's
|
|
159
|
+
// "fatal: not a git repository" never leaks to the lint output.
|
|
160
|
+
stdio: ["pipe", "pipe", "ignore"],
|
|
161
|
+
// Exit 1 means "nothing ignored" — execFileSync throws on non-zero, so the
|
|
162
|
+
// catch handles it; exit 128 (not a repo) lands there too and filters none.
|
|
163
|
+
});
|
|
164
|
+
const ignored = new Set(out.split(/\r?\n/).filter(Boolean));
|
|
165
|
+
return ignored.size === 0 ? files : files.filter((f) => !ignored.has(f));
|
|
166
|
+
} catch {
|
|
167
|
+
// No git, not a repo, or nothing ignored (exit 1) — keep every file.
|
|
168
|
+
return files;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get all TypeScript files recursively, skipping git-ignored paths.
|
|
144
174
|
*/
|
|
145
175
|
function getTypeScriptFiles(dir: string): string[] {
|
|
146
176
|
const files: string[] = [];
|
|
@@ -168,18 +198,22 @@ function getTypeScriptFiles(dir: string): string[] {
|
|
|
168
198
|
}
|
|
169
199
|
|
|
170
200
|
scan(dir);
|
|
171
|
-
return files;
|
|
201
|
+
return filterGitIgnored(files, dir);
|
|
172
202
|
}
|
|
173
203
|
|
|
174
204
|
/**
|
|
175
|
-
* Get default rules and options, optionally applying per-file overrides
|
|
205
|
+
* Get default rules and options, optionally applying per-file overrides.
|
|
206
|
+
*
|
|
207
|
+
* `projectRoot` is where the config lives (see `findProjectRoot`); `filePath`,
|
|
208
|
+
* when given, must be relative to that root so `lint.overrides` globs
|
|
209
|
+
* (`src/lib/**`) match regardless of which subpath is being linted.
|
|
176
210
|
*/
|
|
177
211
|
function getDefaultRules(
|
|
178
|
-
|
|
212
|
+
projectRoot: string,
|
|
179
213
|
filePath?: string,
|
|
180
214
|
allRules: Map<string, LintRule> = new Map(),
|
|
181
215
|
): { rules: LintRule[]; ruleOptions: Map<string, Record<string, unknown>> } {
|
|
182
|
-
const config = loadConfig(
|
|
216
|
+
const config = loadConfig(projectRoot);
|
|
183
217
|
const effectiveRules = filePath ? resolveRulesForFile(config, filePath) : config.rules;
|
|
184
218
|
const rules: LintRule[] = [];
|
|
185
219
|
const ruleOptions = new Map<string, Record<string, unknown>>();
|
|
@@ -263,7 +297,9 @@ async function resolveRegistryContext(
|
|
|
263
297
|
async function runComponentCheckDiagnostics(
|
|
264
298
|
infraPath: string,
|
|
265
299
|
): Promise<{ diagnostics: LintDiagnostic[]; suppressed: Array<LintDiagnostic & { reason?: string }> }> {
|
|
266
|
-
|
|
300
|
+
// Discovery stays scoped to the lint arg; COMP* severity overrides come from
|
|
301
|
+
// the project-root config, same as the AST-rule pass.
|
|
302
|
+
const config = loadConfig(findProjectRoot(infraPath));
|
|
267
303
|
const checks = loadComponentChecks();
|
|
268
304
|
const allCheckIds = new Set(checks.map((c) => c.id));
|
|
269
305
|
|
|
@@ -356,19 +392,23 @@ function applyFixes(filePath: string, fixes: LintFix[]): void {
|
|
|
356
392
|
*/
|
|
357
393
|
export async function lintCommand(options: LintOptions): Promise<LintResult> {
|
|
358
394
|
const infraPath = resolve(options.path);
|
|
359
|
-
|
|
395
|
+
// Config, rules, and lexicons anchor on the project root so a scoped lint
|
|
396
|
+
// (`chant lint src`, the `graph --format ir` gate) still sees `lint.overrides`
|
|
397
|
+
// and the declared lexicons; only the file scan stays scoped to `infraPath`.
|
|
398
|
+
const projectRoot = findProjectRoot(infraPath);
|
|
399
|
+
const config = loadConfig(projectRoot);
|
|
360
400
|
const hasOverrides = config.overrides && config.overrides.length > 0;
|
|
361
401
|
|
|
362
402
|
// Load all rules from lexicon plugins (core "chant" + lexicon-specific)
|
|
363
|
-
let allRules = await loadAllPluginRules(
|
|
403
|
+
let allRules = await loadAllPluginRules(projectRoot);
|
|
364
404
|
|
|
365
405
|
// Merge in any config-level plugin rules (custom .ts rule files)
|
|
366
406
|
if (config.plugins && config.plugins.length > 0) {
|
|
367
|
-
const pluginRules = await loadPluginRules(config.plugins,
|
|
407
|
+
const pluginRules = await loadPluginRules(config.plugins, projectRoot);
|
|
368
408
|
allRules = new Map([...allRules, ...pluginRules]);
|
|
369
409
|
}
|
|
370
410
|
|
|
371
|
-
// Get all TypeScript files
|
|
411
|
+
// Get all TypeScript files (scan scoped to the lint arg, git-ignored trees dropped)
|
|
372
412
|
const files = getTypeScriptFiles(infraPath);
|
|
373
413
|
|
|
374
414
|
// Run lint — use per-file rules when overrides are present
|
|
@@ -381,14 +421,14 @@ export async function lintCommand(options: LintOptions): Promise<LintResult> {
|
|
|
381
421
|
} else if (hasOverrides) {
|
|
382
422
|
diagnostics = [];
|
|
383
423
|
for (const file of files) {
|
|
384
|
-
const relativePath =
|
|
385
|
-
const { rules: fileRules, ruleOptions } = getDefaultRules(
|
|
424
|
+
const relativePath = relative(projectRoot, file);
|
|
425
|
+
const { rules: fileRules, ruleOptions } = getDefaultRules(projectRoot, relativePath, allRules);
|
|
386
426
|
const result = await runLint([file], fileRules, ruleOptions);
|
|
387
427
|
diagnostics.push(...result.diagnostics);
|
|
388
428
|
suppressed.push(...result.suppressed);
|
|
389
429
|
}
|
|
390
430
|
} else {
|
|
391
|
-
const { rules, ruleOptions } = getDefaultRules(
|
|
431
|
+
const { rules, ruleOptions } = getDefaultRules(projectRoot, undefined, allRules);
|
|
392
432
|
const result = await runLint(files, rules, ruleOptions);
|
|
393
433
|
diagnostics = result.diagnostics;
|
|
394
434
|
suppressed = result.suppressed;
|
|
@@ -430,14 +470,14 @@ export async function lintCommand(options: LintOptions): Promise<LintResult> {
|
|
|
430
470
|
diagnostics = [];
|
|
431
471
|
suppressed = [];
|
|
432
472
|
for (const file of files) {
|
|
433
|
-
const relativePath =
|
|
434
|
-
const { rules: fileRules, ruleOptions } = getDefaultRules(
|
|
473
|
+
const relativePath = relative(projectRoot, file);
|
|
474
|
+
const { rules: fileRules, ruleOptions } = getDefaultRules(projectRoot, relativePath, allRules);
|
|
435
475
|
const postResult = await runLint([file], fileRules, ruleOptions);
|
|
436
476
|
diagnostics.push(...postResult.diagnostics);
|
|
437
477
|
suppressed.push(...postResult.suppressed);
|
|
438
478
|
}
|
|
439
479
|
} else {
|
|
440
|
-
const { rules, ruleOptions } = getDefaultRules(
|
|
480
|
+
const { rules, ruleOptions } = getDefaultRules(projectRoot, undefined, allRules);
|
|
441
481
|
const postResult = await runLint(files, rules, ruleOptions);
|
|
442
482
|
diagnostics = postResult.diagnostics;
|
|
443
483
|
suppressed = postResult.suppressed;
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
listReleaseEnvironments,
|
|
35
35
|
InvalidReleaseRecordError,
|
|
36
36
|
} from "../../lifecycle/release-ledger";
|
|
37
|
-
import { reconcileStatus, liveEvidenceFromChangeSet, compareAcrossEnvironments } from "../../lifecycle/status";
|
|
37
|
+
import { reconcileStatus, liveEvidenceFromChangeSet, compareAcrossEnvironments, mergeLiveEvidence, type LiveComponentEvidence } from "../../lifecycle/status";
|
|
38
38
|
import { buildChangeSet } from "../../lifecycle/change-set";
|
|
39
39
|
import { buildLedgerEntries, componentBomSummary, type BuildLedgerEntry } from "../../lifecycle/build-ledger";
|
|
40
40
|
import { findBuildManifestByArtifactDigest } from "../../lifecycle/build-ledger-store";
|
|
@@ -44,7 +44,8 @@ import { build } from "../../build";
|
|
|
44
44
|
import { discoverComponents } from "../../components/discover";
|
|
45
45
|
import { formatError, formatWarning, formatSuccess, formatBold } from "../format";
|
|
46
46
|
import type { CommandContext } from "../registry";
|
|
47
|
-
import type { ResourceMetadata } from "../../lexicon";
|
|
47
|
+
import type { ResourceMetadata, LexiconPlugin } from "../../lexicon";
|
|
48
|
+
import type { Phase, Component } from "../../components/component";
|
|
48
49
|
|
|
49
50
|
/**
|
|
50
51
|
* chant components release <env> --component <name> --digest <sha256:...>
|
|
@@ -189,6 +190,58 @@ interface StatusJsonRow {
|
|
|
189
190
|
* the epic names explicitly: "which build is in `<env>`, and is it the one
|
|
190
191
|
* tested in `<compare-to>`."
|
|
191
192
|
*/
|
|
193
|
+
/** Every distinct `cfn-deploy` stack name a component's deploy phases target. A
|
|
194
|
+
* step may itself be a nested `Phase`, so walk recursively; a resolved component
|
|
195
|
+
* carries the stack as a concrete string. */
|
|
196
|
+
function cfnDeployStacks(deploy: Phase[]): string[] {
|
|
197
|
+
const stacks = new Set<string>();
|
|
198
|
+
const walkSteps = (steps: Phase["steps"]): void => {
|
|
199
|
+
for (const step of steps) {
|
|
200
|
+
// A step may itself be a nested Phase (it carries its own `steps`). Step is
|
|
201
|
+
// open-typed (capability inputs), so discriminate structurally on `steps`.
|
|
202
|
+
const nested = (step as { steps?: unknown }).steps;
|
|
203
|
+
if (Array.isArray(nested)) {
|
|
204
|
+
walkSteps(nested as Phase["steps"]);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const s = step as { kind?: string; stack?: unknown };
|
|
208
|
+
if (s.kind === "cfn-deploy" && typeof s.stack === "string") stacks.add(s.stack);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
for (const phase of deploy) walkSteps(phase.steps);
|
|
212
|
+
return [...stacks];
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Per-component stack presence for `--live`: resolve each component's own
|
|
217
|
+
* `cfn-deploy` stack(s) and observe them directly via a lexicon's
|
|
218
|
+
* `describeStackStatus`. This is the multi-stack component signal that
|
|
219
|
+
* `describeResources` (entity-keyed, single-stack-per-env) misses (#57): a
|
|
220
|
+
* component whose stack is present reconciles as live/owned, joined to the DAG
|
|
221
|
+
* by component name. Components with no `cfn-deploy` stack — or where the
|
|
222
|
+
* observer can't determine any of theirs — are omitted, so the change-set
|
|
223
|
+
* evidence still governs them.
|
|
224
|
+
*/
|
|
225
|
+
async function observeComponentStacks(
|
|
226
|
+
components: Map<string, { component: Component }>,
|
|
227
|
+
observer: LexiconPlugin,
|
|
228
|
+
environment: string,
|
|
229
|
+
): Promise<Map<string, LiveComponentEvidence>> {
|
|
230
|
+
const evidence = new Map<string, LiveComponentEvidence>();
|
|
231
|
+
for (const [name, { component }] of components) {
|
|
232
|
+
const stacks = cfnDeployStacks(component.deploy);
|
|
233
|
+
if (stacks.length === 0) continue;
|
|
234
|
+
const observed = await Promise.all(
|
|
235
|
+
stacks.map((stack) => observer.describeStackStatus!({ environment, stack }).catch(() => null)),
|
|
236
|
+
);
|
|
237
|
+
const determinate = observed.filter((o): o is NonNullable<typeof o> => o !== null);
|
|
238
|
+
if (determinate.length === 0) continue;
|
|
239
|
+
const present = determinate.every((o) => o.present);
|
|
240
|
+
evidence.set(name, { live: present, ownership: present ? "owned" : undefined });
|
|
241
|
+
}
|
|
242
|
+
return evidence;
|
|
243
|
+
}
|
|
244
|
+
|
|
192
245
|
export async function runComponentsStatus(ctx: CommandContext): Promise<number> {
|
|
193
246
|
const { args, plugins, serializers } = ctx;
|
|
194
247
|
const requestedEnv = args.extraPositional;
|
|
@@ -261,6 +314,16 @@ export async function runComponentsStatus(ctx: CommandContext): Promise<number>
|
|
|
261
314
|
merged.entries.push(...cs.entries);
|
|
262
315
|
}
|
|
263
316
|
liveEvidence = liveEvidenceFromChangeSet(merged, liveNameMapping);
|
|
317
|
+
|
|
318
|
+
// Multi-stack component projects (each component owns its own stack) are
|
|
319
|
+
// invisible to the entity-keyed, single-stack `describeResources` above —
|
|
320
|
+
// observe each component's own cfn-deploy stack directly and overlay it as
|
|
321
|
+
// the authoritative presence signal (#57).
|
|
322
|
+
const stackObserver = plugins.find((p) => p.describeStackStatus);
|
|
323
|
+
if (stackObserver) {
|
|
324
|
+
const stackEvidence = await observeComponentStacks(discovery.components, stackObserver, environment);
|
|
325
|
+
liveEvidence = mergeLiveEvidence(liveEvidence, stackEvidence);
|
|
326
|
+
}
|
|
264
327
|
}
|
|
265
328
|
|
|
266
329
|
// #609: resolve the persisted build manifest behind each recorded digest
|
|
@@ -18,6 +18,11 @@ vi.mock("../commands/lint", () => ({
|
|
|
18
18
|
lintCommand: () => lintMock(),
|
|
19
19
|
}));
|
|
20
20
|
|
|
21
|
+
const componentGraphMock = vi.fn();
|
|
22
|
+
vi.mock("../../components/cli-support", () => ({
|
|
23
|
+
computeComponentGraph: () => componentGraphMock(),
|
|
24
|
+
}));
|
|
25
|
+
|
|
21
26
|
// Avoid running a real layout engine in tests; the format dispatch + size/engine
|
|
22
27
|
// plumbing is what matters here (engines have their own unit tests).
|
|
23
28
|
const layoutMock = vi.fn();
|
|
@@ -87,6 +92,7 @@ describe("runGraph", () => {
|
|
|
87
92
|
discoverMock.mockReset();
|
|
88
93
|
lintMock.mockReset();
|
|
89
94
|
layoutMock.mockReset();
|
|
95
|
+
componentGraphMock.mockReset();
|
|
90
96
|
});
|
|
91
97
|
|
|
92
98
|
describe("Op graph (default)", () => {
|
|
@@ -227,6 +233,79 @@ describe("runGraph", () => {
|
|
|
227
233
|
});
|
|
228
234
|
});
|
|
229
235
|
|
|
236
|
+
describe("component DAG view (--components --format ir|layout)", () => {
|
|
237
|
+
// shared-foundation (wave 1) <- loom-db (wave 2) <- loom-backend (wave 3).
|
|
238
|
+
const componentGraphClean = (): void => {
|
|
239
|
+
componentGraphMock.mockResolvedValue({
|
|
240
|
+
success: true,
|
|
241
|
+
order: ["shared-foundation", "loom-db", "loom-backend"],
|
|
242
|
+
waves: [["shared-foundation"], ["loom-db"], ["loom-backend"]],
|
|
243
|
+
edges: [
|
|
244
|
+
{ from: "loom-db", to: "shared-foundation" },
|
|
245
|
+
{ from: "loom-backend", to: "loom-db" },
|
|
246
|
+
],
|
|
247
|
+
files: {
|
|
248
|
+
"shared-foundation": "components/shared-foundation.component.ts",
|
|
249
|
+
"loom-db": "components/loom-db.component.ts",
|
|
250
|
+
"loom-backend": "components/loom-backend.component.ts",
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
test("--components --format ir emits component nodes, byWave groups, and dependsOn edges", async () => {
|
|
256
|
+
lintMock.mockResolvedValue({ success: true });
|
|
257
|
+
componentGraphClean();
|
|
258
|
+
const exit = await runGraph({ args: makeArgs({ format: "ir", components: true }), plugins: [], serializers: [] });
|
|
259
|
+
expect(exit).toBe(0);
|
|
260
|
+
const ir = JSON.parse(stdoutBuf.join("\n"));
|
|
261
|
+
// One node per component (not per resource); wave carried on the node.
|
|
262
|
+
expect(ir.nodes.map((n: { id: string }) => n.id)).toEqual(["shared-foundation", "loom-db", "loom-backend"]);
|
|
263
|
+
expect(ir.nodes.every((n: { kind: string; lexicon: string }) => n.kind === "Component" && n.lexicon === "chant")).toBe(true);
|
|
264
|
+
expect(ir.nodes.find((n: { id: string }) => n.id === "loom-backend").attrs.wave).toBe(3);
|
|
265
|
+
// Each component node deep-links to its source file.
|
|
266
|
+
expect(ir.nodes.find((n: { id: string }) => n.id === "loom-db").sourceLoc).toEqual({
|
|
267
|
+
file: "components/loom-db.component.ts",
|
|
268
|
+
});
|
|
269
|
+
// dependsOn edges, consumer → producer.
|
|
270
|
+
expect(ir.edges).toContainEqual({ from: "loom-db", to: "shared-foundation", kind: "ref" });
|
|
271
|
+
// Waves as groups.
|
|
272
|
+
expect(ir.groups.byWave).toEqual({
|
|
273
|
+
"wave-1": ["shared-foundation"],
|
|
274
|
+
"wave-2": ["loom-db"],
|
|
275
|
+
"wave-3": ["loom-backend"],
|
|
276
|
+
});
|
|
277
|
+
// The entity-graph discovery path is not taken for the component projection.
|
|
278
|
+
expect(discoverMock).not.toHaveBeenCalled();
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
test("--components --format mermaid lanes the components by wave", async () => {
|
|
282
|
+
lintMock.mockResolvedValue({ success: true });
|
|
283
|
+
componentGraphClean();
|
|
284
|
+
const exit = await runGraph({ args: makeArgs({ format: "mermaid", components: true }), plugins: [], serializers: [] });
|
|
285
|
+
expect(exit).toBe(0);
|
|
286
|
+
const out = stdoutBuf.join("\n");
|
|
287
|
+
expect(out).toContain("flowchart TD");
|
|
288
|
+
expect(out).toContain("wave-1");
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
test("--components view is lint-gated like the entity view", async () => {
|
|
292
|
+
lintMock.mockResolvedValue({ success: false });
|
|
293
|
+
const exit = await runGraph({ args: makeArgs({ format: "ir", components: true }), plugins: [], serializers: [] });
|
|
294
|
+
expect(exit).toBe(1);
|
|
295
|
+
expect(stdoutBuf.join("\n")).toBe("");
|
|
296
|
+
expect(stderrBuf.join("\n")).toMatch(/lint errors/i);
|
|
297
|
+
expect(componentGraphMock).not.toHaveBeenCalled();
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
test("propagates a component-graph failure (unknown dep / cycle) as a non-zero exit", async () => {
|
|
301
|
+
lintMock.mockResolvedValue({ success: true });
|
|
302
|
+
componentGraphMock.mockResolvedValue({ success: false, order: [], waves: [], edges: [], error: "cycle: a ↔ b" });
|
|
303
|
+
const exit = await runGraph({ args: makeArgs({ format: "ir", components: true }), plugins: [], serializers: [] });
|
|
304
|
+
expect(exit).toBe(1);
|
|
305
|
+
expect(stderrBuf.join("\n")).toContain("cycle: a ↔ b");
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
|
|
230
309
|
describe("live graph (--live)", () => {
|
|
231
310
|
// Regression: `graph` is not `requiresPlugins`, so `ctx.plugins` is empty. The
|
|
232
311
|
// live path must load the project's plugins itself — otherwise it wrongly
|
|
@@ -24,7 +24,9 @@ import { computeComponentGraph } from "../../components/cli-support";
|
|
|
24
24
|
* cross-lexicon references; `--components` (#560) renders the same
|
|
25
25
|
* order/waves shape for discovered `Component` declarations, from their
|
|
26
26
|
* `dependsOn`; `--format ir|mermaid` emits the lint-gated entity-graph IR (or
|
|
27
|
-
* a Mermaid flowchart of it) for diagrams (#493/#496).
|
|
27
|
+
* a Mermaid flowchart of it) for diagrams (#493/#496). `--components` with a
|
|
28
|
+
* `--format` projects the component DAG itself into that format (nodes =
|
|
29
|
+
* components, wave groups, `dependsOn` edges) — the graph behold renders.
|
|
28
30
|
*/
|
|
29
31
|
export async function runGraph(ctx: CommandContext): Promise<number> {
|
|
30
32
|
const viewFormats = ["ir", "mermaid", "dot", "layout"] as const;
|
|
@@ -35,6 +37,11 @@ export async function runGraph(ctx: CommandContext): Promise<number> {
|
|
|
35
37
|
return runGraphLive(ctx, isViewFormat ? (ctx.args.format as (typeof viewFormats)[number]) : "ir");
|
|
36
38
|
}
|
|
37
39
|
if (isViewFormat) {
|
|
40
|
+
// `--components` projects the component DAG (nodes = components, wave groups,
|
|
41
|
+
// dependsOn edges) into the same view formats; without it, the entity graph.
|
|
42
|
+
if (ctx.args.components) {
|
|
43
|
+
return runComponentGraphView(ctx, ctx.args.format as (typeof viewFormats)[number]);
|
|
44
|
+
}
|
|
38
45
|
return runGraphView(ctx, ctx.args.format as (typeof viewFormats)[number]);
|
|
39
46
|
}
|
|
40
47
|
if (ctx.args.components) return runComponentGraph(ctx);
|
|
@@ -204,6 +211,63 @@ async function runComponentGraph(ctx: CommandContext): Promise<number> {
|
|
|
204
211
|
return 0;
|
|
205
212
|
}
|
|
206
213
|
|
|
214
|
+
/**
|
|
215
|
+
* `chant graph --components --format ir|mermaid|dot|layout` — the component DAG
|
|
216
|
+
* projected into the renderable IR (nodes = components, `groups.byWave` = the
|
|
217
|
+
* parallel-safe deploy waves, edges = `dependsOn` consumer → producer). This is
|
|
218
|
+
* the graph behold paints: read one way it is the deploy order, read the other
|
|
219
|
+
* the CI pipeline. Distinct from `runGraphView`, which emits the AWS *entity*
|
|
220
|
+
* graph — the component projection has one node per component, not per resource.
|
|
221
|
+
*
|
|
222
|
+
* Lint-gated like the entity view: the DAG stands for deployable source, so we
|
|
223
|
+
* refuse to emit it for source that does not pass lint.
|
|
224
|
+
*/
|
|
225
|
+
async function runComponentGraphView(
|
|
226
|
+
ctx: CommandContext,
|
|
227
|
+
format: "ir" | "mermaid" | "dot" | "layout",
|
|
228
|
+
): Promise<number> {
|
|
229
|
+
const projectPath = resolve(ctx.args.path === "." ? "." : ctx.args.path);
|
|
230
|
+
|
|
231
|
+
const lint = await lintCommand({ path: ctx.args.path, format: "stylish" });
|
|
232
|
+
if (!lint.success) {
|
|
233
|
+
console.error(
|
|
234
|
+
formatError({
|
|
235
|
+
message: "Refusing to emit graph: source has lint errors. Run `chant lint` and fix them first.",
|
|
236
|
+
}),
|
|
237
|
+
);
|
|
238
|
+
return 1;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const graph = await computeComponentGraph(projectPath);
|
|
242
|
+
if (!graph.success) {
|
|
243
|
+
console.error(formatError({ message: graph.error ?? "Failed to compute component graph" }));
|
|
244
|
+
return 1;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// One node per component; wave index carried on the node so a renderer that
|
|
248
|
+
// ignores groups can still lane by it. `dependsOn` is a plain name edge —
|
|
249
|
+
// `kind: "ref"` matches the entity graph's edge vocabulary the emitters read.
|
|
250
|
+
const waveOf = new Map<string, number>();
|
|
251
|
+
graph.waves.forEach((wave, i) => wave.forEach((name) => waveOf.set(name, i + 1)));
|
|
252
|
+
|
|
253
|
+
const ir: GraphIR = {
|
|
254
|
+
nodes: graph.order.map((name) => ({
|
|
255
|
+
id: name,
|
|
256
|
+
kind: "Component",
|
|
257
|
+
lexicon: "chant",
|
|
258
|
+
attrs: { wave: waveOf.get(name) ?? null },
|
|
259
|
+
// Deep-link the node to its `*.component.ts` (behold's inspect panel).
|
|
260
|
+
...(graph.files?.[name] ? { sourceLoc: { file: graph.files[name] } } : {}),
|
|
261
|
+
})),
|
|
262
|
+
edges: graph.edges.map(({ from, to }) => ({ from, to, kind: "ref" as const })),
|
|
263
|
+
groups: {
|
|
264
|
+
byWave: Object.fromEntries(graph.waves.map((wave, i) => [`wave-${i + 1}`, [...wave]])),
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
return emitIr(ir, ctx, format);
|
|
269
|
+
}
|
|
270
|
+
|
|
207
271
|
/**
|
|
208
272
|
* `chant graph --format ir|mermaid|dot|layout` — build the graph IR (honouring
|
|
209
273
|
* `--detail`) and emit it as JSON, a Mermaid flowchart, Graphviz DOT, or node
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
type DriverRunResult,
|
|
38
38
|
} from "./driver";
|
|
39
39
|
import { isLexiconPlugin, type LexiconPlugin, type ComponentPipelineOptions } from "../lexicon";
|
|
40
|
+
import { relative } from "node:path";
|
|
40
41
|
import { buildCapabilityRegistry } from "./capability-plugin-loader";
|
|
41
42
|
import type { CapabilityRegistry } from "./capability";
|
|
42
43
|
import { applyConfigDefaults } from "./config-defaults";
|
|
@@ -129,6 +130,10 @@ export interface ComponentGraphResult {
|
|
|
129
130
|
order: string[];
|
|
130
131
|
waves: string[][];
|
|
131
132
|
edges: Array<{ from: string; to: string }>;
|
|
133
|
+
/** Component name → its declaring `*.component.ts` file (relative to `path`),
|
|
134
|
+
* so a renderer can deep-link a component node to source (`chant graph
|
|
135
|
+
* --components --format ir` sets `sourceLoc` from this). */
|
|
136
|
+
files?: Record<string, string>;
|
|
132
137
|
error?: string;
|
|
133
138
|
}
|
|
134
139
|
|
|
@@ -145,13 +150,19 @@ export async function computeComponentGraph(path: string): Promise<ComponentGrap
|
|
|
145
150
|
deploy: component.deploy,
|
|
146
151
|
}));
|
|
147
152
|
|
|
153
|
+
// component name → its declaring file, relative to `path`, for node deep-links.
|
|
154
|
+
const files: Record<string, string> = {};
|
|
155
|
+
for (const [name, discovered] of result.components) {
|
|
156
|
+
files[name] = relative(path, discovered.filePath);
|
|
157
|
+
}
|
|
158
|
+
|
|
148
159
|
try {
|
|
149
160
|
const { order, waves } = resolveComponentGraph(driverComponents);
|
|
150
161
|
const edges: Array<{ from: string; to: string }> = [];
|
|
151
162
|
for (const c of driverComponents) {
|
|
152
163
|
for (const dep of c.dependsOn ?? []) edges.push({ from: c.name, to: dep });
|
|
153
164
|
}
|
|
154
|
-
return { success: true, order, waves, edges };
|
|
165
|
+
return { success: true, order, waves, edges, files };
|
|
155
166
|
} catch (err) {
|
|
156
167
|
if (err instanceof UnknownDependencyError || err instanceof DependencyCycleError) {
|
|
157
168
|
return { success: false, order: [], waves: [], edges: [], error: err.message };
|
package/src/graph-dot.ts
CHANGED
|
@@ -12,12 +12,13 @@ import type { GraphIR, IRNode, IREdge } from "./graph-ir";
|
|
|
12
12
|
export function toDot(ir: GraphIR): string {
|
|
13
13
|
const lines: string[] = ["digraph chant {", " rankdir=TB;", ' node [shape=box];'];
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
// Cluster by wave (component graph) when present, else by lexicon (entity graph).
|
|
16
|
+
const clusters = ir.groups.byWave ?? ir.groups.byLexicon;
|
|
16
17
|
const grouped = new Set<string>();
|
|
17
|
-
if (
|
|
18
|
-
for (const [
|
|
19
|
-
lines.push(` subgraph ${q(`cluster_${
|
|
20
|
-
lines.push(` label=${q(
|
|
18
|
+
if (clusters) {
|
|
19
|
+
for (const [name, members] of Object.entries(clusters)) {
|
|
20
|
+
lines.push(` subgraph ${q(`cluster_${name}`)} {`);
|
|
21
|
+
lines.push(` label=${q(name)};`);
|
|
21
22
|
for (const id of members) {
|
|
22
23
|
const node = ir.nodes.find((n) => n.id === id);
|
|
23
24
|
if (!node) continue;
|
package/src/graph-ir.ts
CHANGED
|
@@ -94,6 +94,11 @@ export interface IRGroups {
|
|
|
94
94
|
* so a boundary-box renderer recurses it. Populated by `chant graph --live`
|
|
95
95
|
* from the reference resolver's containment output; absent for source IR. */
|
|
96
96
|
byContainer?: Record<string, string[]>;
|
|
97
|
+
/** Component-graph deploy wave (`chant graph --components --format ir`):
|
|
98
|
+
* `wave-N → component node ids` that deploy in parallel in that wave. A
|
|
99
|
+
* wave-laned renderer reads this the way `byStack` drives boundary boxes.
|
|
100
|
+
* Present only for the component-DAG projection; absent for entity IR. */
|
|
101
|
+
byWave?: Record<string, string[]>;
|
|
97
102
|
}
|
|
98
103
|
|
|
99
104
|
/** A cross-stack export this stack publishes (a `stackOutput`/`output`): its
|
package/src/graph-mermaid.ts
CHANGED
|
@@ -20,13 +20,15 @@ export function toMermaid(ir: GraphIR): string {
|
|
|
20
20
|
|
|
21
21
|
const lines: string[] = ["flowchart TD"];
|
|
22
22
|
|
|
23
|
-
// Cluster by
|
|
24
|
-
// through to the top level.
|
|
25
|
-
|
|
23
|
+
// Cluster by wave (component graph) when present, else by lexicon (entity
|
|
24
|
+
// graph); nodes outside any group fall through to the top level. Both are
|
|
25
|
+
// sorted, so output is deterministic.
|
|
26
|
+
const clusters = ir.groups.byWave ?? ir.groups.byLexicon;
|
|
27
|
+
const clusterPrefix = ir.groups.byWave ? "wave" : "lex";
|
|
26
28
|
const grouped = new Set<string>();
|
|
27
|
-
if (
|
|
28
|
-
for (const [
|
|
29
|
-
lines.push(` subgraph ${safeId(
|
|
29
|
+
if (clusters) {
|
|
30
|
+
for (const [name, members] of Object.entries(clusters)) {
|
|
31
|
+
lines.push(` subgraph ${safeId(`${clusterPrefix}_${name}`, ids)}[${quote(name)}]`);
|
|
30
32
|
for (const id of members) {
|
|
31
33
|
const node = ir.nodes.find((n) => n.id === id);
|
|
32
34
|
if (!node) continue;
|
package/src/lexicon.ts
CHANGED
|
@@ -231,6 +231,25 @@ export interface ComponentPipelineResult {
|
|
|
231
231
|
jobs: ComponentPipelineJob[];
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
+
/**
|
|
235
|
+
* Live status of a single deploy unit (a CloudFormation stack, a K8s release, …)
|
|
236
|
+
* addressed by its deployed name — the per-component presence signal
|
|
237
|
+
* `chant components status --live` needs (#57). A component's deploy step carries
|
|
238
|
+
* the exact unit name it targets (e.g. a `cfn-deploy` step's `stack`), which is
|
|
239
|
+
* the identity in a multi-stack component project where `describeResources`
|
|
240
|
+
* (entity-keyed, single-stack-per-env) can't see the component's own stack.
|
|
241
|
+
*/
|
|
242
|
+
export interface StackStatusObservation {
|
|
243
|
+
/** The deploy-unit name queried (the stack name). */
|
|
244
|
+
stack: string;
|
|
245
|
+
/** False when the unit does not exist yet — the pre-first-apply state. */
|
|
246
|
+
present: boolean;
|
|
247
|
+
/** Provider-native status string, e.g. CloudFormation "CREATE_COMPLETE". */
|
|
248
|
+
status?: string;
|
|
249
|
+
/** True when `status` is a terminal *success* state (deployed and healthy). */
|
|
250
|
+
healthy?: boolean;
|
|
251
|
+
}
|
|
252
|
+
|
|
234
253
|
export interface LexiconPlugin {
|
|
235
254
|
// ── Required ──────────────────────────────────────────────
|
|
236
255
|
/** Human-readable name (e.g. "aws", "gcp") */
|
|
@@ -388,6 +407,22 @@ export interface LexiconPlugin {
|
|
|
388
407
|
owned?: boolean;
|
|
389
408
|
}): Promise<Record<string, ResourceMetadata>>;
|
|
390
409
|
|
|
410
|
+
/**
|
|
411
|
+
* Report the live status of one deploy unit by its deployed name. Opt-in.
|
|
412
|
+
*
|
|
413
|
+
* Complements {@link describeResources}: that observes a stack's *entities*
|
|
414
|
+
* keyed by chant entity name (and assumes one stack per environment), which
|
|
415
|
+
* can't see a multi-stack component project where each component owns its own
|
|
416
|
+
* stack. `chant components status --live` resolves a component's deploy-step
|
|
417
|
+
* target (e.g. a `cfn-deploy` step's `stack`) and calls this to learn whether
|
|
418
|
+
* that unit is present and healthy — a component-level presence signal.
|
|
419
|
+
*
|
|
420
|
+
* Returns `null` when the lexicon cannot determine status (e.g. the provider
|
|
421
|
+
* CLI failed for a reason other than "does not exist"); a genuinely absent
|
|
422
|
+
* unit returns `{ present: false }`.
|
|
423
|
+
*/
|
|
424
|
+
describeStackStatus?(options: { environment: string; stack: string }): Promise<StackStatusObservation | null>;
|
|
425
|
+
|
|
391
426
|
/**
|
|
392
427
|
* Reference catalog for live edge reconstruction (#778). Declares how this
|
|
393
428
|
* lexicon's observed resources reference each other — an identity map (which
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
liveEvidenceFromChangeSet,
|
|
5
5
|
resolveLiveNames,
|
|
6
6
|
compareAcrossEnvironments,
|
|
7
|
+
mergeLiveEvidence,
|
|
7
8
|
type LiveComponentEvidence,
|
|
8
9
|
type LiveNameMapping,
|
|
9
10
|
} from "./status";
|
|
@@ -327,4 +328,35 @@ describe("status", () => {
|
|
|
327
328
|
expect(result.same).toBe(false);
|
|
328
329
|
});
|
|
329
330
|
});
|
|
331
|
+
|
|
332
|
+
describe("mergeLiveEvidence (#57 — per-component stack presence overlay)", () => {
|
|
333
|
+
test("stack presence overrides change-set 'not live' but keeps its drift action", () => {
|
|
334
|
+
const base = new Map<string, LiveComponentEvidence>([
|
|
335
|
+
["shared-foundation", { live: false }], // entity-keyed observe saw nothing
|
|
336
|
+
["loom-backend", { live: true, action: "update", ownership: "owned" }],
|
|
337
|
+
]);
|
|
338
|
+
const supplement = new Map<string, LiveComponentEvidence>([
|
|
339
|
+
["shared-foundation", { live: true, ownership: "owned" }], // its stack IS present
|
|
340
|
+
["loom-backend", { live: true, ownership: "owned" }],
|
|
341
|
+
]);
|
|
342
|
+
const merged = mergeLiveEvidence(base, supplement);
|
|
343
|
+
expect(merged.get("shared-foundation")).toEqual({ live: true, ownership: "owned", action: undefined });
|
|
344
|
+
// loom-backend: presence confirmed, change-set drift action preserved.
|
|
345
|
+
expect(merged.get("loom-backend")).toEqual({ live: true, ownership: "owned", action: "update" });
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
test("a component only in the supplement is added; base-only entries pass through", () => {
|
|
349
|
+
const base = new Map<string, LiveComponentEvidence>([["only-base", { live: true, ownership: "foreign" }]]);
|
|
350
|
+
const supplement = new Map<string, LiveComponentEvidence>([["only-sup", { live: false }]]);
|
|
351
|
+
const merged = mergeLiveEvidence(base, supplement);
|
|
352
|
+
expect(merged.get("only-base")).toEqual({ live: true, ownership: "foreign" });
|
|
353
|
+
expect(merged.get("only-sup")).toEqual({ live: false, ownership: undefined, action: undefined });
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
test("undefined base (no --live change-set) still yields the supplement", () => {
|
|
357
|
+
const supplement = new Map<string, LiveComponentEvidence>([["c", { live: true, ownership: "owned" }]]);
|
|
358
|
+
const merged = mergeLiveEvidence(undefined, supplement);
|
|
359
|
+
expect(merged.get("c")).toEqual({ live: true, ownership: "owned", action: undefined });
|
|
360
|
+
});
|
|
361
|
+
});
|
|
330
362
|
});
|
package/src/lifecycle/status.ts
CHANGED
|
@@ -86,6 +86,33 @@ export interface LiveComponentEvidence {
|
|
|
86
86
|
ownership?: "owned" | "foreign" | "unknown";
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Overlay per-component stack-presence evidence onto change-set evidence.
|
|
91
|
+
*
|
|
92
|
+
* The change-set axis (`liveEvidenceFromChangeSet`) is entity-keyed and, for
|
|
93
|
+
* AWS, single-stack-per-env — it can't see a multi-stack component project where
|
|
94
|
+
* each component owns its own stack (#57). `supplement` carries the direct
|
|
95
|
+
* per-component stack observation (from a lexicon's `describeStackStatus`), which
|
|
96
|
+
* is authoritative for **presence** (`live`) and **ownership**; the change-set's
|
|
97
|
+
* `action` is kept, since drift is still assessed from the diff. A component in
|
|
98
|
+
* only one map passes through unchanged.
|
|
99
|
+
*/
|
|
100
|
+
export function mergeLiveEvidence(
|
|
101
|
+
base: Map<string, LiveComponentEvidence> | undefined,
|
|
102
|
+
supplement: Map<string, LiveComponentEvidence>,
|
|
103
|
+
): Map<string, LiveComponentEvidence> {
|
|
104
|
+
const merged = new Map(base ?? []);
|
|
105
|
+
for (const [component, sup] of supplement) {
|
|
106
|
+
const b = merged.get(component);
|
|
107
|
+
merged.set(component, {
|
|
108
|
+
live: sup.live,
|
|
109
|
+
ownership: sup.ownership ?? b?.ownership,
|
|
110
|
+
action: b?.action,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return merged;
|
|
114
|
+
}
|
|
115
|
+
|
|
89
116
|
/**
|
|
90
117
|
* Component -> live entity/resource name(s) it owns (#598). Mirrors
|
|
91
118
|
* `Component.liveNames` (../components/component.ts) without importing it —
|
package/src/lint/config.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, test, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import { loadConfig, DEFAULT_CONFIG } from "./config";
|
|
2
|
+
import { loadConfig, DEFAULT_CONFIG, findProjectRoot } from "./config";
|
|
3
3
|
import { writeFileSync, mkdirSync, rmSync } from "fs";
|
|
4
4
|
import { join } from "path";
|
|
5
5
|
|
|
@@ -684,3 +684,31 @@ describe("loadConfig", () => {
|
|
|
684
684
|
expect(config.rules?.["noisy-rule"]).toBe("off");
|
|
685
685
|
});
|
|
686
686
|
});
|
|
687
|
+
|
|
688
|
+
describe("findProjectRoot", () => {
|
|
689
|
+
test("returns the directory holding chant.config.json", () => {
|
|
690
|
+
writeFileSync(join(TEST_DIR, "chant.config.json"), "{}");
|
|
691
|
+
expect(findProjectRoot(TEST_DIR)).toBe(TEST_DIR);
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
test("walks up from a subpath to the config-bearing root", () => {
|
|
695
|
+
writeFileSync(join(TEST_DIR, "chant.config.json"), "{}");
|
|
696
|
+
const sub = join(TEST_DIR, "src", "lib");
|
|
697
|
+
mkdirSync(sub, { recursive: true });
|
|
698
|
+
expect(findProjectRoot(sub)).toBe(TEST_DIR);
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
test("also recognizes chant.config.ts as a project root", () => {
|
|
702
|
+
writeFileSync(join(TEST_DIR, "chant.config.ts"), "export default {};");
|
|
703
|
+
const sub = join(TEST_DIR, "src");
|
|
704
|
+
mkdirSync(sub, { recursive: true });
|
|
705
|
+
expect(findProjectRoot(sub)).toBe(TEST_DIR);
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
test("falls back to the start dir when no config is found", () => {
|
|
709
|
+
const sub = join(TEST_DIR, "nowhere");
|
|
710
|
+
mkdirSync(sub, { recursive: true });
|
|
711
|
+
// No chant.config anywhere under TEST_DIR — returns the (resolved) start dir.
|
|
712
|
+
expect(findProjectRoot(sub)).toBe(sub);
|
|
713
|
+
});
|
|
714
|
+
});
|
package/src/lint/config.ts
CHANGED
|
@@ -323,6 +323,29 @@ function loadConfigFile(configPath: string, visited: Set<string> = new Set()): L
|
|
|
323
323
|
return mergedConfig;
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
+
/**
|
|
327
|
+
* Walk up from `startDir` to the nearest ancestor holding a chant project
|
|
328
|
+
* config (`chant.config.ts` or `chant.config.json`). Returns that directory, or
|
|
329
|
+
* `startDir` unchanged when none is found before the filesystem root.
|
|
330
|
+
*
|
|
331
|
+
* Linting a subpath (`chant graph src --format ir`, `chant lint src/lib`) must
|
|
332
|
+
* still see the project-root config: its `lint.overrides` globs are written
|
|
333
|
+
* project-root-relative (`src/lib/**`), and a rule set scoped only to the lint
|
|
334
|
+
* arg would silently drop them. Config discovery therefore anchors on the
|
|
335
|
+
* project root, not the path being linted.
|
|
336
|
+
*/
|
|
337
|
+
export function findProjectRoot(startDir: string): string {
|
|
338
|
+
let dir = resolve(startDir);
|
|
339
|
+
for (;;) {
|
|
340
|
+
if (existsSync(join(dir, "chant.config.ts")) || existsSync(join(dir, "chant.config.json"))) {
|
|
341
|
+
return dir;
|
|
342
|
+
}
|
|
343
|
+
const parent = dirname(dir);
|
|
344
|
+
if (parent === dir) return resolve(startDir);
|
|
345
|
+
dir = parent;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
326
349
|
/**
|
|
327
350
|
* Load lint configuration from a directory.
|
|
328
351
|
*
|