@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
|
@@ -1,20 +1,9 @@
|
|
|
1
1
|
import type { ComponentApplyContext, CustomComponentConfig, DryRunAction, OverrideComponentConfig, StepError } from '../types/furnace.js';
|
|
2
2
|
import { type RollbackJournal } from './furnace-rollback.js';
|
|
3
|
-
interface DirectoryEntry {
|
|
4
|
-
isFile(): boolean;
|
|
5
|
-
isSymbolicLink?(): boolean;
|
|
6
|
-
name: string;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* True for a plain-file directory entry — symlinks and directories are
|
|
10
|
-
* never copy candidates. Exported for the patch-owned overwrite probe,
|
|
11
|
-
* which walks the same override copy-candidate set as apply.
|
|
12
|
-
*/
|
|
13
|
-
export declare function isRegularFile(entry: DirectoryEntry): boolean;
|
|
14
3
|
/**
|
|
15
4
|
* Filter deciding which files in an override workspace directory are candidates
|
|
16
5
|
* for copying into the engine. Exported so `furnace remove` can invert apply
|
|
17
|
-
* using the
|
|
6
|
+
* using the same file set: the "files to restore" set is defined as the
|
|
18
7
|
* inverse of the "files apply would have written" set.
|
|
19
8
|
*/
|
|
20
9
|
export declare function isOverrideCopyCandidate(entryName: string, type: OverrideComponentConfig['type']): boolean;
|
|
@@ -27,14 +16,14 @@ export declare function getOverrideEngineTargetPath(engineDir: string, config: O
|
|
|
27
16
|
* Behaviour matches the per-file branch of `restoreOverrideEngineFiles` in
|
|
28
17
|
* `furnace remove`: snapshot first, then either `git restore` (if the file
|
|
29
18
|
* exists in HEAD) or hard-delete (if the override introduced the file). The
|
|
30
|
-
* caller
|
|
19
|
+
* caller must guarantee `engineDir` is a git repository. This helper does
|
|
31
20
|
* not re-check, because both `furnace remove` and `furnace apply` already
|
|
32
21
|
* own the precondition check at their entry points and re-checking on every
|
|
33
22
|
* file would balloon git invocations.
|
|
34
23
|
*
|
|
35
24
|
* Returns the action taken so the caller can produce accurate user-facing
|
|
36
25
|
* counts (`restored` vs `removed`). `noop` means the file was neither in HEAD
|
|
37
|
-
* nor on disk, which can happen when the engine was reset out-of-band
|
|
26
|
+
* nor on disk, which can happen when the engine was reset out-of-band. The
|
|
38
27
|
* caller should treat that as a successful no-op rather than an error.
|
|
39
28
|
*/
|
|
40
29
|
export declare function restoreOverrideFileToBaseline(engineDir: string, enginePath: string, journal: RollbackJournal): Promise<'restored' | 'removed' | 'noop'>;
|
|
@@ -43,14 +32,14 @@ export declare function computeComponentChecksums(componentDir: string): Promise
|
|
|
43
32
|
/**
|
|
44
33
|
* Removes engine copies of files that the developer has deleted from a custom
|
|
45
34
|
* component's workspace since the last apply. `.ftl` files live under the
|
|
46
|
-
* shared Fluent tree (`engine/${FTL_DIR}`)
|
|
35
|
+
* shared Fluent tree (`engine/${FTL_DIR}`). Everything else lives under
|
|
47
36
|
* `engine/${config.targetPath}`. Snapshots each removal into the journal so a
|
|
48
37
|
* mid-apply failure can roll the engine back to its pre-undeploy state. Files
|
|
49
38
|
* that are already missing from the engine are silently no-op (the engine
|
|
50
|
-
* may have been reset out-of-band
|
|
51
|
-
* error in a recovery path).
|
|
39
|
+
* may have been reset out-of-band, and refusing here would surface a
|
|
40
|
+
* confusing error in a recovery path).
|
|
52
41
|
*
|
|
53
|
-
* Does
|
|
42
|
+
* Does not touch jar.mn or customElements.js: registration churn is the
|
|
54
43
|
* caller's responsibility, since it must coordinate with the new file list
|
|
55
44
|
* computed by the regular apply step that follows.
|
|
56
45
|
*/
|
|
@@ -62,9 +51,9 @@ export declare function undeployCustomFiles(engineDir: string, config: CustomCom
|
|
|
62
51
|
* HEAD if it was a Firefox baseline file or hard-deletes it if the override
|
|
63
52
|
* had introduced it.
|
|
64
53
|
*
|
|
65
|
-
* Requires `engineDir` to be a git repository
|
|
54
|
+
* Requires `engineDir` to be a git repository: overrides cannot be inverted
|
|
66
55
|
* without git HEAD as the source of truth. The caller is expected to have
|
|
67
|
-
* already validated this precondition for the apply path
|
|
56
|
+
* already validated this precondition for the apply path. We re-check here
|
|
68
57
|
* so unit tests that exercise this helper directly cannot accidentally
|
|
69
58
|
* silent-fail on a non-git fixture.
|
|
70
59
|
*/
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
-
import { createHash } from 'node:crypto';
|
|
3
2
|
import { readdir } from 'node:fs/promises';
|
|
4
3
|
import { join, relative } from 'node:path';
|
|
5
4
|
import { FurnaceError } from '../errors/furnace.js';
|
|
6
5
|
import { toError } from '../utils/errors.js';
|
|
7
6
|
import { copyFile, ensureDir, pathExists, readText, removeFile } from '../utils/fs.js';
|
|
7
|
+
import { sha256Hex } from '../utils/hash.js';
|
|
8
8
|
import { verbose } from '../utils/logger.js';
|
|
9
9
|
import { normalizePathSlashes } from '../utils/paths.js';
|
|
10
10
|
import { buildCustomDryRunActions } from './furnace-apply-dry-run.js';
|
|
@@ -12,30 +12,16 @@ import { applyCustomFtlFile, applySharedFtlPrune, removeCustomFtlJarMnEntry, } f
|
|
|
12
12
|
import { normalizeForChecksum } from './furnace-checksum-utils.js';
|
|
13
13
|
import { CUSTOM_ELEMENTS_JS, JAR_MN } from './furnace-constants.js';
|
|
14
14
|
import { deployFileWithFragments, SHARED_FRAGMENTS_DIR } from './furnace-css-fragments.js';
|
|
15
|
+
import { isRegularFile } from './furnace-dir-entry.js';
|
|
15
16
|
import { addCustomElementRegistration, addJarMnEntries } from './furnace-registration.js';
|
|
16
17
|
import { recordCreatedDir, snapshotFile } from './furnace-rollback.js';
|
|
17
18
|
import { checkRegistrationConsistency } from './furnace-validate-registration.js';
|
|
18
19
|
import { isGitRepository } from './git.js';
|
|
19
20
|
import { fileExistsInHead, restoreTrackedPath } from './git-file-ops.js';
|
|
20
|
-
/**
|
|
21
|
-
* True for a plain-file directory entry — symlinks and directories are
|
|
22
|
-
* never copy candidates. Exported for the patch-owned overwrite probe,
|
|
23
|
-
* which walks the same override copy-candidate set as apply.
|
|
24
|
-
*/
|
|
25
|
-
export function isRegularFile(entry) {
|
|
26
|
-
if (!entry.isFile())
|
|
27
|
-
return false;
|
|
28
|
-
if (typeof entry.isSymbolicLink === 'function' && entry.isSymbolicLink())
|
|
29
|
-
return false;
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
function isChecksummedComponentFile(name) {
|
|
33
|
-
return name.endsWith('.mjs') || name.endsWith('.css') || name.endsWith('.ftl');
|
|
34
|
-
}
|
|
35
21
|
/**
|
|
36
22
|
* Filter deciding which files in an override workspace directory are candidates
|
|
37
23
|
* for copying into the engine. Exported so `furnace remove` can invert apply
|
|
38
|
-
* using the
|
|
24
|
+
* using the same file set: the "files to restore" set is defined as the
|
|
39
25
|
* inverse of the "files apply would have written" set.
|
|
40
26
|
*/
|
|
41
27
|
export function isOverrideCopyCandidate(entryName, type) {
|
|
@@ -60,18 +46,18 @@ export function getOverrideEngineTargetPath(engineDir, config, fileName, ftlDir)
|
|
|
60
46
|
* Behaviour matches the per-file branch of `restoreOverrideEngineFiles` in
|
|
61
47
|
* `furnace remove`: snapshot first, then either `git restore` (if the file
|
|
62
48
|
* exists in HEAD) or hard-delete (if the override introduced the file). The
|
|
63
|
-
* caller
|
|
49
|
+
* caller must guarantee `engineDir` is a git repository. This helper does
|
|
64
50
|
* not re-check, because both `furnace remove` and `furnace apply` already
|
|
65
51
|
* own the precondition check at their entry points and re-checking on every
|
|
66
52
|
* file would balloon git invocations.
|
|
67
53
|
*
|
|
68
54
|
* Returns the action taken so the caller can produce accurate user-facing
|
|
69
55
|
* counts (`restored` vs `removed`). `noop` means the file was neither in HEAD
|
|
70
|
-
* nor on disk, which can happen when the engine was reset out-of-band
|
|
56
|
+
* nor on disk, which can happen when the engine was reset out-of-band. The
|
|
71
57
|
* caller should treat that as a successful no-op rather than an error.
|
|
72
58
|
*/
|
|
73
59
|
export async function restoreOverrideFileToBaseline(engineDir, enginePath, journal) {
|
|
74
|
-
// Engine-relative paths are
|
|
60
|
+
// Engine-relative paths are identifiers here, not filesystem arguments:
|
|
75
61
|
// they are handed to git, recorded in furnace state, and compared against
|
|
76
62
|
// the POSIX paths furnace.json and jar.mn already carry. `relative()`
|
|
77
63
|
// returns backslashes on Windows, so without this the same file has two
|
|
@@ -80,8 +66,8 @@ export async function restoreOverrideFileToBaseline(engineDir, enginePath, journ
|
|
|
80
66
|
// Snapshot before mutation so a later rollback can undo both restoration
|
|
81
67
|
// (writes whatever content we removed back) and deletion (recreates the
|
|
82
68
|
// file). Snapshotting a missing path records `{ existed: false }`, which
|
|
83
|
-
// restoreFile turns into a delete
|
|
84
|
-
//
|
|
69
|
+
// restoreFile turns into a delete, the inverse of "we just wrote a file
|
|
70
|
+
// here", which is correct for the noop case too.
|
|
85
71
|
await snapshotFile(journal, enginePath);
|
|
86
72
|
if (await fileExistsInHead(engineDir, relPath)) {
|
|
87
73
|
await restoreTrackedPath(engineDir, relPath);
|
|
@@ -102,10 +88,13 @@ export async function computeComponentChecksums(componentDir) {
|
|
|
102
88
|
continue;
|
|
103
89
|
if (entry.name === 'override.json')
|
|
104
90
|
continue;
|
|
105
|
-
|
|
91
|
+
// The three extensions a component can deploy. Anything else in the
|
|
92
|
+
// workspace directory is not part of the component's checksum identity.
|
|
93
|
+
const { name: entryName } = entry;
|
|
94
|
+
if (!entryName.endsWith('.mjs') && !entryName.endsWith('.css') && !entryName.endsWith('.ftl'))
|
|
106
95
|
continue;
|
|
107
96
|
const content = await readText(join(componentDir, entry.name));
|
|
108
|
-
const hash =
|
|
97
|
+
const hash = sha256Hex(normalizeForChecksum(content));
|
|
109
98
|
checksums[entry.name] = hash;
|
|
110
99
|
}
|
|
111
100
|
return checksums;
|
|
@@ -113,14 +102,14 @@ export async function computeComponentChecksums(componentDir) {
|
|
|
113
102
|
/**
|
|
114
103
|
* Removes engine copies of files that the developer has deleted from a custom
|
|
115
104
|
* component's workspace since the last apply. `.ftl` files live under the
|
|
116
|
-
* shared Fluent tree (`engine/${FTL_DIR}`)
|
|
105
|
+
* shared Fluent tree (`engine/${FTL_DIR}`). Everything else lives under
|
|
117
106
|
* `engine/${config.targetPath}`. Snapshots each removal into the journal so a
|
|
118
107
|
* mid-apply failure can roll the engine back to its pre-undeploy state. Files
|
|
119
108
|
* that are already missing from the engine are silently no-op (the engine
|
|
120
|
-
* may have been reset out-of-band
|
|
121
|
-
* error in a recovery path).
|
|
109
|
+
* may have been reset out-of-band, and refusing here would surface a
|
|
110
|
+
* confusing error in a recovery path).
|
|
122
111
|
*
|
|
123
|
-
* Does
|
|
112
|
+
* Does not touch jar.mn or customElements.js: registration churn is the
|
|
124
113
|
* caller's responsibility, since it must coordinate with the new file list
|
|
125
114
|
* computed by the regular apply step that follows.
|
|
126
115
|
*/
|
|
@@ -138,7 +127,7 @@ export async function undeployCustomFiles(engineDir, config, deletedFiles, ftlDi
|
|
|
138
127
|
removed.push(normalizePathSlashes(relative(engineDir, enginePath)));
|
|
139
128
|
}
|
|
140
129
|
// When an `.ftl` is deleted from the workspace the corresponding locale
|
|
141
|
-
// jar.mn entry must also be dropped
|
|
130
|
+
// jar.mn entry must also be dropped. Otherwise the chrome URI points at
|
|
142
131
|
// a missing file and runtime Fluent resolution breaks silently.
|
|
143
132
|
// `removeCustomFtlJarMnEntry` early-returns for `sharedFtl` components
|
|
144
133
|
// (the shared bundle is owned elsewhere).
|
|
@@ -153,9 +142,9 @@ export async function undeployCustomFiles(engineDir, config, deletedFiles, ftlDi
|
|
|
153
142
|
* HEAD if it was a Firefox baseline file or hard-deletes it if the override
|
|
154
143
|
* had introduced it.
|
|
155
144
|
*
|
|
156
|
-
* Requires `engineDir` to be a git repository
|
|
145
|
+
* Requires `engineDir` to be a git repository: overrides cannot be inverted
|
|
157
146
|
* without git HEAD as the source of truth. The caller is expected to have
|
|
158
|
-
* already validated this precondition for the apply path
|
|
147
|
+
* already validated this precondition for the apply path. We re-check here
|
|
159
148
|
* so unit tests that exercise this helper directly cannot accidentally
|
|
160
149
|
* silent-fail on a non-git fixture.
|
|
161
150
|
*/
|
|
@@ -169,11 +158,11 @@ export async function undeployOverrideFiles(engineDir, config, deletedFiles, ftl
|
|
|
169
158
|
if (!(await isGitRepository(engineDir))) {
|
|
170
159
|
throw new FurnaceError('Cannot undeploy override files: engine is not a git repository. Run "fireforge download" to initialise it.');
|
|
171
160
|
}
|
|
172
|
-
// Note: we
|
|
161
|
+
// Note: we do not re-filter `deletedFiles` through
|
|
173
162
|
// `isOverrideCopyCandidate(fileName, config.type)`. A file recorded in
|
|
174
163
|
// `previous` was already a valid copy candidate when it was deployed, and
|
|
175
164
|
// re-filtering would block cleanup if the override type later flipped
|
|
176
|
-
// from `full` to `css-only
|
|
165
|
+
// from `full` to `css-only`, which is the case we need cleanup for.
|
|
177
166
|
const restored = [];
|
|
178
167
|
const removed = [];
|
|
179
168
|
for (const fileName of deletedFiles) {
|
|
@@ -233,13 +222,13 @@ export async function hasOverrideEngineDrift(ctx, config, cachedEngineChecksums)
|
|
|
233
222
|
const engineContent = normalizeForChecksum(await readText(enginePath));
|
|
234
223
|
// Fast path: compare engine content hash against cached value from last apply
|
|
235
224
|
if (cachedEngineChecksums) {
|
|
236
|
-
const engineHash =
|
|
225
|
+
const engineHash = sha256Hex(engineContent);
|
|
237
226
|
const cachedHash = cachedEngineChecksums[entry.name];
|
|
238
227
|
if (cachedHash && engineHash !== cachedHash) {
|
|
239
228
|
return true;
|
|
240
229
|
}
|
|
241
230
|
if (cachedHash)
|
|
242
|
-
continue; // Hash match
|
|
231
|
+
continue; // Hash match, skip full source comparison
|
|
243
232
|
}
|
|
244
233
|
// Slow path: byte-compare engine content against workspace source
|
|
245
234
|
const srcContent = normalizeForChecksum(await readText(join(componentDir, entry.name)));
|
|
@@ -270,7 +259,7 @@ export async function hasCustomEngineDrift(ctx, config) {
|
|
|
270
259
|
// Registration drift: only check jar.mn entries for the file types that
|
|
271
260
|
// actually exist in source. jarMn{Mjs,Css} are substring checks, so a
|
|
272
261
|
// component with only .mjs (no .css) should not be flagged when jarMnCss
|
|
273
|
-
// is false
|
|
262
|
+
// is false. That is the expected post-apply state, not drift.
|
|
274
263
|
const entries = await readdir(componentDir, { withFileTypes: true, encoding: 'utf8' });
|
|
275
264
|
let hasMjs = false;
|
|
276
265
|
let hasCss = false;
|
|
@@ -322,16 +311,16 @@ export async function applyCustomComponent(ctx, config, dryRun = false, rollback
|
|
|
322
311
|
// must complete before any copy (they read the original content), but
|
|
323
312
|
// independent files can be processed concurrently.
|
|
324
313
|
const filesToCopy = entries.filter((entry) => isRegularFile(entry) && (entry.name.endsWith('.mjs') || entry.name.endsWith('.css')));
|
|
325
|
-
// Snapshot phase (serial
|
|
314
|
+
// Snapshot phase (serial: journal is not concurrent-safe for the same path)
|
|
326
315
|
for (const entry of filesToCopy) {
|
|
327
316
|
const dest = join(targetDir, entry.name);
|
|
328
317
|
if (rollbackJournal) {
|
|
329
318
|
await snapshotFile(rollbackJournal, dest);
|
|
330
319
|
}
|
|
331
320
|
}
|
|
332
|
-
// Copy phase (parallel
|
|
321
|
+
// Copy phase (parallel: independent file writes to different paths).
|
|
333
322
|
// CSS files carrying @fireforge-include directives are written as their
|
|
334
|
-
// fragment-expanded form
|
|
323
|
+
// fragment-expanded form. The workspace source keeps only the directive,
|
|
335
324
|
// so shared CSS stays single-sourced.
|
|
336
325
|
const sharedDir = join(componentDir, '..', '..', SHARED_FRAGMENTS_DIR);
|
|
337
326
|
await Promise.all(filesToCopy.map(async (entry) => {
|
|
@@ -52,7 +52,7 @@ export function logApplyResult(result, isDryRun) {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
// Patch-owned overwrite warnings print on every non-dry-run
|
|
55
|
-
// outcome
|
|
55
|
+
// outcome, including the rolled-back branch, where the overwrite
|
|
56
56
|
// happened before the rollback restored it and the operator still needs
|
|
57
57
|
// to know the deployed copy was momentarily replaced.
|
|
58
58
|
if (!isDryRun && result.warnings !== undefined) {
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Patch-owned overwrite warnings for `furnace apply`.
|
|
3
3
|
*
|
|
4
|
-
* For Furnace-managed components, apply
|
|
4
|
+
* For Furnace-managed components, apply overwrites the deployed engine
|
|
5
5
|
* copies with the `components/` sources. A fix made directly in `engine/` and
|
|
6
|
-
* exported into a patch
|
|
6
|
+
* exported into a patch (but never back-ported to the component source) is
|
|
7
7
|
* silently undone by the next apply, and a plain drift line reads like
|
|
8
|
-
* "someone's uncommitted work". This module detects that
|
|
9
|
-
* the copy (deployed bytes differ from the component source
|
|
8
|
+
* "someone's uncommitted work". This module detects that case before
|
|
9
|
+
* the copy (deployed bytes differ from the component source and the file is
|
|
10
10
|
* patch-owned) and produces a per-file warning naming the file, the owning
|
|
11
11
|
* patch, and the consequence.
|
|
12
12
|
*
|
|
13
|
-
* The per-file byte comparison already exists
|
|
13
|
+
* The per-file byte comparison already exists:
|
|
14
14
|
* `checkRegistrationConsistency` for custom components (fragment- and
|
|
15
|
-
* ftl-aware) and the copy-candidate walk for overrides
|
|
15
|
+
* ftl-aware) and the copy-candidate walk for overrides. This module only
|
|
16
16
|
* surfaces what was previously computed and thrown away.
|
|
17
17
|
*/
|
|
18
18
|
import type { CustomComponentConfig, OverrideComponentConfig } from '../types/furnace.js';
|
|
@@ -26,7 +26,7 @@ export interface PatchOwnedOverwriteWarning {
|
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
28
|
* Loads the file → owning-patch map for the overwrite warning.
|
|
29
|
-
* A missing or unreadable patches manifest degrades to an empty map
|
|
29
|
+
* A missing or unreadable patches manifest degrades to an empty map. The
|
|
30
30
|
* warning is advisory and must never block an apply.
|
|
31
31
|
*/
|
|
32
32
|
export declare function loadPatchClaimsForApply(root: string): Promise<ReadonlyMap<string, readonly string[]>>;
|
|
@@ -55,8 +55,8 @@ export type PatchOwnedOverwriteProbe = {
|
|
|
55
55
|
};
|
|
56
56
|
/**
|
|
57
57
|
* Finds deployed files this component's apply is about to overwrite whose
|
|
58
|
-
* engine bytes differ from the component source
|
|
59
|
-
* Probe failures degrade to a verbose line and an empty list
|
|
58
|
+
* engine bytes differ from the component source and that are patch-owned.
|
|
59
|
+
* Probe failures degrade to a verbose line and an empty list. The apply
|
|
60
60
|
* itself must not fail because the warning probe could not run.
|
|
61
61
|
*/
|
|
62
62
|
export declare function findPatchOwnedOverwrites(args: PatchOwnedOverwriteProbe): Promise<PatchOwnedOverwriteWarning[]>;
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Patch-owned overwrite warnings for `furnace apply`.
|
|
4
4
|
*
|
|
5
|
-
* For Furnace-managed components, apply
|
|
5
|
+
* For Furnace-managed components, apply overwrites the deployed engine
|
|
6
6
|
* copies with the `components/` sources. A fix made directly in `engine/` and
|
|
7
|
-
* exported into a patch
|
|
7
|
+
* exported into a patch (but never back-ported to the component source) is
|
|
8
8
|
* silently undone by the next apply, and a plain drift line reads like
|
|
9
|
-
* "someone's uncommitted work". This module detects that
|
|
10
|
-
* the copy (deployed bytes differ from the component source
|
|
9
|
+
* "someone's uncommitted work". This module detects that case before
|
|
10
|
+
* the copy (deployed bytes differ from the component source and the file is
|
|
11
11
|
* patch-owned) and produces a per-file warning naming the file, the owning
|
|
12
12
|
* patch, and the consequence.
|
|
13
13
|
*
|
|
14
|
-
* The per-file byte comparison already exists
|
|
14
|
+
* The per-file byte comparison already exists:
|
|
15
15
|
* `checkRegistrationConsistency` for custom components (fragment- and
|
|
16
|
-
* ftl-aware) and the copy-candidate walk for overrides
|
|
16
|
+
* ftl-aware) and the copy-candidate walk for overrides. This module only
|
|
17
17
|
* surfaces what was previously computed and thrown away.
|
|
18
18
|
*/
|
|
19
19
|
import { readdir } from 'node:fs/promises';
|
|
@@ -21,15 +21,17 @@ import { join, relative } from 'node:path';
|
|
|
21
21
|
import { toError } from '../utils/errors.js';
|
|
22
22
|
import { pathExists, readText } from '../utils/fs.js';
|
|
23
23
|
import { verbose } from '../utils/logger.js';
|
|
24
|
+
import { normalizePathSlashes } from '../utils/paths.js';
|
|
24
25
|
import { getProjectPaths } from './config.js';
|
|
25
|
-
import { getOverrideEngineTargetPath, isOverrideCopyCandidate
|
|
26
|
+
import { getOverrideEngineTargetPath, isOverrideCopyCandidate } from './furnace-apply-helpers.js';
|
|
26
27
|
import { FTL_DIR } from './furnace-constants.js';
|
|
28
|
+
import { isRegularFile } from './furnace-dir-entry.js';
|
|
27
29
|
import { checkRegistrationConsistency } from './furnace-validate-registration.js';
|
|
28
30
|
import { loadPatchesManifest } from './patch-manifest.js';
|
|
29
31
|
import { buildPatchClaims } from './status-classify.js';
|
|
30
32
|
/**
|
|
31
33
|
* Loads the file → owning-patch map for the overwrite warning.
|
|
32
|
-
* A missing or unreadable patches manifest degrades to an empty map
|
|
34
|
+
* A missing or unreadable patches manifest degrades to an empty map. The
|
|
33
35
|
* warning is advisory and must never block an apply.
|
|
34
36
|
*/
|
|
35
37
|
export async function loadPatchClaimsForApply(root) {
|
|
@@ -86,7 +88,7 @@ async function findOverrideOverwrites(args) {
|
|
|
86
88
|
// A missing target is a fresh deploy, not a lost engine edit.
|
|
87
89
|
if (!(await pathExists(enginePath)))
|
|
88
90
|
continue;
|
|
89
|
-
const engineRel = relative(engineDir, enginePath)
|
|
91
|
+
const engineRel = normalizePathSlashes(relative(engineDir, enginePath));
|
|
90
92
|
const owners = patchClaims.get(engineRel);
|
|
91
93
|
if (owners === undefined || owners.length === 0)
|
|
92
94
|
continue;
|
|
@@ -102,8 +104,8 @@ async function findOverrideOverwrites(args) {
|
|
|
102
104
|
}
|
|
103
105
|
/**
|
|
104
106
|
* Finds deployed files this component's apply is about to overwrite whose
|
|
105
|
-
* engine bytes differ from the component source
|
|
106
|
-
* Probe failures degrade to a verbose line and an empty list
|
|
107
|
+
* engine bytes differ from the component source and that are patch-owned.
|
|
108
|
+
* Probe failures degrade to a verbose line and an empty list. The apply
|
|
107
109
|
* itself must not fail because the warning probe could not run.
|
|
108
110
|
*/
|
|
109
111
|
export async function findPatchOwnedOverwrites(args) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Dry-run action builders for files deleted from a component workspace since
|
|
3
3
|
* the last apply. Split out of `furnace-apply.ts` to stay under the per-file
|
|
4
|
-
* line budget
|
|
4
|
+
* line budget. The real undeploy paths stay in `furnace-apply-helpers.ts`.
|
|
5
5
|
*/
|
|
6
6
|
import type { CustomComponentConfig, DryRunAction, OverrideComponentConfig } from '../types/furnace.js';
|
|
7
7
|
/** Plans the engine-restore actions for deleted override workspace files. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Dry-run action builders for files deleted from a component workspace since
|
|
4
4
|
* the last apply. Split out of `furnace-apply.ts` to stay under the per-file
|
|
5
|
-
* line budget
|
|
5
|
+
* line budget. The real undeploy paths stay in `furnace-apply-helpers.ts`.
|
|
6
6
|
*/
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import { getOverrideEngineTargetPath } from './furnace-apply-helpers.js';
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { ApplyResult, DryRunAction } from '../types/furnace.js';
|
|
2
2
|
import { type FurnaceOperationContext } from './furnace-operation.js';
|
|
3
3
|
import { type RollbackJournal } from './furnace-rollback.js';
|
|
4
|
-
export { computeComponentChecksums,
|
|
4
|
+
export { computeComponentChecksums, prefixChecksums } from './furnace-apply-helpers.js';
|
|
5
5
|
/**
|
|
6
6
|
* Result of {@link applyAllComponents}.
|
|
7
7
|
*
|
|
8
8
|
* Named so consumers can refer to the shape directly instead of going
|
|
9
9
|
* through `Awaited<ReturnType<typeof applyAllComponents>>`.
|
|
10
10
|
*
|
|
11
|
-
* `actions` is populated only on a dry run
|
|
12
|
-
* `persistState: false` hands journal ownership back to the caller.
|
|
11
|
+
* `actions` is populated only on a dry run. `rollbackJournal` is set only
|
|
12
|
+
* when `persistState: false` hands journal ownership back to the caller.
|
|
13
13
|
*/
|
|
14
14
|
export type ApplyAllComponentsResult = ApplyResult & {
|
|
15
15
|
actions?: DryRunAction[];
|
|
@@ -44,6 +44,6 @@ export declare function applyAllComponents(root: string, dryRun?: boolean, optio
|
|
|
44
44
|
}): Promise<ApplyAllComponentsResult>; /**
|
|
45
45
|
* Shared context threaded through the batch apply loops. Bundles the state
|
|
46
46
|
* both loops mutate (result/actions/checksums) with the immutable run
|
|
47
|
-
* parameters
|
|
47
|
+
* parameters. The 12-13 positional parameters this replaced let call sites
|
|
48
48
|
* drift and made every new parameter a two-signature change.
|
|
49
49
|
*/
|
|
@@ -19,7 +19,18 @@ import { addJarMnEntries, removeCustomElementRegistration, removeJarMnEntries, }
|
|
|
19
19
|
import { createRollbackJournal, restoreRollbackJournalOrThrow, snapshotFile, } from './furnace-rollback.js';
|
|
20
20
|
import { blockingStepErrors, hasBlockingStepErrors } from './furnace-step-errors.js';
|
|
21
21
|
import { runPostApplyConsistencyChecks } from './furnace-validate-registration.js';
|
|
22
|
-
export { computeComponentChecksums,
|
|
22
|
+
export { computeComponentChecksums, prefixChecksums } from './furnace-apply-helpers.js';
|
|
23
|
+
/**
|
|
24
|
+
* Records one component's checksums into the run-wide accumulator, under the
|
|
25
|
+
* flattened `type/name/file` keys the state file stores. A Map keeps the
|
|
26
|
+
* accumulation explicit. The previous `Object.assign` merges read as if
|
|
27
|
+
* they replaced the accumulator rather than adding to it.
|
|
28
|
+
*/
|
|
29
|
+
function recordComponentChecksums(accumulator, checksums, type, name) {
|
|
30
|
+
for (const [key, value] of Object.entries(prefixChecksums(checksums, type, name))) {
|
|
31
|
+
accumulator.set(key, value);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
23
34
|
function addMissingComponentError(result, name, directoryPath) {
|
|
24
35
|
result.errors.push({
|
|
25
36
|
name,
|
|
@@ -48,13 +59,13 @@ async function applyOverrideBatch(ctx) {
|
|
|
48
59
|
const changed = await hasComponentChanged(componentDir, previous, currentChecksums);
|
|
49
60
|
if (!changed) {
|
|
50
61
|
// Fast path holds only if the engine still reflects what we deployed.
|
|
51
|
-
// reset/download/manual edits can silently erase engine files
|
|
52
|
-
// checksum record alone cannot detect that.
|
|
62
|
+
// reset/download/manual edits can silently erase engine files, and
|
|
63
|
+
// the checksum record alone cannot detect that.
|
|
53
64
|
const cachedEngine = extractComponentChecksums(state.engineChecksums, 'override', name);
|
|
54
65
|
const drifted = await hasOverrideEngineDrift({ engineDir, componentDir, ftlDir }, overrideConfig, cachedEngine);
|
|
55
66
|
if (!drifted) {
|
|
56
67
|
result.skipped.push({ name, reason: 'No changes since last apply' });
|
|
57
|
-
|
|
68
|
+
recordComponentChecksums(newChecksums, previous, 'override', name);
|
|
58
69
|
continue;
|
|
59
70
|
}
|
|
60
71
|
}
|
|
@@ -75,9 +86,9 @@ async function applyOverrideBatch(ctx) {
|
|
|
75
86
|
filesAffectedTotal.push(...restored, ...removed);
|
|
76
87
|
}
|
|
77
88
|
if (!dryRun) {
|
|
78
|
-
// Runs unconditionally
|
|
79
|
-
// changed
|
|
80
|
-
//
|
|
89
|
+
// Runs unconditionally, including when the component source
|
|
90
|
+
// changed, because the lost-work case is a deployed engine edit
|
|
91
|
+
// that the incoming copy is about to replace.
|
|
81
92
|
recordOverwriteWarnings(result, await findPatchOwnedOverwrites({
|
|
82
93
|
type: 'override',
|
|
83
94
|
engineDir,
|
|
@@ -95,7 +106,7 @@ async function applyOverrideBatch(ctx) {
|
|
|
95
106
|
filesAffectedTotal.push(...filesAffected);
|
|
96
107
|
result.applied.push({ name, type: 'override', filesAffected: filesAffectedTotal });
|
|
97
108
|
if (!dryRun) {
|
|
98
|
-
|
|
109
|
+
recordComponentChecksums(newChecksums, currentChecksums, 'override', name);
|
|
99
110
|
}
|
|
100
111
|
}
|
|
101
112
|
catch (error) {
|
|
@@ -110,11 +121,12 @@ async function applyOverrideBatch(ctx) {
|
|
|
110
121
|
* After undeploying deleted files, the in-engine jar.mn and
|
|
111
122
|
* customElements.js still carry entries for the removed files. Re-sync them
|
|
112
123
|
* by removing all of `name`'s jar.mn entries and re-adding only those that
|
|
113
|
-
* still exist in the workspace
|
|
124
|
+
* still exist in the workspace. If the .mjs itself was deleted, also drop
|
|
114
125
|
* the customElements.js registration. Snapshots are taken under the same
|
|
115
126
|
* journal so the undo path is symmetric with apply.
|
|
116
127
|
*/
|
|
117
|
-
async function reconcileCustomRegistrationAfterUndeploy(
|
|
128
|
+
async function reconcileCustomRegistrationAfterUndeploy(args) {
|
|
129
|
+
const { engineDir, name, config, deletedFiles, currentChecksums, rollbackJournal, filesAffected, } = args;
|
|
118
130
|
if (!config.register || deletedFiles.length === 0)
|
|
119
131
|
return;
|
|
120
132
|
const deletedRegistrationFiles = deletedFiles.filter((f) => f.endsWith('.mjs') || f.endsWith('.css'));
|
|
@@ -129,13 +141,14 @@ async function reconcileCustomRegistrationAfterUndeploy(engineDir, name, config,
|
|
|
129
141
|
await removeJarMnEntries(engineDir, name);
|
|
130
142
|
const liveJarFiles = Object.keys(currentChecksums).filter((f) => f.endsWith('.mjs') || f.endsWith('.css'));
|
|
131
143
|
if (liveJarFiles.length > 0) {
|
|
132
|
-
// applyCustomComponent has already added live entries
|
|
133
|
-
// dropped them too, so re-add now to leave jar.mn in the correct
|
|
144
|
+
// applyCustomComponent has already added live entries, and the remove
|
|
145
|
+
// above dropped them too, so re-add now to leave jar.mn in the correct
|
|
146
|
+
// state.
|
|
134
147
|
await addJarMnEntries(engineDir, name, liveJarFiles);
|
|
135
148
|
}
|
|
136
149
|
filesAffected.push(JAR_MN);
|
|
137
150
|
// If the .mjs file itself was deleted, the customElements registration
|
|
138
|
-
// must go too
|
|
151
|
+
// must go too. Otherwise we leave a dangling import in the Pattern B
|
|
139
152
|
// block that fails at runtime.
|
|
140
153
|
if (deletedFiles.includes(`${name}.mjs`)) {
|
|
141
154
|
if (rollbackJournal) {
|
|
@@ -212,7 +225,7 @@ async function applyCustomBatch(ctx, root, markerComment) {
|
|
|
212
225
|
const drifted = await hasCustomEngineDrift({ root, name, componentDir, ftlDir }, customConfig);
|
|
213
226
|
if (!drifted) {
|
|
214
227
|
result.skipped.push({ name, reason: 'No changes since last apply' });
|
|
215
|
-
|
|
228
|
+
recordComponentChecksums(newChecksums, previous, 'custom', name);
|
|
216
229
|
continue;
|
|
217
230
|
}
|
|
218
231
|
}
|
|
@@ -233,9 +246,9 @@ async function applyCustomBatch(ctx, root, markerComment) {
|
|
|
233
246
|
filesAffectedTotal.push(...removed);
|
|
234
247
|
}
|
|
235
248
|
if (!dryRun) {
|
|
236
|
-
// Runs unconditionally
|
|
237
|
-
// drift detection entirely, which is
|
|
238
|
-
//
|
|
249
|
+
// Runs unconditionally. The `changed === true` path used to skip
|
|
250
|
+
// drift detection entirely, which is when a deployed engine-only
|
|
251
|
+
// fix gets silently replaced (J6).
|
|
239
252
|
recordOverwriteWarnings(result, await findPatchOwnedOverwrites({
|
|
240
253
|
type: 'custom',
|
|
241
254
|
root,
|
|
@@ -250,7 +263,15 @@ async function applyCustomBatch(ctx, root, markerComment) {
|
|
|
250
263
|
allActions.push(...actions);
|
|
251
264
|
}
|
|
252
265
|
if (!dryRun && deletedFiles.length > 0 && blockingStepErrors(stepErrors).length === 0) {
|
|
253
|
-
await reconcileCustomRegistrationAfterUndeploy(
|
|
266
|
+
await reconcileCustomRegistrationAfterUndeploy({
|
|
267
|
+
engineDir,
|
|
268
|
+
name,
|
|
269
|
+
config: customConfig,
|
|
270
|
+
deletedFiles,
|
|
271
|
+
currentChecksums,
|
|
272
|
+
rollbackJournal,
|
|
273
|
+
filesAffected: filesAffectedTotal,
|
|
274
|
+
});
|
|
254
275
|
}
|
|
255
276
|
filesAffectedTotal.push(...filesAffected);
|
|
256
277
|
result.applied.push({
|
|
@@ -259,12 +280,12 @@ async function applyCustomBatch(ctx, root, markerComment) {
|
|
|
259
280
|
filesAffected: filesAffectedTotal,
|
|
260
281
|
...(stepErrors.length > 0 ? { stepErrors } : {}),
|
|
261
282
|
});
|
|
262
|
-
// Only store checksums when the component applied without
|
|
283
|
+
// Only store checksums when the component applied without blocking
|
|
263
284
|
// step errors, so that partially failed components are re-applied on
|
|
264
|
-
// the next run. Advisory errors (FTL degradation) still persist
|
|
285
|
+
// the next run. Advisory errors (FTL degradation) still persist, since
|
|
265
286
|
// re-applying cannot fix a fork that has no locale jar.mn.
|
|
266
287
|
if (!dryRun && blockingStepErrors(stepErrors).length === 0) {
|
|
267
|
-
|
|
288
|
+
recordComponentChecksums(newChecksums, currentChecksums, 'custom', name);
|
|
268
289
|
}
|
|
269
290
|
}
|
|
270
291
|
catch (error) {
|
|
@@ -308,7 +329,7 @@ export async function applyAllComponents(root, dryRun = false, options) {
|
|
|
308
329
|
// When `markerComment` is unset in fireforge.json, default it to
|
|
309
330
|
// `binaryName.toUpperCase()` so the furnace-emitted edits to upstream
|
|
310
331
|
// files (e.g. customElements.js) carry a marker that satisfies
|
|
311
|
-
// `lintModificationComments
|
|
332
|
+
// `lintModificationComments`. That rule keys on
|
|
312
333
|
// `${binaryName.toUpperCase()}:`. An explicit `markerComment` still wins.
|
|
313
334
|
const forgeConfig = await loadConfig(root).catch(() => undefined);
|
|
314
335
|
const markerComment = resolveFurnaceMarkerComment(forgeConfig);
|
|
@@ -318,7 +339,7 @@ export async function applyAllComponents(root, dryRun = false, options) {
|
|
|
318
339
|
operationContext.registerJournal(rollbackJournal);
|
|
319
340
|
}
|
|
320
341
|
// Everything below this line can write to the engine. A real apply that
|
|
321
|
-
// reached it without a journal would have no way back
|
|
342
|
+
// reached it without a journal would have no way back: neither the
|
|
322
343
|
// lifecycle wrapper's throw path nor the signal handler can restore what
|
|
323
344
|
// was never captured. `operationContext` is legitimately absent for the
|
|
324
345
|
// few callers that drive apply outside the wrapper, so the invariant is on
|
|
@@ -330,7 +351,7 @@ export async function applyAllComponents(root, dryRun = false, options) {
|
|
|
330
351
|
errors: [],
|
|
331
352
|
};
|
|
332
353
|
const allActions = [];
|
|
333
|
-
const newChecksums =
|
|
354
|
+
const newChecksums = new Map();
|
|
334
355
|
const componentName = options?.componentName;
|
|
335
356
|
// When a single component is requested, validate it exists before running
|
|
336
357
|
// the batch functions (which would silently skip an unknown name).
|
|
@@ -341,7 +362,7 @@ export async function applyAllComponents(root, dryRun = false, options) {
|
|
|
341
362
|
}
|
|
342
363
|
}
|
|
343
364
|
// Patch-claim map for the overwrite warning: loaded once per
|
|
344
|
-
// apply. A missing/unreadable manifest degrades to an empty map
|
|
365
|
+
// apply. A missing/unreadable manifest degrades to an empty map. The
|
|
345
366
|
// warning is advisory and must never block the apply.
|
|
346
367
|
const patchClaims = await loadPatchClaimsForApply(root);
|
|
347
368
|
const batchContext = {
|
|
@@ -370,7 +391,7 @@ export async function applyAllComponents(root, dryRun = false, options) {
|
|
|
370
391
|
if (!dryRun && !hasApplyStepErrors && result.errors.length === 0) {
|
|
371
392
|
await runPostApplyConsistencyChecks(root, config, result, ftlDir);
|
|
372
393
|
}
|
|
373
|
-
// Recompute
|
|
394
|
+
// Recompute after the consistency checks: they mutate entry.stepErrors
|
|
374
395
|
// when the applied output is inconsistent (e.g. a jar.mn entry that
|
|
375
396
|
// silently mis-landed). Reading the pre-check snapshot lets those failures
|
|
376
397
|
// skip rollback and persist checksums for a component known to be
|
|
@@ -406,8 +427,8 @@ export async function applyAllComponents(root, dryRun = false, options) {
|
|
|
406
427
|
// instead of byte-comparing against workspace sources.
|
|
407
428
|
await updateFurnaceState(root, {
|
|
408
429
|
lastApply: new Date().toISOString(),
|
|
409
|
-
appliedChecksums: newChecksums,
|
|
410
|
-
engineChecksums:
|
|
430
|
+
appliedChecksums: Object.fromEntries(newChecksums),
|
|
431
|
+
engineChecksums: Object.fromEntries(newChecksums),
|
|
411
432
|
});
|
|
412
433
|
}
|
|
413
434
|
else if (rollbackJournal) {
|
|
@@ -422,6 +443,6 @@ export async function applyAllComponents(root, dryRun = false, options) {
|
|
|
422
443
|
} /**
|
|
423
444
|
* Shared context threaded through the batch apply loops. Bundles the state
|
|
424
445
|
* both loops mutate (result/actions/checksums) with the immutable run
|
|
425
|
-
* parameters
|
|
446
|
+
* parameters. The 12-13 positional parameters this replaced let call sites
|
|
426
447
|
* drift and made every new parameter a two-signature change.
|
|
427
448
|
*/
|