@intentius/chant-lexicon-terraform 0.124.52 → 0.124.55
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 +14 -10
- 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/ci-setup.d.ts +11 -0
- package/dist/ci-setup.d.ts.map +1 -0
- package/dist/ci-setup.js +41 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +4 -3
- package/dist/components/capability-plugin.d.ts +105 -9
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/components/capability-plugin.js +357 -36
- 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/components/release-inputs.d.ts +29 -0
- package/dist/components/release-inputs.d.ts.map +1 -0
- package/dist/components/release-inputs.js +57 -0
- package/dist/components/trace-facts.d.ts +16 -0
- package/dist/components/trace-facts.d.ts.map +1 -0
- package/dist/components/trace-facts.js +19 -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/cone.d.ts +53 -0
- package/dist/cone.d.ts.map +1 -0
- package/dist/cone.js +119 -0
- package/dist/config.d.ts +59 -13
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +43 -9
- package/dist/cost-hold.d.ts +27 -0
- package/dist/cost-hold.d.ts.map +1 -0
- package/dist/cost-hold.js +21 -0
- 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/drift-rows.d.ts +61 -0
- package/dist/drift-rows.d.ts.map +1 -0
- package/dist/drift-rows.js +108 -0
- package/dist/exit-codes.d.ts +55 -0
- package/dist/exit-codes.d.ts.map +1 -0
- package/dist/exit-codes.js +48 -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 +13 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -2
- package/dist/integrity.json +8 -5
- package/dist/lint/audit-catalog.d.ts.map +1 -1
- package/dist/lint/audit-catalog.js +27 -3
- package/dist/lint/audit-lineage.d.ts +14 -2
- package/dist/lint/audit-lineage.d.ts.map +1 -1
- package/dist/lint/post-synth/index.d.ts.map +1 -1
- package/dist/lint/post-synth/index.js +4 -0
- package/dist/lint/post-synth/record-store.d.ts +54 -0
- package/dist/lint/post-synth/record-store.d.ts.map +1 -0
- package/dist/lint/post-synth/record-store.js +104 -0
- package/dist/lint/post-synth/tf001.d.ts +2 -2
- package/dist/lint/post-synth/tf001.js +2 -2
- package/dist/lint/post-synth/tf024.d.ts +35 -11
- package/dist/lint/post-synth/tf024.d.ts.map +1 -1
- package/dist/lint/post-synth/tf024.js +92 -20
- package/dist/lint/post-synth/tf046.d.ts +64 -0
- package/dist/lint/post-synth/tf046.d.ts.map +1 -0
- package/dist/lint/post-synth/tf046.js +175 -0
- package/dist/lint/post-synth/tf047.d.ts +36 -0
- package/dist/lint/post-synth/tf047.d.ts.map +1 -0
- package/dist/lint/post-synth/tf047.js +94 -0
- 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/lock-rows.d.ts +36 -0
- package/dist/lock-rows.d.ts.map +1 -0
- package/dist/lock-rows.js +60 -0
- package/dist/lock-timeout.d.ts +22 -0
- package/dist/lock-timeout.d.ts.map +1 -0
- package/dist/lock-timeout.js +32 -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/module-catalog/index.d.ts +69 -0
- package/dist/module-catalog/index.d.ts.map +1 -0
- package/dist/module-catalog/index.js +110 -0
- package/dist/module-catalog/refresh-cli.d.ts +4 -0
- package/dist/module-catalog/refresh-cli.d.ts.map +1 -0
- package/dist/module-catalog/refresh-cli.js +64 -0
- package/dist/module-catalog/static-tier.d.ts +6 -0
- package/dist/module-catalog/static-tier.d.ts.map +1 -0
- package/dist/module-catalog/static-tier.js +1650 -0
- package/dist/module-catalog/types.d.ts +65 -0
- package/dist/module-catalog/types.d.ts.map +1 -0
- package/dist/module-catalog/types.js +33 -0
- package/dist/okf/index.md +3 -1
- package/dist/okf/rules/TF024.md +2 -2
- package/dist/okf/rules/TF046.md +11 -0
- package/dist/okf/rules/TF047.md +11 -0
- 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 +182 -5
- package/dist/op/activities/terraform.d.ts.map +1 -1
- package/dist/op/activities/terraform.js +224 -24
- 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/consumers.d.ts +35 -0
- package/dist/pin/consumers.d.ts.map +1 -0
- package/dist/pin/consumers.js +70 -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 +37 -18
- package/dist/registry/address.d.ts +63 -0
- package/dist/registry/address.d.ts.map +1 -0
- package/dist/registry/address.js +65 -0
- package/dist/registry/catalog-read.d.ts +14 -0
- package/dist/registry/catalog-read.d.ts.map +1 -0
- package/dist/registry/catalog-read.js +58 -0
- package/dist/registry/deprecated.d.ts +37 -0
- package/dist/registry/deprecated.d.ts.map +1 -0
- package/dist/registry/deprecated.js +43 -0
- package/dist/registry/docs.d.ts +96 -0
- package/dist/registry/docs.d.ts.map +1 -0
- package/dist/registry/docs.js +210 -0
- package/dist/registry/edge/edge.d.ts +46 -0
- package/dist/registry/edge/edge.d.ts.map +1 -0
- package/dist/registry/edge/edge.js +194 -0
- package/dist/registry/edge/index.d.ts +11 -0
- package/dist/registry/edge/index.d.ts.map +1 -0
- package/dist/registry/edge/index.js +10 -0
- package/dist/registry/edge/lambda-edge.d.ts +76 -0
- package/dist/registry/edge/lambda-edge.d.ts.map +1 -0
- package/dist/registry/edge/lambda-edge.js +95 -0
- package/dist/registry/edge/sigv4-web.d.ts +33 -0
- package/dist/registry/edge/sigv4-web.d.ts.map +1 -0
- package/dist/registry/edge/sigv4-web.js +56 -0
- package/dist/registry/edge/token-source.d.ts +73 -0
- package/dist/registry/edge/token-source.d.ts.map +1 -0
- package/dist/registry/edge/token-source.js +115 -0
- package/dist/registry/edge/worker.d.ts +45 -0
- package/dist/registry/edge/worker.d.ts.map +1 -0
- package/dist/registry/edge/worker.js +26 -0
- package/dist/registry/handler.d.ts +25 -0
- package/dist/registry/handler.d.ts.map +1 -0
- package/dist/registry/handler.js +75 -0
- package/dist/registry/headers-file.d.ts +21 -0
- package/dist/registry/headers-file.d.ts.map +1 -0
- package/dist/registry/headers-file.js +57 -0
- package/dist/registry/index.d.ts +31 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +30 -0
- package/dist/registry/mirror-paths.d.ts +9 -0
- package/dist/registry/mirror-paths.d.ts.map +1 -0
- package/dist/registry/mirror-paths.js +8 -0
- package/dist/registry/mirror.d.ts +130 -0
- package/dist/registry/mirror.d.ts.map +1 -0
- package/dist/registry/mirror.js +319 -0
- package/dist/registry/proxies.d.ts +73 -0
- package/dist/registry/proxies.d.ts.map +1 -0
- package/dist/registry/proxies.js +111 -0
- package/dist/registry/reader.d.ts +57 -0
- package/dist/registry/reader.d.ts.map +1 -0
- package/dist/registry/reader.js +198 -0
- package/dist/registry/semver.d.ts +16 -0
- package/dist/registry/semver.d.ts.map +1 -0
- package/dist/registry/semver.js +24 -0
- package/dist/registry/serve.d.ts +24 -0
- package/dist/registry/serve.d.ts.map +1 -0
- package/dist/registry/serve.js +64 -0
- package/dist/registry/source-forms.d.ts +79 -0
- package/dist/registry/source-forms.d.ts.map +1 -0
- package/dist/registry/source-forms.js +202 -0
- package/dist/registry/targets/artifactory.d.ts +28 -0
- package/dist/registry/targets/artifactory.d.ts.map +1 -0
- package/dist/registry/targets/artifactory.js +206 -0
- package/dist/registry/targets/fake-artifactory.d.ts +30 -0
- package/dist/registry/targets/fake-artifactory.d.ts.map +1 -0
- package/dist/registry/targets/fake-artifactory.js +142 -0
- package/dist/registry/targets/fake-gitlab.d.ts +39 -0
- package/dist/registry/targets/fake-gitlab.d.ts.map +1 -0
- package/dist/registry/targets/fake-gitlab.js +136 -0
- package/dist/registry/targets/fake-hcp.d.ts +50 -0
- package/dist/registry/targets/fake-hcp.d.ts.map +1 -0
- package/dist/registry/targets/fake-hcp.js +202 -0
- package/dist/registry/targets/fake-http.d.ts +31 -0
- package/dist/registry/targets/fake-http.d.ts.map +1 -0
- package/dist/registry/targets/fake-http.js +87 -0
- package/dist/registry/targets/fake-nexus.d.ts +27 -0
- package/dist/registry/targets/fake-nexus.d.ts.map +1 -0
- package/dist/registry/targets/fake-nexus.js +137 -0
- package/dist/registry/targets/gitlab.d.ts +53 -0
- package/dist/registry/targets/gitlab.d.ts.map +1 -0
- package/dist/registry/targets/gitlab.js +187 -0
- package/dist/registry/targets/hcp.d.ts +29 -0
- package/dist/registry/targets/hcp.d.ts.map +1 -0
- package/dist/registry/targets/hcp.js +310 -0
- package/dist/registry/targets/hosted.d.ts +62 -0
- package/dist/registry/targets/hosted.d.ts.map +1 -0
- package/dist/registry/targets/hosted.js +74 -0
- package/dist/registry/targets/index.d.ts +18 -0
- package/dist/registry/targets/index.d.ts.map +1 -0
- package/dist/registry/targets/index.js +17 -0
- package/dist/registry/targets/module-target.d.ts +68 -0
- package/dist/registry/targets/module-target.d.ts.map +1 -0
- package/dist/registry/targets/module-target.js +63 -0
- package/dist/registry/targets/nexus.d.ts +43 -0
- package/dist/registry/targets/nexus.d.ts.map +1 -0
- package/dist/registry/targets/nexus.js +250 -0
- package/dist/registry/targets/zip.d.ts +55 -0
- package/dist/registry/targets/zip.d.ts.map +1 -0
- package/dist/registry/targets/zip.js +278 -0
- package/dist/registry/writer.d.ts +101 -0
- package/dist/registry/writer.d.ts.map +1 -0
- package/dist/registry/writer.js +109 -0
- package/dist/report.d.ts +15 -6
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +28 -55
- package/dist/rules/record-store.ts +122 -0
- package/dist/rules/tf001.ts +2 -2
- package/dist/rules/tf024.ts +105 -22
- package/dist/rules/tf046.ts +204 -0
- package/dist/rules/tf047.ts +114 -0
- package/dist/skills/chant-terraform.md +1 -1
- package/dist/state/azure-blob.d.ts +9 -0
- package/dist/state/azure-blob.d.ts.map +1 -0
- package/dist/state/azure-blob.js +8 -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 +8 -0
- package/dist/state/gcs.d.ts.map +1 -0
- package/dist/state/gcs.js +7 -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 +8 -0
- package/dist/state/object-store.d.ts.map +1 -0
- package/dist/state/object-store.js +7 -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 +21 -0
- package/dist/state/s3.d.ts.map +1 -0
- package/dist/state/s3.js +19 -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/state-ops.d.ts +255 -0
- package/dist/state-ops.d.ts.map +1 -0
- package/dist/state-ops.js +305 -0
- package/dist/state-reads.d.ts +57 -0
- package/dist/state-reads.d.ts.map +1 -0
- package/dist/state-reads.js +104 -0
- package/dist/terragrunt/affected.d.ts.map +1 -1
- package/dist/terragrunt/affected.js +2 -1
- package/dist/used-sources.d.ts +54 -0
- package/dist/used-sources.d.ts.map +1 -0
- package/dist/used-sources.js +157 -0
- package/package.json +24 -4
- 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 +16 -0
- package/src/__fixtures__/drift-record/live-plan-sections.json +27 -0
- package/src/__fixtures__/drift-rows/live-root-plan.json +70 -0
- package/src/__fixtures__/drift-rows/refresh-plan.json +61 -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/__fixtures__/used-sources/root/extra.tofu +1 -0
- package/src/__fixtures__/used-sources/root/main.tf +31 -0
- package/src/__fixtures__/used-sources/root/modules/net/main.tf +14 -0
- package/src/__fixtures__/used-sources/root/modules/net/versions.tf.json +7 -0
- package/src/__fixtures__/used-sources/unit/terragrunt.hcl +3 -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/ci-setup.ts +42 -0
- package/src/commands.ts +4 -3
- package/src/components/capability-plugin.test.ts +198 -19
- package/src/components/capability-plugin.ts +383 -35
- 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 +113 -57
- package/src/components/release-inputs.ts +69 -0
- package/src/components/trace-facts.test.ts +21 -0
- package/src/components/trace-facts.ts +27 -0
- 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/cone.ts +138 -0
- package/src/config-file-listers.test.ts +265 -0
- package/src/config.ts +44 -9
- package/src/cost-hold.ts +29 -0
- package/src/describe-resources.engine-facts.test.ts +411 -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/drift-rows.test.ts +135 -0
- package/src/drift-rows.ts +137 -0
- package/src/exit-codes.test.ts +23 -0
- package/src/exit-codes.ts +59 -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 +79 -0
- package/src/lint/audit-catalog.ts +29 -3
- package/src/lint/audit-lineage.ts +14 -2
- package/src/lint/post-synth/fixtures/TF024/live-with-record-store/main.tf +18 -0
- package/src/lint/post-synth/fixtures/TF024/sidecar-with-backend/estate.chdf.hcl +1 -0
- package/src/lint/post-synth/fixtures/TF024/sidecar-with-backend/main.tf +10 -0
- package/src/lint/post-synth/fixtures/TF046/azurerm-no-resource-group/main.tf +15 -0
- package/src/lint/post-synth/fixtures/TF046/backend-config-only/main.tf +14 -0
- package/src/lint/post-synth/fixtures/TF046/derived-s3/backend.tf +7 -0
- package/src/lint/post-synth/fixtures/TF046/derived-s3/main.tf +9 -0
- package/src/lint/post-synth/fixtures/TF046/explicit-local/main.tf +16 -0
- package/src/lint/post-synth/fixtures/TF046/explicit-s3-beside-local-backend/main.tf +15 -0
- package/src/lint/post-synth/fixtures/TF046/implied-local/main.tf +9 -0
- package/src/lint/post-synth/fixtures/TF046/sidecar-implied/estate.chdf.hcl +1 -0
- package/src/lint/post-synth/fixtures/TF046/sidecar-implied/main.tf +5 -0
- package/src/lint/post-synth/fixtures/TF047/clear/main.tf +12 -0
- package/src/lint/post-synth/fixtures/TF047/refused/main.tf +12 -0
- package/src/lint/post-synth/fixtures/TF047/unknown-module/main.tf +12 -0
- package/src/lint/post-synth/fixtures/TF047/unknown-version/main.tf +12 -0
- package/src/lint/post-synth/index.ts +4 -0
- package/src/lint/post-synth/record-store.ts +122 -0
- package/src/lint/post-synth/tf001.ts +2 -2
- package/src/lint/post-synth/tf024.test.ts +26 -5
- package/src/lint/post-synth/tf024.ts +105 -22
- package/src/lint/post-synth/tf046.test.ts +137 -0
- package/src/lint/post-synth/tf046.ts +204 -0
- package/src/lint/post-synth/tf047.test.ts +56 -0
- package/src/lint/post-synth/tf047.ts +114 -0
- package/src/live-plan-reasons.ts +54 -0
- package/src/lock-rows.test.ts +70 -0
- package/src/lock-rows.ts +82 -0
- package/src/lock-timeout.ts +34 -0
- package/src/lsp/completions.test.ts +1 -1
- package/src/lsp/option-keys.ts +2 -0
- package/src/module-catalog/index.test.ts +93 -0
- package/src/module-catalog/index.ts +159 -0
- package/src/module-catalog/refresh-cli.ts +68 -0
- package/src/module-catalog/static-tier.ts +1659 -0
- package/src/module-catalog/types.ts +88 -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 +312 -27
- 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/op-wave-step.test.ts +109 -0
- package/src/pin/__fixtures__/consumers/live/dev/main.tf +4 -0
- package/src/pin/__fixtures__/consumers/live/prod/main.tf +21 -0
- package/src/pin/__fixtures__/consumers/units/vpc/terragrunt.hcl +7 -0
- package/src/pin/bundle.test.ts +2 -0
- package/src/pin/consumers.test.ts +57 -0
- package/src/pin/consumers.ts +95 -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 +39 -19
- package/src/registry/__fixtures__/docs/documented/.terraform-docs.yml +3 -0
- package/src/registry/__fixtures__/docs/documented/README.md +1 -0
- package/src/registry/__fixtures__/docs/documented/main.tf +8 -0
- package/src/registry/__fixtures__/docs/json/main.tf.json +14 -0
- package/src/registry/__fixtures__/docs/vpc/README.md +3 -0
- package/src/registry/__fixtures__/docs/vpc/examples/complete/main.tf +5 -0
- package/src/registry/__fixtures__/docs/vpc/examples/simple/README.md +1 -0
- package/src/registry/__fixtures__/docs/vpc/examples/simple/main.tf +4 -0
- package/src/registry/__fixtures__/docs/vpc/main.tf +14 -0
- package/src/registry/__fixtures__/docs/vpc/outputs.tf +9 -0
- package/src/registry/__fixtures__/docs/vpc/variables.tf +16 -0
- package/src/registry/__fixtures__/proxied-root/main.tf +12 -0
- package/src/registry/address.ts +100 -0
- package/src/registry/catalog-read.ts +56 -0
- package/src/registry/deprecated.test.ts +139 -0
- package/src/registry/deprecated.ts +76 -0
- package/src/registry/docs.test.ts +140 -0
- package/src/registry/docs.ts +299 -0
- package/src/registry/edge/bundle.test.ts +50 -0
- package/src/registry/edge/edge.test.ts +176 -0
- package/src/registry/edge/edge.ts +211 -0
- package/src/registry/edge/index.ts +10 -0
- package/src/registry/edge/lambda-edge.ts +127 -0
- package/src/registry/edge/sigv4-web.ts +79 -0
- package/src/registry/edge/token-source.test.ts +258 -0
- package/src/registry/edge/token-source.ts +169 -0
- package/src/registry/edge/worker.ts +61 -0
- package/src/registry/handler.ts +89 -0
- package/src/registry/headers-file.ts +61 -0
- package/src/registry/index.ts +31 -0
- package/src/registry/mirror-paths.ts +10 -0
- package/src/registry/mirror.test.ts +198 -0
- package/src/registry/mirror.ts +395 -0
- package/src/registry/proxies.test.ts +153 -0
- package/src/registry/proxies.ts +132 -0
- package/src/registry/reader.ts +225 -0
- package/src/registry/registry.test.ts +262 -0
- package/src/registry/semver.ts +34 -0
- package/src/registry/serve.ts +82 -0
- package/src/registry/source-forms.test.ts +87 -0
- package/src/registry/source-forms.ts +216 -0
- package/src/registry/targets/artifactory.test.ts +248 -0
- package/src/registry/targets/artifactory.ts +257 -0
- package/src/registry/targets/fake-artifactory.ts +158 -0
- package/src/registry/targets/fake-gitlab.ts +161 -0
- package/src/registry/targets/fake-hcp.ts +233 -0
- package/src/registry/targets/fake-http.ts +97 -0
- package/src/registry/targets/fake-nexus.ts +152 -0
- package/src/registry/targets/gitlab.test.ts +208 -0
- package/src/registry/targets/gitlab.ts +223 -0
- package/src/registry/targets/hcp.test.ts +230 -0
- package/src/registry/targets/hcp.ts +360 -0
- package/src/registry/targets/hosted.ts +117 -0
- package/src/registry/targets/index.ts +17 -0
- package/src/registry/targets/module-target.ts +131 -0
- package/src/registry/targets/nexus.test.ts +220 -0
- package/src/registry/targets/nexus.ts +314 -0
- package/src/registry/targets/zip.test.ts +65 -0
- package/src/registry/targets/zip.ts +287 -0
- package/src/registry/writer.ts +155 -0
- package/src/report.test.ts +82 -1
- package/src/report.ts +31 -54
- package/src/signal-only-root.test.ts +72 -0
- package/src/skills/chant-terraform.md +1 -1
- package/src/state/azure-blob.ts +8 -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 +7 -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 +7 -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 +21 -0
- package/src/state/store.ts +225 -0
- package/src/state-ops.test.ts +182 -0
- package/src/state-ops.ts +462 -0
- package/src/state-reads.ts +116 -0
- package/src/terragrunt/affected.ts +2 -1
- package/src/used-sources.test.ts +75 -0
- package/src/used-sources.ts +204 -0
- 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
package/src/lock-rows.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The terraform lexicon's lock grain (#4552) and the rows a choudoufu apply
|
|
3
|
+
* holds on the resource grain, in terragucci's format (`planRows` in
|
|
4
|
+
* terragucci's `apply-rows.ts` at 18f6431), unchanged:
|
|
5
|
+
*
|
|
6
|
+
* - `estate <estate> <address>` for every resource instance the apply acts
|
|
7
|
+
* on (a create, update, delete, replace or forget), or `root <root>
|
|
8
|
+
* <address>` when the root has no estate;
|
|
9
|
+
* - the same for `previous_address` on a moved instance;
|
|
10
|
+
* - `object <id>` for anything but a create, from the object's id before,
|
|
11
|
+
* so two estates that meet on one object meet on its row.
|
|
12
|
+
*
|
|
13
|
+
* Data reads and no-ops hold nothing.
|
|
14
|
+
*
|
|
15
|
+
* The grain: `resource` for choudoufu, which keeps one record per resource,
|
|
16
|
+
* writes each conditionally and refuses a plan one of whose changes moved;
|
|
17
|
+
* `target` (the root, or the Terragrunt unit) for Terraform, tofu and
|
|
18
|
+
* Terragrunt, whose state is one file the backend's lock keeps whole. Those
|
|
19
|
+
* three refuse `resource` by name, since nothing in their state is per
|
|
20
|
+
* resource.
|
|
21
|
+
*/
|
|
22
|
+
import type { ChangeSetPart, ChangeSetPlanner } from "@intentius/chant/change-set";
|
|
23
|
+
import { objectRowKey, sortedLockRows, type LockGrain, type LockRow } from "@intentius/chant/lifecycle/lock-rows";
|
|
24
|
+
|
|
25
|
+
const CHANGING = new Set(["create", "update", "delete", "forget"]);
|
|
26
|
+
|
|
27
|
+
/** The scope a root's rows are keyed in: its estate, else its path. */
|
|
28
|
+
function rowScope(root: string, estate: string | undefined): string {
|
|
29
|
+
return estate ? `estate ${estate}` : `root ${root}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** The rows a plan's changes key, from `show -json`'s `resource_changes` (terragucci's `planRows`). */
|
|
33
|
+
export function terraformLockRows(root: string, estate: string | undefined, plan: unknown): LockRow[] {
|
|
34
|
+
const scope = rowScope(root, estate);
|
|
35
|
+
const rows: LockRow[] = [];
|
|
36
|
+
const changes = (plan as { resource_changes?: unknown[] } | undefined)?.resource_changes ?? [];
|
|
37
|
+
for (const c of changes as Array<Record<string, any>>) {
|
|
38
|
+
if (c?.mode === "data" || typeof c?.address !== "string") continue;
|
|
39
|
+
const actions: string[] = Array.isArray(c.change?.actions) ? c.change.actions : [];
|
|
40
|
+
if (!actions.some((a) => CHANGING.has(a))) continue;
|
|
41
|
+
const address = c.address as string;
|
|
42
|
+
rows.push({ key: `${scope} ${address}`, target: root, address });
|
|
43
|
+
if (typeof c.previous_address === "string" && c.previous_address !== address) rows.push({ key: `${scope} ${c.previous_address}`, target: root, address });
|
|
44
|
+
// The live object an update or a delete acts on: two estates that meet on one object meet here.
|
|
45
|
+
const id = c.change?.before?.id;
|
|
46
|
+
if (actions.some((a) => a !== "create") && (typeof id === "string" || typeof id === "number") && String(id) !== "") rows.push({ key: objectRowKey(String(id)), target: root, address });
|
|
47
|
+
}
|
|
48
|
+
return sortedLockRows(rows);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The rows from a member's change-set part, when the plan document is not
|
|
53
|
+
* at hand: the same keys, less the previous address of a moved instance,
|
|
54
|
+
* which the part does not carry. The part's `scope` is the estate.
|
|
55
|
+
*/
|
|
56
|
+
export function terraformLockRowsFromPart(root: string, part: ChangeSetPart): LockRow[] {
|
|
57
|
+
const scope = rowScope(root, part.member.planner === "choudoufu" ? part.member.scope : undefined);
|
|
58
|
+
const rows: LockRow[] = [];
|
|
59
|
+
for (const e of part.entries) {
|
|
60
|
+
if (e.action === "no-op" || e.action === "read") continue;
|
|
61
|
+
rows.push({ key: `${scope} ${e.address}`, target: root, address: e.address });
|
|
62
|
+
if (e.action !== "create" && e.id) rows.push({ key: objectRowKey(e.id), target: root, address: e.address });
|
|
63
|
+
}
|
|
64
|
+
return sortedLockRows(rows);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Whether a binary's name is Terragrunt's. */
|
|
68
|
+
function isTerragrunt(binary: string | undefined): boolean {
|
|
69
|
+
return /^terragrunt(\.exe)?$/.test((binary ?? "").split(/[\\/]/).pop() ?? "");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** The grain a root takes by default: `resource` under choudoufu, `target` under every other binary. */
|
|
73
|
+
export function terraformDefaultLockGrain(planner: ChangeSetPlanner | undefined): LockGrain {
|
|
74
|
+
return planner === "choudoufu" ? "resource" : "target";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Why a root cannot take `grain`, by engine name, or undefined when it can. */
|
|
78
|
+
export function terraformLockGrainRefusal(grain: LockGrain, planner: ChangeSetPlanner | undefined, binary?: string): string | undefined {
|
|
79
|
+
if (grain !== "resource" || planner === "choudoufu") return undefined;
|
|
80
|
+
const engine = isTerragrunt(binary) ? "Terragrunt" : planner === "tofu" ? "tofu" : "Terraform";
|
|
81
|
+
return `${engine} keeps a root's state in one file that its backend's lock keeps whole, so nothing in it is per resource; the resource grain needs choudoufu (ci.lockGrain: target)`;
|
|
82
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State-lock waits for a plan or an apply (#4545): how long `plan` and
|
|
3
|
+
* `apply` wait for another run's state lock before failing. Taken from
|
|
4
|
+
* terragucci's waves, where two jobs of one pipeline can reach the same
|
|
5
|
+
* backend a moment apart and a failed lock fails the wave for nothing.
|
|
6
|
+
*
|
|
7
|
+
* A job that already sets `-lock-timeout` through `TF_CLI_ARGS` or
|
|
8
|
+
* `TF_CLI_ARGS_<command>` keeps its own: the flag is added only when neither
|
|
9
|
+
* names one. Terragrunt waves pass the same flag after `--`
|
|
10
|
+
* (`./terragrunt/wave.ts`, `extra`).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** How long a plan or an apply waits for a state lock unless the job set a `-lock-timeout` of its own. */
|
|
14
|
+
export const DEFAULT_LOCK_TIMEOUT = "5m";
|
|
15
|
+
|
|
16
|
+
/** A duration terraform's `-lock-timeout` takes: `0s`, `30s`, `5m`, `1h30m`. */
|
|
17
|
+
const DURATION = /^(\d+(ms|s|m|h))+$/;
|
|
18
|
+
|
|
19
|
+
/** Whether `value` is a `-lock-timeout` duration. */
|
|
20
|
+
export function isLockTimeout(value: unknown): value is string {
|
|
21
|
+
return typeof value === "string" && DURATION.test(value);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The `-lock-timeout` flag a `command` takes: `-lock-timeout=<timeout>`, or
|
|
26
|
+
* nothing when `TF_CLI_ARGS` or `TF_CLI_ARGS_<command>` in `env` already
|
|
27
|
+
* names one, or `timeout` is `false`. Throws on a duration terraform refuses.
|
|
28
|
+
*/
|
|
29
|
+
export function lockTimeoutArgs(command: "plan" | "apply", timeout: string | false = DEFAULT_LOCK_TIMEOUT, env: Record<string, string | undefined> = process.env): string[] {
|
|
30
|
+
if (timeout === false) return [];
|
|
31
|
+
if (!isLockTimeout(timeout)) throw new Error(`lockTimeout "${timeout}" is not a duration terraform takes, such as "5m" or "30s"`);
|
|
32
|
+
const set = `${env.TF_CLI_ARGS ?? ""} ${env[`TF_CLI_ARGS_${command}`] ?? ""}`;
|
|
33
|
+
return /(^|\s)-{1,2}lock-timeout[=\s]/.test(set) ? [] : [`-lock-timeout=${timeout}`];
|
|
34
|
+
}
|
|
@@ -104,7 +104,7 @@ describe("LSP completions", () => {
|
|
|
104
104
|
it("completes root-entry keys inside chant.config.ts's terraform.roots.<name>", () => {
|
|
105
105
|
const content = "export default {\n terraform: {\n roots: {\n app: {\n ";
|
|
106
106
|
const items = completions(ctx({ content, position: { line: 4, character: 8 } }));
|
|
107
|
-
expect(items.map((i) => i.label).sort()).toEqual(["backendConfig", "delete", "dir", "varFiles", "workspace"]);
|
|
107
|
+
expect(items.map((i) => i.label).sort()).toEqual(["backendConfig", "backendConfigFiles", "delete", "dir", "signalOnly", "varFiles", "workspace"]);
|
|
108
108
|
});
|
|
109
109
|
|
|
110
110
|
it("completes the terraform namespace's own top-level keys", () => {
|
package/src/lsp/option-keys.ts
CHANGED
|
@@ -25,7 +25,9 @@ export const ROOT_ENTRY_KEYS: OptionKey[] = [
|
|
|
25
25
|
{ key: "workspace", detail: "Terraform workspace to select for this root. Omitted means `default`." },
|
|
26
26
|
{ key: "varFiles", detail: "`-var-file` arguments, in order, relative to `dir`." },
|
|
27
27
|
{ key: "backendConfig", detail: "`-backend-config` key/value pairs handed to `init`." },
|
|
28
|
+
{ key: "backendConfigFiles", detail: "Backend-config files handed to `init` as `-backend-config=<path>`, before the pairs, relative to `dir`." },
|
|
28
29
|
{ key: "delete", detail: '"never" | "owned-only" | "gated" — this root\'s delete mode, mapped onto choudoufu\'s policy block on a live root.' },
|
|
30
|
+
{ key: "signalOnly", detail: "`true` when the root is declared only so a change to it brings this project into the change. The build and live reads skip it." },
|
|
29
31
|
];
|
|
30
32
|
|
|
31
33
|
/** `TerraformApplyOpConfig`'s keys (`TerraformApplyOp({ <here> })`). */
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
MODULE_CATALOG_SOURCE,
|
|
4
|
+
exactModuleVersion,
|
|
5
|
+
moduleCompatibility,
|
|
6
|
+
registryModuleAddress,
|
|
7
|
+
staticRows,
|
|
8
|
+
} from "./index";
|
|
9
|
+
import { renderStaticTier } from "./refresh-cli";
|
|
10
|
+
import { parseModuleCompat } from "./types";
|
|
11
|
+
import { SOURCE_COMMIT, STATIC_MEASUREMENT } from "./static-tier";
|
|
12
|
+
|
|
13
|
+
describe("known-module catalog (chant#4560)", () => {
|
|
14
|
+
test("vendors the static tier only, with its source commit", () => {
|
|
15
|
+
expect(MODULE_CATALOG_SOURCE.path).toBe("live/module-compat.json");
|
|
16
|
+
expect(MODULE_CATALOG_SOURCE.commit).toMatch(/^[0-9a-f]{40}$/);
|
|
17
|
+
expect(staticRows.length).toBeGreaterThan(0);
|
|
18
|
+
expect(staticRows.every((r) => r.tier === "static")).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("every vendored row passes the refresh check", () => {
|
|
22
|
+
expect(() =>
|
|
23
|
+
parseModuleCompat({ schema: 1, static_measurement: STATIC_MEASUREMENT, static: [...staticRows] }),
|
|
24
|
+
).not.toThrow();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("the vendored file is what the refresh script writes", () => {
|
|
28
|
+
const rendered = renderStaticTier(SOURCE_COMMIT, STATIC_MEASUREMENT, staticRows);
|
|
29
|
+
expect(rendered).toContain(`at commit\n// ${SOURCE_COMMIT}`);
|
|
30
|
+
expect(rendered).toContain("static tier only");
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test("refuses a row whose verdict disagrees with its refusals", () => {
|
|
34
|
+
const row = { ...staticRows[0], verdict: "refused" as const, refusals: [] };
|
|
35
|
+
expect(() => parseModuleCompat({ schema: 1, static_measurement: STATIC_MEASUREMENT, static: [row] })).toThrow(
|
|
36
|
+
/refused with 0 refusals/,
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test.each([
|
|
41
|
+
["terraform-aws-modules/vpc/aws", "terraform-aws-modules/vpc/aws"],
|
|
42
|
+
["registry.terraform.io/terraform-aws-modules/vpc/aws", "terraform-aws-modules/vpc/aws"],
|
|
43
|
+
["terraform-aws-modules/iam/aws//modules/iam-role", "terraform-aws-modules/iam/aws"],
|
|
44
|
+
["./modules/vpc", undefined],
|
|
45
|
+
["git::https://example.com/vpc.git?ref=v1", undefined],
|
|
46
|
+
])("registryModuleAddress(%s)", (source, want) => {
|
|
47
|
+
expect(registryModuleAddress(source)).toBe(want);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test.each([
|
|
51
|
+
["1.4.0", "1.4.0"],
|
|
52
|
+
["= 1.4.0", "1.4.0"],
|
|
53
|
+
["v1.4.0", "1.4.0"],
|
|
54
|
+
["~> 1.4", undefined],
|
|
55
|
+
])("exactModuleVersion(%s)", (version, want) => {
|
|
56
|
+
expect(exactModuleVersion(version)).toBe(want);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("a clear version", () => {
|
|
60
|
+
expect(moduleCompatibility("terraform-aws-modules/sqs/aws", "5.2.2")).toMatchObject({
|
|
61
|
+
tier: "static",
|
|
62
|
+
status: "clear",
|
|
63
|
+
examples: 1,
|
|
64
|
+
clearExamples: 1,
|
|
65
|
+
refusedExamples: 0,
|
|
66
|
+
refusals: [],
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("a refused version sums sites per refusal ID and lists its examples", () => {
|
|
71
|
+
const c = moduleCompatibility("terraform-aws-modules/eks/aws", "= 21.29.0")!;
|
|
72
|
+
expect(c.status).toBe("refused");
|
|
73
|
+
expect(c.refusedExamples).toBe(c.examples);
|
|
74
|
+
expect(c.refusals.length).toBeGreaterThan(0);
|
|
75
|
+
for (const r of c.refusals) {
|
|
76
|
+
expect(r.sites).toBeGreaterThan(0);
|
|
77
|
+
expect(r.examples.length).toBeGreaterThan(0);
|
|
78
|
+
expect(r.docsUrl).toMatch(/LIMITATIONS\.md#/);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test("unknown module and unknown version", () => {
|
|
83
|
+
expect(moduleCompatibility("cloudposse/label/null", "0.25.0")?.status).toBe("unknown-module");
|
|
84
|
+
const v = moduleCompatibility("terraform-aws-modules/vpc/aws", "5.0.0")!;
|
|
85
|
+
expect(v.status).toBe("unknown-version");
|
|
86
|
+
expect(v.measuredVersions).toContain("6.6.1");
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("a range or a non-registry source has no answer", () => {
|
|
90
|
+
expect(moduleCompatibility("terraform-aws-modules/vpc/aws", "~> 6.0")).toBeUndefined();
|
|
91
|
+
expect(moduleCompatibility("./modules/vpc", "1.0.0")).toBeUndefined();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The known-module catalog (chant#4560): choudoufu's module compatibility
|
|
3
|
+
* table (choudoufu#2292, `live/module-compat.json`), vendored in
|
|
4
|
+
* `./static-tier.ts` and read by TF047 and by terragucci's tip and estate
|
|
5
|
+
* column (terragucci#1286).
|
|
6
|
+
*
|
|
7
|
+
* The catalog holds the static tier only. A static row is one
|
|
8
|
+
* terraform-aws-modules example at one tag, measured offline by choudoufu's
|
|
9
|
+
* refusal probe in the onboarded form: `clear` means `choudoufu live-check`
|
|
10
|
+
* plans it, `refused` lists choudoufu refusal IDs with site counts. The
|
|
11
|
+
* gauntlet tier (end-to-end runs against an emulator) is a separate table in
|
|
12
|
+
* choudoufu, has no rows until choudoufu#2291's run, and is never folded into
|
|
13
|
+
* these numbers: every result here carries `tier: "static"`, and a figure in
|
|
14
|
+
* it counts static rows only.
|
|
15
|
+
*
|
|
16
|
+
* This subpath, `@intentius/chant-lexicon-terraform/module-catalog`, imports
|
|
17
|
+
* nothing but its own data, so a consumer can load it on its own.
|
|
18
|
+
*/
|
|
19
|
+
import { SOURCE_COMMIT, SOURCE_PATH, STATIC_MEASUREMENT, STATIC_ROWS } from "./static-tier";
|
|
20
|
+
import type { StaticRow } from "./types";
|
|
21
|
+
|
|
22
|
+
export type { StaticRefusal, StaticRow, StaticMeasurement, StaticSource } from "./types";
|
|
23
|
+
|
|
24
|
+
/** Where the vendored rows came from. */
|
|
25
|
+
export const MODULE_CATALOG_SOURCE = {
|
|
26
|
+
repo: "INTENTIUS/choudoufu",
|
|
27
|
+
path: SOURCE_PATH,
|
|
28
|
+
commit: SOURCE_COMMIT,
|
|
29
|
+
/** The static tier's measurement date. */
|
|
30
|
+
date: STATIC_MEASUREMENT.date,
|
|
31
|
+
/** The choudoufu commit the static tier was measured at. */
|
|
32
|
+
measuredAt: STATIC_MEASUREMENT.commit,
|
|
33
|
+
/** The hashicorp/aws provider version the static tier was measured with. */
|
|
34
|
+
awsProvider: STATIC_MEASUREMENT.aws_provider,
|
|
35
|
+
} as const;
|
|
36
|
+
|
|
37
|
+
/** choudoufu's site page that renders both tiers. */
|
|
38
|
+
export const MODULE_COMPATIBILITY_PAGE = "https://intentius.io/choudoufu/aws/compatibility/#modules";
|
|
39
|
+
|
|
40
|
+
/** The tiers this catalog holds. */
|
|
41
|
+
export type ModuleCatalogTier = "static";
|
|
42
|
+
|
|
43
|
+
/** Every static row, as vendored. */
|
|
44
|
+
export const staticRows: readonly StaticRow[] = STATIC_ROWS;
|
|
45
|
+
|
|
46
|
+
/** One refusal ID across the examples of a module version that carry it. */
|
|
47
|
+
export interface ModuleRefusalSummary {
|
|
48
|
+
id: string;
|
|
49
|
+
/** Sites summed across the examples that carry it. */
|
|
50
|
+
sites: number;
|
|
51
|
+
docsUrl: string;
|
|
52
|
+
/** Example directories that carry it, sorted. */
|
|
53
|
+
examples: string[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* What the catalog says about one pinned module version.
|
|
58
|
+
*
|
|
59
|
+
* - `unknown-module`: no static row for this module at any version.
|
|
60
|
+
* - `unknown-version`: rows for the module, none measured at this version
|
|
61
|
+
* (`measuredVersions` lists the ones there are).
|
|
62
|
+
* - `refused`: at least one example at this version is refused.
|
|
63
|
+
* - `clear`: every measured example at this version is clear.
|
|
64
|
+
*/
|
|
65
|
+
export interface ModuleCompatibility {
|
|
66
|
+
module: string;
|
|
67
|
+
/** The pinned version, without a leading `v` or `=`. */
|
|
68
|
+
version: string;
|
|
69
|
+
tier: ModuleCatalogTier;
|
|
70
|
+
status: "unknown-module" | "unknown-version" | "clear" | "refused";
|
|
71
|
+
/** Static rows measured at this version (an `unmeasured` row is left out). */
|
|
72
|
+
examples: number;
|
|
73
|
+
clearExamples: number;
|
|
74
|
+
refusedExamples: number;
|
|
75
|
+
/** Refusal IDs at this version, most refused examples first, then by ID. */
|
|
76
|
+
refusals: ModuleRefusalSummary[];
|
|
77
|
+
/** Versions the static tier measured for this module, without a leading `v`. */
|
|
78
|
+
measuredVersions: string[];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The registry address of a module source, without a registry host, a
|
|
83
|
+
* `//subdir` or a query, lowercased: `registry.terraform.io/terraform-aws-modules/iam/aws//modules/iam-role`
|
|
84
|
+
* gives `terraform-aws-modules/iam/aws`. Undefined when the source is not a
|
|
85
|
+
* three-part registry address.
|
|
86
|
+
*/
|
|
87
|
+
export function registryModuleAddress(source: string): string | undefined {
|
|
88
|
+
let s = source.trim().split("?")[0];
|
|
89
|
+
const sub = s.indexOf("//");
|
|
90
|
+
if (sub >= 0) s = s.slice(0, sub);
|
|
91
|
+
const parts = s.split("/");
|
|
92
|
+
if (parts.length === 4 && parts[0].includes(".")) parts.shift();
|
|
93
|
+
if (parts.length !== 3 || parts.some((p) => !/^[A-Za-z0-9][A-Za-z0-9_.-]*$/.test(p))) return undefined;
|
|
94
|
+
return parts.join("/").toLowerCase();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** `= 1.4.0`, `v1.4.0` and `1.4.0` all give `1.4.0`; a range gives undefined. */
|
|
98
|
+
export function exactModuleVersion(version: string): string | undefined {
|
|
99
|
+
const v = version.trim().replace(/^=\s*/, "").replace(/^v/, "");
|
|
100
|
+
return /^\d+(?:\.\d+){0,2}(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(v) ? v : undefined;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const bare = (version: string): string => version.replace(/^v/, "");
|
|
104
|
+
|
|
105
|
+
function byModule(): Map<string, StaticRow[]> {
|
|
106
|
+
const out = new Map<string, StaticRow[]>();
|
|
107
|
+
for (const row of STATIC_ROWS) {
|
|
108
|
+
const key = row.module.toLowerCase();
|
|
109
|
+
const list = out.get(key) ?? [];
|
|
110
|
+
list.push(row);
|
|
111
|
+
out.set(key, list);
|
|
112
|
+
}
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let index: Map<string, StaticRow[]> | undefined;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The catalog's answer for a module `source` pinned at `version`, or
|
|
120
|
+
* undefined when the source is not a registry address or the version is not
|
|
121
|
+
* exact (a range is TF039's finding, and the catalog has no row for one).
|
|
122
|
+
*/
|
|
123
|
+
export function moduleCompatibility(source: string, version: string): ModuleCompatibility | undefined {
|
|
124
|
+
const module = registryModuleAddress(source);
|
|
125
|
+
const pinned = exactModuleVersion(version);
|
|
126
|
+
if (module === undefined || pinned === undefined) return undefined;
|
|
127
|
+
|
|
128
|
+
index ??= byModule();
|
|
129
|
+
const rows = index.get(module) ?? [];
|
|
130
|
+
const measuredVersions = [...new Set(rows.map((r) => bare(r.version)))].sort();
|
|
131
|
+
const at = rows.filter((r) => bare(r.version) === pinned && r.verdict !== "unmeasured");
|
|
132
|
+
const refusedRows = at.filter((r) => r.verdict === "refused");
|
|
133
|
+
|
|
134
|
+
const refusals = new Map<string, ModuleRefusalSummary>();
|
|
135
|
+
for (const row of refusedRows) {
|
|
136
|
+
for (const r of row.refusals) {
|
|
137
|
+
const s = refusals.get(r.id) ?? { id: r.id, sites: 0, docsUrl: r.docs_url, examples: [] };
|
|
138
|
+
s.sites += r.sites;
|
|
139
|
+
if (!s.examples.includes(row.example)) s.examples.push(row.example);
|
|
140
|
+
refusals.set(r.id, s);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
for (const s of refusals.values()) s.examples.sort();
|
|
144
|
+
|
|
145
|
+
const status: ModuleCompatibility["status"] =
|
|
146
|
+
rows.length === 0 ? "unknown-module" : at.length === 0 ? "unknown-version" : refusedRows.length > 0 ? "refused" : "clear";
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
module,
|
|
150
|
+
version: pinned,
|
|
151
|
+
tier: "static",
|
|
152
|
+
status,
|
|
153
|
+
examples: at.length,
|
|
154
|
+
clearExamples: at.filter((r) => r.verdict === "clear").length,
|
|
155
|
+
refusedExamples: refusedRows.length,
|
|
156
|
+
refusals: [...refusals.values()].sort((a, b) => b.examples.length - a.examples.length || a.id.localeCompare(b.id)),
|
|
157
|
+
measuredVersions,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refresh the vendored known-module catalog (chant#4560) from choudoufu's
|
|
3
|
+
* module compatibility table.
|
|
4
|
+
*
|
|
5
|
+
* npm run --prefix lexicons/terraform module-catalog:refresh -- <choudoufu checkout> [ref]
|
|
6
|
+
*
|
|
7
|
+
* It reads `live/module-compat.json` at `ref` (default `origin/main`) with
|
|
8
|
+
* `git show`, so the checkout's working tree is never read and a local edit
|
|
9
|
+
* cannot leak into the snapshot. The header of the written file names the
|
|
10
|
+
* source path and the choudoufu commit that last changed the table at that
|
|
11
|
+
* ref, so a reader can check the snapshot against its source with
|
|
12
|
+
* `git -C <choudoufu> show <commit>:live/module-compat.json`.
|
|
13
|
+
*
|
|
14
|
+
* Only the static tier is vendored. choudoufu keeps the gauntlet tier in a
|
|
15
|
+
* separate array and the two tiers share no figure (choudoufu#2292 ruling);
|
|
16
|
+
* the gauntlet array stays out until it has rows (choudoufu#2291), and then
|
|
17
|
+
* comes in as its own export, never folded into the static rows.
|
|
18
|
+
*/
|
|
19
|
+
import { execFileSync } from "node:child_process";
|
|
20
|
+
import { writeFileSync } from "node:fs";
|
|
21
|
+
import { dirname, join } from "node:path";
|
|
22
|
+
import { fileURLToPath } from "node:url";
|
|
23
|
+
import { parseModuleCompat, type StaticMeasurement, type StaticRow } from "./types";
|
|
24
|
+
|
|
25
|
+
const SOURCE_PATH = "live/module-compat.json";
|
|
26
|
+
const OUT = join(dirname(fileURLToPath(import.meta.url)), "static-tier.ts");
|
|
27
|
+
|
|
28
|
+
function git(dir: string, ...args: string[]): string {
|
|
29
|
+
return execFileSync("git", ["-C", dir, ...args], { encoding: "utf8", maxBuffer: 64 * 1024 * 1024 });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** The TypeScript source of `static-tier.ts` for one snapshot. */
|
|
33
|
+
export function renderStaticTier(commit: string, measurement: StaticMeasurement, rows: readonly StaticRow[]): string {
|
|
34
|
+
return [
|
|
35
|
+
"// Code generated by src/module-catalog/refresh-cli.ts. DO NOT EDIT.",
|
|
36
|
+
"//",
|
|
37
|
+
`// Vendored from INTENTIUS/choudoufu ${SOURCE_PATH} at commit`,
|
|
38
|
+
`// ${commit}, static tier only (chant#4560).`,
|
|
39
|
+
"// The gauntlet tier is a separate array in that file and is not vendored here.",
|
|
40
|
+
"import type { StaticMeasurement, StaticRow } from \"./types\";",
|
|
41
|
+
"",
|
|
42
|
+
`export const SOURCE_PATH = ${JSON.stringify(SOURCE_PATH)};`,
|
|
43
|
+
`export const SOURCE_COMMIT = ${JSON.stringify(commit)};`,
|
|
44
|
+
"",
|
|
45
|
+
`export const STATIC_MEASUREMENT: StaticMeasurement = ${JSON.stringify(measurement, null, 2)};`,
|
|
46
|
+
"",
|
|
47
|
+
`export const STATIC_ROWS: readonly StaticRow[] = ${JSON.stringify(rows, null, 2)};`,
|
|
48
|
+
"",
|
|
49
|
+
].join("\n");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function main(argv: string[]): void {
|
|
53
|
+
const [dir, ref = "origin/main"] = argv;
|
|
54
|
+
if (!dir) {
|
|
55
|
+
console.error("usage: refresh-cli.ts <choudoufu checkout> [ref]");
|
|
56
|
+
process.exit(2);
|
|
57
|
+
}
|
|
58
|
+
const commit = git(dir, "log", "-1", "--format=%H", ref, "--", SOURCE_PATH).trim();
|
|
59
|
+
if (!/^[0-9a-f]{40}$/.test(commit)) {
|
|
60
|
+
console.error(`${SOURCE_PATH} has no history at ${ref} in ${dir}`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
const file = parseModuleCompat(JSON.parse(git(dir, "show", `${commit}:${SOURCE_PATH}`)));
|
|
64
|
+
writeFileSync(OUT, renderStaticTier(commit, file.static_measurement, file.static));
|
|
65
|
+
console.log(`module catalog: ${file.static.length} static rows from ${SOURCE_PATH} at ${commit}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) main(process.argv.slice(2));
|