@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,21 +1,20 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
/**
|
|
3
|
-
* Doctor check for
|
|
3
|
+
* Doctor check for pre-existing orphaned test-harness workers.
|
|
4
4
|
*
|
|
5
5
|
* A mach invocation that dies at harness startup can strand a Python
|
|
6
|
-
* `multiprocessing` spawn worker plus its resource tracker
|
|
6
|
+
* `multiprocessing` spawn worker plus its resource tracker. The worker
|
|
7
7
|
* reparents to launchd (PPID 1) and busy-spins at 100% CPU indefinitely.
|
|
8
|
-
* The dispatch-side fix is the process-group reaping in `utils/process.ts
|
|
9
|
-
*
|
|
8
|
+
* The dispatch-side fix is the process-group reaping in `utils/process.ts`.
|
|
9
|
+
* This check covers orphans that predate it (or leaked from non-FireForge
|
|
10
10
|
* invocations), detecting them by PPID 1 + large accumulated CPU TIME + a
|
|
11
11
|
* `multiprocessing.spawn`/`resource_tracker` command line.
|
|
12
12
|
*
|
|
13
|
-
* Report-only
|
|
14
|
-
*
|
|
13
|
+
* Report-only: FireForge never kills pre-existing processes it did not
|
|
14
|
+
* spawn, so the check names each candidate and suggests the kill.
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* give.
|
|
16
|
+
* Not wired into `test --canary`: a system-wide process scan on the canary
|
|
17
|
+
* hot path buys no coverage the doctor check does not already give.
|
|
19
18
|
*/
|
|
20
19
|
import { toError } from '../utils/errors.js';
|
|
21
20
|
import { exec } from '../utils/process.js';
|
|
@@ -29,19 +28,11 @@ import { ok, warning } from './doctor-check-core.js';
|
|
|
29
28
|
const HARNESS_WORKER_COMMAND_PATTERN = /multiprocessing\.(?:spawn|forkserver)\b|multiprocessing\.resource_tracker|from multiprocessing\.\w+ import/;
|
|
30
29
|
/** Minimum accumulated CPU time before a match is reported (10 minutes). */
|
|
31
30
|
const DEFAULT_MIN_CPU_SECONDS = 600;
|
|
32
|
-
/**
|
|
33
|
-
* Parses a `ps` TIME (accumulated CPU) value. Implemented in terms of
|
|
34
|
-
* {@link parsePsDuration} — `time=` and `etime=` share one grammar, and a
|
|
35
|
-
* second copy is how the two would drift.
|
|
36
|
-
*/
|
|
37
|
-
export function parseCpuTime(time) {
|
|
38
|
-
return parsePsDuration(time);
|
|
39
|
-
}
|
|
40
31
|
/**
|
|
41
32
|
* Scans `ps -axo pid=,ppid=,time=,command=` output for orphaned harness
|
|
42
33
|
* workers: PPID 1 (reparented to init/launchd), a multiprocessing
|
|
43
34
|
* worker/tracker command line, and at least `minCpuSeconds` of accumulated
|
|
44
|
-
* CPU time. Pure
|
|
35
|
+
* CPU time. Pure, so it is fixture-testable without spawning anything.
|
|
45
36
|
*/
|
|
46
37
|
export function findOrphanedHarnessWorkers(psOutput, minCpuSeconds = DEFAULT_MIN_CPU_SECONDS) {
|
|
47
38
|
const workers = [];
|
|
@@ -57,7 +48,7 @@ export function findOrphanedHarnessWorkers(psOutput, minCpuSeconds = DEFAULT_MIN
|
|
|
57
48
|
continue;
|
|
58
49
|
if (!HARNESS_WORKER_COMMAND_PATTERN.test(command))
|
|
59
50
|
continue;
|
|
60
|
-
const cpuSeconds =
|
|
51
|
+
const cpuSeconds = parsePsDuration(cpuTime);
|
|
61
52
|
if (Number.isNaN(cpuSeconds) || cpuSeconds < minCpuSeconds)
|
|
62
53
|
continue;
|
|
63
54
|
workers.push({ pid, ppid, cpuTime, cpuSeconds, command });
|
|
@@ -68,7 +59,7 @@ export function findOrphanedHarnessWorkers(psOutput, minCpuSeconds = DEFAULT_MIN
|
|
|
68
59
|
async function listSystemProcesses() {
|
|
69
60
|
const result = await exec('ps', ['-axo', 'pid=,ppid=,time=,command='], { timeout: 10000 });
|
|
70
61
|
if (result.exitCode !== 0) {
|
|
71
|
-
throw new Error(`ps exited ${
|
|
62
|
+
throw new Error(`ps exited ${result.exitCode}`);
|
|
72
63
|
}
|
|
73
64
|
return result.stdout;
|
|
74
65
|
}
|
|
@@ -86,17 +77,17 @@ async function runOrphanedHarnessCheck() {
|
|
|
86
77
|
return ok(CHECK_NAME);
|
|
87
78
|
}
|
|
88
79
|
const rows = orphans
|
|
89
|
-
.map((w) => `PID ${
|
|
80
|
+
.map((w) => `PID ${w.pid} (CPU time ${w.cpuTime}): ${w.command.slice(0, 160)}`)
|
|
90
81
|
.join('; ');
|
|
91
82
|
const pids = orphans.map((w) => String(w.pid)).join(' ');
|
|
92
|
-
return warning(CHECK_NAME, `Found ${
|
|
83
|
+
return warning(CHECK_NAME, `Found ${orphans.length} orphaned Python multiprocessing worker(s) — PPID 1 with ` +
|
|
93
84
|
`high accumulated CPU time, the shape a test harness that died at startup leaves behind ` +
|
|
94
85
|
`(field incident: one such worker busy-spun for ~26 days). ${rows}`, `These look like workers orphaned by a crashed test harness. Verify each command line, ` +
|
|
95
86
|
`then terminate with: kill ${pids} (or kill -9 if a process survives). ` +
|
|
96
87
|
'FireForge never kills pre-existing processes automatically.');
|
|
97
88
|
}
|
|
98
89
|
/**
|
|
99
|
-
* Doctor check reporting orphaned harness workers. Windows has no `ps
|
|
90
|
+
* Doctor check reporting orphaned harness workers. Windows has no `ps`, so
|
|
100
91
|
* the check is skipped there (best-effort platform gap, matching the
|
|
101
92
|
* process-group reaper's POSIX-only sweep).
|
|
102
93
|
*/
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The patch-manifest consistency check and its two repair paths, split out of
|
|
3
3
|
* `doctor.ts` for the line budget. Exports a single `DoctorCheckDefinition`
|
|
4
|
-
* consumed by the doctor registry
|
|
4
|
+
* consumed by the doctor registry. No registrar is exported and none is
|
|
5
|
+
* wanted.
|
|
5
6
|
*/
|
|
6
7
|
import type { DoctorCheckDefinition } from './doctor-check-core.js';
|
|
7
8
|
/** Patch manifest consistency check, with its opt-in repair paths. */
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* The patch-manifest consistency check and its two repair paths, split out of
|
|
4
4
|
* `doctor.ts` for the line budget. Exports a single `DoctorCheckDefinition`
|
|
5
|
-
* consumed by the doctor registry
|
|
5
|
+
* consumed by the doctor registry. No registrar is exported and none is
|
|
6
|
+
* wanted.
|
|
6
7
|
*/
|
|
7
8
|
import { rebuildPatchesManifest, recommendManifestRepair, repairPatchesFilesAffected, validatePatchesManifestConsistency, } from '../core/patch-manifest.js';
|
|
8
9
|
import { FireForgeError } from '../errors/base.js';
|
|
@@ -65,8 +66,8 @@ function describeCount(count) {
|
|
|
65
66
|
async function runManifestRebuild(ctx) {
|
|
66
67
|
// Repair stamps sourceEsrVersion into every recovered entry. If the
|
|
67
68
|
// earlier "fireforge.json is valid" check failed, ctx.config is
|
|
68
|
-
// undefined and we must refuse rather than fabricate a fallback
|
|
69
|
-
//
|
|
69
|
+
// undefined and we must refuse rather than fabricate a fallback.
|
|
70
|
+
// Persisting 'unknown' into manifest metadata is hard to reverse
|
|
70
71
|
// and would mislead every later command that reads it.
|
|
71
72
|
if (!ctx.config) {
|
|
72
73
|
return failure(CHECK_NAME, 'Cannot repair patches.json: fireforge.json could not be loaded, so the Firefox version to stamp into recovered manifest entries is unknown.', 'Fix the fireforge.json errors reported above and re-run "fireforge doctor --repair-patches-manifest". ' +
|
|
@@ -84,7 +85,7 @@ async function runManifestRebuild(ctx) {
|
|
|
84
85
|
// trustworthy as an audit trail. The rebuilder returns the list of
|
|
85
86
|
// filenames whose metadata was entirely invented, named explicitly
|
|
86
87
|
// here so the operator knows which patches to review. Entries that
|
|
87
|
-
//
|
|
88
|
+
// were preserved (only `filesAffected` / ordering drifted) are not
|
|
88
89
|
// flagged.
|
|
89
90
|
for (const filename of repaired.recoveredFilenames) {
|
|
90
91
|
// Telling the operator to hand-edit patches.json contradicts the
|
|
@@ -101,8 +102,8 @@ async function runManifestRebuild(ctx) {
|
|
|
101
102
|
'Avoid hand-editing patches.json — FireForge owns that file and will regenerate it on the next manifest consistency pass.');
|
|
102
103
|
}
|
|
103
104
|
// A row whose patch file is gone is dropped by the rebuild. That is
|
|
104
|
-
// correct
|
|
105
|
-
// quietly loses rows is
|
|
105
|
+
// correct, since the patch file is the source of truth, but a manifest
|
|
106
|
+
// that quietly loses rows is what makes a repair hard to audit
|
|
106
107
|
// afterwards, so each one is named.
|
|
107
108
|
for (const filename of repaired.droppedFilenames) {
|
|
108
109
|
warn(`Dropped the manifest entry for ${filename}: no such patch file on disk. ` +
|
|
@@ -16,7 +16,7 @@ async function readEngineText(engineDir, relativePath) {
|
|
|
16
16
|
* Reports unreadable directories separately from "none found": the consumer
|
|
17
17
|
* turns an empty result into the issue "no browser.toml files found", which is
|
|
18
18
|
* the opposite diagnosis from "the tree could not be read". A swallowed
|
|
19
|
-
* mid-walk EACCES also silently
|
|
19
|
+
* mid-walk EACCES also silently shrank the result set, so one unreadable
|
|
20
20
|
* subdirectory produced a false clean for that subtree.
|
|
21
21
|
*/
|
|
22
22
|
async function collectBrowserTomlFiles(root) {
|
|
@@ -54,7 +54,7 @@ async function runPostRebaseAudit(ctx) {
|
|
|
54
54
|
// The four probes below are upstream-Firefox shape markers: each names a
|
|
55
55
|
// file and a token that a healthy post-rebase tree must still contain. A
|
|
56
56
|
// rebase that dropped a fork patch, or an upstream reorganisation, shows up
|
|
57
|
-
// as one of these going missing. The tokens are
|
|
57
|
+
// as one of these going missing. The tokens are coarse on purpose: this
|
|
58
58
|
// is a smoke check that runs warn-only behind an opt-in flag, not a
|
|
59
59
|
// structural validator.
|
|
60
60
|
const mozConfigure = await readEngineText(engineDir, 'browser/moz.configure');
|
|
@@ -88,7 +88,7 @@ async function runPostRebaseAudit(ctx) {
|
|
|
88
88
|
}
|
|
89
89
|
const browserTomls = await collectBrowserTomlFiles(engineDir);
|
|
90
90
|
if (browserTomls.unreadable.length > 0) {
|
|
91
|
-
issues.push(`could not read ${
|
|
91
|
+
issues.push(`could not read ${browserTomls.unreadable.length} ` +
|
|
92
92
|
`${browserTomls.unreadable.length === 1 ? 'directory' : 'directories'} under ` +
|
|
93
93
|
`browser/base/content/test: ${browserTomls.unreadable.join(', ')}`);
|
|
94
94
|
}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Doctor check comparing the
|
|
2
|
+
* Doctor check comparing the configured Firefox source pin against what the
|
|
3
3
|
* engine checkout actually is.
|
|
4
4
|
*
|
|
5
5
|
* `fireforge source set` lands `firefox.version` inside `fireforge.json`,
|
|
6
6
|
* beside hand-maintained policy sections. That is convenient and it is also
|
|
7
|
-
* the whole problem: a routine `git checkout -- fireforge.json`
|
|
8
|
-
* accidental reformat, say
|
|
7
|
+
* the whole problem: a routine `git checkout -- fireforge.json` (undoing an
|
|
8
|
+
* accidental reformat, say) silently reverts an uncommitted pin along with
|
|
9
9
|
* it, and nothing afterwards reports that the pin and the checkout have
|
|
10
|
-
* diverged.
|
|
11
|
-
* that should have made it green.
|
|
10
|
+
* diverged. In the field this showed up as a gate flipping green with no
|
|
11
|
+
* change that should have made it green.
|
|
12
12
|
*
|
|
13
|
-
* This is
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* This is not a lock and not a refusal: a tree may legitimately be
|
|
14
|
+
* mid-migration between two versions. It only makes a mismatched tree
|
|
15
|
+
* visible, which is all that was missing.
|
|
16
16
|
*
|
|
17
17
|
* Scope is limited by what is actually recorded. `firefox.product`,
|
|
18
|
-
* `firefox.sha256` and `firefox.candidate` have
|
|
19
|
-
* disk
|
|
20
|
-
* `baseCommit`
|
|
18
|
+
* `firefox.sha256` and `firefox.candidate` have no counterpart anywhere on
|
|
19
|
+
* disk (`.fireforge/state.json` records only `downloadedVersion` and
|
|
20
|
+
* `baseCommit`), so there is nothing to compare them against and the check
|
|
21
21
|
* says nothing about them rather than implying it verified them.
|
|
22
22
|
*/
|
|
23
23
|
import type { DoctorCheckDefinition } from './doctor-check-core.js';
|
|
24
24
|
/**
|
|
25
25
|
* Pin-vs-checkout reporting. Needs the loaded config, so it declares the
|
|
26
|
-
* dependency on the config check that populates `ctx.config
|
|
26
|
+
* dependency on the config check that populates `ctx.config`. It is skipped
|
|
27
27
|
* entirely without an engine, where there is nothing to compare.
|
|
28
28
|
*/
|
|
29
29
|
export declare const SOURCE_PIN_DOCTOR_CHECK: DoctorCheckDefinition;
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
/**
|
|
3
|
-
* Doctor check comparing the
|
|
3
|
+
* Doctor check comparing the configured Firefox source pin against what the
|
|
4
4
|
* engine checkout actually is.
|
|
5
5
|
*
|
|
6
6
|
* `fireforge source set` lands `firefox.version` inside `fireforge.json`,
|
|
7
7
|
* beside hand-maintained policy sections. That is convenient and it is also
|
|
8
|
-
* the whole problem: a routine `git checkout -- fireforge.json`
|
|
9
|
-
* accidental reformat, say
|
|
8
|
+
* the whole problem: a routine `git checkout -- fireforge.json` (undoing an
|
|
9
|
+
* accidental reformat, say) silently reverts an uncommitted pin along with
|
|
10
10
|
* it, and nothing afterwards reports that the pin and the checkout have
|
|
11
|
-
* diverged.
|
|
12
|
-
* that should have made it green.
|
|
11
|
+
* diverged. In the field this showed up as a gate flipping green with no
|
|
12
|
+
* change that should have made it green.
|
|
13
13
|
*
|
|
14
|
-
* This is
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* This is not a lock and not a refusal: a tree may legitimately be
|
|
15
|
+
* mid-migration between two versions. It only makes a mismatched tree
|
|
16
|
+
* visible, which is all that was missing.
|
|
17
17
|
*
|
|
18
18
|
* Scope is limited by what is actually recorded. `firefox.product`,
|
|
19
|
-
* `firefox.sha256` and `firefox.candidate` have
|
|
20
|
-
* disk
|
|
21
|
-
* `baseCommit`
|
|
19
|
+
* `firefox.sha256` and `firefox.candidate` have no counterpart anywhere on
|
|
20
|
+
* disk (`.fireforge/state.json` records only `downloadedVersion` and
|
|
21
|
+
* `baseCommit`), so there is nothing to compare them against and the check
|
|
22
22
|
* says nothing about them rather than implying it verified them.
|
|
23
23
|
*/
|
|
24
24
|
import { getFirefoxVersion } from '../core/firefox.js';
|
|
@@ -40,8 +40,8 @@ async function runSourcePinCheck(ctx) {
|
|
|
40
40
|
let actual;
|
|
41
41
|
try {
|
|
42
42
|
// A blank or whitespace-only version.txt (a truncated write, a partial
|
|
43
|
-
// extraction) carries no version to compare
|
|
44
|
-
// than reporting the engine as being at version "".
|
|
43
|
+
// extraction) carries no version to compare, so treat it as absent
|
|
44
|
+
// rather than reporting the engine as being at version "".
|
|
45
45
|
actual = (await getFirefoxVersion(ctx.paths.engine))?.trim() || undefined;
|
|
46
46
|
}
|
|
47
47
|
catch (error) {
|
|
@@ -70,7 +70,7 @@ async function runSourcePinCheck(ctx) {
|
|
|
70
70
|
}
|
|
71
71
|
/**
|
|
72
72
|
* Pin-vs-checkout reporting. Needs the loaded config, so it declares the
|
|
73
|
-
* dependency on the config check that populates `ctx.config
|
|
73
|
+
* dependency on the config check that populates `ctx.config`. It is skipped
|
|
74
74
|
* entirely without an engine, where there is nothing to compare.
|
|
75
75
|
*/
|
|
76
76
|
export const SOURCE_PIN_DOCTOR_CHECK = {
|
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Partitions engine-tree dirtiness into `branding`, `patch-backed`,
|
|
5
5
|
* `furnace`, `conflict`, and `unmanaged` buckets, and only warns on the
|
|
6
|
-
* last two
|
|
6
|
+
* last two. Everything else is tool-managed state that the operator
|
|
7
7
|
* did not author directly.
|
|
8
8
|
*
|
|
9
9
|
* Split out of `doctor.ts` so that file stays under the per-file LOC
|
|
10
|
-
* budget
|
|
10
|
+
* budget. See the call site in `runEngineGitChecks`.
|
|
11
11
|
*/
|
|
12
12
|
import type { DoctorCheck } from '../types/commands/index.js';
|
|
13
13
|
import type { DoctorCheckContext } from './doctor-check-core.js';
|
|
14
14
|
/**
|
|
15
15
|
* Inspects the engine working tree and returns a single `DoctorCheck`.
|
|
16
16
|
* Ownership-aware: patch-backed / branding / furnace rows are reported as OK
|
|
17
|
-
* with an ownership summary
|
|
17
|
+
* with an ownership summary. Unmanaged drift warns. Cross-patch conflicts
|
|
18
18
|
* warn loudly with a pointer at `fireforge status --ownership` +
|
|
19
19
|
* `fireforge verify`.
|
|
20
20
|
*
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Partitions engine-tree dirtiness into `branding`, `patch-backed`,
|
|
6
6
|
* `furnace`, `conflict`, and `unmanaged` buckets, and only warns on the
|
|
7
|
-
* last two
|
|
7
|
+
* last two. Everything else is tool-managed state that the operator
|
|
8
8
|
* did not author directly.
|
|
9
9
|
*
|
|
10
10
|
* Split out of `doctor.ts` so that file stays under the per-file LOC
|
|
11
|
-
* budget
|
|
11
|
+
* budget. See the call site in `runEngineGitChecks`.
|
|
12
12
|
*/
|
|
13
13
|
import { collectFurnaceManagedPrefixes } from '../core/furnace-config.js';
|
|
14
14
|
import { expandUntrackedDirectoryEntries, getWorkingTreeStatus } from '../core/git-status.js';
|
|
@@ -30,7 +30,7 @@ function formatManagedDetail(counts) {
|
|
|
30
30
|
/**
|
|
31
31
|
* Inspects the engine working tree and returns a single `DoctorCheck`.
|
|
32
32
|
* Ownership-aware: patch-backed / branding / furnace rows are reported as OK
|
|
33
|
-
* with an ownership summary
|
|
33
|
+
* with an ownership summary. Unmanaged drift warns. Cross-patch conflicts
|
|
34
34
|
* warn loudly with a pointer at `fireforge status --ownership` +
|
|
35
35
|
* `fireforge verify`.
|
|
36
36
|
*
|
|
@@ -10,7 +10,7 @@ import type { DoctorCheckDefinition } from './doctor-check-core.js';
|
|
|
10
10
|
* context-population bug at runtime.
|
|
11
11
|
*
|
|
12
12
|
* Exported so tests can exercise the forward-only invariant against
|
|
13
|
-
* fixtures
|
|
13
|
+
* fixtures. The real DOCTOR_CHECKS list is also validated at import
|
|
14
14
|
* time, but a targeted unit test makes the contract explicit and
|
|
15
15
|
* prevents regressions if the validator is ever relaxed.
|
|
16
16
|
*/
|
|
@@ -21,6 +21,8 @@ export declare function validateCheckDependencies(checks: readonly DoctorCheckDe
|
|
|
21
21
|
* context-population dependency chain (see {@link DOCTOR_CHECKS}) must
|
|
22
22
|
* also update this list, which gives us a single place to notice and
|
|
23
23
|
* think through the consequences.
|
|
24
|
+
*
|
|
25
|
+
* @internal Exported only so tests can reach it. Not part of the public surface.
|
|
24
26
|
*/
|
|
25
27
|
export declare const DOCTOR_CHECK_ORDER: readonly string[];
|
|
26
28
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
-
import { configExists, getProjectPaths, loadConfig, loadState
|
|
3
|
+
import { configExists, getProjectPaths, loadConfig, loadState } from '../core/config.js';
|
|
4
4
|
import { furnaceConfigExists as checkFurnaceConfigExists } from '../core/furnace-config.js';
|
|
5
5
|
import { getCurrentBranch, getHead, isGitRepository, isMissingHeadError } from '../core/git.js';
|
|
6
6
|
import { ensureGit } from '../core/git-base.js';
|
|
@@ -14,7 +14,7 @@ import { pathExists } from '../utils/fs.js';
|
|
|
14
14
|
import { error, info, intro, outro, success, warn } from '../utils/logger.js';
|
|
15
15
|
import { addWaitLockOption } from '../utils/options.js';
|
|
16
16
|
import { findExecutable } from '../utils/process.js';
|
|
17
|
-
import { failure, ok,
|
|
17
|
+
import { failure, ok, warning } from './doctor-check-core.js';
|
|
18
18
|
import { EXTERNAL_TOOLCHAIN_DOCTOR_CHECK } from './doctor-external-toolchains.js';
|
|
19
19
|
import { FURNACE_DOCTOR_CHECKS } from './doctor-furnace.js';
|
|
20
20
|
import { ORPHANED_HARNESS_DOCTOR_CHECK } from './doctor-orphaned-harness.js';
|
|
@@ -22,6 +22,7 @@ import { PATCH_MANIFEST_CONSISTENCY_CHECK } from './doctor-patch-manifest.js';
|
|
|
22
22
|
import { POST_REBASE_AUDIT_CHECK } from './doctor-post-rebase-audit.js';
|
|
23
23
|
import { SOURCE_PIN_DOCTOR_CHECK } from './doctor-source-pin.js';
|
|
24
24
|
import { inspectEngineWorkingTree } from './doctor-working-tree.js';
|
|
25
|
+
import { clearPendingResolution } from './pending-resolution.js';
|
|
25
26
|
import { collectPatchQueueHealth } from './verify.js';
|
|
26
27
|
/**
|
|
27
28
|
* Runs a single check definition, converting thrown errors into
|
|
@@ -89,8 +90,8 @@ async function runEngineGitChecks(ctx) {
|
|
|
89
90
|
branch === undefined &&
|
|
90
91
|
currentHead === undefined &&
|
|
91
92
|
!state.baseCommit) {
|
|
92
|
-
// Unborn repository with no recorded baseline
|
|
93
|
-
// explains recovery
|
|
93
|
+
// Unborn repository with no recorded baseline. The earlier failure row
|
|
94
|
+
// explains recovery. Avoid adding a second near-identical row.
|
|
94
95
|
}
|
|
95
96
|
else if (!canValidateBranch) {
|
|
96
97
|
rows.push(warning('Engine branch', 'Skipped branch validation because the baseline commit is missing.', 'Finish recreating the engine baseline with "fireforge download --force".'));
|
|
@@ -113,7 +114,7 @@ async function runEngineGitChecks(ctx) {
|
|
|
113
114
|
* context-population bug at runtime.
|
|
114
115
|
*
|
|
115
116
|
* Exported so tests can exercise the forward-only invariant against
|
|
116
|
-
* fixtures
|
|
117
|
+
* fixtures. The real DOCTOR_CHECKS list is also validated at import
|
|
117
118
|
* time, but a targeted unit test makes the contract explicit and
|
|
118
119
|
* prevents regressions if the validator is ever relaxed.
|
|
119
120
|
*/
|
|
@@ -135,7 +136,7 @@ export function validateCheckDependencies(checks) {
|
|
|
135
136
|
/**
|
|
136
137
|
* The declarative doctor check registry. The order of entries here is the
|
|
137
138
|
* order checks appear in the report. Adding a new check is a one-entry
|
|
138
|
-
* edit
|
|
139
|
+
* edit. Each check only contains its own inspection logic.
|
|
139
140
|
*
|
|
140
141
|
* ## Ordering dependency chain
|
|
141
142
|
*
|
|
@@ -202,11 +203,7 @@ const DOCTOR_CHECKS = [
|
|
|
202
203
|
if (health.errorCount > 0) {
|
|
203
204
|
return failure('Pending Resolution', `Refusing to clear pending resolution for ${patchFilename}: patch queue health check found ${health.errorCount} error(s).`, 'Run "fireforge verify" for details, fix the queue, then retry "fireforge doctor --clear-resolution".');
|
|
204
205
|
}
|
|
205
|
-
await
|
|
206
|
-
const next = { ...current };
|
|
207
|
-
delete next.pendingResolution;
|
|
208
|
-
return next;
|
|
209
|
-
});
|
|
206
|
+
await clearPendingResolution(ctx.projectRoot);
|
|
210
207
|
return ok('Pending Resolution');
|
|
211
208
|
}
|
|
212
209
|
return failure('Pending Resolution', `You are currently resolving a conflict for patch ${patchFilename}.`, 'Build and Export commands may behave unexpectedly until "fireforge resolve" is completed. If the queue now verifies cleanly, run "fireforge doctor --clear-resolution" to discard the stale marker.');
|
|
@@ -217,7 +214,7 @@ const DOCTOR_CHECKS = [
|
|
|
217
214
|
name: 'Engine is git repository',
|
|
218
215
|
skipIf: (ctx) => !ctx.engineExists,
|
|
219
216
|
// runEngineGitChecks consults ctx.config for ownership-aware
|
|
220
|
-
// working-tree classification
|
|
217
|
+
// working-tree classification. Declare the dependency so a future
|
|
221
218
|
// reorder doesn't silently regress the doctor back to the
|
|
222
219
|
// count-only fallback.
|
|
223
220
|
dependsOn: ['fireforge.json is valid'],
|
|
@@ -251,7 +248,7 @@ const DOCTOR_CHECKS = [
|
|
|
251
248
|
// Resolve the absolute path so the OK row names what doctor actually
|
|
252
249
|
// found. A PATH-export discrepancy between the operator's interactive
|
|
253
250
|
// shell and the spawned subprocess otherwise reads as doctor printing
|
|
254
|
-
// "OK" for a binary `which watchman` cannot find
|
|
251
|
+
// "OK" for a binary `which watchman` cannot find. Surfacing the
|
|
255
252
|
// resolved path makes the discrepancy visible without a verbose flag.
|
|
256
253
|
const path = await findExecutable('watchman');
|
|
257
254
|
if (path) {
|
|
@@ -298,7 +295,7 @@ const DOCTOR_CHECKS = [
|
|
|
298
295
|
POST_REBASE_AUDIT_CHECK,
|
|
299
296
|
// Furnace checks live in a sibling module so this file stays under the
|
|
300
297
|
// max-lines threshold. Splicing them in as an array preserves the
|
|
301
|
-
// declarative registry contract
|
|
298
|
+
// declarative registry contract: each entry remains a single
|
|
302
299
|
// `DoctorCheckDefinition` with its own skipIf/run/fix, and the order
|
|
303
300
|
// here is the order they appear in the report.
|
|
304
301
|
...FURNACE_DOCTOR_CHECKS,
|
|
@@ -322,6 +319,8 @@ validateCheckDependencies(DOCTOR_CHECKS);
|
|
|
322
319
|
* context-population dependency chain (see {@link DOCTOR_CHECKS}) must
|
|
323
320
|
* also update this list, which gives us a single place to notice and
|
|
324
321
|
* think through the consequences.
|
|
322
|
+
*
|
|
323
|
+
* @internal Exported only so tests can reach it. Not part of the public surface.
|
|
325
324
|
*/
|
|
326
325
|
export const DOCTOR_CHECK_ORDER = DOCTOR_CHECKS.map((check) => check.name);
|
|
327
326
|
/**
|
|
@@ -336,7 +335,7 @@ export function reportDoctorResults(checks, mutations = []) {
|
|
|
336
335
|
let warningCount = 0;
|
|
337
336
|
let failedCount = 0;
|
|
338
337
|
for (const check of checks) {
|
|
339
|
-
const severity =
|
|
338
|
+
const severity = check.severity;
|
|
340
339
|
if (severity === 'warning') {
|
|
341
340
|
warn(`! ${check.name}: ${check.message}`);
|
|
342
341
|
if (check.fix) {
|
|
@@ -383,7 +382,7 @@ export function reportDoctorResults(checks, mutations = []) {
|
|
|
383
382
|
* Rejects repair-flag combinations that cannot mean what they say.
|
|
384
383
|
*
|
|
385
384
|
* The two manifest repairs are different operations on the same file, and
|
|
386
|
-
* `--dry-run` with nothing to project is a flag that silently does nothing
|
|
385
|
+
* `--dry-run` with nothing to project is a flag that silently does nothing,
|
|
387
386
|
* the shape most likely to be mistaken for a preview that reported "no
|
|
388
387
|
* changes".
|
|
389
388
|
*/
|
|
@@ -78,7 +78,7 @@ async function cleanPatchTouchedFiles(engineDir, patchesDir, preExistingDirty) {
|
|
|
78
78
|
* Prints a one-line nudge pointing at `fireforge import` when the project
|
|
79
79
|
* carries a non-empty patch queue but the just-downloaded engine has not yet
|
|
80
80
|
* had any patches applied. The post-download spinner closes with
|
|
81
|
-
* "Patch-touched files already match baseline" because a fresh tree
|
|
81
|
+
* "Patch-touched files already match baseline" because a fresh tree is at
|
|
82
82
|
* baseline, which reads as "patches are restored" and invites skipping the
|
|
83
83
|
* import step. Suppressed when patches/ is missing or the manifest is empty
|
|
84
84
|
* so unconfigured projects stay quiet.
|
|
@@ -94,10 +94,11 @@ async function noteUnappliedPatches(patchesDir) {
|
|
|
94
94
|
}
|
|
95
95
|
/**
|
|
96
96
|
* Stops `restoreSpinner` with a message that reflects what actually
|
|
97
|
-
* happened. Three branches
|
|
98
|
-
* nothing dirty
|
|
99
|
-
* "Patch-touched files restored" success line.
|
|
100
|
-
* claims restore work that did not happen on a
|
|
97
|
+
* happened. Three branches. An empty queue gives an explicit no-op. A queue
|
|
98
|
+
* that is present but has nothing dirty gives "already clean". A queue with
|
|
99
|
+
* dirty files gives the usual "Patch-touched files restored" success line.
|
|
100
|
+
* Always closing with the third claims restore work that did not happen on a
|
|
101
|
+
* project with zero patches.
|
|
101
102
|
*/
|
|
102
103
|
function closeRestoreSpinner(restoreSpinner, result) {
|
|
103
104
|
if (!result.hadQueue) {
|
|
@@ -110,11 +111,6 @@ function closeRestoreSpinner(restoreSpinner, result) {
|
|
|
110
111
|
}
|
|
111
112
|
restoreSpinner.stop('Patch-touched files restored');
|
|
112
113
|
}
|
|
113
|
-
async function clearStaleFurnaceApplyState(projectRoot) {
|
|
114
|
-
// --force installs a new baseCommit, which invalidates every applied
|
|
115
|
-
// checksum in furnace-state.json.
|
|
116
|
-
await clearAppliedFurnaceState(projectRoot);
|
|
117
|
-
}
|
|
118
114
|
async function activateReplacementEngine(args) {
|
|
119
115
|
const { engineDir, replacementDir, backupDir } = args;
|
|
120
116
|
await rename(engineDir, backupDir);
|
|
@@ -155,28 +151,39 @@ async function restorePreviousEngine(args) {
|
|
|
155
151
|
}
|
|
156
152
|
}
|
|
157
153
|
async function downloadAndExtractFirefox(args) {
|
|
158
|
-
const { version, product, engineDir, cacheDir, sha256, candidate } = args;
|
|
154
|
+
const { version, product, engineDir, cacheDir, sha256, candidate, allowUnverifiedDownload } = args;
|
|
159
155
|
let s = spinner(`Downloading Firefox ${version}...`);
|
|
160
156
|
let lastPercent = 0;
|
|
161
157
|
const phaseState = { value: 'download' };
|
|
162
158
|
try {
|
|
163
|
-
await downloadFirefoxSource(
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
159
|
+
await downloadFirefoxSource({
|
|
160
|
+
version: version,
|
|
161
|
+
product: product,
|
|
162
|
+
destDir: engineDir,
|
|
163
|
+
cacheDir: cacheDir,
|
|
164
|
+
onProgress: (downloaded, total) => {
|
|
165
|
+
if (total <= 0)
|
|
166
|
+
return;
|
|
167
|
+
const percent = Math.floor((downloaded / total) * 100);
|
|
168
|
+
if (percent !== lastPercent && percent % 5 === 0) {
|
|
169
|
+
s.message(`Downloading Firefox ${version}... ${percent}% (${formatBytes(downloaded)} / ${formatBytes(total)})`);
|
|
170
|
+
lastPercent = percent;
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
onPhase: (phase) => {
|
|
174
|
+
if (phase === 'extract' && phaseState.value === 'download') {
|
|
175
|
+
s.stop(`Firefox ${version} downloaded`);
|
|
176
|
+
phaseState.value = 'extract';
|
|
177
|
+
s = spinner(`Extracting Firefox ${version}... (decompressing ~600 MB of source; typically 30–90s)`);
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
expectedSha256: sha256,
|
|
181
|
+
onPhaseProgress: (message) => {
|
|
182
|
+
s.message(message);
|
|
183
|
+
},
|
|
184
|
+
candidate: candidate,
|
|
185
|
+
integrity: allowUnverifiedDownload === undefined ? undefined : { allowUnverifiedDownload },
|
|
186
|
+
});
|
|
180
187
|
s.stop(phaseState.value === 'extract'
|
|
181
188
|
? `Firefox ${version} extracted`
|
|
182
189
|
: `Firefox ${version} downloaded`);
|
|
@@ -188,7 +195,7 @@ async function downloadAndExtractFirefox(args) {
|
|
|
188
195
|
}
|
|
189
196
|
/**
|
|
190
197
|
* Prints the major-version-hop toolchain nudge when this download moved the
|
|
191
|
-
* engine across a Firefox
|
|
198
|
+
* engine across a Firefox major version. The first post-hop build otherwise
|
|
192
199
|
* dies in `mach configure` on a moved cbindgen minimum with nothing in the
|
|
193
200
|
* download output suggesting `fireforge bootstrap`. Quiet on first downloads
|
|
194
201
|
* and same-major re-downloads.
|
|
@@ -235,7 +242,9 @@ async function initializeDownloadedEngine(args) {
|
|
|
235
242
|
throw error;
|
|
236
243
|
}
|
|
237
244
|
if (replacementActivated) {
|
|
238
|
-
|
|
245
|
+
// --force installs a new baseCommit, which invalidates every applied
|
|
246
|
+
// checksum in furnace-state.json.
|
|
247
|
+
await clearAppliedFurnaceState(projectRoot);
|
|
239
248
|
}
|
|
240
249
|
await updateState(projectRoot, {
|
|
241
250
|
downloadedVersion: version,
|
|
@@ -268,7 +277,7 @@ export async function downloadCommand(projectRoot, options) {
|
|
|
268
277
|
intro('FireForge Download');
|
|
269
278
|
const config = await loadConfig(projectRoot), version = config.firefox.version;
|
|
270
279
|
const paths = getProjectPaths(projectRoot);
|
|
271
|
-
// Captured
|
|
280
|
+
// Captured before any state update so the post-download major-hop
|
|
272
281
|
// notice compares against what was actually on disk until now.
|
|
273
282
|
const previousVersion = (await loadState(projectRoot)).downloadedVersion;
|
|
274
283
|
info(`Firefox version: ${version}`);
|
|
@@ -276,7 +285,7 @@ export async function downloadCommand(projectRoot, options) {
|
|
|
276
285
|
// A legitimate holder of this lock runs for 10+ minutes (download +
|
|
277
286
|
// extract + git indexing). A 30 s timeout fails the second invocation with
|
|
278
287
|
// "remove the lock directory if it is stale" advice while the lock is
|
|
279
|
-
// actively held
|
|
288
|
+
// actively held, which is dangerous guidance mid-extraction. Wait generously
|
|
280
289
|
// instead: a dead holder is reaped within seconds by the PID-based stale
|
|
281
290
|
// probe, so a long timeout only ever waits on real work.
|
|
282
291
|
const downloadLockOptions = {
|
|
@@ -289,7 +298,7 @@ export async function downloadCommand(projectRoot, options) {
|
|
|
289
298
|
// Reclaim multi-GB partial trees left behind by interrupted runs.
|
|
290
299
|
// Safe under the download lock: any `.tmp-*`/`.replacement-*` dir
|
|
291
300
|
// present now is orphaned, since live ones only exist while a
|
|
292
|
-
// download holds this lock. `.backup-*` dirs are
|
|
301
|
+
// download holds this lock. `.backup-*` dirs are not swept: a
|
|
293
302
|
// backup can hold the previous engine after a failed forced
|
|
294
303
|
// replacement and is the operator's recovery copy.
|
|
295
304
|
const sweptDirs = await sweepOrphanedEngineWorkDirs(paths.engine);
|
|
@@ -309,7 +318,8 @@ export async function downloadCommand(projectRoot, options) {
|
|
|
309
318
|
}
|
|
310
319
|
catch (error) {
|
|
311
320
|
if (isMissingHeadError(error)) {
|
|
312
|
-
// Partial init detected
|
|
321
|
+
// Partial init detected. Attempt to resume instead of
|
|
322
|
+
// requiring --force.
|
|
313
323
|
info('Detected partially initialized engine. Attempting to resume...');
|
|
314
324
|
// Snapshot patch-touched files that are already dirty so we
|
|
315
325
|
// can preserve them after the resume commit.
|
|
@@ -332,7 +342,7 @@ export async function downloadCommand(projectRoot, options) {
|
|
|
332
342
|
});
|
|
333
343
|
const baseCommit = await getHead(paths.engine);
|
|
334
344
|
resumeSpinner.stop('Git repository resumed successfully');
|
|
335
|
-
// Restore patch-touched files
|
|
345
|
+
// Restore patch-touched files before stamping state. If this
|
|
336
346
|
// step fails (disk full, permission denied, git object issue),
|
|
337
347
|
// state.json keeps the previous downloadedVersion so the
|
|
338
348
|
// invariant "state.downloadedVersion matches a clean engine"
|
|
@@ -351,7 +361,7 @@ export async function downloadCommand(projectRoot, options) {
|
|
|
351
361
|
}
|
|
352
362
|
catch (error) {
|
|
353
363
|
resumeSpinner.error('Resume failed');
|
|
354
|
-
// Preserve the underlying cause so the operator sees
|
|
364
|
+
// Preserve the underlying cause so the operator sees why
|
|
355
365
|
// the resume failed (timeout, permission denied, corrupted
|
|
356
366
|
// object, disk full) instead of only the generic "partial
|
|
357
367
|
// engine exists" story. The cause reaches them through the
|
|
@@ -364,7 +374,7 @@ export async function downloadCommand(projectRoot, options) {
|
|
|
364
374
|
// Re-throw unexpected git errors (corrupted objects, permission
|
|
365
375
|
// denied, …) wrapped in PartialEngineExistsError so the user sees
|
|
366
376
|
// both narratives: "we detected a partial engine and attempted
|
|
367
|
-
// resume"
|
|
377
|
+
// resume" and the underlying git failure. Without the wrap the
|
|
368
378
|
// raw git error loses the context that resume was in flight.
|
|
369
379
|
throw new PartialEngineExistsError(paths.engine, toError(error));
|
|
370
380
|
}
|
|
@@ -389,6 +399,9 @@ export async function downloadCommand(projectRoot, options) {
|
|
|
389
399
|
...(config.firefox.candidate !== undefined
|
|
390
400
|
? { candidate: config.firefox.candidate }
|
|
391
401
|
: {}),
|
|
402
|
+
...(config.firefox.allowUnverifiedDownload !== undefined
|
|
403
|
+
? { allowUnverifiedDownload: config.firefox.allowUnverifiedDownload }
|
|
404
|
+
: {}),
|
|
392
405
|
});
|
|
393
406
|
if (replacementEngineDir && backupEngineDir) {
|
|
394
407
|
warn('Activating replacement engine directory...');
|