@intentius/chant-lexicon-terraform 0.124.51 → 0.124.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -6
- package/dist/__fixtures__/pr-loop/estate.component.d.ts +7 -0
- package/dist/__fixtures__/pr-loop/estate.component.d.ts.map +1 -0
- package/dist/__fixtures__/pr-loop/estate.component.js +7 -0
- package/dist/__fixtures__/report/generate.d.ts +26 -0
- package/dist/__fixtures__/report/generate.d.ts.map +1 -0
- package/dist/__fixtures__/report/generate.js +58 -0
- package/dist/applied-state.d.ts +27 -0
- package/dist/applied-state.d.ts.map +1 -0
- package/dist/applied-state.js +44 -0
- package/dist/backend-config.d.ts +53 -0
- package/dist/backend-config.d.ts.map +1 -0
- package/dist/backend-config.js +136 -0
- package/dist/behaviour/kinds.d.ts.map +1 -1
- package/dist/behaviour/kinds.js +4 -0
- package/dist/behaviour/predict.d.ts.map +1 -1
- package/dist/behaviour/predict.js +6 -2
- package/dist/behaviour/reference-catalog.d.ts +16 -5
- package/dist/behaviour/reference-catalog.d.ts.map +1 -1
- package/dist/behaviour/reference-catalog.js +16 -5
- package/dist/behaviour/request.d.ts.map +1 -1
- package/dist/behaviour/request.js +3 -2
- package/dist/changed-roots.d.ts +6 -4
- package/dist/changed-roots.d.ts.map +1 -1
- package/dist/changed-roots.js +14 -18
- package/dist/commands.d.ts +5 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +87 -4
- package/dist/components/capability-plugin.d.ts +65 -3
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/components/capability-plugin.js +197 -13
- package/dist/components/compose-group.d.ts +145 -0
- package/dist/components/compose-group.d.ts.map +1 -0
- package/dist/components/compose-group.js +407 -0
- package/dist/components/placeholder-preview.d.ts +78 -0
- package/dist/components/placeholder-preview.d.ts.map +1 -0
- package/dist/components/placeholder-preview.js +254 -0
- package/dist/compose/apply-events.d.ts +46 -0
- package/dist/compose/apply-events.d.ts.map +1 -0
- package/dist/compose/apply-events.js +77 -0
- package/dist/compose/estate.d.ts +194 -0
- package/dist/compose/estate.d.ts.map +1 -0
- package/dist/compose/estate.js +363 -0
- package/dist/compose/hcl.d.ts +99 -0
- package/dist/compose/hcl.d.ts.map +1 -0
- package/dist/compose/hcl.js +302 -0
- package/dist/compose/module-address.d.ts +24 -0
- package/dist/compose/module-address.d.ts.map +1 -0
- package/dist/compose/module-address.js +43 -0
- package/dist/compose/root.d.ts +127 -0
- package/dist/compose/root.d.ts.map +1 -0
- package/dist/compose/root.js +586 -0
- package/dist/compose/run.d.ts +183 -0
- package/dist/compose/run.d.ts.map +1 -0
- package/dist/compose/run.js +447 -0
- package/dist/compose/slice.d.ts +102 -0
- package/dist/compose/slice.d.ts.map +1 -0
- package/dist/compose/slice.js +249 -0
- package/dist/compose/state-address.d.ts +28 -0
- package/dist/compose/state-address.d.ts.map +1 -0
- package/dist/compose/state-address.js +154 -0
- package/dist/compose/state-merge.d.ts +52 -0
- package/dist/compose/state-merge.d.ts.map +1 -0
- package/dist/compose/state-merge.js +135 -0
- package/dist/compose.d.ts +179 -0
- package/dist/compose.d.ts.map +1 -0
- package/dist/compose.js +482 -0
- package/dist/composites/terraform-apply-op.d.ts.map +1 -1
- package/dist/composites/terraform-apply-op.js +7 -3
- package/dist/config.d.ts +59 -13
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +43 -9
- package/dist/describe-resources.d.ts +74 -12
- package/dist/describe-resources.d.ts.map +1 -1
- package/dist/describe-resources.js +374 -66
- package/dist/drift-read.d.ts +33 -0
- package/dist/drift-read.d.ts.map +1 -0
- package/dist/drift-read.js +243 -0
- package/dist/drift-record.d.ts +147 -0
- package/dist/drift-record.d.ts.map +1 -0
- package/dist/drift-record.js +383 -0
- package/dist/hcl/edges.d.ts.map +1 -1
- package/dist/hcl/edges.js +24 -1
- package/dist/hcl/files.d.ts +61 -0
- package/dist/hcl/files.d.ts.map +1 -0
- package/dist/hcl/files.js +221 -0
- package/dist/hcl/instances.d.ts +82 -0
- package/dist/hcl/instances.d.ts.map +1 -0
- package/dist/hcl/instances.js +390 -0
- package/dist/hcl/parse.d.ts +81 -9
- package/dist/hcl/parse.d.ts.map +1 -1
- package/dist/hcl/parse.js +114 -16
- package/dist/hcl/roots.d.ts.map +1 -1
- package/dist/hcl/roots.js +5 -0
- package/dist/hcl/suppressions.d.ts.map +1 -1
- package/dist/hcl/suppressions.js +8 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -2
- package/dist/integrity.json +3 -3
- package/dist/live-plan-reasons.d.ts +21 -0
- package/dist/live-plan-reasons.d.ts.map +1 -0
- package/dist/live-plan-reasons.js +47 -0
- package/dist/lsp/option-keys.d.ts.map +1 -1
- package/dist/lsp/option-keys.js +2 -0
- package/dist/manifest.json +1 -1
- package/dist/op/activities/index.d.ts +6 -2
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/index.js +5 -1
- package/dist/op/activities/live-detect.d.ts +4 -3
- package/dist/op/activities/live-detect.d.ts.map +1 -1
- package/dist/op/activities/live-detect.js +57 -32
- package/dist/op/activities/pin-rollout.d.ts +2 -0
- package/dist/op/activities/pin-rollout.d.ts.map +1 -1
- package/dist/op/activities/pin-rollout.js +1 -0
- package/dist/op/activities/terraform.d.ts +153 -5
- package/dist/op/activities/terraform.d.ts.map +1 -1
- package/dist/op/activities/terraform.js +205 -20
- package/dist/op/activity-contracts.d.ts +27 -0
- package/dist/op/activity-contracts.d.ts.map +1 -1
- package/dist/op/activity-contracts.js +19 -1
- package/dist/op/builders.d.ts +7 -1
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/builders.js +9 -0
- package/dist/pin/edit.d.ts.map +1 -1
- package/dist/pin/edit.js +35 -0
- package/dist/pin/rollout.d.ts +2 -0
- package/dist/pin/rollout.d.ts.map +1 -1
- package/dist/pin/rollout.js +14 -11
- package/dist/plan-shape.d.ts +30 -0
- package/dist/plan-shape.d.ts.map +1 -0
- package/dist/plan-shape.js +125 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +32 -18
- package/dist/report.d.ts +216 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +666 -0
- package/dist/skills/chant-terraform.md +1 -1
- package/dist/state/azure-blob.d.ts +68 -0
- package/dist/state/azure-blob.d.ts.map +1 -0
- package/dist/state/azure-blob.js +201 -0
- package/dist/state/backend.d.ts +158 -0
- package/dist/state/backend.d.ts.map +1 -0
- package/dist/state/backend.js +406 -0
- package/dist/state/exec.d.ts +39 -0
- package/dist/state/exec.d.ts.map +1 -0
- package/dist/state/exec.js +80 -0
- package/dist/state/gcs.d.ts +62 -0
- package/dist/state/gcs.d.ts.map +1 -0
- package/dist/state/gcs.js +224 -0
- package/dist/state/index.d.ts +15 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +14 -0
- package/dist/state/locks.d.ts +105 -0
- package/dist/state/locks.d.ts.map +1 -0
- package/dist/state/locks.js +130 -0
- package/dist/state/object-store.d.ts +37 -0
- package/dist/state/object-store.d.ts.map +1 -0
- package/dist/state/object-store.js +20 -0
- package/dist/state/root-states.d.ts +131 -0
- package/dist/state/root-states.d.ts.map +1 -0
- package/dist/state/root-states.js +241 -0
- package/dist/state/s3.d.ts +68 -0
- package/dist/state/s3.d.ts.map +1 -0
- package/dist/state/s3.js +170 -0
- package/dist/state/store.d.ts +51 -0
- package/dist/state/store.d.ts.map +1 -0
- package/dist/state/store.js +185 -0
- package/dist/terragrunt/affected.d.ts.map +1 -1
- package/dist/terragrunt/affected.js +2 -1
- package/package.json +7 -3
- package/src/__fixtures__/ACCEPTANCE.md +69 -7
- package/src/__fixtures__/compose/apply-failed-in-app.jsonl +12 -0
- package/src/__fixtures__/compose/state-app.json +66 -0
- package/src/__fixtures__/compose/state-edge.json +40 -0
- package/src/__fixtures__/compose/state-net.json +58 -0
- package/src/__fixtures__/compose/three-app.plan.json +184 -0
- package/src/__fixtures__/compose/three-composed.plan.json +509 -0
- package/src/__fixtures__/compose/three-edge.plan.json +144 -0
- package/src/__fixtures__/compose/three-net.plan.json +174 -0
- package/src/__fixtures__/compose/unknown-composed.plan.json +228 -0
- package/src/__fixtures__/compose/working-after-apply.json +145 -0
- package/src/__fixtures__/config-blocks/app/main.tf +61 -0
- package/src/__fixtures__/config-blocks/app/modules/network/main.tf +4 -0
- package/src/__fixtures__/config-blocks/app-json/main.tf.json +39 -0
- package/src/__fixtures__/config-files/shadow/main.tf +3 -0
- package/src/__fixtures__/config-files/shadow/main.tofu +3 -0
- package/src/__fixtures__/config-files/shadow/other.tf +3 -0
- package/src/__fixtures__/config-files/tf/main.tf +11 -0
- package/src/__fixtures__/config-files/tf-json/main.tf.json +18 -0
- package/src/__fixtures__/config-files/tofu/main.tofu +11 -0
- package/src/__fixtures__/config-files/tofu-json/main.tofu.json +18 -0
- package/src/__fixtures__/config-files/tofu-only/main.tofu +3 -0
- package/src/__fixtures__/drift-record/README.md +11 -0
- package/src/__fixtures__/drift-record/live-plan-sections.json +27 -0
- package/src/__fixtures__/instance-forms/app/main.tf +110 -0
- package/src/__fixtures__/instance-forms/app/modules/svc/main.tf +3 -0
- package/src/__fixtures__/instance-vars/app/main.tf +52 -0
- package/src/__fixtures__/instance-vars/app/modules/app/main.tf +12 -0
- package/src/__fixtures__/instance-vars/app/modules/edge/main.tf +3 -0
- package/src/__fixtures__/instance-vars/app/terraform.tfvars +1 -0
- package/src/__fixtures__/live-module-keyed/live-graph.json +259 -0
- package/src/__fixtures__/live-module-keyed/live-plan.json +87 -0
- package/src/__fixtures__/live-module-keyed/root/estate.chdf.hcl +1 -0
- package/src/__fixtures__/live-module-keyed/root/main.tf +21 -0
- package/src/__fixtures__/live-module-keyed/root/modules/app/main.tf +17 -0
- package/src/__fixtures__/live-module-keyed/root/modules/edge/main.tf +7 -0
- package/src/__fixtures__/live-module-keyed/root/versions.tf +30 -0
- package/src/__fixtures__/live-module-keyed/show-state.json +146 -0
- package/src/__fixtures__/pr-loop/README.md +50 -0
- package/src/__fixtures__/pr-loop/chant.config.json +13 -0
- package/src/__fixtures__/pr-loop/estate.component.ts +10 -0
- package/src/__fixtures__/pr-loop/roots/a/main.tf +11 -0
- package/src/__fixtures__/pr-loop/roots/app/main.tf +19 -0
- package/src/__fixtures__/pr-loop/roots/b/main.tf +7 -0
- package/src/__fixtures__/pr-loop/roots/dns/main.tf +3 -0
- package/src/__fixtures__/pr-loop/roots/net/main.tf +7 -0
- package/src/__fixtures__/report/applied.show.json +51 -0
- package/src/__fixtures__/report/generate.ts +63 -0
- package/src/__fixtures__/report/plan.show.json +200 -0
- package/src/__fixtures__/report/tf-apply/change-set.json +170 -0
- package/src/__fixtures__/report/tf-apply/report.json +338 -0
- package/src/__fixtures__/report/tf-plan/change-set.json +170 -0
- package/src/__fixtures__/report/tf-plan/report.json +320 -0
- package/src/__fixtures__/three-cloud-azure.graph.json +290 -0
- package/src/applied-state.ts +52 -0
- package/src/backend-config.test.ts +105 -0
- package/src/backend-config.ts +133 -0
- package/src/behaviour/kinds.ts +4 -0
- package/src/behaviour/predict.ts +5 -2
- package/src/behaviour/reference-catalog.plugin.test.ts +65 -0
- package/src/behaviour/reference-catalog.ts +16 -5
- package/src/behaviour/request.ts +3 -2
- package/src/change-set-instances.test.ts +98 -0
- package/src/changed-roots.ts +14 -16
- package/src/commands.ts +84 -4
- package/src/components/capability-plugin.test.ts +172 -5
- package/src/components/capability-plugin.ts +212 -11
- package/src/components/change-set-graph.e2e.test.ts +11 -5
- package/src/components/compose-group.test.ts +486 -0
- package/src/components/compose-group.ts +489 -0
- package/src/components/demo-composed-roots.e2e.test.ts +440 -0
- package/src/components/member-outputs.test.ts +76 -0
- package/src/components/placeholder-preview.test.ts +147 -0
- package/src/components/placeholder-preview.ts +257 -0
- package/src/components/pr-loop-compose.tofu.e2e.test.ts +363 -0
- package/src/components/pr-loop.tofu.test.ts +112 -56
- package/src/compose/apply-events.test.ts +62 -0
- package/src/compose/apply-events.ts +100 -0
- package/src/compose/estate.choudoufu.e2e.test.ts +112 -0
- package/src/compose/estate.test.ts +421 -0
- package/src/compose/estate.ts +443 -0
- package/src/compose/hcl.ts +311 -0
- package/src/compose/module-address.ts +49 -0
- package/src/compose/root.test.ts +416 -0
- package/src/compose/root.ts +592 -0
- package/src/compose/run.test.ts +440 -0
- package/src/compose/run.tofu.test.ts +176 -0
- package/src/compose/run.ts +527 -0
- package/src/compose/slice.test.ts +184 -0
- package/src/compose/slice.ts +290 -0
- package/src/compose/state-address.ts +157 -0
- package/src/compose/state-merge.test.ts +131 -0
- package/src/compose/state-merge.ts +148 -0
- package/src/compose.test.ts +248 -0
- package/src/compose.ts +627 -0
- package/src/composites/terraform-apply-op.test.ts +9 -0
- package/src/composites/terraform-apply-op.ts +7 -3
- package/src/composites/terraform-pin-rollout-op.test.ts +2 -2
- package/src/config-file-listers.test.ts +265 -0
- package/src/config.ts +44 -9
- package/src/describe-resources.engine-facts.test.ts +412 -0
- package/src/describe-resources.live-module-keyed.test.ts +290 -0
- package/src/describe-resources.ts +416 -70
- package/src/drift-read.ts +284 -0
- package/src/drift-record.test.ts +223 -0
- package/src/drift-record.ts +455 -0
- package/src/hcl/config-blocks.test.ts +174 -0
- package/src/hcl/edges.ts +21 -1
- package/src/hcl/files.ts +234 -0
- package/src/hcl/instance-forms.test.ts +94 -0
- package/src/hcl/instances.test.ts +137 -0
- package/src/hcl/instances.ts +422 -0
- package/src/hcl/parse.test.ts +139 -1
- package/src/hcl/parse.ts +149 -16
- package/src/hcl/roots.ts +6 -0
- package/src/hcl/suppressions.ts +8 -2
- package/src/index.ts +76 -0
- package/src/live-plan-reasons.ts +54 -0
- package/src/lsp/completions.test.ts +1 -1
- package/src/lsp/option-keys.ts +2 -0
- package/src/op/activities/choudoufu-plan-set-op.test.ts +111 -0
- package/src/op/activities/index.ts +9 -0
- package/src/op/activities/live-detect.ts +55 -26
- package/src/op/activities/pin-rollout.ts +3 -0
- package/src/op/activities/registry.test.ts +2 -1
- package/src/op/activities/terraform.test.ts +55 -0
- package/src/op/activities/terraform.ts +266 -22
- package/src/op/activity-contracts.test.ts +1 -0
- package/src/op/activity-contracts.ts +24 -1
- package/src/op/builders.ts +14 -0
- package/src/pin/bundle.test.ts +2 -0
- package/src/pin/edit.ts +30 -0
- package/src/pin/rollout.ts +16 -11
- package/src/plan-shape.test.ts +148 -0
- package/src/plan-shape.ts +128 -0
- package/src/plugin.ts +33 -19
- package/src/report.test.ts +423 -0
- package/src/report.ts +752 -0
- package/src/signal-only-root.test.ts +72 -0
- package/src/skills/chant-terraform.md +1 -1
- package/src/state/azure-blob.ts +223 -0
- package/src/state/backend-verdict.test.ts +187 -0
- package/src/state/backend.test.ts +127 -0
- package/src/state/backend.ts +488 -0
- package/src/state/exec.ts +111 -0
- package/src/state/gcs.ts +254 -0
- package/src/state/index.ts +15 -0
- package/src/state/locks.test.ts +84 -0
- package/src/state/locks.ts +201 -0
- package/src/state/object-store.ts +35 -0
- package/src/state/root-states-floci.e2e.test.ts +66 -0
- package/src/state/root-states.test.ts +462 -0
- package/src/state/root-states.ts +309 -0
- package/src/state/s3.ts +193 -0
- package/src/state/store.ts +225 -0
- package/src/terragrunt/affected.ts +2 -1
- package/src/workspace-kinds.test.ts +4 -17
- package/workspace-kinds.json +1 -24
- package/dist/workspace-member.d.ts +0 -30
- package/dist/workspace-member.d.ts.map +0 -1
- package/dist/workspace-member.js +0 -91
- package/schemas/pulumi.schema.json +0 -34
- package/src/testdata/pulumi-member/Pulumi.yaml +0 -2
- package/src/testdata/pulumi-member/stack-export.json +0 -53
- package/src/testdata/pulumi-unexported/Pulumi.yaml +0 -2
- package/src/workspace-member.test.ts +0 -89
- package/src/workspace-member.ts +0 -126
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which files of a directory are a root's configuration, and how a JSON-syntax
|
|
3
|
+
* one reads (chant#4457). Every lister in the lexicon asks here, so the parser,
|
|
4
|
+
* change detection, the backend readers, the report and the rollout pin all
|
|
5
|
+
* see the same file set for one root.
|
|
6
|
+
*
|
|
7
|
+
* The set follows the root's binary. Terraform reads `.tf` and `.tf.json`.
|
|
8
|
+
* OpenTofu (and choudoufu, which is OpenTofu) also reads `.tofu` and
|
|
9
|
+
* `.tofu.json`, and when `x.tofu` and `x.tf` both exist it reads `x.tofu`
|
|
10
|
+
* only (likewise `x.tofu.json` over `x.tf.json`). A binary that is not given
|
|
11
|
+
* is `terraform`, the config's default.
|
|
12
|
+
*
|
|
13
|
+
* `parse.ts` re-exports all of this; the module is separate so the readers
|
|
14
|
+
* that never parse HCL (`state/backend.ts`, `changed-roots.ts`) do not load
|
|
15
|
+
* the parser's dependencies.
|
|
16
|
+
*/
|
|
17
|
+
import { readdirSync, statSync } from "node:fs";
|
|
18
|
+
import { join } from "node:path";
|
|
19
|
+
/** The configuration file suffixes Terraform reads. */
|
|
20
|
+
export const TERRAFORM_SUFFIXES = [".tf", ".tf.json"];
|
|
21
|
+
/** The ones OpenTofu reads as well. */
|
|
22
|
+
export const TOFU_SUFFIXES = [".tofu", ".tofu.json"];
|
|
23
|
+
/** Whether a root run by `binary` reads `.tofu` files: `tofu` and `choudoufu` do (by name or path), `terraform` and an unset binary do not. */
|
|
24
|
+
export function readsTofuFiles(binary) {
|
|
25
|
+
const base = (binary ?? "terraform").split(/[\\/]/).pop() ?? "";
|
|
26
|
+
return base.startsWith("tofu") || base.startsWith("choudoufu");
|
|
27
|
+
}
|
|
28
|
+
/** Whether `name` is a configuration file in Terraform's JSON syntax (`.tf.json`, `.tofu.json`). */
|
|
29
|
+
export function isJsonConfigFile(name) {
|
|
30
|
+
return name.endsWith(".tf.json") || name.endsWith(".tofu.json");
|
|
31
|
+
}
|
|
32
|
+
/** Whether `name` is a `.tofu` or `.tofu.json` file. */
|
|
33
|
+
export function isTofuConfigFile(name) {
|
|
34
|
+
return TOFU_SUFFIXES.some((s) => name.endsWith(s));
|
|
35
|
+
}
|
|
36
|
+
/** Whether `name` is a configuration file a root run by `binary` reads, before the `.tofu`-over-`.tf` rule. */
|
|
37
|
+
export function isConfigFileFor(name, binary) {
|
|
38
|
+
if (TERRAFORM_SUFFIXES.some((s) => name.endsWith(s)))
|
|
39
|
+
return true;
|
|
40
|
+
return readsTofuFiles(binary) && isTofuConfigFile(name);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The configuration files among `names` a root run by `binary` reads, in
|
|
44
|
+
* filename order. For a tofu or choudoufu root, `x.tf` is dropped when
|
|
45
|
+
* `x.tofu` is present and `x.tf.json` when `x.tofu.json` is, which is
|
|
46
|
+
* OpenTofu's own rule. Names may carry a directory; the rule compares names
|
|
47
|
+
* in the same directory.
|
|
48
|
+
*/
|
|
49
|
+
export function selectConfigFiles(names, binary) {
|
|
50
|
+
const kept = [...names].filter((n) => isConfigFileFor(n, binary));
|
|
51
|
+
const present = new Set(kept);
|
|
52
|
+
return kept
|
|
53
|
+
.filter((n) => {
|
|
54
|
+
if (n.endsWith(".tf"))
|
|
55
|
+
return !present.has(`${n.slice(0, -".tf".length)}.tofu`);
|
|
56
|
+
if (n.endsWith(".tf.json"))
|
|
57
|
+
return !present.has(`${n.slice(0, -".tf.json".length)}.tofu.json`);
|
|
58
|
+
return true;
|
|
59
|
+
})
|
|
60
|
+
.sort();
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The configuration files directly under `dir` a root run by `binary` reads,
|
|
64
|
+
* by name, in filename order. Non-recursive, matching Terraform's module
|
|
65
|
+
* scoping; directories named like a file are left out. Throws when `dir`
|
|
66
|
+
* cannot be read.
|
|
67
|
+
*/
|
|
68
|
+
export function listConfigFiles(dir, binary) {
|
|
69
|
+
const files = readdirSync(dir).filter((n) => {
|
|
70
|
+
if (!isConfigFileFor(n, binary))
|
|
71
|
+
return false;
|
|
72
|
+
try {
|
|
73
|
+
return statSync(join(dir, n)).isFile();
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return selectConfigFiles(files, binary);
|
|
80
|
+
}
|
|
81
|
+
/** {@link listConfigFiles}, empty when `dir` cannot be read. */
|
|
82
|
+
export function listConfigFilesSafe(dir, binary) {
|
|
83
|
+
try {
|
|
84
|
+
return listConfigFiles(dir, binary);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const LIFECYCLE = { labels: 0, exprs: ["ignore_changes", "replace_triggered_by"] };
|
|
91
|
+
const RESOURCE_NESTED = {
|
|
92
|
+
lifecycle: LIFECYCLE,
|
|
93
|
+
provisioner: { labels: 1, nested: { connection: { labels: 0 } } },
|
|
94
|
+
connection: { labels: 0 },
|
|
95
|
+
};
|
|
96
|
+
const REFERS = ["provider", "depends_on"];
|
|
97
|
+
const TOP_LEVEL = {
|
|
98
|
+
terraform: {
|
|
99
|
+
labels: 0,
|
|
100
|
+
nested: {
|
|
101
|
+
backend: { labels: 1 },
|
|
102
|
+
cloud: { labels: 0, nested: { workspaces: { labels: 0 } } },
|
|
103
|
+
required_providers: { labels: 0 },
|
|
104
|
+
provider_meta: { labels: 1 },
|
|
105
|
+
live: { labels: 0 },
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
locals: { labels: 0 },
|
|
109
|
+
provider: { labels: 1 },
|
|
110
|
+
module: { labels: 1, exprs: ["depends_on", "providers"] },
|
|
111
|
+
variable: { labels: 1, nested: { validation: { labels: 0 } }, exprs: ["type"] },
|
|
112
|
+
output: { labels: 1, nested: { precondition: { labels: 0 } }, exprs: ["depends_on"] },
|
|
113
|
+
resource: { labels: 2, nested: RESOURCE_NESTED, exprs: REFERS },
|
|
114
|
+
data: { labels: 2, nested: { lifecycle: LIFECYCLE }, exprs: REFERS },
|
|
115
|
+
moved: { labels: 0, exprs: ["from", "to"] },
|
|
116
|
+
import: { labels: 0, exprs: ["to", "provider"] },
|
|
117
|
+
removed: { labels: 0, nested: { lifecycle: LIFECYCLE, provisioner: RESOURCE_NESTED.provisioner }, exprs: ["from"] },
|
|
118
|
+
check: { labels: 1, nested: { data: { labels: 2 }, assert: { labels: 0 } } },
|
|
119
|
+
};
|
|
120
|
+
const isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
121
|
+
/** A bare expression string as hcl2json writes the expression: `aws.west` becomes `${aws.west}`; a template is kept. */
|
|
122
|
+
function asExpression(v) {
|
|
123
|
+
if (typeof v === "string")
|
|
124
|
+
return v.includes("${") ? v : `\${${v}}`;
|
|
125
|
+
if (Array.isArray(v))
|
|
126
|
+
return v.map(asExpression);
|
|
127
|
+
if (isObject(v))
|
|
128
|
+
return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, asExpression(x)]));
|
|
129
|
+
return v;
|
|
130
|
+
}
|
|
131
|
+
/** A JSON body with its `"//"` comment keys dropped (Terraform ignores them), its known nested blocks wrapped and its expression attributes written as hcl2json writes them. */
|
|
132
|
+
function normaliseBody(body, shape) {
|
|
133
|
+
const out = {};
|
|
134
|
+
if (!isObject(body))
|
|
135
|
+
return out;
|
|
136
|
+
for (const [k, v] of Object.entries(body)) {
|
|
137
|
+
if (k === "//")
|
|
138
|
+
continue;
|
|
139
|
+
const inner = shape.nested?.[k];
|
|
140
|
+
out[k] = inner ? wrapBlock(v, inner) : shape.exprs?.includes(k) ? asExpression(v) : v;
|
|
141
|
+
}
|
|
142
|
+
return out;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* A block in JSON syntax as hcl2json gives the same block in HCL: one object
|
|
146
|
+
* level per label, then an array of bodies. JSON syntax writes a single body
|
|
147
|
+
* as an object or several as an array, and allows an array of objects at a
|
|
148
|
+
* label level to be merged, so both are read.
|
|
149
|
+
*/
|
|
150
|
+
function wrapBlock(value, shape, labels = shape.labels) {
|
|
151
|
+
if (labels === 0)
|
|
152
|
+
return (Array.isArray(value) ? value : [value]).filter(isObject).map((b) => normaliseBody(b, shape));
|
|
153
|
+
const out = {};
|
|
154
|
+
for (const part of Array.isArray(value) ? value : [value]) {
|
|
155
|
+
if (!isObject(part))
|
|
156
|
+
continue;
|
|
157
|
+
for (const [label, inner] of Object.entries(part)) {
|
|
158
|
+
if (label === "//")
|
|
159
|
+
continue;
|
|
160
|
+
const wrapped = wrapBlock(inner, shape, labels - 1);
|
|
161
|
+
const had = out[label];
|
|
162
|
+
if (Array.isArray(had) && Array.isArray(wrapped))
|
|
163
|
+
out[label] = [...had, ...wrapped];
|
|
164
|
+
else if (isObject(had) && isObject(wrapped))
|
|
165
|
+
out[label] = mergeLabelled(had, wrapped);
|
|
166
|
+
else
|
|
167
|
+
out[label] = wrapped;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return out;
|
|
171
|
+
}
|
|
172
|
+
function mergeLabelled(a, b) {
|
|
173
|
+
const out = { ...a };
|
|
174
|
+
for (const [k, v] of Object.entries(b)) {
|
|
175
|
+
const had = out[k];
|
|
176
|
+
if (Array.isArray(had) && Array.isArray(v))
|
|
177
|
+
out[k] = [...had, ...v];
|
|
178
|
+
else if (isObject(had) && isObject(v))
|
|
179
|
+
out[k] = mergeLabelled(had, v);
|
|
180
|
+
else
|
|
181
|
+
out[k] = v;
|
|
182
|
+
}
|
|
183
|
+
return out;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* A `.tf.json` or `.tofu.json` document in the tree shape hcl2json gives an
|
|
187
|
+
* HCL file, so `blocksToEntities` reads both the same way. Top-level keys it
|
|
188
|
+
* does not know are kept as written. Throws on malformed JSON, as hcl2json
|
|
189
|
+
* throws on malformed HCL.
|
|
190
|
+
*/
|
|
191
|
+
export function jsonConfigTree(source) {
|
|
192
|
+
const doc = JSON.parse(source);
|
|
193
|
+
if (!isObject(doc))
|
|
194
|
+
throw new Error("a JSON configuration file must hold an object");
|
|
195
|
+
const out = {};
|
|
196
|
+
for (const [k, v] of Object.entries(doc)) {
|
|
197
|
+
if (k === "//")
|
|
198
|
+
continue;
|
|
199
|
+
const shape = TOP_LEVEL[k];
|
|
200
|
+
out[k] = shape ? wrapBlock(v, shape) : v;
|
|
201
|
+
}
|
|
202
|
+
return out;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* The bodies of the `live` blocks nested in the `terraform` blocks of a
|
|
206
|
+
* `.tf.json` or `.tofu.json` document, in the order written (chant#4504).
|
|
207
|
+
* The fast live readers (`report.ts`'s `estateOfDir`, `op/activities/live-detect.ts`)
|
|
208
|
+
* read HCL by text and a JSON file through this. Malformed JSON reads as no
|
|
209
|
+
* `live` block, as those readers treat any file they cannot read.
|
|
210
|
+
*/
|
|
211
|
+
export function jsonLiveBlocks(source) {
|
|
212
|
+
let tree;
|
|
213
|
+
try {
|
|
214
|
+
tree = jsonConfigTree(source);
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
return [];
|
|
218
|
+
}
|
|
219
|
+
const terraform = Array.isArray(tree.terraform) ? tree.terraform : [];
|
|
220
|
+
return terraform.flatMap((t) => (isObject(t) && Array.isArray(t.live) ? t.live.filter(isObject) : []));
|
|
221
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Instance nodes the declared graph can count from variables, and instance
|
|
3
|
+
* nodes under expanded module calls (chant #4486).
|
|
4
|
+
*
|
|
5
|
+
* `./parse.ts` gives a block its `instanceKeys` when its `count` or
|
|
6
|
+
* `for_each` is a literal (#4454). This pass runs once a root and its child
|
|
7
|
+
* modules are parsed and adds two cases that need the whole root:
|
|
8
|
+
*
|
|
9
|
+
* - An expansion that reads a variable, `count = var.n`, gets its keys when
|
|
10
|
+
* the variable's value is known from the files a plan would read: the
|
|
11
|
+
* `variable` block's `default`, then `terraform.tfvars`,
|
|
12
|
+
* `terraform.tfvars.json`, `*.auto.tfvars(.json)` in filename order, then
|
|
13
|
+
* `terraform.roots.<name>.varFiles`, later over earlier. In a child module
|
|
14
|
+
* the value is the call's argument, when it is a literal or a `var.x`
|
|
15
|
+
* known in the caller, else the child variable's default when the call
|
|
16
|
+
* passes nothing. `TF_CLI_ARGS` is not read, so the declared graph does not
|
|
17
|
+
* change with the environment the build runs in.
|
|
18
|
+
* - A block under a module call that is itself expanded gets one instance
|
|
19
|
+
* per module instance (times its own instances), with the module key on
|
|
20
|
+
* the call's segment: `estate/module.app[0]/aws_eip.pool[1]`. The entity
|
|
21
|
+
* lists those as `instances` (full ids), which core's `withInstanceNodes`
|
|
22
|
+
* reads in place of `instanceKeys` (`@intentius/chant/instance-nodes`
|
|
23
|
+
* holds the id rule). A module call with a countable expansion gets
|
|
24
|
+
* instance nodes of its own, `estate/module.app[0]`.
|
|
25
|
+
*
|
|
26
|
+
* The forms read are `var.n`, `length(var.x)`, `var.m` (a map, or a set
|
|
27
|
+
* variable) for `for_each`, and `toset(var.l)`; since #4489 the same with
|
|
28
|
+
* `local.<x>` in place of `var.<x>`, where the local's value is a literal or
|
|
29
|
+
* one of the `var` forms in its scope, and `var.on ? 1 : 0` (any two whole
|
|
30
|
+
* numbers, and `local.on` too) over a known bool. Anything else, or any
|
|
31
|
+
* value that is unknown, leaves the block as one node, which is what it
|
|
32
|
+
* was, and the entity gets an `instanceRollup` saying why (#4489, the codes
|
|
33
|
+
* in `@intentius/chant/instance-nodes`). `each.value` and `merge()` stay
|
|
34
|
+
* rolled up by ruling. A block under an expanded call whose own expansion
|
|
35
|
+
* or whose call's expansion cannot be counted gets no instances at all,
|
|
36
|
+
* since a partial list would name ids the plan never prints.
|
|
37
|
+
*/
|
|
38
|
+
import { type Declarable } from "@intentius/chant/declarable";
|
|
39
|
+
import type { InstanceRollup } from "@intentius/chant/instance-nodes";
|
|
40
|
+
import { type Hcl2Json } from "@intentius/chant/terraform/hcl2json";
|
|
41
|
+
import { type BlockBody } from "./parse.js";
|
|
42
|
+
/** A variable's known value, and whether it is declared as a set. */
|
|
43
|
+
interface VarValue {
|
|
44
|
+
value: unknown;
|
|
45
|
+
set: boolean;
|
|
46
|
+
}
|
|
47
|
+
/** Variable name to known value, for one module scope. A name that is absent is unknown. */
|
|
48
|
+
type ScopeVars = Map<string, VarValue>;
|
|
49
|
+
/** A scope's known `var` and `local` values (#4489). */
|
|
50
|
+
interface Scope {
|
|
51
|
+
vars: ScopeVars;
|
|
52
|
+
locals: ScopeVars;
|
|
53
|
+
}
|
|
54
|
+
export interface ResolveInstancesOptions {
|
|
55
|
+
/** The root's directory, where its tfvars files sit. */
|
|
56
|
+
dir: string;
|
|
57
|
+
/** `terraform.roots.<name>.varFiles`, relative to `dir`. */
|
|
58
|
+
varFiles?: readonly string[];
|
|
59
|
+
hcl2json?: Hcl2Json;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A block's expansion in a scope: its instance keys as Terraform prints them,
|
|
63
|
+
* `null` when the block is not expanded, or why the keys are not known.
|
|
64
|
+
*/
|
|
65
|
+
export declare function expansionIn(body: BlockBody, scope: Scope): {
|
|
66
|
+
keys: string[];
|
|
67
|
+
} | {
|
|
68
|
+
rollup: InstanceRollup;
|
|
69
|
+
} | null;
|
|
70
|
+
/**
|
|
71
|
+
* The instance keys a block's `count` or `for_each` gives in `vars`, as
|
|
72
|
+
* Terraform prints them. `null` when the block is not expanded, undefined
|
|
73
|
+
* when it is and the keys are not known.
|
|
74
|
+
*/
|
|
75
|
+
export declare function instanceKeysIn(body: BlockBody, vars: ScopeVars, locals?: ScopeVars): string[] | null | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* Add instance nodes the declared graph can count to one root's entities, in
|
|
78
|
+
* place (#4486). Entities of other roots in the map are left alone.
|
|
79
|
+
*/
|
|
80
|
+
export declare function resolveInstanceNodes(entities: Map<string, Declarable>, root: string, opts: ResolveInstancesOptions): Promise<void>;
|
|
81
|
+
export {};
|
|
82
|
+
//# sourceMappingURL=instances.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instances.d.ts","sourceRoot":"","sources":["../../src/hcl/instances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAIH,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACpF,OAAO,KAAK,EAAE,cAAc,EAAsB,MAAM,iCAAiC,CAAC;AAC1F,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EASL,KAAK,SAAS,EAEf,MAAM,SAAS,CAAC;AAiBjB,qEAAqE;AACrE,UAAU,QAAQ;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;CACd;AAED,4FAA4F;AAC5F,KAAK,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAEvC,wDAAwD;AACxD,UAAU,KAAK;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,SAAS,CAAC;CACnB;AAWD,MAAM,WAAW,uBAAuB;IACtC,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAqED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE,GAAG,IAAI,CAwBjH;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAE,SAAqB,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,CAG3H;AAoDD;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAyJf"}
|