@intentius/chant-lexicon-terraform 0.124.54 → 0.124.56
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 -4
- 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/components/capability-plugin.d.ts +40 -6
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/components/capability-plugin.js +174 -30
- package/dist/components/compose-group.d.ts +1 -1
- package/dist/components/compose-group.d.ts.map +1 -1
- package/dist/components/compose-group.js +1 -1
- 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/cone.d.ts +53 -0
- package/dist/cone.d.ts.map +1 -0
- package/dist/cone.js +119 -0
- 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/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/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/integrity.json +7 -4
- 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/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/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/terraform.d.ts +29 -0
- package/dist/op/activities/terraform.d.ts.map +1 -1
- package/dist/op/activities/terraform.js +19 -4
- 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/plugin.d.ts.map +1 -1
- package/dist/plugin.js +5 -0
- 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/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/state/azure-blob.d.ts +8 -67
- package/dist/state/azure-blob.d.ts.map +1 -1
- package/dist/state/azure-blob.js +6 -199
- package/dist/state/gcs.d.ts +7 -61
- package/dist/state/gcs.d.ts.map +1 -1
- package/dist/state/gcs.js +5 -222
- package/dist/state/object-store.d.ts +4 -33
- package/dist/state/object-store.d.ts.map +1 -1
- package/dist/state/object-store.js +4 -17
- package/dist/state/s3.d.ts +11 -58
- package/dist/state/s3.d.ts.map +1 -1
- package/dist/state/s3.js +10 -161
- package/dist/state/store.js +2 -2
- 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/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 +19 -3
- package/src/__fixtures__/drift-record/README.md +5 -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__/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/ci-setup.ts +42 -0
- package/src/components/capability-plugin.test.ts +26 -14
- package/src/components/capability-plugin.ts +185 -31
- package/src/components/compose-group.ts +1 -1
- package/src/components/pr-loop-compose.tofu.e2e.test.ts +1 -1
- package/src/components/pr-loop.tofu.test.ts +1 -1
- 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/cone.ts +138 -0
- package/src/cost-hold.ts +29 -0
- package/src/describe-resources.engine-facts.test.ts +2 -3
- 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/index.ts +3 -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/lock-rows.test.ts +70 -0
- package/src/lock-rows.ts +82 -0
- package/src/lock-timeout.ts +34 -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/terraform.ts +46 -5
- 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/consumers.test.ts +57 -0
- package/src/pin/consumers.ts +95 -0
- package/src/plugin.ts +6 -0
- 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/state/azure-blob.ts +6 -221
- package/src/state/gcs.ts +5 -252
- package/src/state/object-store.ts +4 -32
- package/src/state/s3.ts +10 -182
- package/src/state/store.ts +2 -2
- package/src/state-ops.test.ts +182 -0
- package/src/state-ops.ts +462 -0
- package/src/state-reads.ts +116 -0
- package/src/used-sources.test.ts +75 -0
- package/src/used-sources.ts +204 -0
|
@@ -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
|
+
}
|
|
@@ -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));
|