@intentius/chant 0.124.44 → 0.124.46
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/capabilities/aws.paths +148 -0
- package/dist/capabilities/base-mappings.json +122 -0
- package/dist/capabilities/catalog.d.ts +89 -0
- package/dist/capabilities/catalog.d.ts.map +1 -0
- package/dist/capabilities/catalog.js +204 -0
- package/dist/capabilities/language.d.ts +103 -0
- package/dist/capabilities/language.d.ts.map +1 -0
- package/dist/capabilities/language.js +335 -0
- package/dist/capabilities/matcher.d.ts +65 -0
- package/dist/capabilities/matcher.d.ts.map +1 -0
- package/dist/capabilities/matcher.js +299 -0
- package/dist/capabilities/view.d.ts +207 -0
- package/dist/capabilities/view.d.ts.map +1 -0
- package/dist/capabilities/view.js +484 -0
- package/dist/ci-identity.d.ts +183 -12
- package/dist/ci-identity.d.ts.map +1 -1
- package/dist/ci-identity.js +362 -53
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/lint.js +1 -0
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +17 -1
- package/dist/cli/handlers/declared-graph.d.ts +44 -0
- package/dist/cli/handlers/declared-graph.d.ts.map +1 -0
- package/dist/cli/handlers/declared-graph.js +87 -0
- package/dist/cli/handlers/graph.d.ts +25 -0
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/cli/handlers/graph.js +93 -87
- package/dist/cli/handlers/pr-env.d.ts +8 -2
- package/dist/cli/handlers/pr-env.d.ts.map +1 -1
- package/dist/cli/handlers/pr-env.js +127 -225
- package/dist/cli/handlers/pr.d.ts +3 -0
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +1 -0
- package/dist/cli/handlers/search-count.d.ts +89 -0
- package/dist/cli/handlers/search-count.d.ts.map +1 -0
- package/dist/cli/handlers/search-count.js +132 -0
- package/dist/cli/handlers/search.d.ts +358 -6
- package/dist/cli/handlers/search.d.ts.map +1 -1
- package/dist/cli/handlers/search.js +1065 -155
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +23 -3
- package/dist/cli/mcp/server.d.ts.map +1 -1
- package/dist/cli/mcp/server.js +3 -0
- package/dist/cli/mcp/tools/capabilities.d.ts +7 -0
- package/dist/cli/mcp/tools/capabilities.d.ts.map +1 -0
- package/dist/cli/mcp/tools/capabilities.js +27 -0
- package/dist/cli/mcp/workspace-tools.d.ts +3 -1
- package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
- package/dist/cli/mcp/workspace-tools.js +47 -2
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +64 -17
- package/dist/cli/registry.d.ts +22 -0
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +2 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/cli-support.js +4 -2
- package/dist/components/fan-out-support.d.ts +3 -0
- package/dist/components/fan-out-support.d.ts.map +1 -1
- package/dist/components/fan-out-support.js +1 -1
- package/dist/components/pr-env-ports.d.ts +29 -0
- package/dist/components/pr-env-ports.d.ts.map +1 -0
- package/dist/components/pr-env-ports.js +77 -0
- package/dist/components/pr-env-run.d.ts +254 -0
- package/dist/components/pr-env-run.d.ts.map +1 -0
- package/dist/components/pr-env-run.js +376 -0
- package/dist/components/pr-environment.d.ts +91 -15
- package/dist/components/pr-environment.d.ts.map +1 -1
- package/dist/components/pr-environment.js +95 -9
- package/dist/components/pr-pipeline.d.ts +10 -1
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/config-environments.d.ts +92 -0
- package/dist/config-environments.d.ts.map +1 -0
- package/dist/config-environments.js +102 -0
- package/dist/config.d.ts +24 -84
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +9 -96
- package/dist/graph-detail.d.ts.map +1 -1
- package/dist/graph-detail.js +15 -3
- package/dist/graph-effective.d.ts +33 -2
- package/dist/graph-effective.d.ts.map +1 -1
- package/dist/graph-effective.js +215 -68
- package/dist/graph-ir.d.ts +23 -0
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/graph-ir.js +130 -0
- package/dist/graph-sub-template.d.ts +11 -0
- package/dist/graph-sub-template.d.ts.map +1 -0
- package/dist/graph-sub-template.js +19 -0
- package/dist/lexicon.d.ts +9 -0
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/observe.d.ts +28 -0
- package/dist/lifecycle/observe.d.ts.map +1 -1
- package/dist/lifecycle/observe.js +23 -1
- package/dist/lint/rule.d.ts +6 -0
- package/dist/lint/rule.d.ts.map +1 -1
- package/dist/live-endpoint.d.ts +1 -1
- package/dist/live-endpoint.d.ts.map +1 -1
- package/dist/live-endpoint.js +1 -1
- package/dist/observation.d.ts +48 -1
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +21 -5
- package/dist/op/activities/activity-contracts.d.ts +4 -4
- package/dist/op/op-waves.d.ts +17 -0
- package/dist/op/op-waves.d.ts.map +1 -1
- package/dist/op/op-waves.js +23 -1
- package/dist/pr-forge.d.ts +15 -1
- package/dist/pr-forge.d.ts.map +1 -1
- package/dist/pr-forge.js +28 -16
- package/dist/pr-requires.d.ts +5 -1
- package/dist/pr-requires.d.ts.map +1 -1
- package/dist/wave-runtime.mjs +251 -250
- package/dist/workspace/capabilities-contract.d.ts +66 -0
- package/dist/workspace/capabilities-contract.d.ts.map +1 -0
- package/dist/workspace/capabilities-contract.js +107 -0
- package/dist/workspace/capabilities.schema.json +229 -0
- package/dist/workspace/ci-cloud-identity.d.ts +3 -1
- package/dist/workspace/ci-cloud-identity.d.ts.map +1 -1
- package/dist/workspace/ci-cloud-identity.js +16 -1
- package/dist/workspace/ci-run.d.ts +35 -8
- package/dist/workspace/ci-run.d.ts.map +1 -1
- package/dist/workspace/ci-run.js +95 -21
- package/dist/workspace/ci-secrets.d.ts.map +1 -1
- package/dist/workspace/ci-secrets.js +4 -3
- package/dist/workspace/compose-graph.d.ts +9 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/compose-graph.js +3 -1
- package/dist/workspace/conformance/index.d.ts +1 -1
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/conformance/index.js +39 -2
- package/dist/workspace/declaration.d.ts +10 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +17 -1
- package/dist/workspace/declaration.schema.json +36 -1
- package/dist/workspace/graph-cache.d.ts +8 -0
- package/dist/workspace/graph-cache.d.ts.map +1 -1
- package/dist/workspace/graph-cache.js +27 -3
- package/dist/workspace/graph-cli.d.ts +39 -2
- package/dist/workspace/graph-cli.d.ts.map +1 -1
- package/dist/workspace/graph-cli.js +66 -24
- package/dist/workspace/graph.schema.json +148 -0
- package/dist/workspace/kind-readers.d.ts +3 -0
- package/dist/workspace/kind-readers.d.ts.map +1 -1
- package/dist/workspace/kind-readers.js +7 -1
- package/dist/workspace/member-commands.d.ts +10 -1
- package/dist/workspace/member-commands.d.ts.map +1 -1
- package/dist/workspace/member-commands.js +17 -1
- package/dist/workspace/nested-graph.d.ts +2 -0
- package/dist/workspace/nested-graph.d.ts.map +1 -1
- package/dist/workspace/nested-graph.js +32 -1
- package/dist/workspace/reason-codes.d.ts +10 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +12 -0
- package/dist/workspace/search-cli.d.ts +204 -0
- package/dist/workspace/search-cli.d.ts.map +1 -0
- package/dist/workspace/search-cli.js +466 -0
- package/dist/workspace/search-contract.d.ts +56 -0
- package/dist/workspace/search-contract.d.ts.map +1 -0
- package/dist/workspace/search-contract.js +70 -0
- package/dist/workspace/search.schema.json +822 -0
- package/package.json +1 -1
- package/src/__snapshots__/okf.test.ts.snap +10 -0
- package/src/capabilities/aws.paths +148 -0
- package/src/capabilities/base-mappings.json +122 -0
- package/src/capabilities/catalog.ts +230 -0
- package/src/capabilities/language.test.ts +191 -0
- package/src/capabilities/language.ts +373 -0
- package/src/capabilities/matcher.ts +315 -0
- package/src/capabilities/view-compose.test.ts +76 -0
- package/src/capabilities/view.ts +631 -0
- package/src/ci-identity-targets.test.ts +275 -0
- package/src/ci-identity.ts +394 -61
- package/src/cli/commands/lint.ts +1 -0
- package/src/cli/handlers/build.ts +15 -1
- package/src/cli/handlers/declared-graph.ts +99 -0
- package/src/cli/handlers/graph.test.ts +94 -3
- package/src/cli/handlers/graph.ts +123 -96
- package/src/cli/handlers/pr-env.ts +135 -227
- package/src/cli/handlers/pr.ts +4 -0
- package/src/cli/handlers/search-build-roots.test.ts +144 -0
- package/src/cli/handlers/search-count.test.ts +191 -0
- package/src/cli/handlers/search-count.ts +165 -0
- package/src/cli/handlers/search-json.test.ts +333 -0
- package/src/cli/handlers/search-live.test.ts +387 -0
- package/src/cli/handlers/search-paths.test.ts +235 -0
- package/src/cli/handlers/search.ts +1312 -166
- package/src/cli/main.test.ts +28 -3
- package/src/cli/main.ts +23 -3
- package/src/cli/mcp/server.test.ts +3 -3
- package/src/cli/mcp/server.ts +3 -0
- package/src/cli/mcp/tools/capabilities.ts +32 -0
- package/src/cli/mcp/workspace-tools.e2e.test.ts +21 -1
- package/src/cli/mcp/workspace-tools.ts +47 -2
- package/src/cli/parse-args.ts +52 -13
- package/src/cli/registry.ts +22 -0
- package/src/components/cli-support.ts +6 -1
- package/src/components/fan-out-support.ts +4 -1
- package/src/components/pr-env-ports.ts +89 -0
- package/src/components/pr-env-run-bundle.test.ts +54 -0
- package/src/components/pr-env-run.test.ts +290 -0
- package/src/components/pr-env-run.ts +563 -0
- package/src/components/pr-environment.ts +161 -13
- package/src/components/pr-pipeline.ts +10 -1
- package/src/config-environments.ts +133 -0
- package/src/config.ts +37 -124
- package/src/graph-detail.ts +15 -3
- package/src/graph-effective.ts +226 -75
- package/src/graph-ir.test.ts +163 -0
- package/src/graph-ir.ts +147 -0
- package/src/graph-sub-template.ts +22 -0
- package/src/lexicon.ts +10 -0
- package/src/lifecycle/observe.test.ts +27 -1
- package/src/lifecycle/observe.ts +43 -1
- package/src/lint/rule.ts +6 -0
- package/src/live-endpoint.ts +1 -1
- package/src/observation.test.ts +25 -0
- package/src/observation.ts +69 -5
- package/src/op/op-waves.ts +38 -1
- package/src/pr-forge-bundle.test.ts +1 -1
- package/src/pr-forge.ts +44 -17
- package/src/pr-requires.test.ts +43 -6
- package/src/pr-requires.ts +5 -1
- package/src/workspace/capabilities-contract.test.ts +88 -0
- package/src/workspace/capabilities-contract.ts +132 -0
- package/src/workspace/capabilities.schema.json +229 -0
- package/src/workspace/ci-cloud-identity.test.ts +20 -0
- package/src/workspace/ci-cloud-identity.ts +14 -1
- package/src/workspace/ci-run.test.ts +74 -1
- package/src/workspace/ci-run.ts +122 -29
- package/src/workspace/ci-secrets.test.ts +1 -1
- package/src/workspace/ci-secrets.ts +4 -3
- package/src/workspace/compose-graph.ts +10 -1
- package/src/workspace/conformance/conformance.e2e.test.ts +14 -1
- package/src/workspace/conformance/index.ts +31 -2
- package/src/workspace/declaration.schema.json +36 -1
- package/src/workspace/declaration.test.ts +7 -0
- package/src/workspace/declaration.ts +24 -2
- package/src/workspace/graph-cache.ts +27 -3
- package/src/workspace/graph-cli.ts +96 -24
- package/src/workspace/graph.schema.json +148 -0
- package/src/workspace/kind-readers.e2e.test.ts +28 -0
- package/src/workspace/kind-readers.test.ts +1 -1
- package/src/workspace/kind-readers.ts +7 -1
- package/src/workspace/member-commands.ts +22 -1
- package/src/workspace/nested-graph.ts +32 -1
- package/src/workspace/reason-codes.test.ts +7 -0
- package/src/workspace/reason-codes.ts +12 -0
- package/src/workspace/search-cli.e2e.test.ts +305 -0
- package/src/workspace/search-cli.ts +591 -0
- package/src/workspace/search-contract.ts +95 -0
- package/src/workspace/search.schema.json +822 -0
|
@@ -25,17 +25,24 @@
|
|
|
25
25
|
* `down` reads the environment's record on chant/lifecycle, checks it names
|
|
26
26
|
* this pull request's environment, and tears down what `planTeardown` finds
|
|
27
27
|
* under the record's marker, after dropping any entry whose marker is not
|
|
28
|
-
* exactly that one.
|
|
29
|
-
*
|
|
28
|
+
* exactly that one. The lexicons tear down what they own, and the command
|
|
29
|
+
* `ci.prEnvironment.teardown` names tears down the rest (#4330). No gate
|
|
30
|
+
* holds it: closing the pull request is the decision, as is the TTL the base
|
|
31
|
+
* set for `sweep`.
|
|
32
|
+
*
|
|
33
|
+
* The runs themselves are ../../components/pr-env-run.ts, which a product
|
|
34
|
+
* calls with an adapter of its own (#4330). This file supplies the
|
|
35
|
+
* components adapter and the CLI's ports.
|
|
30
36
|
*/
|
|
31
37
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
32
38
|
import { join, resolve } from "node:path";
|
|
33
39
|
import { loadChantConfig } from "../../config.js";
|
|
34
40
|
import { ENV_VAR } from "../../env.js";
|
|
35
41
|
import { isEmptyChangeSet } from "../../change-set.js";
|
|
36
|
-
import { PR_ENV_EXIT, PR_ENV_GATE,
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
42
|
+
import { PR_ENV_EXIT, PR_ENV_GATE, PR_ENV_RECORD_FILE, PR_ENV_REPORT_DIR, acceptHandedRecord, handedPrEnvReport, PR_ENV_TEMPLATE_VAR, derivePrEnvironment, prEnvApproveCommand, prEnvStatusState, prEnvironmentName, prEnvironmentSite, renderPrEnvNote, ttlMs, } from "../../components/pr-environment.js";
|
|
43
|
+
import { commandTeardownAdapter, prEnvDown as prEnvDownRun, prEnvOp, prEnvSweep as prEnvSweepRun, prEnvUp as prEnvUpRun, } from "../../components/pr-env-run.js";
|
|
44
|
+
import { forgePrEnvPublisher, lifecyclePrEnvPorts } from "../../components/pr-env-ports.js";
|
|
45
|
+
import { applyPrSet } from "../../components/pr-run.js";
|
|
39
46
|
import { prOp } from "../../pr-loop.js";
|
|
40
47
|
import { FORGE_KINDS, forgeFromEnv, forgePrincipalOf } from "../../pr-forge.js";
|
|
41
48
|
import { formatError, formatInfo, formatWarning } from "../format.js";
|
|
@@ -77,36 +84,29 @@ function actor() {
|
|
|
77
84
|
function memberOf(ctx) {
|
|
78
85
|
return ctx.args.members?.length === 1 ? ctx.args.members[0] : undefined;
|
|
79
86
|
}
|
|
80
|
-
// ── the
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
await fetchLifecycle().catch(() => false);
|
|
84
|
-
return parsePrEnvRecords(await readBlobFromPath(PR_ENV_LEDGER_DIR, PR_ENV_LEDGER_FILE));
|
|
85
|
-
}
|
|
87
|
+
// ── the ports ──────────────────────────────────────────────────────────────
|
|
88
|
+
const log = (line) => console.error(formatInfo(line));
|
|
89
|
+
const warn = (message) => console.error(formatWarning({ message }));
|
|
86
90
|
/**
|
|
87
|
-
*
|
|
88
|
-
* the
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
+
* The ports `pr-env` runs with (../../components/pr-env-run.ts): the records
|
|
92
|
+
* and the gate ledger on chant/lifecycle here, and the report written under
|
|
93
|
+
* `--output` and posted through `forge`. With `--no-push` (#4295) the record
|
|
94
|
+
* is written to `pr-env-record.json` under `--output` instead, for `pr-env
|
|
95
|
+
* post` to append from a job that runs none of the change's code.
|
|
91
96
|
*/
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
console.error(formatWarning({ message: pushed.pushWarning }));
|
|
106
|
-
}
|
|
107
|
-
catch (err) {
|
|
108
|
-
console.error(formatWarning({ message: `could not record ${record.env}'s ${record.kind} on chant/lifecycle: ${err instanceof Error ? err.message : String(err)}` }));
|
|
109
|
-
}
|
|
97
|
+
function cliPorts(ctx, forge) {
|
|
98
|
+
const lifecycle = lifecyclePrEnvPorts({ ...(forge ? { forge } : {}), log, warn });
|
|
99
|
+
return {
|
|
100
|
+
...lifecycle,
|
|
101
|
+
async appendRecord(record) {
|
|
102
|
+
if (!ctx.args.noPush)
|
|
103
|
+
return lifecycle.appendRecord(record);
|
|
104
|
+
const dir = resolve(ctx.args.output ?? PR_ENV_REPORT_DIR);
|
|
105
|
+
mkdirSync(dir, { recursive: true });
|
|
106
|
+
writeFileSync(join(dir, PR_ENV_RECORD_FILE), JSON.stringify(record, null, 2) + "\n");
|
|
107
|
+
},
|
|
108
|
+
publish: (report) => finish(ctx, forge, report),
|
|
109
|
+
};
|
|
110
110
|
}
|
|
111
111
|
// ── the report and the note ────────────────────────────────────────────────
|
|
112
112
|
async function finish(ctx, forge, report) {
|
|
@@ -117,27 +117,8 @@ async function finish(ctx, forge, report) {
|
|
|
117
117
|
writeFileSync(join(dir, "pr-env-note.md"), note);
|
|
118
118
|
if (ctx.args.json)
|
|
119
119
|
console.log(JSON.stringify(report, null, 2));
|
|
120
|
-
if (
|
|
121
|
-
|
|
122
|
-
if (report.head) {
|
|
123
|
-
try {
|
|
124
|
-
await forge.setStatus(report.head, {
|
|
125
|
-
context: prEnvStatusContext(report.member),
|
|
126
|
-
state: prEnvStatusState(report),
|
|
127
|
-
description: prEnvStatusDescription(report),
|
|
128
|
-
...(forge.runUrl ? { url: forge.runUrl } : {}),
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
catch (err) {
|
|
132
|
-
console.error(formatWarning({ message: `could not set the ${prEnvStatusContext(report.member)} status: ${err instanceof Error ? err.message : String(err)}` }));
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
try {
|
|
136
|
-
await forge.upsertNote(report.pr, prEnvNoteMarker(report.env, report.member), note);
|
|
137
|
-
}
|
|
138
|
-
catch (err) {
|
|
139
|
-
console.error(formatWarning({ message: `could not post the note on #${report.pr}: ${err instanceof Error ? err.message : String(err)}` }));
|
|
140
|
-
}
|
|
120
|
+
if (forge)
|
|
121
|
+
await forgePrEnvPublisher(forge, warn)(report);
|
|
141
122
|
}
|
|
142
123
|
// ── up ─────────────────────────────────────────────────────────────────────
|
|
143
124
|
async function prEnvUp(ctx) {
|
|
@@ -159,7 +140,6 @@ async function prEnvUp(ctx) {
|
|
|
159
140
|
const derived = derivePrEnvironment(config, setting.template, pr);
|
|
160
141
|
if ("refusal" in derived)
|
|
161
142
|
return fail(derived.refusal);
|
|
162
|
-
const ttl = ttlMs(setting.ttl) ?? ttlMs("72h");
|
|
163
143
|
// The build sees pr-<n> as its environment and the template's name beside it.
|
|
164
144
|
process.env[ENV_VAR] = derived.env;
|
|
165
145
|
process.env[PR_ENV_TEMPLATE_VAR] = derived.template;
|
|
@@ -168,108 +148,77 @@ async function prEnvUp(ctx) {
|
|
|
168
148
|
args: { ...args, env: derived.env, param: [...(args.param ?? []).filter((p) => !p.startsWith(`${derived.param}=`)), `${derived.param}=${derived.env}`] },
|
|
169
149
|
};
|
|
170
150
|
console.error(formatInfo(`pr-env up: ${derived.env}, derived from ${derived.template}${derived.endpoint ? ` at ${derived.endpoint}` : ""}, marker ${derived.stack}/${derived.env}`));
|
|
171
|
-
return withComponentEndpoint(envCtx, () => up(envCtx, pr, derived, ttl), { config: { ...config, environments: derived.environments }, environment: derived.env });
|
|
151
|
+
return withComponentEndpoint(envCtx, () => up(envCtx, pr, derived, setting.ttl), { config: { ...config, environments: derived.environments }, environment: derived.env });
|
|
172
152
|
}
|
|
173
153
|
async function up(ctx, pr, derived, ttl) {
|
|
174
154
|
const { prepare, planAll, placeHooks, runStageHook } = await import("./pr.js");
|
|
175
155
|
const p = await prepare(ctx, "plan");
|
|
176
156
|
if (typeof p === "number")
|
|
177
157
|
return p;
|
|
178
|
-
const forge = p.forge;
|
|
179
|
-
const op = prOp(pr, p.member);
|
|
180
158
|
// ci.hooks (#4288), read at base as the other pull-request jobs read them, around the plan and the apply.
|
|
181
|
-
placeHooks(ctx, p, "apply",
|
|
182
|
-
const
|
|
183
|
-
stage: "up",
|
|
159
|
+
placeHooks(ctx, p, "apply", prEnvOp(pr, p.member));
|
|
160
|
+
const result = await prEnvUpRun({
|
|
184
161
|
pr,
|
|
185
|
-
env: derived.env,
|
|
186
|
-
...(p.member ? { member: p.member } : {}),
|
|
187
|
-
template: derived.template,
|
|
188
162
|
head: p.head,
|
|
189
|
-
op,
|
|
190
|
-
gate: PR_ENV_GATE,
|
|
191
|
-
digest: "",
|
|
192
|
-
status: "nothing",
|
|
193
|
-
...(derived.endpoint ? { endpoint: derived.endpoint } : {}),
|
|
194
|
-
components: [],
|
|
195
|
-
};
|
|
196
|
-
if (p.plan.order.length === 0) {
|
|
197
|
-
await finish(ctx, forge, { ...base, ...(p.routedAway ? { message: p.routedAway } : {}) });
|
|
198
|
-
console.error(formatInfo(`pr-env up: nothing this change touches is deployed by a component, so ${derived.env} gets nothing`));
|
|
199
|
-
return PR_ENV_EXIT.done;
|
|
200
|
-
}
|
|
201
|
-
const set = await planAll(p);
|
|
202
|
-
const rows = (status) => p.plan.order.map((component) => {
|
|
203
|
-
const ms = set.members.filter((m) => m.component === component);
|
|
204
|
-
const sum = (k) => ms.reduce((n, m) => n + m.counts[k], 0);
|
|
205
|
-
return { component, status: status(component), create: sum("create"), update: sum("update"), replace: sum("replace"), delete: sum("delete") };
|
|
206
|
-
});
|
|
207
|
-
const digest = set.doc.digest;
|
|
208
|
-
if (set.failed) {
|
|
209
|
-
await finish(ctx, forge, { ...base, digest, status: "plan-failed", ...(p.hookFailed ? { message: p.hookFailed } : {}), components: rows((c) => (set.members.some((m) => m.component === c && m.status === "plan-failed") ? "plan failed" : "planned")) });
|
|
210
|
-
return PR_ENV_EXIT.failed;
|
|
211
|
-
}
|
|
212
|
-
// ws-080, ws-104: a non-empty plan applies only under a person's approval of its digest. An empty one passes.
|
|
213
|
-
let approvedBy;
|
|
214
|
-
if (!isEmptyChangeSet(set.doc)) {
|
|
215
|
-
let approval;
|
|
216
|
-
try {
|
|
217
|
-
approval = approvalOf(await decidePrGate(readOnlyLedger(gitGateLedgerPort()), { op, gate: PR_ENV_GATE, digest, description: `${derived.env}: ${p.plan.order.join(", ")}` }));
|
|
218
|
-
}
|
|
219
|
-
catch (err) {
|
|
220
|
-
return fail(`could not read the gate ledger, so ${derived.env} does not apply: ${err instanceof Error ? err.message : String(err)}`);
|
|
221
|
-
}
|
|
222
|
-
if (approval.status !== "approved") {
|
|
223
|
-
const status = approval.status === "changed" ? "changed" : "waiting";
|
|
224
|
-
await finish(ctx, forge, { ...base, digest, status, components: rows(() => "planned") });
|
|
225
|
-
console.error(formatInfo(`pr-env up: ${derived.env} waits for an approval of ${digest}`));
|
|
226
|
-
console.error(formatInfo(`approve : ${prEnvApproveCommand(op, digest)}`));
|
|
227
|
-
return PR_ENV_EXIT.waiting;
|
|
228
|
-
}
|
|
229
|
-
approvedBy = approval.approvedBy ?? [];
|
|
230
|
-
}
|
|
231
|
-
const hookStop = runStageHook(p, "before-apply", p.plan.order, set);
|
|
232
|
-
if (hookStop) {
|
|
233
|
-
await finish(ctx, forge, { ...base, digest, status: "failed", message: hookStop, components: rows(() => "planned"), ...(approvedBy ? { approvedBy } : {}) });
|
|
234
|
-
return PR_ENV_EXIT.failed;
|
|
235
|
-
}
|
|
236
|
-
const applied = await applyPrSet({ components: p.components, plan: p.plan, registry: p.registry, env: derived.env, set, gate: PR_ENV_GATE });
|
|
237
|
-
const afterHook = runStageHook(p, "after-apply", p.plan.order, set, "the environment stands as applied");
|
|
238
|
-
const status = (component) => applied.members.find((m) => m.component === component)?.status ?? "planned";
|
|
239
|
-
const ok = applied.status === "applied";
|
|
240
|
-
const now = new Date();
|
|
241
|
-
const expiresAt = new Date(now.getTime() + ttl).toISOString();
|
|
242
|
-
// A copy that failed part way is live too: what applied is torn down on close or at expiry like the rest.
|
|
243
|
-
await appendRecord(ctx, {
|
|
244
|
-
version: 1,
|
|
245
|
-
kind: "up",
|
|
246
|
-
pr,
|
|
247
|
-
env: derived.env,
|
|
248
|
-
...(p.member ? { member: p.member } : {}),
|
|
249
163
|
template: derived.template,
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
...(approvedBy ? { approvedBy } : {}),
|
|
259
|
-
releaseTarget: false,
|
|
260
|
-
...(forge?.runUrl ? { runUrl: forge.runUrl } : {}),
|
|
164
|
+
ttl,
|
|
165
|
+
stack: derived.stack,
|
|
166
|
+
...(p.member ? { member: p.member } : {}),
|
|
167
|
+
...(derived.endpoint ? { endpoint: derived.endpoint } : {}),
|
|
168
|
+
adapter: componentsPrEnvAdapter(p, { planAll, runStageHook }),
|
|
169
|
+
ports: cliPorts(ctx, p.forge),
|
|
170
|
+
actor: actor(),
|
|
171
|
+
...(p.forge?.runUrl ? { runUrl: p.forge.runUrl } : {}),
|
|
261
172
|
});
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
173
|
+
if (result.report.status === "waiting" || result.report.status === "changed")
|
|
174
|
+
console.error(formatInfo(`approve : ${prEnvApproveCommand(result.report.op, result.report.digest)}`));
|
|
175
|
+
return result.exit;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* The components as a pull request environment's adapter: the plan is
|
|
179
|
+
* `pr-plan`'s, with the plan-side hooks around it, and the apply is the
|
|
180
|
+
* fan-out's, with the apply-side hooks around it. Each row carries the
|
|
181
|
+
* component's site in `pr-<n>`, carried over from the template's (#4330,
|
|
182
|
+
* `prEnvironmentSite`).
|
|
183
|
+
*/
|
|
184
|
+
function componentsPrEnvAdapter(p, run) {
|
|
185
|
+
let set;
|
|
186
|
+
const rows = (target, status) => p.plan.order.map((component) => {
|
|
187
|
+
const ms = (set?.members ?? []).filter((m) => m.component === component);
|
|
188
|
+
const sum = (k) => ms.reduce((n, m) => n + m.counts[k], 0);
|
|
189
|
+
const found = prEnvironmentSite(p.sites?.[component], target.template, target.env);
|
|
190
|
+
const site = found ? { ...(found.runtime ? { runtime: found.runtime } : {}), ...(found.url ? { url: found.url } : {}), ...(found.domain ? { domain: found.domain } : {}) } : undefined;
|
|
191
|
+
return { component, status: status(component), create: sum("create"), update: sum("update"), replace: sum("replace"), delete: sum("delete"), ...(site && Object.keys(site).length > 0 ? { site } : {}) };
|
|
270
192
|
});
|
|
271
|
-
|
|
272
|
-
|
|
193
|
+
return {
|
|
194
|
+
async plan(target) {
|
|
195
|
+
if (p.plan.order.length === 0)
|
|
196
|
+
return { digest: "", empty: true, rows: [], ...(p.routedAway ? { message: p.routedAway } : {}) };
|
|
197
|
+
set = await run.planAll(p);
|
|
198
|
+
const planned = set;
|
|
199
|
+
return {
|
|
200
|
+
digest: planned.doc.digest,
|
|
201
|
+
empty: isEmptyChangeSet(planned.doc),
|
|
202
|
+
...(planned.failed ? { failed: true } : {}),
|
|
203
|
+
rows: rows(target, (c) => (planned.failed && planned.members.some((m) => m.component === c && m.status === "plan-failed") ? "plan failed" : "planned")),
|
|
204
|
+
...(p.hookFailed ? { message: p.hookFailed } : {}),
|
|
205
|
+
};
|
|
206
|
+
},
|
|
207
|
+
async apply(target) {
|
|
208
|
+
const planned = set;
|
|
209
|
+
const hookStop = run.runStageHook(p, "before-apply", p.plan.order, planned);
|
|
210
|
+
if (hookStop)
|
|
211
|
+
return { status: "stopped", rows: rows(target, () => "planned"), message: hookStop };
|
|
212
|
+
const applied = await applyPrSet({ components: p.components, plan: p.plan, registry: p.registry, env: target.env, set: planned, gate: PR_ENV_GATE });
|
|
213
|
+
const afterHook = run.runStageHook(p, "after-apply", p.plan.order, planned, "the environment stands as applied");
|
|
214
|
+
const status = (component) => applied.members.find((m) => m.component === component)?.status ?? "planned";
|
|
215
|
+
return {
|
|
216
|
+
status: applied.status === "applied" ? "applied" : applied.status === "waiting" ? "waiting" : "failed",
|
|
217
|
+
rows: rows(target, status),
|
|
218
|
+
...(afterHook ? { afterFailure: afterHook } : {}),
|
|
219
|
+
};
|
|
220
|
+
},
|
|
221
|
+
};
|
|
273
222
|
}
|
|
274
223
|
// ── post ───────────────────────────────────────────────────────────────────
|
|
275
224
|
/**
|
|
@@ -319,7 +268,7 @@ async function prEnvPost(ctx) {
|
|
|
319
268
|
code = PR_ENV_EXIT.failed;
|
|
320
269
|
}
|
|
321
270
|
else {
|
|
322
|
-
await
|
|
271
|
+
await lifecyclePrEnvPorts({ warn }).appendRecord(accepted.record);
|
|
323
272
|
if (accepted.record.expiresAt)
|
|
324
273
|
report.expiresAt = accepted.record.expiresAt;
|
|
325
274
|
}
|
|
@@ -329,6 +278,18 @@ async function prEnvPost(ctx) {
|
|
|
329
278
|
return code;
|
|
330
279
|
}
|
|
331
280
|
// ── down ───────────────────────────────────────────────────────────────────
|
|
281
|
+
/**
|
|
282
|
+
* What tears the environment down: the lexicons, and the command
|
|
283
|
+
* `ci.prEnvironment.teardown` names in the declaration at this commit
|
|
284
|
+
* (#4330), which the down and sweep jobs check out from the base branch.
|
|
285
|
+
*/
|
|
286
|
+
async function teardownSources() {
|
|
287
|
+
const projectPath = resolve(".");
|
|
288
|
+
const { config } = await loadChantConfig(projectPath).catch(() => ({ config: {} }));
|
|
289
|
+
const { scopeSource } = await import("../../workspace/write-scope.js");
|
|
290
|
+
const hook = scopeSource(projectPath, "HEAD").declaration?.ci?.prEnvironment?.teardown;
|
|
291
|
+
return { config, adapters: hook ? [commandTeardownAdapter(hook, { cwd: projectPath })] : [] };
|
|
292
|
+
}
|
|
332
293
|
async function prEnvDown(ctx) {
|
|
333
294
|
const { args } = ctx;
|
|
334
295
|
if (args.pr === undefined)
|
|
@@ -339,61 +300,21 @@ async function prEnvDown(ctx) {
|
|
|
339
300
|
const forge = forgeOf(ctx);
|
|
340
301
|
if (typeof forge === "number")
|
|
341
302
|
return forge;
|
|
342
|
-
const live = livePrEnvironments(await readRecords()).get(prEnvironmentName(args.pr));
|
|
343
|
-
return teardown(ctx, forge, args.pr, live, reason);
|
|
344
|
-
}
|
|
345
|
-
async function teardown(ctx, forge, pr, live, reason) {
|
|
346
|
-
const env = prEnvironmentName(pr);
|
|
347
303
|
const member = memberOf(ctx);
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
console.error(formatInfo(`pr-env down: ${env} has no live record, so there is nothing to tear down`));
|
|
351
|
-
if (forge)
|
|
352
|
-
await finish(ctx, forge, report);
|
|
353
|
-
return PR_ENV_EXIT.done;
|
|
354
|
-
}
|
|
355
|
-
const { config } = await loadChantConfig(resolve(".")).catch(() => ({ config: {} }));
|
|
356
|
-
const torn = await tearDownPrEnvironment({ pr, live, config, plugins: ctx.plugins, warn: (message) => console.error(formatWarning({ message })) });
|
|
357
|
-
if ("refusal" in torn) {
|
|
358
|
-
await finish(ctx, forge, { ...report, template: live.template, status: "refused", message: torn.refusal });
|
|
359
|
-
return fail(torn.refusal);
|
|
360
|
-
}
|
|
361
|
-
const { report: result, dropped, marker } = torn;
|
|
362
|
-
const counts = teardownCounts(result);
|
|
363
|
-
const complete = teardownComplete(result);
|
|
364
|
-
const lexicons = [...new Set(result.outcomes.map((o) => o.lexicon))].sort();
|
|
365
|
-
const head = await headCommit();
|
|
366
|
-
await appendRecord(ctx, {
|
|
367
|
-
version: 1,
|
|
368
|
-
kind: "down",
|
|
369
|
-
pr,
|
|
370
|
-
env,
|
|
371
|
-
...(live.member ? { member: live.member } : {}),
|
|
372
|
-
template: live.template,
|
|
373
|
-
marker,
|
|
374
|
-
commit: head,
|
|
375
|
-
components: lexicons,
|
|
376
|
-
planDigest: "",
|
|
377
|
-
result: complete ? "destroyed" : "incomplete",
|
|
378
|
-
by: actor(),
|
|
379
|
-
timestamp: new Date().toISOString(),
|
|
304
|
+
const result = await prEnvDownRun({
|
|
305
|
+
pr: args.pr,
|
|
380
306
|
reason,
|
|
381
|
-
|
|
382
|
-
|
|
307
|
+
...(member ? { member } : {}),
|
|
308
|
+
ports: cliPorts(ctx, forge),
|
|
309
|
+
...(await teardownSources()),
|
|
310
|
+
plugins: ctx.plugins,
|
|
311
|
+
commit: await headCommit(),
|
|
312
|
+
actor: actor(),
|
|
383
313
|
...(forge?.runUrl ? { runUrl: forge.runUrl } : {}),
|
|
384
314
|
});
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
if (result.unimplemented.length > 0)
|
|
389
|
-
why.push(`no teardown execution in ${result.unimplemented.join(", ")}`);
|
|
390
|
-
if (result.plan.holes.length > 0)
|
|
391
|
-
why.push(`${result.plan.holes.length} part${result.plan.holes.length === 1 ? "" : "s"} could not be read`);
|
|
392
|
-
for (const o of result.outcomes.filter((x) => x.outcome === "failed"))
|
|
393
|
-
why.push(`${o.lexicon} ${o.name}: ${o.detail ?? "failed"}`);
|
|
394
|
-
await finish(ctx, forge, { ...report, template: live.template, status: complete ? "destroyed" : "incomplete", outcomes: counts, ...(why.length > 0 ? { message: why.join("; ") } : {}) });
|
|
395
|
-
console.error((complete ? formatInfo : (m) => formatWarning({ message: m }))(`pr-env down: ${env} ${complete ? "torn down" : "not wholly torn down; it stays live and the sweep tries again"} (${counts.deleted} deleted, ${counts.failed} failed, ${counts.skipped} skipped)`));
|
|
396
|
-
return complete ? PR_ENV_EXIT.done : PR_ENV_EXIT.failed;
|
|
315
|
+
if (result.report.status === "refused")
|
|
316
|
+
return fail(result.report.message ?? "refused");
|
|
317
|
+
return result.exit;
|
|
397
318
|
}
|
|
398
319
|
async function headCommit() {
|
|
399
320
|
const { spawnSync } = await import("node:child_process");
|
|
@@ -405,32 +326,13 @@ async function prEnvSweep(ctx) {
|
|
|
405
326
|
const forge = forgeOf(ctx);
|
|
406
327
|
if (typeof forge === "number")
|
|
407
328
|
return forge;
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
if (!reason && forge?.pullRequestState) {
|
|
418
|
-
try {
|
|
419
|
-
const state = await forge.pullRequestState(e.pr);
|
|
420
|
-
if (state !== "open")
|
|
421
|
-
reason = "closed";
|
|
422
|
-
}
|
|
423
|
-
catch (err) {
|
|
424
|
-
console.error(formatWarning({ message: `could not read whether #${e.pr} is open (${err instanceof Error ? err.message : String(err)}); its TTL still holds` }));
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
if (!reason) {
|
|
428
|
-
console.error(formatInfo(`pr-env sweep: ${e.env} stays; it expires ${e.expiresAt}`));
|
|
429
|
-
continue;
|
|
430
|
-
}
|
|
431
|
-
const c = await teardown(ctx, forge, e.pr, e, reason);
|
|
432
|
-
if (c !== PR_ENV_EXIT.done)
|
|
433
|
-
code = PR_ENV_EXIT.failed;
|
|
434
|
-
}
|
|
435
|
-
return code;
|
|
329
|
+
const result = await prEnvSweepRun({
|
|
330
|
+
ports: cliPorts(ctx, forge),
|
|
331
|
+
...(await teardownSources()),
|
|
332
|
+
plugins: ctx.plugins,
|
|
333
|
+
commit: await headCommit(),
|
|
334
|
+
actor: actor(),
|
|
335
|
+
...(forge?.runUrl ? { runUrl: forge.runUrl } : {}),
|
|
336
|
+
});
|
|
337
|
+
return result.exit;
|
|
436
338
|
}
|
|
@@ -72,6 +72,7 @@ import type { CommandContext } from "../registry.js";
|
|
|
72
72
|
import type { ComponentChangeSignal, FanOutPlan } from "../../components/fan-out.js";
|
|
73
73
|
import { type DriverComponent } from "../../components/driver.js";
|
|
74
74
|
import type { CapabilityRegistry } from "../../components/capability.js";
|
|
75
|
+
import type { ComponentEnvironmentDeclaration } from "../../components/component.js";
|
|
75
76
|
import { type PrHookPlace, type PrLoopHooks } from "../../components/pr-hooks.js";
|
|
76
77
|
import { type PrLoopPolicy } from "../../components/pr-policy.js";
|
|
77
78
|
import type { OpWaveHookMoment } from "../../op/op-waves.js";
|
|
@@ -97,6 +98,8 @@ export interface Prepared {
|
|
|
97
98
|
signal: ComponentChangeSignal;
|
|
98
99
|
registry: CapabilityRegistry;
|
|
99
100
|
seededOutputs: Record<string, Record<string, unknown>>;
|
|
101
|
+
/** Component name to the environments it declares (#3153), whose sites `pr-env up` carries over (#4330). */
|
|
102
|
+
sites?: Record<string, ComponentEnvironmentDeclaration[]>;
|
|
100
103
|
/** `ci.hooks` from the declaration at base (#4288). */
|
|
101
104
|
hooks: PrLoopHooks;
|
|
102
105
|
/** Every hook the stage ran so far, for the report's `hooks`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pr.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/pr.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AAKH,OAAO,EAA+C,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAG7F,OAAO,EAYL,KAAK,SAAS,EACf,MAAM,yBAAyB,CAAC;AAQjC,OAAO,EAA0C,KAAK,YAAY,EAAuB,MAAM,wBAAwB,CAAC;AAIxH,OAAO,EAWL,KAAK,aAAa,EAElB,KAAK,cAAc,EAKpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAA+D,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAU3G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,KAAK,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAClF,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAA6B,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC1G,OAAO,EAA8F,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC3J,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,qDAAqD;AACrD,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,uDAAuD;IACvD,KAAK,EAAE,WAAW,CAAC;IACnB,iEAAiE;IACjE,YAAY,EAAE,aAAa,EAAE,CAAC;IAC9B,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,MAAM,EAAE,YAAY,CAAC;IACrB,sEAAsE;IACtE,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,8FAA8F;IAC9F,WAAW,CAAC,EAAE,aAAa,CAAC;CAC7B;AAOD,uJAAuJ;AACvJ,wBAAsB,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"pr.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/pr.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/handlers/pr.js
CHANGED
|
@@ -218,6 +218,7 @@ export async function prepare(ctx, stage) {
|
|
|
218
218
|
components: derived.components,
|
|
219
219
|
plan: routedAway ? { ...derived.plan, order: [], waves: [], seeds: [], indeterminate: [] } : derived.plan,
|
|
220
220
|
signal: derived.signal,
|
|
221
|
+
...(derived.sites ? { sites: derived.sites } : {}),
|
|
221
222
|
registry,
|
|
222
223
|
seededOutputs,
|
|
223
224
|
hooks,
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { GraphIR, IRNode } from "../../graph-ir.js";
|
|
2
|
+
import { terraformType } from "../../graph-effective.js";
|
|
3
|
+
export { terraformType };
|
|
4
|
+
/**
|
|
5
|
+
* `chant search --count-by <kind|module|attr:<name>>` (#4360): grouped counts
|
|
6
|
+
* over the matched set, one line per group, instead of one row per match.
|
|
7
|
+
*
|
|
8
|
+
* An agent asking "how many resources of each type does each module own" used
|
|
9
|
+
* to run one search per value, or read every row and count them itself. The
|
|
10
|
+
* second is the token cost `search` exists to avoid.
|
|
11
|
+
*
|
|
12
|
+
* Every matched node lands in exactly one group. A node with no value for the
|
|
13
|
+
* grouped dimension is counted under `(none)`, never dropped, so the groups
|
|
14
|
+
* always add up to the total line.
|
|
15
|
+
*/
|
|
16
|
+
export type CountBy = {
|
|
17
|
+
by: "kind";
|
|
18
|
+
} | {
|
|
19
|
+
by: "module";
|
|
20
|
+
} | {
|
|
21
|
+
by: "attr";
|
|
22
|
+
name: string;
|
|
23
|
+
};
|
|
24
|
+
/** The group a node with no value for the grouped dimension is counted under. */
|
|
25
|
+
export declare const NONE_GROUP = "(none)";
|
|
26
|
+
/** The module group of a Terraform block declared in the root module itself. */
|
|
27
|
+
export declare const ROOT_MODULE_GROUP = "(root)";
|
|
28
|
+
/** Parse a `--count-by` value, or say what the accepted spellings are. */
|
|
29
|
+
export declare function parseCountBy(raw: string): CountBy | {
|
|
30
|
+
error: string;
|
|
31
|
+
hint: string;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The group one node belongs to.
|
|
35
|
+
*
|
|
36
|
+
* `module` on a Terraform node is its call chain. When the graph holds more
|
|
37
|
+
* than one Terraform root, the chain is prefixed with the root (`app/(root)`,
|
|
38
|
+
* `net/module.vpc`): `module.vpc` in two roots is two modules, applied
|
|
39
|
+
* separately, and counting them as one would add up resources that never sit
|
|
40
|
+
* in the same state. A node of another lexicon groups under the composite that
|
|
41
|
+
* expanded it, chant's own unit of reuse, or `(none)`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function groupOf(n: IRNode, countBy: CountBy, multiRoot?: boolean): string;
|
|
44
|
+
/** Whether the graph holds blocks from more than one Terraform root. */
|
|
45
|
+
export declare function hasManyTerraformRoots(ir: GraphIR): boolean;
|
|
46
|
+
/** Count `matches` per group, sorted by count (highest first) and then by name. */
|
|
47
|
+
export declare function countGroups(matches: IRNode[], countBy: CountBy, multiRoot?: boolean): Array<{
|
|
48
|
+
group: string;
|
|
49
|
+
count: number;
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* The groups with the ids of the matches in each, in match order (#4382), in
|
|
53
|
+
* the order {@link countGroups} gives. `count` is always `ids.length`. A
|
|
54
|
+
* reader that draws the groups (behold#922) lights each group's nodes from
|
|
55
|
+
* `ids`, so it never has to read a node's group itself.
|
|
56
|
+
*/
|
|
57
|
+
export declare function groupMembers(matches: IRNode[], countBy: CountBy, multiRoot?: boolean): Array<{
|
|
58
|
+
group: string;
|
|
59
|
+
count: number;
|
|
60
|
+
ids: string[];
|
|
61
|
+
}>;
|
|
62
|
+
/** `--count-by` with `--json`: the groups, in printed order, each with its matched ids, and the total they add up to. */
|
|
63
|
+
export interface CountsJson {
|
|
64
|
+
query: string;
|
|
65
|
+
source: unknown;
|
|
66
|
+
countBy: string;
|
|
67
|
+
groups: Array<{
|
|
68
|
+
group: string;
|
|
69
|
+
count: number;
|
|
70
|
+
ids: string[];
|
|
71
|
+
}>;
|
|
72
|
+
total: number;
|
|
73
|
+
liveFailures?: string[];
|
|
74
|
+
}
|
|
75
|
+
export declare function countsJson(query: string, source: unknown, groups: Array<{
|
|
76
|
+
group: string;
|
|
77
|
+
count: number;
|
|
78
|
+
ids: string[];
|
|
79
|
+
}>, countBy: CountBy, liveFailures?: string[]): CountsJson;
|
|
80
|
+
/**
|
|
81
|
+
* Render grouped counts: one `<count> <group>` line per group, counts right
|
|
82
|
+
* aligned, then the total. The total is the number of matches, which is the
|
|
83
|
+
* sum of the group counts by construction.
|
|
84
|
+
*/
|
|
85
|
+
export declare function formatCounts(groups: Array<{
|
|
86
|
+
group: string;
|
|
87
|
+
count: number;
|
|
88
|
+
}>, countBy: CountBy): string[];
|
|
89
|
+
//# sourceMappingURL=search-count.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-count.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/search-count.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAItD,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,OAAO,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,QAAQ,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvF,iFAAiF;AACjF,eAAO,MAAM,UAAU,WAAW,CAAC;AACnC,gFAAgF;AAChF,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAE1C,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAUnF;AAiCD;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,UAAQ,GAAG,MAAM,CAQ9E;AAED,wEAAwE;AACxE,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAI1D;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,UAAQ,GAAG,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAE3H;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,UAAQ,GAAG,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAW3I;AAED,yHAAyH;AACzH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,EAC9D,OAAO,EAAE,OAAO,EAChB,YAAY,GAAE,MAAM,EAAO,GAC1B,UAAU,CASZ;AAOD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,CAMxG"}
|