@intentius/chant 0.80.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/discover.d.ts +8 -16
- 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 +4 -5
- package/dist/audit/terraform-state.d.ts.map +1 -1
- package/dist/cli/commands/audit.d.ts +25 -9
- package/dist/cli/commands/audit.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.map +1 -1
- package/dist/cli/commands/lint.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/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/operator.d.ts +7 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/promote.d.ts +7 -4
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/run-generate.d.ts.map +1 -1
- 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/plugins.d.ts +12 -7
- package/dist/cli/plugins.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +32 -0
- 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/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/gate-plan.d.ts +40 -0
- package/dist/components/gate-plan.d.ts.map +1 -0
- package/dist/components/promote.d.ts +60 -7
- package/dist/components/promote.d.ts.map +1 -1
- 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 +32 -10
- 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 +10 -5
- package/dist/discovery/files.d.ts.map +1 -1
- package/dist/discovery/fold-import.d.ts +20 -4
- 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 +4 -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 +51 -6
- package/dist/lexicon-module.d.ts.map +1 -1
- package/dist/lexicon.d.ts +58 -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 +41 -8
- package/dist/lifecycle/legacy-digest.d.ts.map +1 -1
- 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 +18 -2
- 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/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/discover.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/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/records-cli.d.ts +28 -4
- package/dist/workspace/records-cli.d.ts.map +1 -1
- package/dist/workspace/records.d.ts.map +1 -1
- 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 +2 -1
- package/src/audit/discover.ts +66 -78
- package/src/audit/report-html.ts +3 -1
- package/src/audit/report-model.ts +14 -1
- package/src/audit/terraform-state.test.ts +4 -9
- package/src/audit/terraform-state.ts +4 -5
- package/src/cli/commands/audit-truncation.test.ts +167 -0
- package/src/cli/commands/audit.ts +89 -60
- package/src/cli/commands/check-lexicon.ts +24 -0
- package/src/cli/commands/doctor.test.ts +30 -0
- package/src/cli/commands/doctor.ts +18 -0
- package/src/cli/commands/import-agents.ts +6 -2
- package/src/cli/commands/init.ts +22 -3
- package/src/cli/commands/lint.test.ts +17 -23
- package/src/cli/commands/lint.ts +24 -84
- package/src/cli/commands/update.ts +13 -4
- package/src/cli/commands/vendor.ts +11 -6
- 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.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 +5 -3
- package/src/cli/handlers/fan-out.ts +9 -2
- package/src/cli/handlers/init.ts +54 -1
- package/src/cli/handlers/operator.test.ts +68 -0
- package/src/cli/handlers/operator.ts +37 -9
- package/src/cli/handlers/promote.test.ts +118 -2
- package/src/cli/handlers/promote.ts +82 -16
- package/src/cli/handlers/run-generate-member.test.ts +83 -0
- package/src/cli/handlers/run-generate.test.ts +6 -8
- package/src/cli/handlers/run-generate.ts +36 -1
- package/src/cli/handlers/run.test.ts +47 -0
- package/src/cli/handlers/run.ts +28 -5
- package/src/cli/handlers/vendor.ts +147 -43
- package/src/cli/main.test.ts +105 -1
- package/src/cli/main.ts +230 -17
- package/src/cli/plugins.ts +17 -17
- package/src/cli/registry.ts +32 -0
- 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/cli-support.ts +6 -1
- package/src/components/discover.test.ts +27 -57
- package/src/components/discover.ts +13 -68
- package/src/components/driver.test.ts +78 -1
- package/src/components/driver.ts +43 -7
- package/src/components/gate-plan.ts +53 -0
- package/src/components/promote.test.ts +276 -2
- package/src/components/promote.ts +119 -15
- 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 +2 -2
- package/src/config.ts +48 -15
- package/src/content-digest.test.ts +120 -0
- package/src/content-digest.ts +21 -0
- package/src/discovery/files.test.ts +10 -10
- package/src/discovery/files.ts +25 -81
- package/src/discovery/fold-import.ts +49 -5
- 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/walk.test.ts +263 -0
- package/src/discovery/walk.ts +334 -0
- package/src/effect-receipt.ts +2 -2
- package/src/graph-ir.ts +4 -1
- package/src/join-key.test.ts +25 -0
- package/src/join-key.ts +39 -0
- package/src/lexicon-module.ts +108 -10
- package/src/lexicon.ts +79 -1
- package/src/lifecycle/build-ledger-store.ts +11 -10
- 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 +115 -23
- package/src/lifecycle/legacy-digest.ts +60 -19
- 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 +23 -7
- package/src/lifecycle/status.test.ts +151 -1
- package/src/lifecycle/status.ts +228 -7
- 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/discover.test.ts +14 -4
- package/src/op/discover.ts +19 -27
- 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/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/records-cli.ts +86 -14
- package/src/workspace/records-contract.test.ts +5 -0
- package/src/workspace/records.schema.json +32 -2
- package/src/workspace/records.ts +3 -2
- 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
- package/dist/components/unbound-gate-approval.d.ts +0 -24
- package/dist/components/unbound-gate-approval.d.ts.map +0 -1
- package/dist/discovery/convergence.d.ts +0 -97
- package/dist/discovery/convergence.d.ts.map +0 -1
- package/src/cli/commands/audit-walk-warnings.test.ts +0 -156
- package/src/components/unbound-gate-approval.test.ts +0 -82
- package/src/components/unbound-gate-approval.ts +0 -51
- package/src/discovery/convergence.test.ts +0 -231
- package/src/discovery/convergence.ts +0 -399
- package/src/op/discover-convergence.test.ts +0 -70
|
@@ -6,7 +6,6 @@ import { join, resolve } from "node:path";
|
|
|
6
6
|
import { tmpdir } from "node:os";
|
|
7
7
|
import { execFileSync } from "node:child_process";
|
|
8
8
|
import { params, setBuildParams } from "../../params";
|
|
9
|
-
import { resetDiscoveryWarnings } from "../../discovery/convergence";
|
|
10
9
|
|
|
11
10
|
describe("lintCommand", () => {
|
|
12
11
|
let testDir: string;
|
|
@@ -643,58 +642,53 @@ describe("lintCommand — git-ignored files are not linted", () => {
|
|
|
643
642
|
});
|
|
644
643
|
|
|
645
644
|
/**
|
|
646
|
-
* chant#2527
|
|
647
|
-
*
|
|
648
|
-
*
|
|
649
|
-
* what they did, with a warning naming the files and the glob.
|
|
645
|
+
* chant#2527: lint walks through the one discovery walk. A child project
|
|
646
|
+
* inside a project is a boundary, `include` re-admits it, and a scan root
|
|
647
|
+
* that is itself git-ignored is linted.
|
|
650
648
|
*/
|
|
651
|
-
describe("lintCommand —
|
|
649
|
+
describe("lintCommand — the converged discovery walk (#2527)", () => {
|
|
652
650
|
let testDir: string;
|
|
653
|
-
let stderr: string[];
|
|
654
651
|
const EVL003 = `const t = { a: 1 };\nexport function g(k: string) { return t[k]; }\n`;
|
|
655
652
|
|
|
656
653
|
beforeEach(async () => {
|
|
657
654
|
testDir = join(tmpdir(), `chant-lint-2527-${Date.now()}-${Math.random()}`);
|
|
658
655
|
await mkdir(testDir, { recursive: true });
|
|
659
656
|
process.env.NO_COLOR = "1";
|
|
660
|
-
resetDiscoveryWarnings();
|
|
661
|
-
stderr = [];
|
|
662
|
-
vi.spyOn(console, "error").mockImplementation((...args: unknown[]) => void stderr.push(args.join(" ")));
|
|
663
657
|
});
|
|
664
658
|
|
|
665
659
|
afterEach(async () => {
|
|
666
|
-
vi.restoreAllMocks();
|
|
667
660
|
await rm(testDir, { recursive: true, force: true });
|
|
668
661
|
delete process.env.NO_COLOR;
|
|
669
662
|
});
|
|
670
663
|
|
|
671
|
-
|
|
672
|
-
await writeFile(join(testDir, "chant.config.json"), JSON.stringify({ knowledge: { dir: "knowledge" } }));
|
|
664
|
+
async function childProject(config: Record<string, unknown>): Promise<void> {
|
|
665
|
+
await writeFile(join(testDir, "chant.config.json"), JSON.stringify({ knowledge: { dir: "knowledge" }, ...config }));
|
|
673
666
|
await writeFile(join(testDir, "index.ts"), `export const x = 1;\n`);
|
|
674
667
|
await mkdir(join(testDir, "stacks", "east"), { recursive: true });
|
|
675
668
|
await writeFile(join(testDir, "stacks", "east", "chant.config.ts"), `export default {};\n`);
|
|
676
669
|
await writeFile(join(testDir, "stacks", "east", "east.ts"), EVL003);
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
test("a nested child project is not linted from the parent", async () => {
|
|
673
|
+
await childProject({});
|
|
674
|
+
const result = await lintCommand({ path: testDir, format: "stylish" });
|
|
675
|
+
expect(result.diagnostics.some((d) => d.file.includes("east.ts"))).toBe(false);
|
|
676
|
+
});
|
|
677
677
|
|
|
678
|
+
test("include re-admits the child project", async () => {
|
|
679
|
+
await childProject({ include: ["stacks/east"] });
|
|
678
680
|
const result = await lintCommand({ path: testDir, format: "stylish" });
|
|
679
681
|
expect(result.diagnostics.some((d) => d.file.includes("east.ts") && d.ruleId === "EVL003")).toBe(true);
|
|
680
|
-
const warning = stderr.find((l) => l.startsWith("warning: chant lint under"));
|
|
681
|
-
expect(warning).toContain(" stacks/east/chant.config.ts, stacks/east/east.ts: stacks/east/ is a child project");
|
|
682
|
-
expect(warning).toContain('To keep reading them after the change, add "stacks/east" to include in');
|
|
683
682
|
});
|
|
684
683
|
|
|
685
|
-
test("an ignored scan root
|
|
684
|
+
test("an ignored scan root is linted: ignore rules apply below the root only", async () => {
|
|
686
685
|
execFileSync("git", ["init", "-q"], { cwd: testDir });
|
|
687
686
|
await writeFile(join(testDir, ".gitignore"), "/carveout/\n");
|
|
688
687
|
await mkdir(join(testDir, "carveout", "src"), { recursive: true });
|
|
689
688
|
await writeFile(join(testDir, "carveout", "src", "main.ts"), EVL003);
|
|
690
689
|
|
|
691
690
|
const result = await lintCommand({ path: join(testDir, "carveout", "src"), format: "stylish" });
|
|
692
|
-
expect(result.diagnostics.
|
|
693
|
-
const warning = stderr.find((l) => l.startsWith("warning: chant lint under"));
|
|
694
|
-
expect(warning).toContain(" main.ts: ");
|
|
695
|
-
expect(warning).toContain("is itself git-ignored, so today nothing under it is linted. ");
|
|
696
|
-
expect(warning).toContain("so the files under it are linted.");
|
|
697
|
-
expect(warning).toContain('To keep skipping it, add "**" to exclude in');
|
|
691
|
+
expect(result.diagnostics.some((d) => d.file.includes("main.ts") && d.ruleId === "EVL003")).toBe(true);
|
|
698
692
|
});
|
|
699
693
|
});
|
|
700
694
|
|
package/src/cli/commands/lint.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { resolve, join, relative } from "path";
|
|
2
2
|
import type { BuildParamProvenance } from "../../provenance";
|
|
3
|
-
import { readFileSync, writeFileSync, readdirSync
|
|
4
|
-
import { execFileSync } from "child_process";
|
|
3
|
+
import { readFileSync, writeFileSync, readdirSync } from "fs";
|
|
5
4
|
import { runLint, parseDisableComments } from "../../lint/engine";
|
|
6
5
|
import type { LintRule, LintDiagnostic, LintFix } from "../../lint/rule";
|
|
7
6
|
import type { IntrinsicDef, LexiconPlugin } from "../../lexicon";
|
|
@@ -19,8 +18,8 @@ import { runPostSynthChecks } from "../../lint/post-synth";
|
|
|
19
18
|
import { rule } from "../../lint/declarative";
|
|
20
19
|
import { watchDirectory, formatTimestamp, formatChangedFiles } from "../watch";
|
|
21
20
|
import { formatError, formatInfo } from "../format";
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
21
|
+
import { hasDiscoveryMarkerSync, isSourceFileName } from "../../discovery/files";
|
|
22
|
+
import { walkDiscovery, workspaceMemberDirs } from "../../discovery/walk";
|
|
24
23
|
import { buildParamValues, resolveBuildParams } from "../../build-params";
|
|
25
24
|
import { setBuildParams } from "../../params";
|
|
26
25
|
import { isNoLexiconDetected } from "../../detectLexicon";
|
|
@@ -270,80 +269,26 @@ export interface LintResult {
|
|
|
270
269
|
}
|
|
271
270
|
|
|
272
271
|
/**
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
*
|
|
272
|
+
* Every TypeScript file `chant lint` reads under `dir`, through the one
|
|
273
|
+
* discovery walk (`../../discovery/walk.ts`, #2527): git-ignored paths
|
|
274
|
+
* (vendored trees and the like, which the project never wrote), dot-directories,
|
|
275
|
+
* `dist` and, inside a project, child projects are skipped, and so is what the
|
|
276
|
+
* project's `exclude` globs (#2519) name, unless `include` re-admits it. Test
|
|
277
|
+
* and spec files, chant-generated files and skip-marked files are left out.
|
|
278
|
+
* Symlinks are followed, as lint always did.
|
|
279
279
|
*/
|
|
280
|
-
function
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
// Exit 1 means "nothing ignored" — execFileSync throws on non-zero, so the
|
|
293
|
-
// catch handles it; exit 128 (not a repo) lands there too and filters none.
|
|
294
|
-
});
|
|
295
|
-
const ignored = new Set(out.split(/\r?\n/).filter(Boolean));
|
|
296
|
-
for (const p of ignored) ignoredOut?.add(p);
|
|
297
|
-
return ignored.size === 0 ? files : files.filter((f) => !ignored.has(f));
|
|
298
|
-
} catch {
|
|
299
|
-
// No git, not a repo, or nothing ignored (exit 1) — keep every file.
|
|
300
|
-
return files;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/** What {@link getTypeScriptFiles} saw before its git-ignore filter, for #2527's warning. */
|
|
305
|
-
interface TypeScriptScan {
|
|
306
|
-
raw: string[];
|
|
307
|
-
ignored: Set<string>;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Get all TypeScript files recursively, skipping git-ignored paths and the
|
|
312
|
-
* files `skip` (the project's `exclude` globs, #2519) names. `scanOut`, when
|
|
313
|
-
* given, receives the files found before the ignore filter and the paths git
|
|
314
|
-
* reported ignored.
|
|
315
|
-
*/
|
|
316
|
-
function getTypeScriptFiles(dir: string, skip?: (file: string) => boolean, scanOut?: TypeScriptScan): string[] {
|
|
317
|
-
const files: string[] = [];
|
|
318
|
-
|
|
319
|
-
function scan(currentDir: string): void {
|
|
320
|
-
const entries = readdirSync(currentDir);
|
|
321
|
-
|
|
322
|
-
for (const entry of entries) {
|
|
323
|
-
const fullPath = join(currentDir, entry);
|
|
324
|
-
const stat = statSync(fullPath);
|
|
325
|
-
|
|
326
|
-
if (stat.isDirectory()) {
|
|
327
|
-
if (entry !== "node_modules" && !entry.startsWith(".")) {
|
|
328
|
-
scan(fullPath);
|
|
329
|
-
}
|
|
330
|
-
} else if (entry.endsWith(".ts") && !entry.endsWith(".test.ts") && !entry.endsWith(".spec.ts")) {
|
|
331
|
-
if (skip?.(fullPath)) continue;
|
|
332
|
-
// Skip chant-generated files (worker/workflow/activities bootstrap): they
|
|
333
|
-
// hold no authored source and use runtime patterns the EVL* rules forbid.
|
|
334
|
-
// A hand-written file opts out with the skip marker (#2519).
|
|
335
|
-
const head = readFileSync(fullPath, "utf-8").slice(0, 1024);
|
|
336
|
-
if (head.slice(0, 256).includes(GENERATED_MARKER) || hasSkipMarker(head)) {
|
|
337
|
-
continue;
|
|
338
|
-
}
|
|
339
|
-
files.push(fullPath);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
scan(dir);
|
|
345
|
-
scanOut?.raw.push(...files);
|
|
346
|
-
return filterGitIgnored(files, dir, scanOut?.ignored);
|
|
280
|
+
async function getTypeScriptFiles(dir: string): Promise<string[]> {
|
|
281
|
+
// A missing or non-directory path fails here, as lint's own walk always did;
|
|
282
|
+
// the shared walk skips an unreadable directory in silence.
|
|
283
|
+
readdirSync(dir);
|
|
284
|
+
return walkDiscovery({
|
|
285
|
+
walker: "lint",
|
|
286
|
+
root: dir,
|
|
287
|
+
globs: await resolveDiscoveryGlobs(dir),
|
|
288
|
+
excludeDirs: await workspaceMemberDirs(dir),
|
|
289
|
+
followSymlinks: true,
|
|
290
|
+
accept: (name, full) => isSourceFileName(name) && !hasDiscoveryMarkerSync(full),
|
|
291
|
+
});
|
|
347
292
|
}
|
|
348
293
|
|
|
349
294
|
/**
|
|
@@ -723,13 +668,8 @@ export async function lintCommand(options: LintOptions): Promise<LintResult> {
|
|
|
723
668
|
allRules = new Map([...allRules, ...pluginRules]);
|
|
724
669
|
}
|
|
725
670
|
|
|
726
|
-
// Get all TypeScript files
|
|
727
|
-
|
|
728
|
-
const scanned: TypeScriptScan = { raw: [], ignored: new Set() };
|
|
729
|
-
const files = getTypeScriptFiles(infraPath, compileDiscoveryFilter(await resolveDiscoveryGlobs(infraPath)), scanned);
|
|
730
|
-
// #2527's warning release: which of these the converged walker reads
|
|
731
|
-
// differently. `files` is today's list, unchanged.
|
|
732
|
-
await warnDiscoveryChanges({ walker: "lint", root: infraPath, files, lintIgnored: scanned });
|
|
671
|
+
// Get all TypeScript files, through the one discovery walk (#2527)
|
|
672
|
+
const files = await getTypeScriptFiles(infraPath);
|
|
733
673
|
|
|
734
674
|
// Run lint — use per-file rules when overrides are present
|
|
735
675
|
let diagnostics: LintDiagnostic[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { lexiconModulePath, lexiconNames } from "../../lexicon-module";
|
|
2
2
|
import { existsSync, mkdirSync, writeFileSync, cpSync, readdirSync, statSync, readFileSync } from "fs";
|
|
3
|
-
import { join, resolve } from "path";
|
|
3
|
+
import { dirname, join, resolve } from "path";
|
|
4
4
|
import { createRequire } from "module";
|
|
5
5
|
import { formatSuccess, formatWarning, formatError } from "../format";
|
|
6
6
|
import { loadChantConfig } from "../../config";
|
|
@@ -29,6 +29,15 @@ export interface UpdateResult {
|
|
|
29
29
|
error?: string;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Where `chant update` writes a lexicon skill, relative to the project. The
|
|
34
|
+
* workspace drift check (#2541) compares these files with what the skills
|
|
35
|
+
* render to, so both read the path from here.
|
|
36
|
+
*/
|
|
37
|
+
export function skillFilePath(skillName: string): string {
|
|
38
|
+
return `skills/${skillName}/SKILL.md`;
|
|
39
|
+
}
|
|
40
|
+
|
|
32
41
|
/**
|
|
33
42
|
* Copy directory contents recursively, filtering to .ts and .d.ts files
|
|
34
43
|
*/
|
|
@@ -170,9 +179,9 @@ export async function updateCommand(options: UpdateOptions): Promise<UpdateResul
|
|
|
170
179
|
const skills = plugin.skills();
|
|
171
180
|
if (skills.length > 0) {
|
|
172
181
|
for (const skill of skills) {
|
|
173
|
-
const
|
|
174
|
-
mkdirSync(
|
|
175
|
-
writeFileSync(
|
|
182
|
+
const file = join(projectDir, skillFilePath(skill.name));
|
|
183
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
184
|
+
writeFileSync(file, skill.content);
|
|
176
185
|
}
|
|
177
186
|
synced.push(`${plugin.name} skills (${skills.length})`);
|
|
178
187
|
}
|
|
@@ -76,7 +76,7 @@ export function contentHash(files: Map<string, Buffer>): string {
|
|
|
76
76
|
// ── Source resolution → a { relpath → bytes } file set ──────────────────────
|
|
77
77
|
|
|
78
78
|
/** Walk a local directory into a relpath→bytes map (or a single file). */
|
|
79
|
-
function readLocal(absPath: string): Map<string, Buffer> {
|
|
79
|
+
export function readLocal(absPath: string): Map<string, Buffer> {
|
|
80
80
|
const files = new Map<string, Buffer>();
|
|
81
81
|
const stat = statSync(absPath);
|
|
82
82
|
if (stat.isFile()) {
|
|
@@ -135,12 +135,17 @@ export function scopeArchiveFiles(
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
async function resolveSource(entry: VendorEntry, manifestDir: string): Promise<Map<string, Buffer>> {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
return resolveVendorSource(entry.source, manifestDir);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Resolve a vendor source (a local path, or an archive URL) to its file set. */
|
|
142
|
+
export async function resolveVendorSource(source: VendorEntry["source"], manifestDir: string): Promise<Map<string, Buffer>> {
|
|
143
|
+
if (source.type === "local") {
|
|
144
|
+
const abs = resolve(manifestDir, source.path);
|
|
145
|
+
if (!existsSync(abs)) throw new Error(`local source not found: ${source.path}`);
|
|
141
146
|
return readLocal(abs);
|
|
142
147
|
}
|
|
143
|
-
return readArchive(
|
|
148
|
+
return readArchive(source.url, source.subpath);
|
|
144
149
|
}
|
|
145
150
|
|
|
146
151
|
// ── File I/O ────────────────────────────────────────────────────────────────
|
|
@@ -154,7 +159,7 @@ function writeFiles(targetDir: string, files: Map<string, Buffer>): void {
|
|
|
154
159
|
}
|
|
155
160
|
}
|
|
156
161
|
|
|
157
|
-
function readTarget(targetDir: string): Map<string, Buffer> {
|
|
162
|
+
export function readTarget(targetDir: string): Map<string, Buffer> {
|
|
158
163
|
if (!existsSync(targetDir)) return new Map();
|
|
159
164
|
return readLocal(targetDir);
|
|
160
165
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`a project outside any workspace (level 0) > the pipeline is the generator's output, unchanged 1`] = `
|
|
4
|
+
"name: chant-components-staging
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
workflow_dispatch: {}
|
|
8
|
+
|
|
9
|
+
env:
|
|
10
|
+
CHANT_ENV: staging
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
shared-alb:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
container: node:22-slim
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- run: chant run --components shared-alb --env staging --dump-outputs shared-alb.outputs.json
|
|
19
|
+
- name: Upload shared-alb outputs
|
|
20
|
+
uses: actions/upload-artifact@v4
|
|
21
|
+
with:
|
|
22
|
+
name: shared-alb-outputs
|
|
23
|
+
path: shared-alb.outputs.json
|
|
24
|
+
api:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
needs:
|
|
27
|
+
- shared-alb
|
|
28
|
+
container: node:22-slim
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v4
|
|
31
|
+
- name: Download shared-alb outputs
|
|
32
|
+
uses: actions/download-artifact@v4
|
|
33
|
+
with:
|
|
34
|
+
name: shared-alb-outputs
|
|
35
|
+
path: .
|
|
36
|
+
- run: chant run --components api --env staging --seed-outputs shared-alb.outputs.json
|
|
37
|
+
"
|
|
38
|
+
`;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant build --components --generate` inside a workspace member (#2542).
|
|
3
|
+
* Component discovery is stubbed with a fixed graph; the github generator is
|
|
4
|
+
* the real one, so the files checked here are what a user gets. A project
|
|
5
|
+
* outside any workspace is held to its old output byte for byte, and to a
|
|
6
|
+
* snapshot, since level 0 must not move (#2525).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
|
10
|
+
import { execFileSync } from "node:child_process";
|
|
11
|
+
import { existsSync, mkdtempSync, readFileSync, realpathSync, rmSync } from "node:fs";
|
|
12
|
+
import { tmpdir } from "node:os";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import type { DriverComponent } from "../../components/driver";
|
|
15
|
+
import type { ComponentPipelineOptions } from "../../lexicon";
|
|
16
|
+
import type { ParsedArgs } from "../registry";
|
|
17
|
+
import { generateGithubPipeline } from "@intentius/chant-lexicon-github/components/generate-pipeline";
|
|
18
|
+
import { twoMemberWorkspace } from "../../workspace/__fixtures__/two-member-workspace";
|
|
19
|
+
|
|
20
|
+
const components: DriverComponent[] = [
|
|
21
|
+
{ name: "shared-alb", dependsOn: [], deploy: [] },
|
|
22
|
+
{ name: "api", dependsOn: ["shared-alb"], deploy: [] },
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const received: (ComponentPipelineOptions | undefined)[] = [];
|
|
26
|
+
vi.mock("../../components/cli-support", () => ({
|
|
27
|
+
generateComponentsPipeline: async (_path: string, _lexicon: string, options?: ComponentPipelineOptions) => {
|
|
28
|
+
received.push(options);
|
|
29
|
+
const { yaml, stages, jobs, env } = generateGithubPipeline(components, options);
|
|
30
|
+
return { success: true, yaml, stages, jobs, env };
|
|
31
|
+
},
|
|
32
|
+
}));
|
|
33
|
+
vi.mock("../../config", async () => {
|
|
34
|
+
const actual = await vi.importActual<typeof import("../../config")>("../../config");
|
|
35
|
+
return { ...actual, loadChantConfigUpward: async () => ({ config: {} }) };
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const { runBuild } = await import("./build");
|
|
39
|
+
|
|
40
|
+
function args(overrides: Partial<ParsedArgs>): ParsedArgs {
|
|
41
|
+
return {
|
|
42
|
+
command: "build",
|
|
43
|
+
path: ".",
|
|
44
|
+
format: "",
|
|
45
|
+
fix: false,
|
|
46
|
+
watch: false,
|
|
47
|
+
verbose: false,
|
|
48
|
+
help: false,
|
|
49
|
+
live: false,
|
|
50
|
+
components: true,
|
|
51
|
+
generate: "github",
|
|
52
|
+
...overrides,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let repo: string;
|
|
57
|
+
let logs: string[];
|
|
58
|
+
beforeEach(() => {
|
|
59
|
+
received.length = 0;
|
|
60
|
+
logs = [];
|
|
61
|
+
vi.spyOn(console, "error").mockImplementation(() => {});
|
|
62
|
+
vi.spyOn(console, "log").mockImplementation((s: string) => {
|
|
63
|
+
logs.push(s);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
afterEach(() => {
|
|
67
|
+
vi.restoreAllMocks();
|
|
68
|
+
rmSync(repo, { recursive: true, force: true });
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe("a project inside a workspace member", () => {
|
|
72
|
+
beforeEach(() => {
|
|
73
|
+
repo = twoMemberWorkspace();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("the pipeline is written to the member's file at the repository root, filtered and recorded", async () => {
|
|
77
|
+
expect(await runBuild({ args: args({ path: join(repo, "services/api"), env: "staging" }), plugins: [], serializers: [] })).toBe(0);
|
|
78
|
+
|
|
79
|
+
expect(received[0]?.member).toEqual({ name: "api", dir: "services/api", file: ".github/workflows/chant-api-staging.yml" });
|
|
80
|
+
const file = join(repo, ".github/workflows/chant-api-staging.yml");
|
|
81
|
+
const text = readFileSync(file, "utf-8");
|
|
82
|
+
const [header, ...rest] = text.split("\n");
|
|
83
|
+
expect(header).toContain("Regenerate with: chant build --components --generate github --env staging");
|
|
84
|
+
expect(rest.join("\n")).toBe(generateGithubPipeline(components, { env: "staging", member: received[0]!.member }).yaml);
|
|
85
|
+
expect(text).toContain("working-directory: services/api");
|
|
86
|
+
|
|
87
|
+
const record = JSON.parse(readFileSync(join(repo, "services/api/.chant/generated.json"), "utf-8"));
|
|
88
|
+
expect(record.files).toEqual([{ path: ".github/workflows/chant-api-staging.yml", command: "chant build --components --generate github --env staging", env: "staging" }]);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test("two members write two files and never collide", async () => {
|
|
92
|
+
await runBuild({ args: args({ path: join(repo, "services/api"), env: "prod" }), plugins: [], serializers: [] });
|
|
93
|
+
await runBuild({ args: args({ path: join(repo, "apps/web"), env: "prod" }), plugins: [], serializers: [] });
|
|
94
|
+
expect(existsSync(join(repo, ".github/workflows/chant-api-prod.yml"))).toBe(true);
|
|
95
|
+
expect(existsSync(join(repo, ".github/workflows/chant-web-prod.yml"))).toBe(true);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("--format json names the member and the file and writes nothing", async () => {
|
|
99
|
+
expect(await runBuild({ args: args({ path: join(repo, "apps/web"), env: "prod", format: "json" }), plugins: [], serializers: [] })).toBe(0);
|
|
100
|
+
const out = JSON.parse(logs.join("\n"));
|
|
101
|
+
expect(out).toMatchObject({ member: "web", file: ".github/workflows/chant-web-prod.yml", env: "prod" });
|
|
102
|
+
expect(existsSync(join(repo, ".github/workflows/chant-web-prod.yml"))).toBe(false);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("an example project in a group is not a member, and gets the plain pipeline", async () => {
|
|
106
|
+
expect(await runBuild({ args: args({ path: join(repo, "examples/demo") }), plugins: [], serializers: [] })).toBe(0);
|
|
107
|
+
expect(received[0]).toEqual({ env: undefined });
|
|
108
|
+
expect(logs.join("\n")).toBe(generateGithubPipeline(components, {}).yaml);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe("a project outside any workspace (level 0)", () => {
|
|
113
|
+
beforeEach(() => {
|
|
114
|
+
repo = realpathSync(mkdtempSync(join(tmpdir(), "chant-build-level0-")));
|
|
115
|
+
execFileSync("git", ["init", "-q"], { cwd: repo });
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test("the pipeline is the generator's output, unchanged", async () => {
|
|
119
|
+
const output = join(repo, "pipeline.yml");
|
|
120
|
+
expect(await runBuild({ args: args({ path: repo, env: "staging", output }), plugins: [], serializers: [] })).toBe(0);
|
|
121
|
+
expect(received[0]).toEqual({ env: "staging" });
|
|
122
|
+
const text = readFileSync(output, "utf-8");
|
|
123
|
+
expect(text).toBe(generateGithubPipeline(components, { env: "staging" }).yaml);
|
|
124
|
+
expect(text).toMatchSnapshot();
|
|
125
|
+
expect(existsSync(join(repo, ".chant"))).toBe(false);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
@@ -6,6 +6,7 @@ import type { CommandContext } from "../registry";
|
|
|
6
6
|
import { generateComponentsPipeline } from "../../components/cli-support";
|
|
7
7
|
import { loadChantConfigUpward, type ChantConfig } from "../../config";
|
|
8
8
|
import { resolveCliBuildParams, parseParamFlags } from "../build-params-cli";
|
|
9
|
+
import { findWorkspaceRoot } from "../../project-root";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* `chant build --components --generate <lexicon>` — generate mode (#563,
|
|
@@ -44,6 +45,33 @@ async function runGenerateComponents(ctx: CommandContext): Promise<number> {
|
|
|
44
45
|
return 1;
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
// A project inside a workspace member gets that member's pipeline (#2542):
|
|
49
|
+
// path-filtered, run in the member's directory, written to a file named
|
|
50
|
+
// after the member and recorded as the member's generated file. The
|
|
51
|
+
// workspace module loads only when a declaration was found, so a project
|
|
52
|
+
// outside any workspace generates exactly what it did before.
|
|
53
|
+
const found = findWorkspaceRoot(resolve(args.path));
|
|
54
|
+
let plan: import("../../workspace/member-pipeline").MemberComponentPlan | undefined;
|
|
55
|
+
let memberPipeline: typeof import("../../workspace/member-pipeline") | undefined;
|
|
56
|
+
if (found) {
|
|
57
|
+
memberPipeline = await import("../../workspace/member-pipeline");
|
|
58
|
+
try {
|
|
59
|
+
plan = memberPipeline.planMemberComponentPipeline({
|
|
60
|
+
projectDir: resolve(args.path),
|
|
61
|
+
found,
|
|
62
|
+
lexicon,
|
|
63
|
+
env: args.env,
|
|
64
|
+
promoteTo: args.promoteTo,
|
|
65
|
+
output: args.output,
|
|
66
|
+
params: args.param,
|
|
67
|
+
paramsFile: args.paramsFile,
|
|
68
|
+
});
|
|
69
|
+
} catch (err) {
|
|
70
|
+
console.error(formatError({ message: memberPipeline.describeError(err) }));
|
|
71
|
+
return 1;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
47
75
|
// Which lexicons support generate mode is a property of the loaded lexicon
|
|
48
76
|
// plugins (those implementing `generateComponentPipeline`, #688), not a
|
|
49
77
|
// hard-coded core list — `generateComponentsPipeline` returns a descriptive
|
|
@@ -51,7 +79,7 @@ async function runGenerateComponents(ctx: CommandContext): Promise<number> {
|
|
|
51
79
|
const result = await generateComponentsPipeline(
|
|
52
80
|
args.path,
|
|
53
81
|
lexicon,
|
|
54
|
-
{ env: args.env, ...(args.promoteTo ? { promoteTo: args.promoteTo } : {}) },
|
|
82
|
+
{ env: args.env, ...(args.promoteTo ? { promoteTo: args.promoteTo } : {}), ...(plan ? { member: plan.member } : {}) },
|
|
55
83
|
args.sandbox,
|
|
56
84
|
paramsResolution.provenance,
|
|
57
85
|
);
|
|
@@ -73,11 +101,17 @@ async function runGenerateComponents(ctx: CommandContext): Promise<number> {
|
|
|
73
101
|
// generator's own resolution, forwarded rather than left for a
|
|
74
102
|
// consumer to re-derive by parsing the YAML back (#2060).
|
|
75
103
|
...(result.env ? { env: result.env } : {}),
|
|
104
|
+
// A workspace member's pipeline (#2542): the member and the file
|
|
105
|
+
// the pipeline belongs in, relative to the repository root.
|
|
106
|
+
...(plan ? { member: plan.member.name, file: plan.file } : {}),
|
|
76
107
|
},
|
|
77
108
|
null,
|
|
78
109
|
2,
|
|
79
110
|
),
|
|
80
111
|
);
|
|
112
|
+
} else if (plan && memberPipeline) {
|
|
113
|
+
memberPipeline.writeMemberComponentPipeline(plan, yaml);
|
|
114
|
+
console.error(formatSuccess(`wrote ${formatBold(plan.file)} for member ${formatBold(plan.member.name)}`));
|
|
81
115
|
} else if (args.output) {
|
|
82
116
|
const outputPath = resolve(args.output);
|
|
83
117
|
mkdirSync(dirname(outputPath), { recursive: true });
|