@intentius/chant 0.79.0 → 0.81.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit/core.d.ts.map +1 -1
- package/dist/audit/discover.d.ts +30 -0
- package/dist/audit/discover.d.ts.map +1 -1
- package/dist/audit/report-html.d.ts +5 -0
- package/dist/audit/report-html.d.ts.map +1 -1
- package/dist/audit/report-model.d.ts +13 -0
- package/dist/audit/report-model.d.ts.map +1 -1
- package/dist/audit/terraform-state.d.ts +13 -0
- package/dist/audit/terraform-state.d.ts.map +1 -1
- package/dist/cli/command-group.d.ts +6 -0
- package/dist/cli/command-group.d.ts.map +1 -1
- package/dist/cli/commands/audit.d.ts +44 -3
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon-examples.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon.d.ts +8 -0
- package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/import-agents.d.ts.map +1 -1
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/onboard.d.ts.map +1 -1
- package/dist/cli/commands/update.d.ts +6 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/vendor.d.ts +5 -0
- package/dist/cli/commands/vendor.d.ts.map +1 -1
- package/dist/cli/conflict-check.d.ts +6 -0
- package/dist/cli/conflict-check.d.ts.map +1 -1
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/components.d.ts.map +1 -1
- package/dist/cli/handlers/dev.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/init.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +7 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/promote.d.ts +20 -0
- package/dist/cli/handlers/promote.d.ts.map +1 -0
- package/dist/cli/handlers/run-generate.d.ts +39 -0
- package/dist/cli/handlers/run-generate.d.ts.map +1 -0
- package/dist/cli/handlers/run.d.ts +4 -1
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/handlers/vendor.d.ts +8 -3
- package/dist/cli/handlers/vendor.d.ts.map +1 -1
- package/dist/cli/main.d.ts +12 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/op-tools.d.ts.map +1 -1
- package/dist/cli/plugins.d.ts +14 -0
- package/dist/cli/plugins.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +46 -1
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/fetch.d.ts +10 -0
- package/dist/codegen/fetch.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +3 -1
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/discover.d.ts.map +1 -1
- package/dist/components/driver.d.ts +16 -2
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/fan-out-support.d.ts.map +1 -1
- package/dist/components/gate-plan.d.ts +40 -0
- package/dist/components/gate-plan.d.ts.map +1 -0
- package/dist/components/pilots/alb-ecs.pilot.d.ts +7 -1
- package/dist/components/pilots/alb-ecs.pilot.d.ts.map +1 -1
- package/dist/components/presets/ecs-fargate.d.ts +10 -4
- package/dist/components/presets/ecs-fargate.d.ts.map +1 -1
- package/dist/components/promote.d.ts +264 -0
- package/dist/components/promote.d.ts.map +1 -0
- package/dist/components/sandbox/driver.d.ts.map +1 -1
- package/dist/components/sandbox/run.d.ts.map +1 -1
- package/dist/components/verbs/build-archive.d.ts +22 -11
- package/dist/components/verbs/build-archive.d.ts.map +1 -1
- package/dist/components/verbs/run-agent.d.ts.map +1 -1
- package/dist/config-static.d.ts +59 -0
- package/dist/config-static.d.ts.map +1 -0
- package/dist/config.d.ts +104 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/content-digest.d.ts +17 -0
- package/dist/content-digest.d.ts.map +1 -0
- package/dist/discovery/files.d.ts +48 -4
- package/dist/discovery/files.d.ts.map +1 -1
- package/dist/discovery/fold-import.d.ts +32 -1
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/sandbox/driver.d.ts +20 -0
- package/dist/discovery/sandbox/driver.d.ts.map +1 -1
- package/dist/discovery/sandbox/fork.d.ts +20 -0
- package/dist/discovery/sandbox/fork.d.ts.map +1 -1
- package/dist/discovery/walk.d.ts +119 -0
- package/dist/discovery/walk.d.ts.map +1 -0
- package/dist/graph-ir.d.ts +17 -1
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/join-key.d.ts +31 -0
- package/dist/join-key.d.ts.map +1 -0
- package/dist/lexicon-module.d.ts +110 -0
- package/dist/lexicon-module.d.ts.map +1 -0
- package/dist/lexicon.d.ts +82 -1
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/build-ledger-store.d.ts.map +1 -1
- package/dist/lifecycle/digest.d.ts +5 -1
- package/dist/lifecycle/digest.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +20 -5
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts +64 -0
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/lease.d.ts +8 -1
- package/dist/lifecycle/lease.d.ts.map +1 -1
- package/dist/lifecycle/legacy-digest.d.ts +59 -0
- package/dist/lifecycle/legacy-digest.d.ts.map +1 -0
- package/dist/lifecycle/member-ledger.d.ts +67 -0
- package/dist/lifecycle/member-ledger.d.ts.map +1 -0
- package/dist/lifecycle/plan-digest.d.ts +4 -3
- package/dist/lifecycle/plan-digest.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.d.ts +42 -1
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/status.d.ts +90 -5
- package/dist/lifecycle/status.d.ts.map +1 -1
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts +2 -3
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.d.ts +32 -0
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/index.d.ts +2 -0
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/propose-upgrade.d.ts +75 -0
- package/dist/op/activities/propose-upgrade.d.ts.map +1 -0
- package/dist/op/activity-contract-registry.d.ts.map +1 -1
- package/dist/op/activity-registry.d.ts.map +1 -1
- package/dist/op/discover.d.ts.map +1 -1
- package/dist/op/gate-approval.d.ts.map +1 -1
- package/dist/op/gate-name.d.ts +7 -0
- package/dist/op/gate-name.d.ts.map +1 -1
- package/dist/op/gate-summary.d.ts +16 -0
- package/dist/op/gate-summary.d.ts.map +1 -1
- package/dist/op/gate.d.ts +16 -2
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/generate-pipeline.d.ts.map +1 -1
- package/dist/op/runtimes/local.d.ts.map +1 -1
- package/dist/project-root.d.ts +26 -0
- package/dist/project-root.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/contract-repo.d.ts +37 -0
- package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -0
- package/dist/workspace/__fixtures__/two-member-workspace.d.ts +11 -0
- package/dist/workspace/__fixtures__/two-member-workspace.d.ts.map +1 -0
- package/dist/workspace/checks/generated.d.ts +156 -0
- package/dist/workspace/checks/generated.d.ts.map +1 -0
- package/dist/workspace/checks/ledgers.d.ts +78 -0
- package/dist/workspace/checks/ledgers.d.ts.map +1 -0
- package/dist/workspace/checks/links.d.ts +25 -0
- package/dist/workspace/checks/links.d.ts.map +1 -0
- package/dist/workspace/checks/pipelines.d.ts +76 -0
- package/dist/workspace/checks/pipelines.d.ts.map +1 -0
- package/dist/workspace/checks.d.ts +161 -0
- package/dist/workspace/checks.d.ts.map +1 -0
- package/dist/workspace/compose-graph.d.ts +115 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -0
- package/dist/workspace/compose-reports.d.ts +68 -0
- package/dist/workspace/compose-reports.d.ts.map +1 -0
- package/dist/workspace/declaration.d.ts +220 -0
- package/dist/workspace/declaration.d.ts.map +1 -0
- package/dist/workspace/declaration.schema.json +434 -0
- package/dist/workspace/generated-files.d.ts +65 -0
- package/dist/workspace/generated-files.d.ts.map +1 -0
- package/dist/workspace/glob.d.ts +13 -0
- package/dist/workspace/glob.d.ts.map +1 -0
- package/dist/workspace/graph-cli.d.ts +75 -0
- package/dist/workspace/graph-cli.d.ts.map +1 -0
- package/dist/workspace/init.d.ts +96 -0
- package/dist/workspace/init.d.ts.map +1 -0
- package/dist/workspace/jsonc.d.ts +38 -0
- package/dist/workspace/jsonc.d.ts.map +1 -0
- package/dist/workspace/kinds.d.ts +192 -0
- package/dist/workspace/kinds.d.ts.map +1 -0
- package/dist/workspace/lineage-check.d.ts +84 -0
- package/dist/workspace/lineage-check.d.ts.map +1 -0
- package/dist/workspace/lineage-cli.d.ts +31 -0
- package/dist/workspace/lineage-cli.d.ts.map +1 -0
- package/dist/workspace/lineage-init.d.ts +101 -0
- package/dist/workspace/lineage-init.d.ts.map +1 -0
- package/dist/workspace/lineage-lock.d.ts +258 -0
- package/dist/workspace/lineage-lock.d.ts.map +1 -0
- package/dist/workspace/lineage-merge.d.ts +14 -0
- package/dist/workspace/lineage-merge.d.ts.map +1 -0
- package/dist/workspace/lineage-migrations.d.ts +178 -0
- package/dist/workspace/lineage-migrations.d.ts.map +1 -0
- package/dist/workspace/lineage-update.d.ts +59 -0
- package/dist/workspace/lineage-update.d.ts.map +1 -0
- package/dist/workspace/lineage-upgrade-cli.d.ts +40 -0
- package/dist/workspace/lineage-upgrade-cli.d.ts.map +1 -0
- package/dist/workspace/lineage-upgrade.d.ts +146 -0
- package/dist/workspace/lineage-upgrade.d.ts.map +1 -0
- package/dist/workspace/lineage-vendor.d.ts +63 -0
- package/dist/workspace/lineage-vendor.d.ts.map +1 -0
- package/dist/workspace/lineage-version.d.ts +32 -0
- package/dist/workspace/lineage-version.d.ts.map +1 -0
- package/dist/workspace/links.d.ts +150 -0
- package/dist/workspace/links.d.ts.map +1 -0
- package/dist/workspace/ls.d.ts +99 -0
- package/dist/workspace/ls.d.ts.map +1 -0
- package/dist/workspace/member-commands.d.ts +139 -0
- package/dist/workspace/member-commands.d.ts.map +1 -0
- package/dist/workspace/member-handles.d.ts +54 -0
- package/dist/workspace/member-handles.d.ts.map +1 -0
- package/dist/workspace/member-pipeline.d.ts +143 -0
- package/dist/workspace/member-pipeline.d.ts.map +1 -0
- package/dist/workspace/member-run.d.ts +67 -0
- package/dist/workspace/member-run.d.ts.map +1 -0
- package/dist/workspace/reason-codes.d.ts +65 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -0
- package/dist/workspace/record-source.d.ts +22 -0
- package/dist/workspace/record-source.d.ts.map +1 -0
- package/dist/workspace/records-cli.d.ts +81 -0
- package/dist/workspace/records-cli.d.ts.map +1 -0
- package/dist/workspace/records.d.ts +118 -0
- package/dist/workspace/records.d.ts.map +1 -0
- package/dist/workspace/root-refusal.d.ts +53 -0
- package/dist/workspace/root-refusal.d.ts.map +1 -0
- package/dist/workspace/status.d.ts +150 -0
- package/dist/workspace/status.d.ts.map +1 -0
- package/dist/workspace/template-manifest.d.ts +90 -0
- package/dist/workspace/template-manifest.d.ts.map +1 -0
- package/dist/workspace/tree.d.ts +36 -0
- package/dist/workspace/tree.d.ts.map +1 -0
- package/dist/workspace/trust/attestor.d.ts +67 -0
- package/dist/workspace/trust/attestor.d.ts.map +1 -0
- package/dist/workspace/trust/policy.d.ts +111 -0
- package/dist/workspace/trust/policy.d.ts.map +1 -0
- package/dist/workspace/trust/provenance.d.ts +67 -0
- package/dist/workspace/trust/provenance.d.ts.map +1 -0
- package/dist/workspace/trust/ssh-commit.d.ts +43 -0
- package/dist/workspace/trust/ssh-commit.d.ts.map +1 -0
- package/dist/workspace/trust/test-repo.d.ts +42 -0
- package/dist/workspace/trust/test-repo.d.ts.map +1 -0
- package/dist/workspace/trust/verify-cli.d.ts +9 -0
- package/dist/workspace/trust/verify-cli.d.ts.map +1 -0
- package/dist/workspace/trust/verify.d.ts +66 -0
- package/dist/workspace/trust/verify.d.ts.map +1 -0
- package/dist/workspace/which-chant.d.ts +58 -0
- package/dist/workspace/which-chant.d.ts.map +1 -0
- package/dist/workspace/workspace-kinds.schema.json +133 -0
- package/package.json +4 -3
- package/src/audit/core.ts +13 -2
- package/src/audit/discover.ts +102 -36
- package/src/audit/report-html.ts +3 -1
- package/src/audit/report-model.ts +14 -1
- package/src/audit/terraform-state.test.ts +81 -1
- package/src/audit/terraform-state.ts +25 -0
- package/src/cli/command-group.ts +7 -0
- package/src/cli/commands/audit-truncation.test.ts +167 -0
- package/src/cli/commands/audit.ts +132 -29
- package/src/cli/commands/check-lexicon-examples.ts +2 -1
- package/src/cli/commands/check-lexicon.ts +24 -0
- package/src/cli/commands/doctor.test.ts +30 -0
- package/src/cli/commands/doctor.ts +21 -0
- package/src/cli/commands/import-agents.ts +15 -4
- package/src/cli/commands/init.ts +76 -25
- package/src/cli/commands/lint.test.ts +52 -1
- package/src/cli/commands/lint.ts +41 -71
- package/src/cli/commands/onboard.ts +15 -0
- package/src/cli/commands/update.ts +18 -5
- package/src/cli/commands/vendor.ts +11 -6
- package/src/cli/conflict-check.test.ts +18 -1
- package/src/cli/conflict-check.ts +13 -0
- package/src/cli/discovery-skip.test.ts +168 -0
- package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +38 -0
- package/src/cli/handlers/build-member.test.ts +127 -0
- package/src/cli/handlers/build.test.ts +11 -0
- package/src/cli/handlers/build.ts +35 -1
- package/src/cli/handlers/components.test.ts +127 -0
- package/src/cli/handlers/components.ts +70 -8
- package/src/cli/handlers/dev.ts +6 -1
- package/src/cli/handlers/fan-out.ts +9 -2
- package/src/cli/handlers/graph.test.ts +20 -0
- package/src/cli/handlers/graph.ts +4 -2
- package/src/cli/handlers/init.ts +54 -1
- package/src/cli/handlers/lifecycle.ts +2 -1
- package/src/cli/handlers/misc.ts +16 -0
- package/src/cli/handlers/operator.test.ts +68 -0
- package/src/cli/handlers/operator.ts +39 -10
- package/src/cli/handlers/promote.test.ts +377 -0
- package/src/cli/handlers/promote.ts +391 -0
- package/src/cli/handlers/run-generate-member.test.ts +83 -0
- package/src/cli/handlers/run-generate.test.ts +158 -0
- package/src/cli/handlers/run-generate.ts +168 -0
- package/src/cli/handlers/run.test.ts +47 -0
- package/src/cli/handlers/run.ts +41 -6
- package/src/cli/handlers/vendor.ts +147 -43
- package/src/cli/main.test.ts +137 -1
- package/src/cli/main.ts +290 -24
- package/src/cli/mcp/op-tools.ts +2 -1
- package/src/cli/path-lexicon-messages.test.ts +152 -0
- package/src/cli/plugins.ts +43 -5
- package/src/cli/registry.ts +46 -1
- package/src/cli/static-config-read.test.ts +208 -0
- package/src/codegen/fetch.test.ts +63 -1
- package/src/codegen/fetch.ts +30 -1
- package/src/components/__fixtures__/alb-ecs-service.json +0 -8
- package/src/components/capability-plugin-loader.ts +3 -1
- package/src/components/cli-support.ts +9 -3
- package/src/components/discover.test.ts +27 -57
- package/src/components/discover.ts +20 -51
- package/src/components/driver.test.ts +90 -12
- package/src/components/driver.ts +43 -5
- package/src/components/fan-out-support.ts +2 -1
- package/src/components/gate-plan.ts +53 -0
- package/src/components/pilots/README.md +1 -1
- package/src/components/pilots/alb-ecs.pilot.ts +7 -7
- package/src/components/presets/ecs-fargate.ts +10 -5
- package/src/components/promote.test.ts +645 -0
- package/src/components/promote.ts +641 -0
- package/src/components/sandbox/driver.ts +8 -8
- package/src/components/sandbox/run.ts +4 -1
- package/src/components/verbs/build-archive.ts +27 -21
- package/src/components/verbs/run-agent.ts +3 -5
- package/src/config-static.test.ts +136 -0
- package/src/config-static.ts +232 -0
- package/src/config.test.ts +40 -0
- package/src/config.ts +161 -11
- package/src/content-digest.test.ts +120 -0
- package/src/content-digest.ts +21 -0
- package/src/discovery/files.test.ts +127 -1
- package/src/discovery/files.ts +91 -59
- package/src/discovery/fold-import.ts +127 -9
- package/src/discovery/index.ts +1 -0
- package/src/discovery/sandbox/driver.ts +73 -35
- package/src/discovery/sandbox/fork-diagnostic.test.ts +136 -13
- package/src/discovery/sandbox/fork.ts +83 -43
- package/src/discovery/sandbox/path-lexicon-multifile.test.ts +285 -0
- package/src/discovery/sandbox/path-lexicon-parity.test.ts +162 -0
- package/src/discovery/walk.test.ts +263 -0
- package/src/discovery/walk.ts +334 -0
- package/src/effect-receipt.ts +2 -2
- package/src/graph-ir.ts +18 -1
- package/src/join-key.test.ts +25 -0
- package/src/join-key.ts +39 -0
- package/src/lexicon-module.test.ts +203 -0
- package/src/lexicon-module.ts +215 -0
- package/src/lexicon.ts +105 -1
- package/src/lifecycle/build-ledger-store.ts +13 -2
- package/src/lifecycle/digest.ts +9 -5
- package/src/lifecycle/gate-ledger.test.ts +20 -0
- package/src/lifecycle/gate-ledger.ts +28 -6
- package/src/lifecycle/git.test.ts +13 -1
- package/src/lifecycle/git.ts +221 -176
- package/src/lifecycle/lease.ts +25 -10
- package/src/lifecycle/legacy-digest.test.ts +206 -0
- package/src/lifecycle/legacy-digest.ts +103 -0
- package/src/lifecycle/member-ledger.test.ts +319 -0
- package/src/lifecycle/member-ledger.ts +145 -0
- package/src/lifecycle/plan-digest.ts +7 -7
- package/src/lifecycle/release-ledger.test.ts +20 -0
- package/src/lifecycle/release-ledger.ts +53 -3
- package/src/lifecycle/status.test.ts +151 -1
- package/src/lifecycle/status.ts +228 -7
- package/src/lint/rules/comp/comp003-mutating-no-rollback.ts +2 -3
- package/src/op/activities/activity-contracts.ts +37 -0
- package/src/op/activities/index.ts +10 -0
- package/src/op/activities/propose-upgrade.ts +206 -0
- package/src/op/activity-contract-registry.ts +18 -4
- package/src/op/activity-registry.ts +26 -0
- package/src/op/discover.test.ts +14 -4
- package/src/op/discover.ts +19 -23
- package/src/op/gate-approval.ts +3 -1
- package/src/op/gate-name.ts +8 -0
- package/src/op/gate-summary.test.ts +14 -0
- package/src/op/gate-summary.ts +25 -2
- package/src/op/gate.ts +36 -7
- package/src/op/generate-pipeline.test.ts +14 -5
- package/src/op/generate-pipeline.ts +2 -1
- package/src/op/runtimes/local.ts +2 -1
- package/src/project-root.test.ts +66 -1
- package/src/project-root.ts +48 -0
- package/src/workspace/__fixtures__/contract-repo.ts +100 -0
- package/src/workspace/__fixtures__/two-member-workspace.ts +35 -0
- package/src/workspace/behold-kinds.test.ts +162 -0
- package/src/workspace/check-contract.test.ts +127 -0
- package/src/workspace/check.schema.json +347 -0
- package/src/workspace/checks/generated.test.ts +287 -0
- package/src/workspace/checks/generated.ts +475 -0
- package/src/workspace/checks/ledgers.test.ts +139 -0
- package/src/workspace/checks/ledgers.ts +246 -0
- package/src/workspace/checks/links.ts +183 -0
- package/src/workspace/checks/pipelines.test.ts +133 -0
- package/src/workspace/checks/pipelines.ts +225 -0
- package/src/workspace/checks-repo.test.ts +71 -0
- package/src/workspace/checks.test.ts +450 -0
- package/src/workspace/checks.ts +461 -0
- package/src/workspace/compose-graph.test.ts +146 -0
- package/src/workspace/compose-graph.ts +228 -0
- package/src/workspace/compose-reports.test.ts +109 -0
- package/src/workspace/compose-reports.ts +186 -0
- package/src/workspace/declaration.schema.json +434 -0
- package/src/workspace/declaration.test.ts +347 -0
- package/src/workspace/declaration.ts +623 -0
- package/src/workspace/generated-files.test.ts +114 -0
- package/src/workspace/generated-files.ts +94 -0
- package/src/workspace/glob.ts +49 -0
- package/src/workspace/graph-cli.ts +220 -0
- package/src/workspace/graph-contract.test.ts +204 -0
- package/src/workspace/graph.schema.json +662 -0
- package/src/workspace/init.test.ts +223 -0
- package/src/workspace/init.ts +585 -0
- package/src/workspace/jsonc.test.ts +65 -0
- package/src/workspace/jsonc.ts +231 -0
- package/src/workspace/kinds.test.ts +288 -0
- package/src/workspace/kinds.ts +506 -0
- package/src/workspace/lineage-check.ts +264 -0
- package/src/workspace/lineage-cli.ts +114 -0
- package/src/workspace/lineage-init.test.ts +231 -0
- package/src/workspace/lineage-init.ts +365 -0
- package/src/workspace/lineage-lock.test.ts +224 -0
- package/src/workspace/lineage-lock.ts +357 -0
- package/src/workspace/lineage-merge.ts +44 -0
- package/src/workspace/lineage-migrations.test.ts +178 -0
- package/src/workspace/lineage-migrations.ts +343 -0
- package/src/workspace/lineage-update.ts +160 -0
- package/src/workspace/lineage-upgrade-cli.ts +151 -0
- package/src/workspace/lineage-upgrade.test.ts +474 -0
- package/src/workspace/lineage-upgrade.ts +624 -0
- package/src/workspace/lineage-vendor.test.ts +126 -0
- package/src/workspace/lineage-vendor.ts +215 -0
- package/src/workspace/lineage-version.ts +127 -0
- package/src/workspace/links.test.ts +344 -0
- package/src/workspace/links.ts +331 -0
- package/src/workspace/ls-contract.test.ts +200 -0
- package/src/workspace/ls.schema.json +190 -0
- package/src/workspace/ls.ts +254 -0
- package/src/workspace/member-commands.e2e.test.ts +244 -0
- package/src/workspace/member-commands.test.ts +217 -0
- package/src/workspace/member-commands.ts +540 -0
- package/src/workspace/member-handles.test.ts +76 -0
- package/src/workspace/member-handles.ts +228 -0
- package/src/workspace/member-pipeline.test.ts +135 -0
- package/src/workspace/member-pipeline.ts +317 -0
- package/src/workspace/member-run.ts +146 -0
- package/src/workspace/read-contract.test.ts +129 -0
- package/src/workspace/reason-codes.test.ts +113 -0
- package/src/workspace/reason-codes.ts +81 -0
- package/src/workspace/record-source.ts +117 -0
- package/src/workspace/records-cli.ts +198 -0
- package/src/workspace/records-contract.test.ts +93 -0
- package/src/workspace/records.schema.json +150 -0
- package/src/workspace/records.test.ts +243 -0
- package/src/workspace/records.ts +384 -0
- package/src/workspace/root-refusal.ts +97 -0
- package/src/workspace/status-contract.test.ts +308 -0
- package/src/workspace/status.schema.json +210 -0
- package/src/workspace/status.ts +412 -0
- package/src/workspace/template-manifest.test.ts +79 -0
- package/src/workspace/template-manifest.ts +221 -0
- package/src/workspace/tree.ts +132 -0
- package/src/workspace/trust/attestor.ts +93 -0
- package/src/workspace/trust/policy.ts +306 -0
- package/src/workspace/trust/provenance.ts +181 -0
- package/src/workspace/trust/ssh-commit.ts +138 -0
- package/src/workspace/trust/test-repo.ts +138 -0
- package/src/workspace/trust/trust.test.ts +397 -0
- package/src/workspace/trust/verify-cli.ts +56 -0
- package/src/workspace/trust/verify.ts +194 -0
- package/src/workspace/which-chant.test.ts +117 -0
- package/src/workspace/which-chant.ts +151 -0
- package/src/workspace/workspace-kinds.schema.json +133 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers the read-contract tests share (#2536): throwaway git repositories,
|
|
3
|
+
* a draft 2020-12 validator, and a fake chant toolchain.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { execFileSync } from "node:child_process";
|
|
7
|
+
import { chmodSync, mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
import { dirname, join } from "node:path";
|
|
10
|
+
import Ajv2020 from "ajv/dist/2020";
|
|
11
|
+
import { expect } from "vitest";
|
|
12
|
+
|
|
13
|
+
/** The chant checkout these tests run in. */
|
|
14
|
+
export const REPO = realpathSync(join(import.meta.dirname, "..", "..", "..", "..", ".."));
|
|
15
|
+
|
|
16
|
+
const scratch: string[] = [];
|
|
17
|
+
|
|
18
|
+
/** Remove every directory {@link scratchDir} and {@link repo} made. Call it from `afterAll`. */
|
|
19
|
+
export function cleanScratch(): void {
|
|
20
|
+
for (const d of scratch.splice(0)) rmSync(d, { recursive: true, force: true });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function scratchDir(prefix = "chant-contract-"): string {
|
|
24
|
+
const d = realpathSync(mkdtempSync(join(tmpdir(), prefix)));
|
|
25
|
+
scratch.push(d);
|
|
26
|
+
return d;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function git(cwd: string, ...args: string[]): string {
|
|
30
|
+
return execFileSync("git", ["-c", "user.name=t", "-c", "user.email=t@example.com", "-c", "commit.gpgsign=false", ...args], {
|
|
31
|
+
cwd,
|
|
32
|
+
encoding: "utf-8",
|
|
33
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
34
|
+
}).trim();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Write `files` under `root`; a value of `{ text, mode }` sets the mode too. */
|
|
38
|
+
export function writeFiles(root: string, files: Record<string, string | { text: string; mode: number }>): void {
|
|
39
|
+
for (const [path, value] of Object.entries(files)) {
|
|
40
|
+
const full = join(root, path);
|
|
41
|
+
mkdirSync(dirname(full), { recursive: true });
|
|
42
|
+
writeFileSync(full, typeof value === "string" ? value : value.text);
|
|
43
|
+
if (typeof value !== "string") chmodSync(full, value.mode);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** A git repository holding `files`, with nothing committed unless `commit` is set. */
|
|
48
|
+
export function repo(files: Record<string, string | { text: string; mode: number }>, commit = false): string {
|
|
49
|
+
const root = scratchDir("chant-contract-repo-");
|
|
50
|
+
writeFiles(root, files);
|
|
51
|
+
git(root, "init", "-q");
|
|
52
|
+
if (commit) {
|
|
53
|
+
git(root, "add", "-A");
|
|
54
|
+
git(root, "commit", "-q", "-m", "one");
|
|
55
|
+
}
|
|
56
|
+
return root;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function commitAll(root: string, message = "next"): string {
|
|
60
|
+
git(root, "add", "-A");
|
|
61
|
+
git(root, "commit", "-q", "-m", message);
|
|
62
|
+
return git(root, "rev-parse", "HEAD");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const ajv = new Ajv2020({ strict: true, allErrors: true });
|
|
66
|
+
|
|
67
|
+
/** A validator for `schema`, and an assertion that a document passes it. */
|
|
68
|
+
export function contract(schema: object): { validate: ReturnType<typeof ajv.compile>; expectValid(doc: unknown): void } {
|
|
69
|
+
const validate = ajv.compile(schema);
|
|
70
|
+
return {
|
|
71
|
+
validate,
|
|
72
|
+
expectValid(doc) {
|
|
73
|
+
const ok = validate(doc);
|
|
74
|
+
expect(ok, `${JSON.stringify(validate.errors, null, 2)}\n${JSON.stringify(doc, null, 2).slice(0, 2000)}`).toBe(true);
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function validSchema(schema: object): boolean {
|
|
80
|
+
return ajv.validateSchema(schema) as boolean;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const declaration = (members: unknown[], extra: Record<string, unknown> = {}) =>
|
|
84
|
+
JSON.stringify({ name: "acme", schema: 1, ...extra, members }, null, 2);
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* A chant older than `workspace member-run`: it answers `chant graph` in the
|
|
88
|
+
* member's directory with one node per line of the member's `ids.txt`.
|
|
89
|
+
*/
|
|
90
|
+
export const FAKE_GRAPH_CHANT = `#!/bin/sh
|
|
91
|
+
case "$1" in
|
|
92
|
+
graph)
|
|
93
|
+
printf '{"version":1,"nodes":['
|
|
94
|
+
sep=""
|
|
95
|
+
while read -r id; do printf '%s{"id":"%s","kind":"Thing","lexicon":"fake","attrs":{}}' "$sep" "$id"; sep=","; done < ids.txt
|
|
96
|
+
printf '],"edges":[],"groups":{"byLexicon":{}}}\\n'
|
|
97
|
+
;;
|
|
98
|
+
*) echo "Error: Unknown command: $1" >&2; exit 1 ;;
|
|
99
|
+
esac
|
|
100
|
+
`;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A throwaway git repository holding a workspace with two members (api and
|
|
3
|
+
* web), optionally a root member, and an example group with one match. Used
|
|
4
|
+
* by the per-member pipeline tests (#2542).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { execFileSync } from "node:child_process";
|
|
8
|
+
import { mkdirSync, mkdtempSync, realpathSync, writeFileSync } from "node:fs";
|
|
9
|
+
import { tmpdir } from "node:os";
|
|
10
|
+
import { dirname, join } from "node:path";
|
|
11
|
+
|
|
12
|
+
/** A git repository holding a workspace with two members, a root member and an example group. */
|
|
13
|
+
export function twoMemberWorkspace(options: { root?: boolean; prefix?: string } = {}): string {
|
|
14
|
+
const repo = realpathSync(mkdtempSync(join(tmpdir(), "chant-member-pipeline-")));
|
|
15
|
+
execFileSync("git", ["init", "-q"], { cwd: repo });
|
|
16
|
+
const ws = options.prefix ? join(repo, options.prefix) : repo;
|
|
17
|
+
const members: unknown[] = [
|
|
18
|
+
{ name: "api", dir: "services/api", kind: "chant" },
|
|
19
|
+
{ name: "web", dir: "apps/web", kind: "chant" },
|
|
20
|
+
{ name: "samples", kind: "examples", glob: "examples/*" },
|
|
21
|
+
];
|
|
22
|
+
if (options.root) members.unshift({ name: "platform", dir: ".", kind: "chant" });
|
|
23
|
+
const files: Record<string, string> = {
|
|
24
|
+
"chant.workspace.json": JSON.stringify({ name: "shop", schema: 1, members }, null, 2),
|
|
25
|
+
"services/api/chant.config.ts": "export default {};\n",
|
|
26
|
+
"services/api/src/infra.ts": "\n",
|
|
27
|
+
"apps/web/chant.config.ts": "export default {};\n",
|
|
28
|
+
"examples/demo/chant.config.ts": "export default {};\n",
|
|
29
|
+
};
|
|
30
|
+
for (const [path, text] of Object.entries(files)) {
|
|
31
|
+
mkdirSync(dirname(join(ws, path)), { recursive: true });
|
|
32
|
+
writeFileSync(join(ws, path), text);
|
|
33
|
+
}
|
|
34
|
+
return repo;
|
|
35
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* behold's two closed member kinds, read through chant's workspace (#2545).
|
|
3
|
+
*
|
|
4
|
+
* `terraform` ships from the terraform lexicon's `./workspace-kinds` subpath,
|
|
5
|
+
* and `choudoufu` from the kinds-only package
|
|
6
|
+
* `@intentius/workspace-kind-choudoufu`. A workspace that pins both lists
|
|
7
|
+
* members of either kind through `chant workspace ls --json`, with the kinds
|
|
8
|
+
* behold gave the same directories, and reading the kinds imports neither
|
|
9
|
+
* package.
|
|
10
|
+
*
|
|
11
|
+
* The installed packages are the repo's own: their package.json and kinds
|
|
12
|
+
* file are copied as they ship, and every code entry their `exports` name is
|
|
13
|
+
* replaced by a module that leaves a marker file when it is imported.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
17
|
+
import { tmpdir } from "node:os";
|
|
18
|
+
import { dirname, join } from "node:path";
|
|
19
|
+
import { afterAll, afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
|
20
|
+
import { parseArgs } from "../cli/main";
|
|
21
|
+
import { runDeclarationChecks } from "./checks";
|
|
22
|
+
import { loadKindRegistry, resolveKind } from "./kinds";
|
|
23
|
+
import { runWorkspaceLs, type LsDocument } from "./ls";
|
|
24
|
+
import { workingTree } from "./tree";
|
|
25
|
+
|
|
26
|
+
const REPO = join(import.meta.dirname, "..", "..", "..", "..");
|
|
27
|
+
const TERRAFORM = join(REPO, "lexicons", "terraform");
|
|
28
|
+
const CHOUDOUFU = join(REPO, "packages", "workspace-kind-choudoufu");
|
|
29
|
+
const FIXTURES = join(TERRAFORM, "src", "__fixtures__");
|
|
30
|
+
|
|
31
|
+
const scratch: string[] = [];
|
|
32
|
+
afterAll(() => {
|
|
33
|
+
for (const d of scratch) rmSync(d, { recursive: true, force: true });
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const version = (dir: string): string => (JSON.parse(readFileSync(join(dir, "package.json"), "utf-8")) as { version: string }).version;
|
|
37
|
+
|
|
38
|
+
const MARKER = `import { writeFileSync } from "node:fs";\nwriteFileSync(new URL("./IMPORTED", import.meta.url), "");\n(globalThis as { __chantKindsImported?: boolean }).__chantKindsImported = true;\n`;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Install the package in `from` under `root/node_modules`: its package.json
|
|
42
|
+
* and kinds file as they are, and a marker module at every code target its
|
|
43
|
+
* exports name, the `./*` pattern's target for `workspace-kinds` included.
|
|
44
|
+
*/
|
|
45
|
+
function install(root: string, from: string): string {
|
|
46
|
+
const manifest = JSON.parse(readFileSync(join(from, "package.json"), "utf-8")) as { name: string; exports: Record<string, unknown> };
|
|
47
|
+
const dir = join(root, "node_modules", ...manifest.name.split("/"));
|
|
48
|
+
mkdirSync(dir, { recursive: true });
|
|
49
|
+
cpSync(join(from, "package.json"), join(dir, "package.json"));
|
|
50
|
+
cpSync(join(from, "workspace-kinds.json"), join(dir, "workspace-kinds.json"));
|
|
51
|
+
const targets = new Set<string>(["./index.js"]);
|
|
52
|
+
const collect = (entry: unknown): void => {
|
|
53
|
+
if (typeof entry === "string") targets.add(entry.replace("*", "workspace-kinds"));
|
|
54
|
+
else if (entry && typeof entry === "object") for (const v of Object.values(entry)) collect(v);
|
|
55
|
+
};
|
|
56
|
+
for (const [key, entry] of Object.entries(manifest.exports)) if (key !== "./workspace-kinds") collect(entry);
|
|
57
|
+
for (const t of targets) {
|
|
58
|
+
if (!/\.(ts|js|mjs)$/.test(t)) continue;
|
|
59
|
+
mkdirSync(dirname(join(dir, t)), { recursive: true });
|
|
60
|
+
writeFileSync(join(dir, t), MARKER);
|
|
61
|
+
}
|
|
62
|
+
return dir;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function workspace(): { root: string; installed: string[] } {
|
|
66
|
+
const root = realpathSync(mkdtempSync(join(tmpdir(), "chant-behold-kinds-")));
|
|
67
|
+
scratch.push(root);
|
|
68
|
+
const installed = [install(root, TERRAFORM), install(root, CHOUDOUFU)];
|
|
69
|
+
// Estates in the shapes behold serves: a stock root, a choudoufu root with
|
|
70
|
+
// the sidecar, one with the live block, and a chant project beside .tf files.
|
|
71
|
+
cpSync(join(FIXTURES, "no-backend"), join(root, "estates", "stock"), { recursive: true });
|
|
72
|
+
cpSync(join(FIXTURES, "live-estate"), join(root, "estates", "sidecar"), { recursive: true });
|
|
73
|
+
cpSync(join(FIXTURES, "live"), join(root, "estates", "inline"), { recursive: true });
|
|
74
|
+
mkdirSync(join(root, "app"), { recursive: true });
|
|
75
|
+
writeFileSync(join(root, "app", "chant.config.ts"), "export default {};\n");
|
|
76
|
+
writeFileSync(join(root, "app", "main.tf"), 'resource "null_resource" "x" {}\n');
|
|
77
|
+
writeFileSync(
|
|
78
|
+
join(root, "chant.workspace.json"),
|
|
79
|
+
JSON.stringify(
|
|
80
|
+
{
|
|
81
|
+
name: "estate",
|
|
82
|
+
schema: 1,
|
|
83
|
+
pins: [
|
|
84
|
+
{ package: "@intentius/chant-lexicon-terraform", version: version(TERRAFORM) },
|
|
85
|
+
{ package: "@intentius/workspace-kind-choudoufu", version: version(CHOUDOUFU) },
|
|
86
|
+
],
|
|
87
|
+
members: [
|
|
88
|
+
{ name: "stock", dir: "estates/stock", kind: "terraform" },
|
|
89
|
+
{ name: "sidecar", dir: "estates/sidecar", kind: "choudoufu" },
|
|
90
|
+
{ name: "inline", dir: "estates/inline", kind: "choudoufu" },
|
|
91
|
+
{ name: "app", dir: "app", kind: "chant" },
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
null,
|
|
95
|
+
2,
|
|
96
|
+
),
|
|
97
|
+
);
|
|
98
|
+
return { root, installed };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
describe("behold's member kinds from their packages (#2545)", () => {
|
|
102
|
+
let out: string[];
|
|
103
|
+
beforeEach(() => {
|
|
104
|
+
out = [];
|
|
105
|
+
vi.spyOn(console, "log").mockImplementation((...a: unknown[]) => void out.push(a.join(" ")));
|
|
106
|
+
});
|
|
107
|
+
afterEach(() => vi.restoreAllMocks());
|
|
108
|
+
|
|
109
|
+
test("chant workspace ls --json lists terraform and choudoufu members, readable, and imports neither package", async () => {
|
|
110
|
+
const { root, installed } = workspace();
|
|
111
|
+
const code = await runWorkspaceLs({ args: parseArgs(["workspace", "ls", root, "--json"]), plugins: [] } as never);
|
|
112
|
+
expect(code).toBe(0);
|
|
113
|
+
const doc = JSON.parse(out.join("\n")) as Extract<LsDocument, { members: unknown }>;
|
|
114
|
+
expect(doc.members.map((m) => [m.name, m.kind, m.readable])).toEqual([
|
|
115
|
+
["stock", "terraform", true],
|
|
116
|
+
["sidecar", "choudoufu", true],
|
|
117
|
+
["inline", "choudoufu", true],
|
|
118
|
+
["app", "chant", true],
|
|
119
|
+
]);
|
|
120
|
+
for (const dir of installed) expect(existsSync(join(dir, "IMPORTED")), dir).toBe(false);
|
|
121
|
+
expect(existsSync(join(installed[0], "src", "IMPORTED"))).toBe(false);
|
|
122
|
+
expect((globalThis as { __chantKindsImported?: boolean }).__chantKindsImported).toBeUndefined();
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("each directory's kind is the one behold gave it: chant over choudoufu over terraform", () => {
|
|
126
|
+
const { root } = workspace();
|
|
127
|
+
const pins = [
|
|
128
|
+
{ package: "@intentius/chant-lexicon-terraform", version: version(TERRAFORM), path: null },
|
|
129
|
+
{ package: "@intentius/workspace-kind-choudoufu", version: version(CHOUDOUFU), path: null },
|
|
130
|
+
];
|
|
131
|
+
const { registry, problems } = loadKindRegistry(pins, root);
|
|
132
|
+
expect(problems).toEqual([]);
|
|
133
|
+
expect(registry.get("terraform")).toMatchObject({ source: "@intentius/chant-lexicon-terraform", precedence: 400 });
|
|
134
|
+
expect(registry.get("choudoufu")).toMatchObject({ source: "@intentius/workspace-kind-choudoufu", precedence: 450 });
|
|
135
|
+
const tree = workingTree(root);
|
|
136
|
+
const winner = (dir: string) => resolveKind(registry, tree, dir).winner?.name;
|
|
137
|
+
expect(winner("estates/stock")).toBe("terraform");
|
|
138
|
+
expect(winner("estates/sidecar")).toBe("choudoufu");
|
|
139
|
+
expect(winner("estates/inline")).toBe("choudoufu");
|
|
140
|
+
expect(winner("app")).toBe("chant");
|
|
141
|
+
expect(resolveKind(registry, tree, "estates/inline").claims.map((k) => k.name)).toEqual(["choudoufu", "terraform"]);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test("chant workspace check passes with no error: no member is outranked, and no probes tie", async () => {
|
|
145
|
+
const { root } = workspace();
|
|
146
|
+
const report = await runDeclarationChecks(root);
|
|
147
|
+
expect(report.diagnostics.filter((d) => d.severity === "error")).toEqual([]);
|
|
148
|
+
expect(report.ok).toBe(true);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test("without the pins, the same members are an unknown kind, and the message names the known ones", async () => {
|
|
152
|
+
const { root } = workspace();
|
|
153
|
+
const file = join(root, "chant.workspace.json");
|
|
154
|
+
const decl = JSON.parse(readFileSync(file, "utf-8")) as { pins?: unknown };
|
|
155
|
+
delete decl.pins;
|
|
156
|
+
writeFileSync(file, JSON.stringify(decl));
|
|
157
|
+
await runWorkspaceLs({ args: parseArgs(["workspace", "ls", root, "--json"]), plugins: [] } as never);
|
|
158
|
+
const doc = JSON.parse(out.join("\n")) as Extract<LsDocument, { members: unknown }>;
|
|
159
|
+
expect(doc.members.map((m) => m.reason?.code ?? null)).toEqual(["unknown-kind", "unknown-kind", "unknown-kind", null]);
|
|
160
|
+
expect(doc.members[0].reason?.message).toMatch(/known kinds: chant, other, workspace$/);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The read contract for `chant workspace check --json` and `--format json`
|
|
3
|
+
* (#2536, #2524 D15): the output schema is a valid draft 2020-12 document, its
|
|
4
|
+
* closed code lists match the code, and real output validates against it, for
|
|
5
|
+
* the chant repo (#2557), for built workspaces, and for `--at <rev>`.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { afterAll, describe, expect, test } from "vitest";
|
|
11
|
+
import { cleanScratch, commitAll, contract, declaration, git, REPO, repo, scratchDir, validSchema } from "./__fixtures__/contract-repo";
|
|
12
|
+
import schema from "./check.schema.json";
|
|
13
|
+
import { WORKSPACE_ERROR_CODES } from "./declaration";
|
|
14
|
+
import { CHECK_CODES, CHECK_CONTRACT_VERSION, CHECK_ERROR_CODES, CHECK_OUTPUT_SCHEMA_ID, runChecks, type CheckDocument } from "./lineage-check";
|
|
15
|
+
|
|
16
|
+
afterAll(cleanScratch);
|
|
17
|
+
|
|
18
|
+
const { expectValid } = contract(schema);
|
|
19
|
+
|
|
20
|
+
function result(doc: CheckDocument): Extract<CheckDocument, { findings: unknown }> {
|
|
21
|
+
if ("error" in doc) throw new Error(`${doc.error.code}: ${doc.error.message}`);
|
|
22
|
+
return doc;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const ruleIds = (doc: Extract<CheckDocument, { findings: unknown }>) => doc.declaration?.diagnostics.map((d) => d.ruleId) ?? [];
|
|
26
|
+
|
|
27
|
+
describe("check output schema", () => {
|
|
28
|
+
test("is a valid draft 2020-12 document with the published $id", () => {
|
|
29
|
+
expect(schema.$schema).toBe("https://json-schema.org/draft/2020-12/schema");
|
|
30
|
+
expect(validSchema(schema)).toBe(true);
|
|
31
|
+
expect(schema.$id).toBe(CHECK_OUTPUT_SCHEMA_ID);
|
|
32
|
+
expect(CHECK_CONTRACT_VERSION).toBe(1);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("lists exactly the codes the code can return", () => {
|
|
36
|
+
expect(schema.$defs.lockFinding.properties.code.enum).toEqual([...CHECK_CODES]);
|
|
37
|
+
expect(schema.$defs.failure.properties.error.properties.code.enum).toEqual([...CHECK_ERROR_CODES]);
|
|
38
|
+
expect(schema.$defs.diagnostic.properties.code.enum).toEqual([...WORKSPACE_ERROR_CODES]);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe("chant workspace check on the chant repo (#2557)", () => {
|
|
43
|
+
test("validates in the working tree and at HEAD", async () => {
|
|
44
|
+
const now = result(await runChecks(REPO));
|
|
45
|
+
expectValid(now);
|
|
46
|
+
expect(now.workspace).toEqual({ name: "chant", root: "." });
|
|
47
|
+
expect(now.declaration?.file).toBe("chant.workspace.json");
|
|
48
|
+
|
|
49
|
+
const head = result(await runChecks(join(REPO, "packages", "core"), "HEAD"));
|
|
50
|
+
expectValid(head);
|
|
51
|
+
expect(head.at).toBe(git(REPO, "rev-parse", "HEAD"));
|
|
52
|
+
expect(head.workspace).toEqual({ name: "chant", root: "." });
|
|
53
|
+
expect(head.declaration?.file).toBe("../../chant.workspace.json");
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe("chant workspace check on built workspaces", () => {
|
|
58
|
+
test("a lock with no declaration: the lock findings carry their reason code", async () => {
|
|
59
|
+
const root = repo({ ".chant/workspace.lock.json": "{ not json" });
|
|
60
|
+
const doc = result(await runChecks(root));
|
|
61
|
+
expectValid(doc);
|
|
62
|
+
expect(doc.workspace).toBeNull();
|
|
63
|
+
expect(doc.declaration).toBeUndefined();
|
|
64
|
+
expect(doc.ok).toBe(false);
|
|
65
|
+
expect(doc.findings.map((f) => f.code)).toEqual(["lock-invalid"]);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("declaration findings carry WSP ids, and an unreadable declaration is WSP001 with its reason code", async () => {
|
|
69
|
+
const root = repo({
|
|
70
|
+
"chant.workspace.json": declaration([
|
|
71
|
+
{ name: "gone", dir: "gone", kind: "chant" },
|
|
72
|
+
{ name: "infra", dir: "infra", kind: "terraform" },
|
|
73
|
+
]),
|
|
74
|
+
"infra/main.tf": "",
|
|
75
|
+
});
|
|
76
|
+
const doc = result(await runChecks(root));
|
|
77
|
+
expectValid(doc);
|
|
78
|
+
expect(doc.ok).toBe(false);
|
|
79
|
+
expect(doc.workspace).toEqual({ name: "acme", root: "." });
|
|
80
|
+
expect(ruleIds(doc)).toEqual(["WSP004", "WSP003"]);
|
|
81
|
+
|
|
82
|
+
const tooOld = repo({ "chant.workspace.json": declaration([], { minReader: "999.0.0" }) });
|
|
83
|
+
const pinned = repo({ "chant.workspace.json": declaration([], { pins: [{ package: "@intentius/chant", version: "0.0.1" }] }) });
|
|
84
|
+
for (const [dir, code] of [
|
|
85
|
+
[tooOld, "reader-too-old"],
|
|
86
|
+
[pinned, "root-chant-required"],
|
|
87
|
+
] as const) {
|
|
88
|
+
const d = result(await runChecks(dir));
|
|
89
|
+
expectValid(d);
|
|
90
|
+
expect(d.workspace).toEqual({ name: null, root: "." });
|
|
91
|
+
expect(d.declaration?.diagnostics.map((x) => [x.ruleId, x.code])).toEqual([["WSP001", code]]);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("--at <rev> checks the declaration and lock as they were at the revision", async () => {
|
|
96
|
+
const root = repo({
|
|
97
|
+
"chant.workspace.json": declaration([{ name: "web", dir: "web", kind: "chant" }]),
|
|
98
|
+
"web/chant.config.ts": "",
|
|
99
|
+
});
|
|
100
|
+
const first = commitAll(root, "one");
|
|
101
|
+
// Break the working tree after the commit: the declaration, a member and the lock.
|
|
102
|
+
writeFileSync(join(root, "chant.workspace.json"), "{ broken");
|
|
103
|
+
mkdirSync(join(root, "web", ".chant"), { recursive: true });
|
|
104
|
+
writeFileSync(join(root, "web", ".chant", "workspace.lock.json"), "{ broken");
|
|
105
|
+
|
|
106
|
+
const at = result(await runChecks(join(root, "web"), first));
|
|
107
|
+
expectValid(at);
|
|
108
|
+
expect(at.at).toBe(first);
|
|
109
|
+
expect(at.ok).toBe(true);
|
|
110
|
+
expect(at.lock).toBeNull();
|
|
111
|
+
expect(at.declaration).toMatchObject({ file: "../chant.workspace.json", diagnostics: [], ok: true });
|
|
112
|
+
|
|
113
|
+
const now = result(await runChecks(join(root, "web")));
|
|
114
|
+
expectValid(now);
|
|
115
|
+
expect(now.ok).toBe(false);
|
|
116
|
+
expect(now.findings.map((f) => f.code)).toEqual(["lock-invalid"]);
|
|
117
|
+
expect(now.declaration?.diagnostics.map((d) => [d.ruleId, d.code])).toEqual([["WSP001", "declaration-unparseable"]]);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test("--at outside git or at an unknown revision is a failure document", async () => {
|
|
121
|
+
const outside = scratchDir("chant-check-nogit-");
|
|
122
|
+
const empty = repo({});
|
|
123
|
+
const docs = [await runChecks(outside, "HEAD"), await runChecks(empty, "no-such-rev")];
|
|
124
|
+
for (const d of docs) expectValid(d);
|
|
125
|
+
expect(docs.map((d) => ("error" in d ? d.error.code : "ok"))).toEqual(["not-a-git-repository", "revision-unknown"]);
|
|
126
|
+
});
|
|
127
|
+
});
|