@hominis/fireforge 0.45.0 → 0.46.1
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/CHANGELOG.md +409 -446
- package/dist/bin/fireforge.d.ts +1 -1
- package/dist/bin/fireforge.js +21 -15
- package/dist/build-info.json +4 -4
- package/dist/src/cli-usage-error.d.ts +46 -0
- package/dist/src/cli-usage-error.js +81 -0
- package/dist/src/cli.d.ts +7 -2
- package/dist/src/cli.js +47 -47
- package/dist/src/commands/bootstrap-checks.js +2 -1
- package/dist/src/commands/bootstrap.js +3 -4
- package/dist/src/commands/build.js +27 -17
- package/dist/src/commands/config.js +9 -9
- package/dist/src/commands/destructive-decision.d.ts +19 -0
- package/dist/src/commands/destructive-decision.js +31 -0
- package/dist/src/commands/discard.js +5 -5
- package/dist/src/commands/doctor-check-core.d.ts +4 -10
- package/dist/src/commands/doctor-check-core.js +0 -8
- package/dist/src/commands/doctor-external-toolchains.js +2 -2
- package/dist/src/commands/doctor-furnace-config-sync.d.ts +2 -2
- package/dist/src/commands/doctor-furnace-config-sync.js +20 -20
- package/dist/src/commands/doctor-furnace-jar.d.ts +1 -1
- package/dist/src/commands/doctor-furnace-jar.js +1 -1
- package/dist/src/commands/doctor-furnace.js +22 -22
- package/dist/src/commands/doctor-orphaned-harness.d.ts +10 -17
- package/dist/src/commands/doctor-orphaned-harness.js +14 -23
- package/dist/src/commands/doctor-patch-manifest.d.ts +2 -1
- package/dist/src/commands/doctor-patch-manifest.js +7 -6
- package/dist/src/commands/doctor-post-rebase-audit.js +3 -3
- package/dist/src/commands/doctor-source-pin.d.ts +12 -12
- package/dist/src/commands/doctor-source-pin.js +14 -14
- package/dist/src/commands/doctor-working-tree.d.ts +3 -3
- package/dist/src/commands/doctor-working-tree.js +3 -3
- package/dist/src/commands/doctor.d.ts +3 -1
- package/dist/src/commands/doctor.js +15 -16
- package/dist/src/commands/download.js +50 -37
- package/dist/src/commands/export-all.js +29 -12
- package/dist/src/commands/export-flow.d.ts +5 -5
- package/dist/src/commands/export-flow.js +29 -59
- package/dist/src/commands/export-placement-conflicts.d.ts +3 -3
- package/dist/src/commands/export-placement-conflicts.js +12 -12
- package/dist/src/commands/export-placement-gate.d.ts +2 -2
- package/dist/src/commands/export-placement-gate.js +7 -13
- package/dist/src/commands/export-placement-policy.d.ts +1 -1
- package/dist/src/commands/export-placement-policy.js +4 -6
- package/dist/src/commands/export-shared.d.ts +51 -32
- package/dist/src/commands/export-shared.js +17 -32
- package/dist/src/commands/export.js +14 -5
- package/dist/src/commands/furnace/apply.js +16 -16
- package/dist/src/commands/furnace/authoring-config.d.ts +13 -0
- package/dist/src/commands/furnace/authoring-config.js +19 -0
- package/dist/src/commands/furnace/chrome-doc-remove.d.ts +1 -1
- package/dist/src/commands/furnace/chrome-doc-remove.js +2 -2
- package/dist/src/commands/furnace/chrome-doc-templates.d.ts +14 -14
- package/dist/src/commands/furnace/chrome-doc-templates.js +17 -17
- package/dist/src/commands/furnace/chrome-doc-tests.d.ts +2 -2
- package/dist/src/commands/furnace/chrome-doc-tests.js +4 -4
- package/dist/src/commands/furnace/chrome-doc.d.ts +8 -8
- package/dist/src/commands/furnace/chrome-doc.js +18 -18
- package/dist/src/commands/furnace/create-browser-test.d.ts +1 -1
- package/dist/src/commands/furnace/create-browser-test.js +7 -12
- package/dist/src/commands/furnace/create-dry-run.d.ts +4 -4
- package/dist/src/commands/furnace/create-dry-run.js +6 -9
- package/dist/src/commands/furnace/create-features.d.ts +2 -2
- package/dist/src/commands/furnace/create-features.js +2 -2
- package/dist/src/commands/furnace/create-mochikit.d.ts +4 -4
- package/dist/src/commands/furnace/create-mochikit.js +7 -7
- package/dist/src/commands/furnace/create-templates.d.ts +31 -15
- package/dist/src/commands/furnace/create-templates.js +20 -19
- package/dist/src/commands/furnace/create-xpcshell.d.ts +5 -5
- package/dist/src/commands/furnace/create-xpcshell.js +8 -8
- package/dist/src/commands/furnace/create.d.ts +1 -1
- package/dist/src/commands/furnace/create.js +35 -29
- package/dist/src/commands/furnace/deploy.js +15 -6
- package/dist/src/commands/furnace/diff.js +7 -7
- package/dist/src/commands/furnace/index.js +1 -1
- package/dist/src/commands/furnace/init.js +17 -16
- package/dist/src/commands/furnace/list.js +2 -2
- package/dist/src/commands/furnace/override.d.ts +1 -1
- package/dist/src/commands/furnace/override.js +43 -34
- package/dist/src/commands/furnace/preview.js +17 -17
- package/dist/src/commands/furnace/refresh.js +15 -7
- package/dist/src/commands/furnace/remove-mutations.d.ts +9 -10
- package/dist/src/commands/furnace/remove-mutations.js +19 -19
- package/dist/src/commands/furnace/remove-state.d.ts +1 -1
- package/dist/src/commands/furnace/remove-state.js +1 -1
- package/dist/src/commands/furnace/remove.js +4 -8
- package/dist/src/commands/furnace/rename-browser-test.js +10 -15
- package/dist/src/commands/furnace/rename-xpcshell.d.ts +2 -2
- package/dist/src/commands/furnace/rename-xpcshell.js +3 -3
- package/dist/src/commands/furnace/rename.js +36 -36
- package/dist/src/commands/furnace/scan.js +3 -3
- package/dist/src/commands/furnace/status.js +19 -16
- package/dist/src/commands/furnace/sync.js +6 -6
- package/dist/src/commands/furnace/test-file-name.d.ts +28 -0
- package/dist/src/commands/furnace/test-file-name.js +39 -0
- package/dist/src/commands/furnace/validate.js +11 -12
- package/dist/src/commands/furnace/validation-output.d.ts +21 -9
- package/dist/src/commands/furnace/validation-output.js +3 -8
- package/dist/src/commands/import.js +22 -29
- package/dist/src/commands/lint-per-patch.d.ts +2 -2
- package/dist/src/commands/lint-per-patch.js +27 -12
- package/dist/src/commands/lint-per-run-checkjs.d.ts +14 -15
- package/dist/src/commands/lint-per-run-checkjs.js +14 -15
- package/dist/src/commands/lint-report.d.ts +3 -3
- package/dist/src/commands/lint-report.js +4 -4
- package/dist/src/commands/lint.d.ts +5 -4
- package/dist/src/commands/lint.js +36 -36
- package/dist/src/commands/manifest.d.ts +4 -4
- package/dist/src/commands/manifest.js +1 -1
- package/dist/src/commands/package.js +4 -6
- package/dist/src/commands/patch/compact.d.ts +2 -2
- package/dist/src/commands/patch/compact.js +19 -20
- package/dist/src/commands/patch/delete.d.ts +1 -1
- package/dist/src/commands/patch/delete.js +23 -33
- package/dist/src/commands/patch/entry-projection.d.ts +13 -0
- package/dist/src/commands/patch/entry-projection.js +24 -0
- package/dist/src/commands/patch/lint-ignore.d.ts +3 -12
- package/dist/src/commands/patch/lint-ignore.js +33 -44
- package/dist/src/commands/patch/move-files-create.d.ts +2 -2
- package/dist/src/commands/patch/move-files-create.js +29 -15
- package/dist/src/commands/patch/move-files-into.d.ts +2 -2
- package/dist/src/commands/patch/move-files-into.js +41 -37
- package/dist/src/commands/patch/move-files.js +5 -14
- package/dist/src/commands/patch/patch-context.d.ts +1 -1
- package/dist/src/commands/patch/rename.d.ts +4 -4
- package/dist/src/commands/patch/rename.js +35 -49
- package/dist/src/commands/patch/reorder.js +35 -48
- package/dist/src/commands/patch/split-plan.d.ts +7 -8
- package/dist/src/commands/patch/split-plan.js +10 -13
- package/dist/src/commands/patch/split.d.ts +2 -2
- package/dist/src/commands/patch/split.js +50 -48
- package/dist/src/commands/patch/staged-dependency-validate.d.ts +1 -1
- package/dist/src/commands/patch/staged-dependency-validate.js +3 -3
- package/dist/src/commands/patch/staged-dependency.d.ts +1 -1
- package/dist/src/commands/patch/staged-dependency.js +22 -28
- package/dist/src/commands/patch/tier.d.ts +2 -2
- package/dist/src/commands/patch/tier.js +20 -30
- package/dist/src/commands/patch-rename-map.d.ts +19 -0
- package/dist/src/commands/patch-rename-map.js +36 -0
- package/dist/src/commands/pending-resolution.d.ts +15 -0
- package/dist/src/commands/pending-resolution.js +25 -0
- package/dist/src/commands/re-export-adjacent.d.ts +25 -3
- package/dist/src/commands/re-export-adjacent.js +40 -24
- package/dist/src/commands/re-export-bulk-scan.d.ts +3 -3
- package/dist/src/commands/re-export-bulk-scan.js +23 -27
- package/dist/src/commands/re-export-drift.d.ts +10 -10
- package/dist/src/commands/re-export-drift.js +33 -33
- package/dist/src/commands/re-export-files.d.ts +2 -3
- package/dist/src/commands/re-export-files.js +52 -44
- package/dist/src/commands/re-export-lint.d.ts +29 -30
- package/dist/src/commands/re-export-lint.js +36 -29
- package/dist/src/commands/re-export-options.d.ts +1 -1
- package/dist/src/commands/re-export-options.js +1 -1
- package/dist/src/commands/re-export-register.d.ts +1 -1
- package/dist/src/commands/re-export-register.js +1 -1
- package/dist/src/commands/re-export-scan.d.ts +1 -1
- package/dist/src/commands/re-export-scan.js +12 -9
- package/dist/src/commands/re-export-single.d.ts +23 -4
- package/dist/src/commands/re-export-single.js +39 -31
- package/dist/src/commands/re-export.js +35 -17
- package/dist/src/commands/rebase/abort.js +9 -14
- package/dist/src/commands/rebase/continue.js +20 -19
- package/dist/src/commands/rebase/index.d.ts +1 -1
- package/dist/src/commands/rebase/index.js +5 -5
- package/dist/src/commands/rebase/patch-loop.d.ts +2 -2
- package/dist/src/commands/rebase/patch-loop.js +20 -24
- package/dist/src/commands/register.js +5 -5
- package/dist/src/commands/reset.js +1 -1
- package/dist/src/commands/resolve.d.ts +2 -2
- package/dist/src/commands/resolve.js +21 -13
- package/dist/src/commands/run.d.ts +0 -13
- package/dist/src/commands/run.js +38 -51
- package/dist/src/commands/setup-support.d.ts +16 -4
- package/dist/src/commands/setup-support.js +20 -20
- package/dist/src/commands/setup.js +4 -10
- package/dist/src/commands/source.js +9 -2
- package/dist/src/commands/status-check.d.ts +3 -3
- package/dist/src/commands/status-check.js +6 -6
- package/dist/src/commands/status-json.d.ts +14 -13
- package/dist/src/commands/status-json.js +9 -8
- package/dist/src/commands/status-output.d.ts +3 -3
- package/dist/src/commands/status-output.js +5 -5
- package/dist/src/commands/status-ownership.d.ts +3 -3
- package/dist/src/commands/status-ownership.js +3 -3
- package/dist/src/commands/status.js +25 -26
- package/dist/src/commands/test-build-phase.d.ts +3 -3
- package/dist/src/commands/test-build-phase.js +48 -24
- package/dist/src/commands/test-diagnose.d.ts +1 -1
- package/dist/src/commands/test-diagnose.js +20 -20
- package/dist/src/commands/test-modes.d.ts +4 -4
- package/dist/src/commands/test-modes.js +4 -5
- package/dist/src/commands/test-register.js +5 -3
- package/dist/src/commands/test-run.d.ts +11 -11
- package/dist/src/commands/test-run.js +40 -33
- package/dist/src/commands/test-stale-gate.d.ts +12 -12
- package/dist/src/commands/test-stale-gate.js +17 -17
- package/dist/src/commands/test-verdict.d.ts +19 -5
- package/dist/src/commands/test-verdict.js +26 -11
- package/dist/src/commands/test.d.ts +3 -3
- package/dist/src/commands/test.js +73 -36
- package/dist/src/commands/token-coverage.js +3 -3
- package/dist/src/commands/token-list.d.ts +26 -0
- package/dist/src/commands/token-list.js +153 -0
- package/dist/src/commands/token.js +26 -10
- package/dist/src/commands/tree.js +26 -21
- package/dist/src/commands/typecheck.d.ts +6 -6
- package/dist/src/commands/typecheck.js +16 -16
- package/dist/src/commands/verify.d.ts +3 -3
- package/dist/src/commands/verify.js +10 -10
- package/dist/src/commands/watch.js +11 -11
- package/dist/src/commands/wire.js +17 -16
- package/dist/src/core/ast-utils.d.ts +7 -7
- package/dist/src/core/ast-utils.js +8 -8
- package/dist/src/core/branding.d.ts +5 -12
- package/dist/src/core/branding.js +6 -5
- package/dist/src/core/browser-wire.d.ts +1 -1
- package/dist/src/core/browser-wire.js +10 -7
- package/dist/src/core/build-audit-platform.d.ts +32 -3
- package/dist/src/core/build-audit-platform.js +153 -13
- package/dist/src/core/build-audit-registration.d.ts +5 -5
- package/dist/src/core/build-audit-registration.js +10 -9
- package/dist/src/core/build-audit-resolve.d.ts +5 -5
- package/dist/src/core/build-audit-resolve.js +6 -6
- package/dist/src/core/build-audit-skip.d.ts +57 -0
- package/dist/src/core/build-audit-skip.js +112 -0
- package/dist/src/core/build-audit-transforms.d.ts +2 -2
- package/dist/src/core/build-audit-transforms.js +3 -3
- package/dist/src/core/build-audit.d.ts +21 -8
- package/dist/src/core/build-audit.js +142 -40
- package/dist/src/core/build-baseline-types.d.ts +19 -18
- package/dist/src/core/build-baseline-types.js +1 -1
- package/dist/src/core/build-baseline.d.ts +48 -31
- package/dist/src/core/build-baseline.js +20 -43
- package/dist/src/core/build-jar-escalation.d.ts +8 -8
- package/dist/src/core/build-jar-escalation.js +18 -17
- package/dist/src/core/build-overwrite-guard.d.ts +4 -4
- package/dist/src/core/build-overwrite-guard.js +14 -14
- package/dist/src/core/build-prepare.d.ts +4 -12
- package/dist/src/core/build-prepare.js +22 -26
- package/dist/src/core/config-mutate.js +4 -4
- package/dist/src/core/config-paths.d.ts +2 -6
- package/dist/src/core/config-paths.js +4 -2
- package/dist/src/core/config-state.d.ts +0 -6
- package/dist/src/core/config-state.js +3 -21
- package/dist/src/core/config-validate-build-audit.d.ts +8 -0
- package/dist/src/core/config-validate-build-audit.js +80 -0
- package/dist/src/core/config-validate-file-size.d.ts +1 -1
- package/dist/src/core/config-validate-file-size.js +3 -3
- package/dist/src/core/config-validate-patch-policy.d.ts +2 -2
- package/dist/src/core/config-validate-patch-policy.js +3 -3
- package/dist/src/core/config-validate-test-toolchains.d.ts +2 -2
- package/dist/src/core/config-validate-test-toolchains.js +4 -5
- package/dist/src/core/config-validate.js +22 -12
- package/dist/src/core/config.d.ts +12 -12
- package/dist/src/core/config.js +21 -25
- package/dist/src/core/coverage-extend.d.ts +16 -16
- package/dist/src/core/coverage-extend.js +20 -20
- package/dist/src/core/destructive.d.ts +14 -14
- package/dist/src/core/destructive.js +9 -9
- package/dist/src/core/diff-hunks.d.ts +2 -2
- package/dist/src/core/diff-hunks.js +7 -7
- package/dist/src/core/discard-baseline.d.ts +10 -10
- package/dist/src/core/discard-baseline.js +22 -23
- package/dist/src/core/display-state.d.ts +11 -11
- package/dist/src/core/display-state.js +12 -12
- package/dist/src/core/engine-changes.d.ts +2 -2
- package/dist/src/core/engine-changes.js +2 -2
- package/dist/src/core/engine-precondition.d.ts +5 -13
- package/dist/src/core/engine-precondition.js +5 -10
- package/dist/src/core/engine-session-lock.d.ts +18 -18
- package/dist/src/core/engine-session-lock.js +50 -54
- package/dist/src/core/export-moved-code-shape.d.ts +7 -7
- package/dist/src/core/export-moved-code-shape.js +10 -10
- package/dist/src/core/file-lock-owner.d.ts +103 -0
- package/dist/src/core/file-lock-owner.js +259 -0
- package/dist/src/core/file-lock.d.ts +14 -19
- package/dist/src/core/file-lock.js +90 -128
- package/dist/src/core/firefox-cache.d.ts +13 -1
- package/dist/src/core/firefox-cache.js +61 -36
- package/dist/src/core/firefox-download.d.ts +15 -0
- package/dist/src/core/firefox-download.js +38 -22
- package/dist/src/core/firefox-extract.d.ts +8 -7
- package/dist/src/core/firefox-extract.js +45 -27
- package/dist/src/core/firefox.d.ts +34 -36
- package/dist/src/core/firefox.js +13 -44
- package/dist/src/core/furnace-apply-dry-run.d.ts +1 -6
- package/dist/src/core/furnace-apply-dry-run.js +2 -8
- package/dist/src/core/furnace-apply-ftl.d.ts +5 -5
- package/dist/src/core/furnace-apply-ftl.js +8 -8
- package/dist/src/core/furnace-apply-helpers.d.ts +9 -20
- package/dist/src/core/furnace-apply-helpers.js +28 -39
- package/dist/src/core/furnace-apply-output.js +1 -1
- package/dist/src/core/furnace-apply-overwrite-warn.d.ts +9 -9
- package/dist/src/core/furnace-apply-overwrite-warn.js +13 -11
- package/dist/src/core/furnace-apply-undeploy-actions.d.ts +1 -1
- package/dist/src/core/furnace-apply-undeploy-actions.js +1 -1
- package/dist/src/core/furnace-apply.d.ts +4 -4
- package/dist/src/core/furnace-apply.js +50 -29
- package/dist/src/core/furnace-checksum-utils.d.ts +5 -5
- package/dist/src/core/furnace-checksum-utils.js +5 -5
- package/dist/src/core/furnace-config-custom.d.ts +1 -1
- package/dist/src/core/furnace-config-custom.js +2 -2
- package/dist/src/core/furnace-config-order.js +1 -1
- package/dist/src/core/furnace-config-tokens.d.ts +3 -3
- package/dist/src/core/furnace-config-tokens.js +3 -3
- package/dist/src/core/furnace-config-validate.js +2 -2
- package/dist/src/core/furnace-config.d.ts +5 -5
- package/dist/src/core/furnace-config.js +40 -53
- package/dist/src/core/furnace-constants.d.ts +6 -6
- package/dist/src/core/furnace-constants.js +9 -8
- package/dist/src/core/furnace-css-fragments.d.ts +6 -6
- package/dist/src/core/furnace-css-fragments.js +11 -11
- package/dist/src/core/furnace-dir-entry.d.ts +20 -0
- package/dist/src/core/furnace-dir-entry.js +21 -0
- package/dist/src/core/furnace-jsconfig.d.ts +7 -7
- package/dist/src/core/furnace-jsconfig.js +22 -20
- package/dist/src/core/furnace-operation.d.ts +22 -19
- package/dist/src/core/furnace-operation.js +38 -34
- package/dist/src/core/furnace-precondition.d.ts +10 -10
- package/dist/src/core/furnace-precondition.js +8 -8
- package/dist/src/core/furnace-refresh.d.ts +18 -6
- package/dist/src/core/furnace-refresh.js +5 -8
- package/dist/src/core/furnace-registration-ast.d.ts +2 -3
- package/dist/src/core/furnace-registration-ast.js +9 -12
- package/dist/src/core/furnace-registration-remove.d.ts +4 -4
- package/dist/src/core/furnace-registration-remove.js +6 -6
- package/dist/src/core/furnace-registration-validate.d.ts +2 -2
- package/dist/src/core/furnace-registration-validate.js +2 -2
- package/dist/src/core/furnace-registration.d.ts +7 -6
- package/dist/src/core/furnace-registration.js +29 -36
- package/dist/src/core/furnace-rollback.d.ts +1 -1
- package/dist/src/core/furnace-rollback.js +5 -5
- package/dist/src/core/furnace-scanner.js +3 -6
- package/dist/src/core/furnace-stale-export.d.ts +17 -16
- package/dist/src/core/furnace-stale-export.js +16 -15
- package/dist/src/core/furnace-staleness.d.ts +2 -2
- package/dist/src/core/furnace-staleness.js +2 -2
- package/dist/src/core/furnace-state-persist.d.ts +12 -12
- package/dist/src/core/furnace-state-persist.js +10 -10
- package/dist/src/core/furnace-step-errors.d.ts +6 -6
- package/dist/src/core/furnace-step-errors.js +6 -6
- package/dist/src/core/furnace-validate-accessibility.js +14 -14
- package/dist/src/core/furnace-validate-compatibility.js +9 -9
- package/dist/src/core/furnace-validate-registration.d.ts +2 -2
- package/dist/src/core/furnace-validate-registration.js +18 -20
- package/dist/src/core/furnace-validate-structure.d.ts +1 -1
- package/dist/src/core/furnace-validate-structure.js +4 -4
- package/dist/src/core/furnace-validate.js +9 -9
- package/dist/src/core/furnace-version-drift.d.ts +5 -5
- package/dist/src/core/furnace-version-drift.js +5 -5
- package/dist/src/core/git-base.d.ts +6 -4
- package/dist/src/core/git-base.js +29 -7
- package/dist/src/core/git-diff-new-file.d.ts +40 -0
- package/dist/src/core/git-diff-new-file.js +119 -0
- package/dist/src/core/git-diff.d.ts +13 -13
- package/dist/src/core/git-diff.js +121 -189
- package/dist/src/core/git-file-ops.d.ts +6 -13
- package/dist/src/core/git-file-ops.js +11 -35
- package/dist/src/core/git-readonly-index.d.ts +12 -14
- package/dist/src/core/git-readonly-index.js +12 -16
- package/dist/src/core/git-status.d.ts +9 -2
- package/dist/src/core/git-status.js +23 -11
- package/dist/src/core/git.d.ts +3 -9
- package/dist/src/core/git.js +28 -57
- package/dist/src/core/harness-orphans.d.ts +17 -17
- package/dist/src/core/harness-orphans.js +28 -27
- package/dist/src/core/history-log.d.ts +19 -0
- package/dist/src/core/history-log.js +29 -0
- package/dist/src/core/license-headers.d.ts +19 -18
- package/dist/src/core/license-headers.js +29 -28
- package/dist/src/core/mach-build-artifacts.d.ts +21 -21
- package/dist/src/core/mach-build-artifacts.js +23 -23
- package/dist/src/core/mach-error-hints.d.ts +5 -10
- package/dist/src/core/mach-error-hints.js +14 -14
- package/dist/src/core/mach-known-noise-filter.d.ts +42 -38
- package/dist/src/core/mach-known-noise-filter.js +57 -56
- package/dist/src/core/mach-mozconfig.d.ts +6 -6
- package/dist/src/core/mach-mozconfig.js +17 -16
- package/dist/src/core/mach-python.d.ts +3 -0
- package/dist/src/core/mach-python.js +13 -7
- package/dist/src/core/mach-resource-shim.d.ts +24 -12
- package/dist/src/core/mach-resource-shim.js +124 -21
- package/dist/src/core/mach.d.ts +59 -73
- package/dist/src/core/mach.js +47 -115
- package/dist/src/core/marionette-port.d.ts +15 -30
- package/dist/src/core/marionette-port.js +46 -89
- package/dist/src/core/marionette-preflight.d.ts +6 -6
- package/dist/src/core/marionette-preflight.js +32 -50
- package/dist/src/core/markdown-table.d.ts +9 -9
- package/dist/src/core/markdown-table.js +14 -14
- package/dist/src/core/mochitest-server-port.d.ts +8 -8
- package/dist/src/core/mochitest-server-port.js +17 -17
- package/dist/src/core/module-resolution-preflight.d.ts +8 -8
- package/dist/src/core/module-resolution-preflight.js +11 -11
- package/dist/src/core/moz-manifest-helpers.d.ts +7 -7
- package/dist/src/core/moz-manifest-helpers.js +7 -7
- package/dist/src/core/moz-manifest-register.d.ts +1 -1
- package/dist/src/core/moz-manifest-register.js +2 -2
- package/dist/src/core/moz-manifest-rules.js +46 -42
- package/dist/src/core/moz-manifest-tokenizers.js +1 -1
- package/dist/src/core/ownership-table.d.ts +5 -5
- package/dist/src/core/ownership-table.js +7 -7
- package/dist/src/core/parser-fallback.d.ts +3 -3
- package/dist/src/core/parser-fallback.js +3 -3
- package/dist/src/core/patch-apply-fuzz.d.ts +5 -5
- package/dist/src/core/patch-apply-fuzz.js +13 -13
- package/dist/src/core/patch-apply.d.ts +13 -14
- package/dist/src/core/patch-apply.js +36 -42
- package/dist/src/core/patch-export-coverage.d.ts +0 -9
- package/dist/src/core/patch-export-coverage.js +1 -30
- package/dist/src/core/patch-export-update.d.ts +21 -4
- package/dist/src/core/patch-export-update.js +7 -6
- package/dist/src/core/patch-export.d.ts +20 -30
- package/dist/src/core/patch-export.js +55 -77
- package/dist/src/core/patch-files.d.ts +0 -4
- package/dist/src/core/patch-files.js +0 -11
- package/dist/src/core/patch-identifier-suggest.d.ts +1 -1
- package/dist/src/core/patch-identifier-suggest.js +4 -4
- package/dist/src/core/patch-lint-binary.d.ts +12 -18
- package/dist/src/core/patch-lint-cache.d.ts +18 -2
- package/dist/src/core/patch-lint-cache.js +16 -19
- package/dist/src/core/patch-lint-checkjs.d.ts +55 -38
- package/dist/src/core/patch-lint-checkjs.js +78 -64
- package/dist/src/core/patch-lint-chrome-jsdoc.d.ts +8 -9
- package/dist/src/core/patch-lint-chrome-jsdoc.js +10 -11
- package/dist/src/core/patch-lint-creators.d.ts +5 -9
- package/dist/src/core/patch-lint-creators.js +3 -3
- package/dist/src/core/patch-lint-cross.d.ts +27 -19
- package/dist/src/core/patch-lint-cross.js +67 -110
- package/dist/src/core/patch-lint-css.d.ts +1 -1
- package/dist/src/core/patch-lint-css.js +15 -11
- package/dist/src/core/patch-lint-diff-tag.d.ts +5 -5
- package/dist/src/core/patch-lint-diff-tag.js +5 -5
- package/dist/src/core/patch-lint-diff.d.ts +4 -4
- package/dist/src/core/patch-lint-diff.js +4 -4
- package/dist/src/core/patch-lint-file-size.d.ts +3 -3
- package/dist/src/core/patch-lint-file-size.js +6 -6
- package/dist/src/core/patch-lint-forward-registration.d.ts +58 -0
- package/dist/src/core/patch-lint-forward-registration.js +210 -0
- package/dist/src/core/patch-lint-jsdoc.d.ts +2 -2
- package/dist/src/core/patch-lint-jsdoc.js +46 -46
- package/dist/src/core/patch-lint-module-registration.d.ts +3 -9
- package/dist/src/core/patch-lint-module-registration.js +1 -1
- package/dist/src/core/patch-lint-mozbuild.d.ts +1 -1
- package/dist/src/core/patch-lint-mozbuild.js +10 -10
- package/dist/src/core/patch-lint-observer.d.ts +3 -3
- package/dist/src/core/patch-lint-observer.js +7 -7
- package/dist/src/core/patch-lint-ownership.d.ts +6 -6
- package/dist/src/core/patch-lint-ownership.js +6 -6
- package/dist/src/core/patch-lint-prettier.d.ts +6 -6
- package/dist/src/core/patch-lint-prettier.js +7 -7
- package/dist/src/core/patch-lint-queue-types.d.ts +60 -0
- package/dist/src/core/patch-lint-queue-types.js +12 -0
- package/dist/src/core/patch-lint-staged-registration.d.ts +61 -0
- package/dist/src/core/patch-lint-staged-registration.js +90 -0
- package/dist/src/core/patch-lint-unmanaged-companion.d.ts +23 -23
- package/dist/src/core/patch-lint-unmanaged-companion.js +26 -26
- package/dist/src/core/patch-lint.d.ts +41 -35
- package/dist/src/core/patch-lint.js +52 -49
- package/dist/src/core/patch-lock.d.ts +1 -1
- package/dist/src/core/patch-lock.js +11 -11
- package/dist/src/core/patch-manifest-consistency.d.ts +7 -7
- package/dist/src/core/patch-manifest-consistency.js +16 -17
- package/dist/src/core/patch-manifest-files-affected.d.ts +1 -1
- package/dist/src/core/patch-manifest-files-affected.js +3 -3
- package/dist/src/core/patch-manifest-io.d.ts +14 -14
- package/dist/src/core/patch-manifest-io.js +35 -34
- package/dist/src/core/patch-manifest-query.d.ts +1 -1
- package/dist/src/core/patch-manifest-query.js +4 -4
- package/dist/src/core/patch-manifest-resolve.d.ts +5 -5
- package/dist/src/core/patch-manifest-resolve.js +7 -7
- package/dist/src/core/patch-manifest-validate.js +3 -3
- package/dist/src/core/patch-manifest.d.ts +2 -2
- package/dist/src/core/patch-manifest.js +2 -2
- package/dist/src/core/patch-parse.d.ts +32 -21
- package/dist/src/core/patch-parse.js +40 -15
- package/dist/src/core/patch-policy.js +15 -27
- package/dist/src/core/patch-registration-refs.d.ts +4 -4
- package/dist/src/core/patch-registration-refs.js +7 -7
- package/dist/src/core/patch-source-metadata.d.ts +1 -3
- package/dist/src/core/patch-source-metadata.js +0 -4
- package/dist/src/core/patch-transform.d.ts +8 -16
- package/dist/src/core/patch-transform.js +13 -23
- package/dist/src/core/process-cpu-time.d.ts +1 -1
- package/dist/src/core/process-cpu-time.js +6 -6
- package/dist/src/core/rebase-session.d.ts +9 -15
- package/dist/src/core/rebase-session.js +13 -25
- package/dist/src/core/register-browser-content.js +3 -2
- package/dist/src/core/register-browser-test.js +2 -1
- package/dist/src/core/register-module.js +2 -1
- package/dist/src/core/register-result.d.ts +1 -1
- package/dist/src/core/register-result.js +1 -1
- package/dist/src/core/register-scaffold.d.ts +2 -2
- package/dist/src/core/register-scaffold.js +8 -7
- package/dist/src/core/register-shared-css.d.ts +3 -3
- package/dist/src/core/register-shared-css.js +6 -5
- package/dist/src/core/register-xpcshell-test.d.ts +2 -2
- package/dist/src/core/register-xpcshell-test.js +2 -2
- package/dist/src/core/run-log-redact.d.ts +38 -0
- package/dist/src/core/run-log-redact.js +69 -0
- package/dist/src/core/run-log.d.ts +21 -10
- package/dist/src/core/run-log.js +76 -27
- package/dist/src/core/shared-ftl.d.ts +2 -2
- package/dist/src/core/shared-ftl.js +6 -6
- package/dist/src/core/signal-critical.d.ts +2 -2
- package/dist/src/core/signal-critical.js +4 -6
- package/dist/src/core/smoke-patterns.d.ts +5 -6
- package/dist/src/core/smoke-patterns.js +15 -20
- package/dist/src/core/state-file.d.ts +15 -4
- package/dist/src/core/state-file.js +14 -1
- package/dist/src/core/status-binary.d.ts +8 -8
- package/dist/src/core/status-binary.js +12 -12
- package/dist/src/core/status-classify.d.ts +17 -17
- package/dist/src/core/status-classify.js +13 -12
- package/dist/src/core/test-changed-prefs.d.ts +12 -12
- package/dist/src/core/test-changed-prefs.js +40 -25
- package/dist/src/core/test-harness-crash.d.ts +39 -39
- package/dist/src/core/test-harness-crash.js +69 -69
- package/dist/src/core/test-harness-output.d.ts +7 -7
- package/dist/src/core/test-harness-output.js +7 -7
- package/dist/src/core/test-harness-verdict-notes.d.ts +13 -14
- package/dist/src/core/test-harness-verdict-notes.js +4 -4
- package/dist/src/core/test-path-scope.d.ts +8 -8
- package/dist/src/core/test-path-scope.js +11 -11
- package/dist/src/core/test-stale-check.d.ts +22 -23
- package/dist/src/core/test-stale-check.js +31 -30
- package/dist/src/core/test-stale-symlink.d.ts +1 -1
- package/dist/src/core/test-stale-symlink.js +1 -1
- package/dist/src/core/test-stall-triage.d.ts +9 -9
- package/dist/src/core/test-stall-triage.js +22 -22
- package/dist/src/core/test-xpcshell-retry.d.ts +26 -7
- package/dist/src/core/test-xpcshell-retry.js +14 -11
- package/dist/src/core/token-category.d.ts +35 -2
- package/dist/src/core/token-category.js +67 -58
- package/dist/src/core/token-coverage.js +4 -5
- package/dist/src/core/token-dark-mode.d.ts +9 -9
- package/dist/src/core/token-dark-mode.js +13 -25
- package/dist/src/core/token-docs.d.ts +1 -1
- package/dist/src/core/token-inventory.d.ts +56 -0
- package/dist/src/core/token-inventory.js +109 -0
- package/dist/src/core/token-manager.d.ts +4 -4
- package/dist/src/core/token-manager.js +22 -22
- package/dist/src/core/token-scaffold.d.ts +4 -4
- package/dist/src/core/token-scaffold.js +4 -4
- package/dist/src/core/token-variant.d.ts +14 -14
- package/dist/src/core/token-variant.js +52 -53
- package/dist/src/core/toolchain-preflight.d.ts +15 -15
- package/dist/src/core/toolchain-preflight.js +23 -23
- package/dist/src/core/tree-cow.d.ts +3 -5
- package/dist/src/core/tree-cow.js +8 -8
- package/dist/src/core/tree-guard.d.ts +3 -3
- package/dist/src/core/tree-guard.js +23 -23
- package/dist/src/core/tree-store.d.ts +15 -15
- package/dist/src/core/tree-store.js +39 -38
- package/dist/src/core/typecheck-shim.d.ts +16 -15
- package/dist/src/core/typecheck-shim.js +26 -25
- package/dist/src/core/typecheck.d.ts +12 -12
- package/dist/src/core/typecheck.js +33 -33
- package/dist/src/core/wire-destroy.d.ts +2 -2
- package/dist/src/core/wire-destroy.js +5 -5
- package/dist/src/core/wire-dom-fragment.d.ts +3 -3
- package/dist/src/core/wire-dom-fragment.js +12 -23
- package/dist/src/core/wire-init.d.ts +2 -2
- package/dist/src/core/wire-init.js +7 -7
- package/dist/src/core/wire-subscript.d.ts +1 -1
- package/dist/src/core/wire-subscript.js +3 -3
- package/dist/src/core/wire-utils.d.ts +9 -9
- package/dist/src/core/wire-utils.js +16 -28
- package/dist/src/core/xpcshell-appdir.d.ts +20 -20
- package/dist/src/core/xpcshell-appdir.js +28 -30
- package/dist/src/core/xpcshell-profile-dir.d.ts +3 -3
- package/dist/src/core/xpcshell-profile-dir.js +7 -7
- package/dist/src/errors/base.d.ts +69 -16
- package/dist/src/errors/base.js +95 -26
- package/dist/src/errors/build.d.ts +6 -6
- package/dist/src/errors/build.js +26 -34
- package/dist/src/errors/codes.d.ts +10 -10
- package/dist/src/errors/codes.js +10 -10
- package/dist/src/errors/config.d.ts +0 -14
- package/dist/src/errors/config.js +13 -34
- package/dist/src/errors/download.d.ts +13 -0
- package/dist/src/errors/download.js +53 -24
- package/dist/src/errors/furnace.d.ts +2 -2
- package/dist/src/errors/furnace.js +8 -9
- package/dist/src/errors/git.d.ts +9 -9
- package/dist/src/errors/git.js +21 -31
- package/dist/src/errors/patch.d.ts +3 -3
- package/dist/src/errors/patch.js +11 -13
- package/dist/src/errors/rebase.d.ts +1 -1
- package/dist/src/errors/rebase.js +8 -8
- package/dist/src/errors/run.d.ts +1 -1
- package/dist/src/errors/run.js +1 -1
- package/dist/src/index.d.ts +4 -4
- package/dist/src/index.js +4 -4
- package/dist/src/types/commands/options.d.ts +155 -200
- package/dist/src/types/commands/patches.d.ts +19 -19
- package/dist/src/types/commands/project.d.ts +3 -3
- package/dist/src/types/config.d.ts +52 -19
- package/dist/src/types/furnace.d.ts +17 -17
- package/dist/src/types/index.d.ts +0 -1
- package/dist/src/types/json.d.ts +3 -3
- package/dist/src/types/json.js +2 -2
- package/dist/src/types/typecheck.d.ts +3 -3
- package/dist/src/utils/assert.d.ts +4 -16
- package/dist/src/utils/assert.js +7 -24
- package/dist/src/utils/build-info.d.ts +6 -6
- package/dist/src/utils/build-info.js +6 -6
- package/dist/src/utils/child-env.d.ts +7 -6
- package/dist/src/utils/child-env.js +5 -5
- package/dist/src/utils/concurrency.d.ts +2 -2
- package/dist/src/utils/concurrency.js +2 -2
- package/dist/src/utils/elapsed.js +10 -1
- package/dist/src/utils/errors.d.ts +8 -8
- package/dist/src/utils/errors.js +8 -8
- package/dist/src/utils/fs.d.ts +1 -1
- package/dist/src/utils/fs.js +15 -20
- package/dist/src/utils/hash.d.ts +12 -0
- package/dist/src/utils/hash.js +16 -0
- package/dist/src/utils/line-dispatch.d.ts +15 -0
- package/dist/src/utils/line-dispatch.js +48 -0
- package/dist/src/utils/logger.d.ts +4 -4
- package/dist/src/utils/logger.js +11 -11
- package/dist/src/utils/machine-output.js +2 -2
- package/dist/src/utils/options.d.ts +14 -20
- package/dist/src/utils/options.js +26 -27
- package/dist/src/utils/package-root.js +5 -14
- package/dist/src/utils/paths.d.ts +4 -4
- package/dist/src/utils/paths.js +4 -4
- package/dist/src/utils/platform.d.ts +0 -4
- package/dist/src/utils/process-group.d.ts +10 -9
- package/dist/src/utils/process-group.js +37 -36
- package/dist/src/utils/process.d.ts +70 -55
- package/dist/src/utils/process.js +129 -179
- package/dist/src/utils/ps-duration.d.ts +4 -4
- package/dist/src/utils/ps-duration.js +9 -9
- package/dist/src/utils/regex.d.ts +4 -4
- package/dist/src/utils/regex.js +7 -7
- package/dist/src/utils/sleep.d.ts +26 -0
- package/dist/src/utils/sleep.js +31 -0
- package/dist/src/utils/stdio-drain.d.ts +7 -7
- package/dist/src/utils/stdio-drain.js +8 -8
- package/dist/src/utils/validation.d.ts +12 -49
- package/dist/src/utils/validation.js +26 -36
- package/docs/README.md +2 -2
- package/docs/configuration.md +163 -69
- package/docs/exit-codes.md +66 -49
- package/docs/furnace.md +20 -19
- package/docs/lifecycle-invariants.md +414 -247
- package/docs/machine-output.md +58 -34
- package/docs/patch-workflow.md +48 -44
- package/docs/run-logs.md +72 -28
- package/docs/testing.md +105 -98
- package/docs/verification-trees.md +23 -22
- package/package.json +7 -6
- package/dist/src/commands/rebase.d.ts +0 -4
- package/dist/src/commands/rebase.js +0 -5
- package/dist/src/core/patch-artifact-normalize.d.ts +0 -21
- package/dist/src/core/patch-artifact-normalize.js +0 -24
- package/dist/src/core/patch-lint-reexports.d.ts +0 -7
- package/dist/src/core/patch-lint-reexports.js +0 -8
- package/dist/src/core/wire-targets.d.ts +0 -7
- package/dist/src/core/wire-targets.js +0 -8
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
* automatically on every deploy.
|
|
12
12
|
*
|
|
13
13
|
* Ownership contract: only entries whose key starts with
|
|
14
|
-
* `chrome://global/content/elements/`
|
|
14
|
+
* `chrome://global/content/elements/` and whose mapped path resolves into
|
|
15
15
|
* the Furnace custom-components workspace are managed (added, updated,
|
|
16
|
-
* pruned). Everything else in the jsconfig
|
|
17
|
-
* entries pointing elsewhere
|
|
16
|
+
* pruned). Everything else in the jsconfig, including hand-written `paths`
|
|
17
|
+
* entries pointing elsewhere, is preserved verbatim. No `baseUrl` is
|
|
18
18
|
* required or written: relative `paths` resolve against the config file's
|
|
19
19
|
* directory.
|
|
20
20
|
*/
|
|
@@ -32,13 +32,13 @@ export interface JsconfigSyncResult {
|
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* Reconciles the managed `compilerOptions.paths` entries of the configured
|
|
35
|
-
* jsconfig against the current Furnace workspace. Idempotent
|
|
36
|
-
* when something actually changes
|
|
35
|
+
* jsconfig against the current Furnace workspace. Idempotent, and writes
|
|
36
|
+
* only when something actually changes. Dry-run returns the diff without
|
|
37
37
|
* writing.
|
|
38
38
|
*
|
|
39
39
|
* The consumer owns the jsconfig file: a missing file is an error with
|
|
40
40
|
* guidance rather than a silent scaffold. JSONC comments and trailing commas
|
|
41
|
-
* are preserved
|
|
41
|
+
* are preserved. Furnace edits only `compilerOptions.paths`.
|
|
42
42
|
*
|
|
43
43
|
* @param root - Project root directory
|
|
44
44
|
* @param config - Loaded Furnace configuration (must carry `typecheckJsconfig`)
|
|
@@ -49,7 +49,7 @@ export declare function syncFurnaceJsconfigPaths(root: string, config: FurnaceCo
|
|
|
49
49
|
}): Promise<JsconfigSyncResult>;
|
|
50
50
|
/**
|
|
51
51
|
* Computes jsconfig `paths` drift for `furnace validate`: managed entries
|
|
52
|
-
* that are missing or stale relative to the current workspace. Read-only
|
|
52
|
+
* that are missing or stale relative to the current workspace. Read-only:
|
|
53
53
|
* delegates to {@link syncFurnaceJsconfigPaths} in dry-run mode.
|
|
54
54
|
*/
|
|
55
55
|
export declare function findJsconfigPathsDrift(root: string, config: FurnaceConfig): Promise<JsconfigSyncResult>;
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
* automatically on every deploy.
|
|
13
13
|
*
|
|
14
14
|
* Ownership contract: only entries whose key starts with
|
|
15
|
-
* `chrome://global/content/elements/`
|
|
15
|
+
* `chrome://global/content/elements/` and whose mapped path resolves into
|
|
16
16
|
* the Furnace custom-components workspace are managed (added, updated,
|
|
17
|
-
* pruned). Everything else in the jsconfig
|
|
18
|
-
* entries pointing elsewhere
|
|
17
|
+
* pruned). Everything else in the jsconfig, including hand-written `paths`
|
|
18
|
+
* entries pointing elsewhere, is preserved verbatim. No `baseUrl` is
|
|
19
19
|
* required or written: relative `paths` resolve against the config file's
|
|
20
20
|
* directory.
|
|
21
21
|
*/
|
|
@@ -32,18 +32,18 @@ import { getFurnacePaths } from './furnace-config.js';
|
|
|
32
32
|
const CHROME_ELEMENTS_URL_PREFIX = 'chrome://global/content/elements/';
|
|
33
33
|
/**
|
|
34
34
|
* Computes the desired managed `paths` entries: one per `.mjs` file of
|
|
35
|
-
* every custom component
|
|
35
|
+
* every custom component, registered or not, keyed by its deployed
|
|
36
36
|
* chrome URL and mapped to the workspace source relative to the jsconfig
|
|
37
37
|
* directory. `register: false` components (notably `kind: "library"`
|
|
38
|
-
* base-class modules, which
|
|
38
|
+
* base-class modules, which require register: false) are included because
|
|
39
39
|
* deploy copies their files and writes jar.mn entries under
|
|
40
|
-
* `content/global/elements/` unconditionally
|
|
41
|
-
* registration is gated on `register
|
|
40
|
+
* `content/global/elements/` unconditionally. Only the customElements.js
|
|
41
|
+
* registration is gated on `register`, so their chrome URLs are just as
|
|
42
42
|
* real as a registered component's.
|
|
43
43
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* has not been deployed yet.
|
|
44
|
+
* The mapping target is the workspace source, not the deployed engine
|
|
45
|
+
* copy. Those are the files developers edit, and they exist even when the
|
|
46
|
+
* engine has not been deployed yet.
|
|
47
47
|
*/
|
|
48
48
|
async function computeDesiredChromePathEntries(config, customDir, jsconfigAbsPath) {
|
|
49
49
|
const jsconfigDir = dirname(jsconfigAbsPath);
|
|
@@ -58,7 +58,7 @@ async function computeDesiredChromePathEntries(config, customDir, jsconfigAbsPat
|
|
|
58
58
|
continue;
|
|
59
59
|
// Emit a `./`-prefixed relative value. TypeScript treats a bare
|
|
60
60
|
// `paths` value (`moz-widget/moz-widget.mjs`) as non-relative and
|
|
61
|
-
// rejects it without `baseUrl` (TS5090)
|
|
61
|
+
// rejects it without `baseUrl` (TS5090). A `./`-prefixed value
|
|
62
62
|
// resolves against the jsconfig directory with no `baseUrl` (which
|
|
63
63
|
// TS6 deprecates, TS5101). `../`-prefixed paths are already relative
|
|
64
64
|
// and left untouched.
|
|
@@ -86,18 +86,19 @@ function isManagedEntry(key, value, jsconfigDir, customDir) {
|
|
|
86
86
|
return false;
|
|
87
87
|
// Containment via `relative`, not a string prefix: a hard-coded `'/'`
|
|
88
88
|
// separator never matches the backslashes `resolve` emits on Windows, which
|
|
89
|
-
// demoted every managed entry to "unmanaged" there
|
|
89
|
+
// demoted every managed entry to "unmanaged" there, so no pruning and no
|
|
90
|
+
// updates.
|
|
90
91
|
return isPathInsideRoot(customDir, resolve(jsconfigDir, value[0]));
|
|
91
92
|
}
|
|
92
93
|
/**
|
|
93
94
|
* Reconciles the managed `compilerOptions.paths` entries of the configured
|
|
94
|
-
* jsconfig against the current Furnace workspace. Idempotent
|
|
95
|
-
* when something actually changes
|
|
95
|
+
* jsconfig against the current Furnace workspace. Idempotent, and writes
|
|
96
|
+
* only when something actually changes. Dry-run returns the diff without
|
|
96
97
|
* writing.
|
|
97
98
|
*
|
|
98
99
|
* The consumer owns the jsconfig file: a missing file is an error with
|
|
99
100
|
* guidance rather than a silent scaffold. JSONC comments and trailing commas
|
|
100
|
-
* are preserved
|
|
101
|
+
* are preserved. Furnace edits only `compilerOptions.paths`.
|
|
101
102
|
*
|
|
102
103
|
* @param root - Project root directory
|
|
103
104
|
* @param config - Loaded Furnace configuration (must carry `typecheckJsconfig`)
|
|
@@ -143,8 +144,8 @@ export async function syncFurnaceJsconfigPaths(root, config, options) {
|
|
|
143
144
|
...(jsconfigObject.compilerOptions?.paths ?? {}),
|
|
144
145
|
};
|
|
145
146
|
const nextPaths = {};
|
|
146
|
-
// Preserve every unmanaged entry verbatim
|
|
147
|
-
// no longer desired
|
|
147
|
+
// Preserve every unmanaged entry verbatim. Prune managed entries that are
|
|
148
|
+
// no longer desired. Update managed entries whose target moved.
|
|
148
149
|
for (const [key, value] of Object.entries(currentPaths)) {
|
|
149
150
|
if (!isManagedEntry(key, value, jsconfigDir, furnacePaths.customDir)) {
|
|
150
151
|
nextPaths[key] = value;
|
|
@@ -157,8 +158,9 @@ export async function syncFurnaceJsconfigPaths(root, config, options) {
|
|
|
157
158
|
}
|
|
158
159
|
// Treat `./x` and bare `x` as equal so a previously-synced bare value (or
|
|
159
160
|
// a hand-written `./` prefix) is not rewritten as "stale" on every run.
|
|
160
|
-
// The existing value is kept verbatim when equivalent
|
|
161
|
-
// way
|
|
161
|
+
// The existing value is kept verbatim when equivalent, so there is no
|
|
162
|
+
// churn either way. Only a genuinely different target updates (to the
|
|
163
|
+
// `./` form).
|
|
162
164
|
if (!samePathValue(value[0], want[0] ?? '')) {
|
|
163
165
|
result.updated.push(key);
|
|
164
166
|
nextPaths[key] = want;
|
|
@@ -184,7 +186,7 @@ export async function syncFurnaceJsconfigPaths(root, config, options) {
|
|
|
184
186
|
}
|
|
185
187
|
/**
|
|
186
188
|
* Computes jsconfig `paths` drift for `furnace validate`: managed entries
|
|
187
|
-
* that are missing or stale relative to the current workspace. Read-only
|
|
189
|
+
* that are missing or stale relative to the current workspace. Read-only:
|
|
188
190
|
* delegates to {@link syncFurnaceJsconfigPaths} in dry-run mode.
|
|
189
191
|
*/
|
|
190
192
|
export async function findJsconfigPathsDrift(root, config) {
|
|
@@ -3,7 +3,7 @@ import { type RollbackJournal } from './furnace-rollback.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* The signal names the lifecycle wrapper knows how to react to. Spelled out
|
|
5
5
|
* as a literal union (rather than `NodeJS.Signals`) so the public type
|
|
6
|
-
* surface does not depend on the NodeJS global namespace
|
|
6
|
+
* surface does not depend on the NodeJS global namespace. Consumers of
|
|
7
7
|
* FireForge's published scoped npm package may compile against tsconfigs
|
|
8
8
|
* that omit `@types/node`.
|
|
9
9
|
*/
|
|
@@ -36,9 +36,9 @@ export interface FurnaceOperationContext {
|
|
|
36
36
|
* Bodies that catch-and-restore on their own (the `furnace/*` command
|
|
37
37
|
* bodies, `furnace-apply`) call this from their catch block after the
|
|
38
38
|
* restore, then re-throw. Without it the wrapper would restore the same
|
|
39
|
-
* journal again on the way out
|
|
40
|
-
* rename-based and converge, but it would race a second
|
|
41
|
-
* write against the state-file lock.
|
|
39
|
+
* journal again on the way out. That is harmless for the file writes,
|
|
40
|
+
* which are rename-based and converge, but it would race a second
|
|
41
|
+
* `pendingRepair` write against the state-file lock.
|
|
42
42
|
*/
|
|
43
43
|
markRolledBack(): void;
|
|
44
44
|
}
|
|
@@ -49,7 +49,7 @@ export interface RunFurnaceMutationOptions {
|
|
|
49
49
|
* Used by dry-run paths where no engine mutation occurs.
|
|
50
50
|
*
|
|
51
51
|
* Note: a dry-run can overlap with a real mutation because it does not
|
|
52
|
-
* acquire the lock. This is safe because dry-runs only read
|
|
52
|
+
* acquire the lock. This is safe because dry-runs only read. However, a
|
|
53
53
|
* dry-run that starts before a real mutation and finishes after it may
|
|
54
54
|
* observe partially-written engine state. Accept this trade-off so that
|
|
55
55
|
* concurrent dry-runs never block each other or a real apply.
|
|
@@ -58,11 +58,11 @@ export interface RunFurnaceMutationOptions {
|
|
|
58
58
|
/**
|
|
59
59
|
* Override the default 30 s furnace-lock timeout.
|
|
60
60
|
*
|
|
61
|
-
* Set from the caller's resolved `--wait-lock` budget, so
|
|
61
|
+
* Set from the caller's resolved `--wait-lock` budget, so one flag governs
|
|
62
62
|
* both locks a furnace mutation takes. Before that it was declared and
|
|
63
63
|
* never passed: `furnace deploy --wait-lock 1800` waited 1800 s for the
|
|
64
64
|
* engine session lock and then met `.fireforge/furnace.lock` with a fixed
|
|
65
|
-
* 30 s, which is the worst shape a budget can have
|
|
65
|
+
* 30 s, which is the worst shape a budget can have: it pays the whole
|
|
66
66
|
* wait and still refuses. When absent, {@link sessionWaitLockMs} supplies
|
|
67
67
|
* the session-wide budget so the twelve furnace mutators that declare no
|
|
68
68
|
* flag are covered too.
|
|
@@ -78,7 +78,7 @@ export interface RunFurnaceMutationOptions {
|
|
|
78
78
|
/**
|
|
79
79
|
* Converts a resolved `--wait-lock` budget in seconds into the
|
|
80
80
|
* {@link RunFurnaceMutationOptions} slice that applies it to the furnace
|
|
81
|
-
* lock. Undefined in, empty out
|
|
81
|
+
* lock. Undefined in, empty out, so the caller can spread it
|
|
82
82
|
* unconditionally without assigning `undefined` under
|
|
83
83
|
* `exactOptionalPropertyTypes`.
|
|
84
84
|
*
|
|
@@ -94,7 +94,7 @@ export declare function waitLockMutationOptions(waitLockSeconds: number | undefi
|
|
|
94
94
|
* Returns true while a signal-driven rollback is in progress. The bin entry
|
|
95
95
|
* point uses this as a re-entrancy guard so a user mashing Ctrl+C cannot
|
|
96
96
|
* trigger a second rollback that races the first. Exposed for the bin shim
|
|
97
|
-
* (and the test suite)
|
|
97
|
+
* (and the test suite). Production callers should not need it.
|
|
98
98
|
*/
|
|
99
99
|
export declare function isSignalRollbackInFlight(): boolean;
|
|
100
100
|
/**
|
|
@@ -105,7 +105,7 @@ export declare function isSignalRollbackInFlight(): boolean;
|
|
|
105
105
|
export declare function rollbackActiveOperationsForSignal(signal: FurnaceShutdownSignal): Promise<void>;
|
|
106
106
|
/**
|
|
107
107
|
* Resolves the path of the lock directory used to serialize furnace mutations
|
|
108
|
-
* for a given project root. Exposed for tests
|
|
108
|
+
* for a given project root. Exposed for tests. Production callers should not
|
|
109
109
|
* touch this directly.
|
|
110
110
|
*/
|
|
111
111
|
export declare function getFurnaceLockPath(root: string): string;
|
|
@@ -119,10 +119,10 @@ export declare function getFurnaceLockPath(root: string): string;
|
|
|
119
119
|
* restructure control flow through the engine's rollback path for a
|
|
120
120
|
* cosmetic gain.
|
|
121
121
|
*
|
|
122
|
-
* The ordering is the part worth centralising: `markRolledBack()`
|
|
122
|
+
* The ordering is the part worth centralising: `markRolledBack()` must run
|
|
123
123
|
* before the restore, so a restore that itself fails does not leave the
|
|
124
|
-
* lifecycle wrapper replaying the same journal on the way out.
|
|
125
|
-
*
|
|
124
|
+
* lifecycle wrapper replaying the same journal on the way out. The
|
|
125
|
+
* original error is rethrown unless the rollback is what failed: the
|
|
126
126
|
* operator needs to know what went wrong, and separately whether the engine
|
|
127
127
|
* could be put back.
|
|
128
128
|
*
|
|
@@ -130,7 +130,7 @@ export declare function getFurnaceLockPath(root: string): string;
|
|
|
130
130
|
* @param journal - Rollback journal this body populated
|
|
131
131
|
* @param error - The error the body threw
|
|
132
132
|
* @param options - Project root, pending-repair tag, and message fragments
|
|
133
|
-
* @returns Never
|
|
133
|
+
* @returns Never, because it always throws
|
|
134
134
|
*/
|
|
135
135
|
export declare function completeJournalRollback(ctx: FurnaceOperationContext, journal: RollbackJournal, error: unknown, options: {
|
|
136
136
|
projectRoot: string;
|
|
@@ -144,11 +144,11 @@ export declare function completeJournalRollback(ctx: FurnaceOperationContext, jo
|
|
|
144
144
|
* Forcibly removes the furnace lock directory for every active operation.
|
|
145
145
|
*
|
|
146
146
|
* The bin-layer signal handler calls `process.exit` after rollback, which
|
|
147
|
-
* short-circuits Node's normal unwinding
|
|
148
|
-
* }` never runs
|
|
147
|
+
* short-circuits Node's normal unwinding, so `withFileLock`'s `finally { rm
|
|
148
|
+
* }` never runs and the lock directory survives the process. The next
|
|
149
149
|
* FireForge command then has to either wait out the staleness window or
|
|
150
150
|
* have the operator remove the lock manually. This sweeper runs inside
|
|
151
|
-
* the signal-handler pipeline
|
|
151
|
+
* the signal-handler pipeline before `process.exit`, so the lock is gone
|
|
152
152
|
* by the time the next command starts.
|
|
153
153
|
*
|
|
154
154
|
* Errors are logged and swallowed: we do not want a slow I/O failure at
|
|
@@ -161,7 +161,7 @@ export declare function forceReleaseFurnaceLocksForActiveOperations(): Promise<v
|
|
|
161
161
|
* Runs a furnace-mutating body under the apply-wide lock and registers it
|
|
162
162
|
* with the process-wide SIGINT/SIGTERM rollback pathway. The lock prevents
|
|
163
163
|
* two `furnace apply`/`deploy`/`create`/etc. runs from racing on the engine
|
|
164
|
-
* working copy
|
|
164
|
+
* working copy. The CLI entrypoint's global signal handlers consult this
|
|
165
165
|
* registry and invoke rollback (writing a `pendingRepair` marker when needed)
|
|
166
166
|
* if the user hits Ctrl+C mid-run.
|
|
167
167
|
*
|
|
@@ -169,7 +169,7 @@ export declare function forceReleaseFurnaceLocksForActiveOperations(): Promise<v
|
|
|
169
169
|
* the lock entirely (concurrent dry-runs are safe and shouldn't block each
|
|
170
170
|
* other).
|
|
171
171
|
*
|
|
172
|
-
* The body receives a {@link FurnaceOperationContext}
|
|
172
|
+
* The body receives a {@link FurnaceOperationContext}. It must call
|
|
173
173
|
* `ctx.registerJournal(journal)` once it has constructed its rollback journal.
|
|
174
174
|
* Bodies that don't manage a journal directly (e.g. apply, which delegates to
|
|
175
175
|
* `applyAllComponents`) can pass an internal callback through.
|
|
@@ -188,5 +188,8 @@ export declare function recordFurnaceRollbackFailure(root: string, operation: Fu
|
|
|
188
188
|
* reuse the module across tests, so the test suite must call this between
|
|
189
189
|
* cases that exercise the signal pathway. Not exported from the package
|
|
190
190
|
* entry point.
|
|
191
|
+
*
|
|
192
|
+
* @internal Exported only so tests can reach it. Not part of the public
|
|
193
|
+
* surface.
|
|
191
194
|
*/
|
|
192
195
|
export declare function __resetFurnaceOperationStateForTests(): void;
|
|
@@ -14,7 +14,7 @@ const FURNACE_LOCK_FILENAME = 'furnace.lock';
|
|
|
14
14
|
/**
|
|
15
15
|
* Converts a resolved `--wait-lock` budget in seconds into the
|
|
16
16
|
* {@link RunFurnaceMutationOptions} slice that applies it to the furnace
|
|
17
|
-
* lock. Undefined in, empty out
|
|
17
|
+
* lock. Undefined in, empty out, so the caller can spread it
|
|
18
18
|
* unconditionally without assigning `undefined` under
|
|
19
19
|
* `exactOptionalPropertyTypes`.
|
|
20
20
|
*
|
|
@@ -33,7 +33,7 @@ export function waitLockMutationOptions(waitLockSeconds) {
|
|
|
33
33
|
* already has it.
|
|
34
34
|
*
|
|
35
35
|
* Must stay synchronous and must be called before the caller's first
|
|
36
|
-
* await
|
|
36
|
+
* await. That is what makes the claim atomic against the signal handler.
|
|
37
37
|
*
|
|
38
38
|
* @param operation - The in-flight operation to claim
|
|
39
39
|
* @returns True when the caller now owns the rollback
|
|
@@ -52,7 +52,7 @@ let signalRollbackInFlight = false;
|
|
|
52
52
|
* Returns true while a signal-driven rollback is in progress. The bin entry
|
|
53
53
|
* point uses this as a re-entrancy guard so a user mashing Ctrl+C cannot
|
|
54
54
|
* trigger a second rollback that races the first. Exposed for the bin shim
|
|
55
|
-
* (and the test suite)
|
|
55
|
+
* (and the test suite). Production callers should not need it.
|
|
56
56
|
*/
|
|
57
57
|
export function isSignalRollbackInFlight() {
|
|
58
58
|
return signalRollbackInFlight;
|
|
@@ -60,7 +60,7 @@ export function isSignalRollbackInFlight() {
|
|
|
60
60
|
/**
|
|
61
61
|
* Rolls back every in-flight furnace operation and writes a pendingRepair
|
|
62
62
|
* marker for each. The bin entry point installs SIGINT/SIGTERM handlers that
|
|
63
|
-
* call this and then exit
|
|
63
|
+
* call this and then exit. Calling it directly from inside the library would
|
|
64
64
|
* violate the "process.exit only in bin" invariant. The function is also
|
|
65
65
|
* exposed under this name so the test suite can exercise the teardown path
|
|
66
66
|
* without going through `process.emit` / `process.exit`.
|
|
@@ -91,8 +91,9 @@ export async function rollbackActiveOperationsForSignal(signal) {
|
|
|
91
91
|
// Snapshot the active operations so we don't race with `runFurnaceMutation`
|
|
92
92
|
// clearing slots during normal completion. Filter completed bodies so a
|
|
93
93
|
// body sitting in its finally-block cleanup window is not counted as live
|
|
94
|
-
// work
|
|
95
|
-
// run` (which never registers a mutation but can receive
|
|
94
|
+
// work. Counting it would mis-trigger the rollback banner for plain
|
|
95
|
+
// `fireforge run` (which never registers a mutation but can receive
|
|
96
|
+
// SIGTERM).
|
|
96
97
|
const snapshot = [...activeOperations.values()].filter((op) => !op.completed);
|
|
97
98
|
if (snapshot.length === 0) {
|
|
98
99
|
// Nothing to roll back. Stay silent so commands that never mutated (run,
|
|
@@ -124,9 +125,9 @@ export async function rollbackActiveOperationsForSignal(signal) {
|
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
127
|
if (!op.journal) {
|
|
127
|
-
// The body had not yet handed us a journal
|
|
128
|
-
// still write a marker because the body may have started
|
|
129
|
-
// engine before reaching the registerJournal call.
|
|
128
|
+
// The body had not yet handed us a journal, so there is nothing to
|
|
129
|
+
// roll back. We still write a marker because the body may have started
|
|
130
|
+
// mutating the engine before reaching the registerJournal call.
|
|
130
131
|
const cleanupSuffix = cleanupErrors.length > 0 ? `; cleanup errors: ${cleanupErrors.join('; ')}` : '';
|
|
131
132
|
await persistPendingRepair(op.root, op.kind, `interrupted by ${signal} before any state was captured${cleanupSuffix}`).catch((error) => {
|
|
132
133
|
warn(`Could not persist pending-repair marker: ${toError(error).message}`);
|
|
@@ -190,7 +191,7 @@ async function rollbackOperationForThrow(operation) {
|
|
|
190
191
|
}
|
|
191
192
|
if (!operation.journal) {
|
|
192
193
|
// Nothing was captured, so there is nothing to restore. Unlike the signal
|
|
193
|
-
// path we do
|
|
194
|
+
// path we do not write a pendingRepair marker here: a body that threw
|
|
194
195
|
// before registering a journal is overwhelmingly a refusal raised during
|
|
195
196
|
// pre-flight (a validation failure, a missing file), and marking the root
|
|
196
197
|
// as needing repair would block every later furnace mutation behind a
|
|
@@ -243,7 +244,7 @@ async function persistPendingRepair(root, operation, reason) {
|
|
|
243
244
|
}
|
|
244
245
|
/**
|
|
245
246
|
* Resolves the path of the lock directory used to serialize furnace mutations
|
|
246
|
-
* for a given project root. Exposed for tests
|
|
247
|
+
* for a given project root. Exposed for tests. Production callers should not
|
|
247
248
|
* touch this directly.
|
|
248
249
|
*/
|
|
249
250
|
export function getFurnaceLockPath(root) {
|
|
@@ -259,10 +260,10 @@ export function getFurnaceLockPath(root) {
|
|
|
259
260
|
* restructure control flow through the engine's rollback path for a
|
|
260
261
|
* cosmetic gain.
|
|
261
262
|
*
|
|
262
|
-
* The ordering is the part worth centralising: `markRolledBack()`
|
|
263
|
+
* The ordering is the part worth centralising: `markRolledBack()` must run
|
|
263
264
|
* before the restore, so a restore that itself fails does not leave the
|
|
264
|
-
* lifecycle wrapper replaying the same journal on the way out.
|
|
265
|
-
*
|
|
265
|
+
* lifecycle wrapper replaying the same journal on the way out. The
|
|
266
|
+
* original error is rethrown unless the rollback is what failed: the
|
|
266
267
|
* operator needs to know what went wrong, and separately whether the engine
|
|
267
268
|
* could be put back.
|
|
268
269
|
*
|
|
@@ -270,7 +271,7 @@ export function getFurnaceLockPath(root) {
|
|
|
270
271
|
* @param journal - Rollback journal this body populated
|
|
271
272
|
* @param error - The error the body threw
|
|
272
273
|
* @param options - Project root, pending-repair tag, and message fragments
|
|
273
|
-
* @returns Never
|
|
274
|
+
* @returns Never, because it always throws
|
|
274
275
|
*/
|
|
275
276
|
export async function completeJournalRollback(ctx, journal, error, options) {
|
|
276
277
|
// This body owns its rollback end to end, so tell the lifecycle wrapper
|
|
@@ -289,11 +290,11 @@ export async function completeJournalRollback(ctx, journal, error, options) {
|
|
|
289
290
|
* Forcibly removes the furnace lock directory for every active operation.
|
|
290
291
|
*
|
|
291
292
|
* The bin-layer signal handler calls `process.exit` after rollback, which
|
|
292
|
-
* short-circuits Node's normal unwinding
|
|
293
|
-
* }` never runs
|
|
293
|
+
* short-circuits Node's normal unwinding, so `withFileLock`'s `finally { rm
|
|
294
|
+
* }` never runs and the lock directory survives the process. The next
|
|
294
295
|
* FireForge command then has to either wait out the staleness window or
|
|
295
296
|
* have the operator remove the lock manually. This sweeper runs inside
|
|
296
|
-
* the signal-handler pipeline
|
|
297
|
+
* the signal-handler pipeline before `process.exit`, so the lock is gone
|
|
297
298
|
* by the time the next command starts.
|
|
298
299
|
*
|
|
299
300
|
* Errors are logged and swallowed: we do not want a slow I/O failure at
|
|
@@ -305,9 +306,9 @@ export async function forceReleaseFurnaceLocksForActiveOperations() {
|
|
|
305
306
|
const paths = new Set([...activeOperations.values()].map((op) => getFurnaceLockPath(op.root)));
|
|
306
307
|
for (const lockPath of paths) {
|
|
307
308
|
// Ownership-checked, like every other release path. The bare `rm` this
|
|
308
|
-
// replaced would delete a lock a
|
|
309
|
-
// window between our operation dying and this sweep running
|
|
310
|
-
// race `releaseLock`'s PID verification was added to close, reopened
|
|
309
|
+
// replaced would delete a lock a different process had acquired in the
|
|
310
|
+
// window between our operation dying and this sweep running. That is the
|
|
311
|
+
// exact race `releaseLock`'s PID verification was added to close, reopened
|
|
311
312
|
// here because the sweeper has no acquisition token to check.
|
|
312
313
|
const removed = await releaseLockIfOwned(lockPath);
|
|
313
314
|
verbose(removed
|
|
@@ -319,7 +320,7 @@ export async function forceReleaseFurnaceLocksForActiveOperations() {
|
|
|
319
320
|
* Runs a furnace-mutating body under the apply-wide lock and registers it
|
|
320
321
|
* with the process-wide SIGINT/SIGTERM rollback pathway. The lock prevents
|
|
321
322
|
* two `furnace apply`/`deploy`/`create`/etc. runs from racing on the engine
|
|
322
|
-
* working copy
|
|
323
|
+
* working copy. The CLI entrypoint's global signal handlers consult this
|
|
323
324
|
* registry and invoke rollback (writing a `pendingRepair` marker when needed)
|
|
324
325
|
* if the user hits Ctrl+C mid-run.
|
|
325
326
|
*
|
|
@@ -327,7 +328,7 @@ export async function forceReleaseFurnaceLocksForActiveOperations() {
|
|
|
327
328
|
* the lock entirely (concurrent dry-runs are safe and shouldn't block each
|
|
328
329
|
* other).
|
|
329
330
|
*
|
|
330
|
-
* The body receives a {@link FurnaceOperationContext}
|
|
331
|
+
* The body receives a {@link FurnaceOperationContext}. It must call
|
|
331
332
|
* `ctx.registerJournal(journal)` once it has constructed its rollback journal.
|
|
332
333
|
* Bodies that don't manage a journal directly (e.g. apply, which delegates to
|
|
333
334
|
* `applyAllComponents`) can pass an internal callback through.
|
|
@@ -356,10 +357,10 @@ export async function runFurnaceMutation(root, kind, body, options = {}) {
|
|
|
356
357
|
const token = nextOperationToken++;
|
|
357
358
|
const operation = { root, kind, cleanups: [] };
|
|
358
359
|
const lockPath = getFurnaceLockPath(root);
|
|
359
|
-
// An explicit budget wins
|
|
360
|
-
// the lock in the refusal
|
|
361
|
-
//
|
|
362
|
-
//
|
|
360
|
+
// An explicit budget wins. Otherwise the session-wide one applies. Naming
|
|
361
|
+
// the lock in the refusal matters: a mutation takes two, and a message
|
|
362
|
+
// that says only "timed out" sends the operator to raise a budget that
|
|
363
|
+
// was already large enough for the other lock.
|
|
363
364
|
const timeoutMs = options.lockTimeoutMs ?? sessionWaitLockMs();
|
|
364
365
|
const lockOptions = {
|
|
365
366
|
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
@@ -374,14 +375,14 @@ export async function runFurnaceMutation(root, kind, body, options = {}) {
|
|
|
374
375
|
return withFileLock(lockPath, async () => {
|
|
375
376
|
// Everything the body does from here is serialized only by the furnace
|
|
376
377
|
// lock, so confirm we are actually inside it before registering as a
|
|
377
|
-
// live mutation. The owner record is
|
|
378
|
-
//
|
|
379
|
-
//
|
|
380
|
-
//
|
|
378
|
+
// live mutation. The owner record is best-effort in `withFileLock`
|
|
379
|
+
// (a live holder can legitimately have no readable PID), so the PID
|
|
380
|
+
// half only tightens the check when a record is present. Asserting on
|
|
381
|
+
// its existence would fire on a lock we really do hold.
|
|
381
382
|
const lockStatus = await readLockStatus(lockPath);
|
|
382
383
|
assert(lockStatus.held, 'furnace lock held before the mutation body runs');
|
|
383
384
|
assert(lockStatus.holder === undefined || lockStatus.holder.pid === process.pid, () => `furnace lock is owned by this process ` +
|
|
384
|
-
`(held by PID ${
|
|
385
|
+
`(held by PID ${lockStatus.holder?.pid}, we are ${process.pid})`);
|
|
385
386
|
activeOperations.set(token, operation);
|
|
386
387
|
try {
|
|
387
388
|
return await body({
|
|
@@ -401,8 +402,8 @@ export async function runFurnaceMutation(root, kind, body, options = {}) {
|
|
|
401
402
|
// so it gets the same treatment. A bare finally here would
|
|
402
403
|
// deregister the operation and mark it completed, removing it from
|
|
403
404
|
// the signal handler's view too, so a body that threw outside its
|
|
404
|
-
// own catch
|
|
405
|
-
// two per-component try blocks
|
|
405
|
+
// own catch (notably anywhere in `applyAllComponents` outside its
|
|
406
|
+
// two per-component try blocks) would leave the checkout torn with
|
|
406
407
|
// no marker.
|
|
407
408
|
//
|
|
408
409
|
// This runs inside the withFileLock callback, so the furnace lock is
|
|
@@ -432,6 +433,9 @@ export async function recordFurnaceRollbackFailure(root, operation, reason) {
|
|
|
432
433
|
* reuse the module across tests, so the test suite must call this between
|
|
433
434
|
* cases that exercise the signal pathway. Not exported from the package
|
|
434
435
|
* entry point.
|
|
436
|
+
*
|
|
437
|
+
* @internal Exported only so tests can reach it. Not part of the public
|
|
438
|
+
* surface.
|
|
435
439
|
*/
|
|
436
440
|
export function __resetFurnaceOperationStateForTests() {
|
|
437
441
|
activeOperations.clear();
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
* `furnace.json` exists.
|
|
4
4
|
*
|
|
5
5
|
* Kept separate from the `GeneralError` ladder in `engine-precondition.ts`
|
|
6
|
-
* because the error
|
|
7
|
-
* carries its own `userMessage` and exit code 9, so a helper
|
|
8
|
-
* `GeneralError` would silently change both.
|
|
6
|
+
* because the error class matters here and is not merely cosmetic:
|
|
7
|
+
* `FurnaceError` carries its own `userMessage` and exit code 9, so a helper
|
|
8
|
+
* raising `GeneralError` would silently change both.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* Four sites are not routed through this helper: `furnace list`,
|
|
11
|
+
* `furnace status`, `furnace init`, and `verify`. Each informs rather than
|
|
12
|
+
* refuses, and each says so at its own site. `furnace validate` refusing is
|
|
13
|
+
* the intended line between inspecting and validating.
|
|
14
14
|
*/
|
|
15
15
|
import type { FurnaceConfig } from '../types/furnace.js';
|
|
16
16
|
import type { ProjectPaths } from '../types/index.js';
|
|
@@ -18,8 +18,8 @@ import type { ProjectPaths } from '../types/index.js';
|
|
|
18
18
|
export interface FurnacePreconditionOptions {
|
|
19
19
|
/**
|
|
20
20
|
* Appended to the engine-missing refusal, e.g.
|
|
21
|
-
* `' to scaffold a chrome-doc.'`. The base message ends
|
|
22
|
-
* punctuation so the suffix reads as one sentence
|
|
21
|
+
* `' to scaffold a chrome-doc.'`. The base message ends without
|
|
22
|
+
* punctuation so the suffix reads as one sentence. Callers passing nothing
|
|
23
23
|
* get a plain full stop.
|
|
24
24
|
*/
|
|
25
25
|
engineMissingSuffix?: string;
|
|
@@ -48,7 +48,7 @@ export declare function assertFurnaceEngineReady(projectRoot: string, options?:
|
|
|
48
48
|
paths: ProjectPaths;
|
|
49
49
|
}>;
|
|
50
50
|
/**
|
|
51
|
-
* Asserts the full Furnace ladder
|
|
51
|
+
* Asserts the full Furnace ladder (engine checkout, then `furnace.json`)
|
|
52
52
|
* and returns the loaded config so callers do not read it a second time.
|
|
53
53
|
*
|
|
54
54
|
* @param projectRoot - Project root directory
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
* `furnace.json` exists.
|
|
5
5
|
*
|
|
6
6
|
* Kept separate from the `GeneralError` ladder in `engine-precondition.ts`
|
|
7
|
-
* because the error
|
|
8
|
-
* carries its own `userMessage` and exit code 9, so a helper
|
|
9
|
-
* `GeneralError` would silently change both.
|
|
7
|
+
* because the error class matters here and is not merely cosmetic:
|
|
8
|
+
* `FurnaceError` carries its own `userMessage` and exit code 9, so a helper
|
|
9
|
+
* raising `GeneralError` would silently change both.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* Four sites are not routed through this helper: `furnace list`,
|
|
12
|
+
* `furnace status`, `furnace init`, and `verify`. Each informs rather than
|
|
13
|
+
* refuses, and each says so at its own site. `furnace validate` refusing is
|
|
14
|
+
* the intended line between inspecting and validating.
|
|
15
15
|
*/
|
|
16
16
|
import { FurnaceError } from '../errors/furnace.js';
|
|
17
17
|
import { pathExists } from '../utils/fs.js';
|
|
@@ -47,7 +47,7 @@ export async function assertFurnaceEngineReady(projectRoot, options = {}) {
|
|
|
47
47
|
return { paths };
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
|
-
* Asserts the full Furnace ladder
|
|
50
|
+
* Asserts the full Furnace ladder (engine checkout, then `furnace.json`)
|
|
51
51
|
* and returns the loaded config so callers do not read it a second time.
|
|
52
52
|
*
|
|
53
53
|
* @param projectRoot - Project root directory
|
|
@@ -3,14 +3,26 @@ export interface RefreshFileResult {
|
|
|
3
3
|
status: 'merged' | 'conflict' | 'unchanged' | 'new-file';
|
|
4
4
|
conflictMarkers?: number;
|
|
5
5
|
}
|
|
6
|
+
export interface RefreshOverrideFileOptions {
|
|
7
|
+
/** Path to the engine git repository. */
|
|
8
|
+
engineDir: string;
|
|
9
|
+
/** Path to the current override file in the workspace. */
|
|
10
|
+
overridePath: string;
|
|
11
|
+
/** Engine-relative path for git show. */
|
|
12
|
+
engineRelPath: string;
|
|
13
|
+
/** The git ref at which the override was originally created. */
|
|
14
|
+
baseCommit: string;
|
|
15
|
+
/** Display name for the file. */
|
|
16
|
+
fileName: string;
|
|
17
|
+
/** When true, compute the merge but write nothing. */
|
|
18
|
+
dryRun?: boolean | undefined;
|
|
19
|
+
/** Conflict resolution preference handed to `git merge-file`. */
|
|
20
|
+
strategy?: 'ours' | 'theirs' | undefined;
|
|
21
|
+
}
|
|
6
22
|
/**
|
|
7
23
|
* Refreshes a single override file against the current engine HEAD.
|
|
8
24
|
*
|
|
9
|
-
* @param
|
|
10
|
-
* @param overridePath - Path to the current override file in the workspace
|
|
11
|
-
* @param engineRelPath - Engine-relative path for git show
|
|
12
|
-
* @param baseCommit - The git ref at which the override was originally created
|
|
13
|
-
* @param fileName - Display name for the file
|
|
25
|
+
* @param options - See {@link RefreshOverrideFileOptions}
|
|
14
26
|
* @returns Merge result with the updated content written to the override file
|
|
15
27
|
*/
|
|
16
|
-
export declare function refreshOverrideFile(
|
|
28
|
+
export declare function refreshOverrideFile(options: RefreshOverrideFileOptions): Promise<RefreshFileResult>;
|
|
@@ -81,24 +81,21 @@ async function threeWayMergeFile(base, ours, theirs, label, strategy) {
|
|
|
81
81
|
/**
|
|
82
82
|
* Refreshes a single override file against the current engine HEAD.
|
|
83
83
|
*
|
|
84
|
-
* @param
|
|
85
|
-
* @param overridePath - Path to the current override file in the workspace
|
|
86
|
-
* @param engineRelPath - Engine-relative path for git show
|
|
87
|
-
* @param baseCommit - The git ref at which the override was originally created
|
|
88
|
-
* @param fileName - Display name for the file
|
|
84
|
+
* @param options - See {@link RefreshOverrideFileOptions}
|
|
89
85
|
* @returns Merge result with the updated content written to the override file
|
|
90
86
|
*/
|
|
91
|
-
export async function refreshOverrideFile(
|
|
87
|
+
export async function refreshOverrideFile(options) {
|
|
88
|
+
const { engineDir, overridePath, engineRelPath, baseCommit, fileName, dryRun, strategy } = options;
|
|
92
89
|
// Read the three versions
|
|
93
90
|
const oursContent = await readText(overridePath);
|
|
94
91
|
const baseContent = await getFileContentAtRef(engineDir, engineRelPath, baseCommit);
|
|
95
92
|
if (baseContent === null) {
|
|
96
|
-
// File didn't exist at baseCommit
|
|
93
|
+
// File didn't exist at baseCommit: this is a new file introduced by the override
|
|
97
94
|
return { fileName, status: 'new-file' };
|
|
98
95
|
}
|
|
99
96
|
const theirsContent = await getFileContentAtRef(engineDir, engineRelPath, 'HEAD');
|
|
100
97
|
if (theirsContent === null) {
|
|
101
|
-
// File was removed upstream
|
|
98
|
+
// File was removed upstream, so no merge is needed. Keep the override as-is
|
|
102
99
|
return { fileName, status: 'unchanged' };
|
|
103
100
|
}
|
|
104
101
|
// If upstream hasn't changed, nothing to merge
|