@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
package/dist/bin/fireforge.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* FireForge CLI entry point, and the only file that may call process.exit().
|
|
4
4
|
* Library code propagates errors via CommandError or FireForgeError instead.
|
|
5
5
|
*
|
|
6
|
-
* The signal pipeline below composes several lifecycle modules
|
|
6
|
+
* The signal pipeline below composes several lifecycle modules. See
|
|
7
7
|
* docs/lifecycle-invariants.md for who owns what.
|
|
8
8
|
*/
|
|
9
9
|
export {};
|
package/dist/bin/fireforge.js
CHANGED
|
@@ -4,13 +4,14 @@
|
|
|
4
4
|
* FireForge CLI entry point, and the only file that may call process.exit().
|
|
5
5
|
* Library code propagates errors via CommandError or FireForgeError instead.
|
|
6
6
|
*
|
|
7
|
-
* The signal pipeline below composes several lifecycle modules
|
|
7
|
+
* The signal pipeline below composes several lifecycle modules. See
|
|
8
8
|
* docs/lifecycle-invariants.md for who owns what.
|
|
9
9
|
*/
|
|
10
10
|
import { installBrokenPipeHandler, main } from '../src/cli.js';
|
|
11
11
|
import { emitKilledVerdict } from '../src/commands/test-verdict.js';
|
|
12
12
|
import { forceReleaseHeldLocksForSignal } from '../src/core/file-lock.js';
|
|
13
13
|
import { forceReleaseFurnaceLocksForActiveOperations, isSignalRollbackInFlight, rollbackActiveOperationsForSignal, } from '../src/core/furnace-operation.js';
|
|
14
|
+
import { closeActiveRunLog } from '../src/core/run-log.js';
|
|
14
15
|
import { waitForActiveCriticalSections } from '../src/core/signal-critical.js';
|
|
15
16
|
import { CommandError } from '../src/errors/base.js';
|
|
16
17
|
import { waitForActiveChildShutdown } from '../src/utils/process.js';
|
|
@@ -27,22 +28,22 @@ const SIGNAL_CRITICAL_SECTION_TIMEOUT_MS = 5_000;
|
|
|
27
28
|
* under `run`/`test`, mach under `build`) to shut down after the signal was
|
|
28
29
|
* forwarded to them. Must exceed the largest child grace window
|
|
29
30
|
* (execSmokeRun's killGraceMs default of 10 s) so the SIGTERM → grace →
|
|
30
|
-
* SIGKILL escalation can complete
|
|
31
|
+
* SIGKILL escalation can complete. Exiting earlier orphans hung Firefox
|
|
31
32
|
* trees. A second Ctrl+C escalates to SIGKILL immediately.
|
|
32
33
|
*/
|
|
33
34
|
const CHILD_SHUTDOWN_TIMEOUT_MS = 12_000;
|
|
34
35
|
/**
|
|
35
36
|
* Upper bound (ms) a delayed exit waits for stdout/stderr to drain. A pipe
|
|
36
|
-
* is
|
|
37
|
-
* kernel buffer
|
|
38
|
-
* a stalled reader cannot wedge a failing process
|
|
39
|
-
* releases the wait immediately.
|
|
37
|
+
* is async, so `process.exit()` discards anything queued past the 64 KiB
|
|
38
|
+
* kernel buffer, which is enough to truncate a JSON payload mid-object.
|
|
39
|
+
* Bounded so a stalled reader cannot wedge a failing process. An
|
|
40
|
+
* EPIPE'd/closed pipe releases the wait immediately.
|
|
40
41
|
*/
|
|
41
42
|
const STDIO_FLUSH_TIMEOUT_MS = 5_000;
|
|
42
43
|
/**
|
|
43
|
-
* Drains stdio, then exits. Every delayed exit routes through here
|
|
44
|
-
* the second-Ctrl+C force-exit (an explicit
|
|
45
|
-
* own call terminate directly.
|
|
44
|
+
* Drains stdio, then exits. Every delayed exit routes through here. Only
|
|
45
|
+
* the second-Ctrl+C force-exit (an explicit request to quit at once) and
|
|
46
|
+
* this helper's own call terminate directly.
|
|
46
47
|
*/
|
|
47
48
|
function exitAfterStdioFlush(code) {
|
|
48
49
|
void waitForStdioDrain(STDIO_FLUSH_TIMEOUT_MS).finally(() => {
|
|
@@ -75,9 +76,9 @@ function installFurnaceSignalHandler(signal, exitCode) {
|
|
|
75
76
|
// A diagnostic must never keep the process from exiting.
|
|
76
77
|
}
|
|
77
78
|
if (isSignalRollbackInFlight()) {
|
|
78
|
-
// A second Ctrl+C while we're already rolling back
|
|
79
|
-
// out now
|
|
80
|
-
//
|
|
79
|
+
// A second Ctrl+C while we're already rolling back means the user
|
|
80
|
+
// wants out now, so let it terminate the process forcefully rather
|
|
81
|
+
// than queueing another rollback that will race the first.
|
|
81
82
|
process.exit(exitCode);
|
|
82
83
|
}
|
|
83
84
|
// Rollback, critical-section drain, and child shutdown run in parallel.
|
|
@@ -86,7 +87,7 @@ function installFurnaceSignalHandler(signal, exitCode) {
|
|
|
86
87
|
// applied to the engine but a stale session file that mis-tracks progress
|
|
87
88
|
// on `--continue`. Waiting on child shutdown keeps the parent alive through
|
|
88
89
|
// the SIGTERM → grace → SIGKILL escalation execInherit/execSmokeRun forward
|
|
89
|
-
// to Firefox/mach
|
|
90
|
+
// to Firefox/mach. Exiting first orphans those trees.
|
|
90
91
|
void Promise.allSettled([
|
|
91
92
|
rollbackActiveOperationsForSignal(signal).catch((error) => {
|
|
92
93
|
console.error(`Furnace rollback after ${signal} failed:`, error instanceof Error ? error.message : error);
|
|
@@ -97,11 +98,16 @@ function installFurnaceSignalHandler(signal, exitCode) {
|
|
|
97
98
|
// `withFileLock`'s `finally { rm }` never runs across `process.exit`,
|
|
98
99
|
// so both sweeps exist for the same reason. The generic one covers
|
|
99
100
|
// every lock this process holds (engine session, patch directory,
|
|
100
|
-
// build)
|
|
101
|
+
// build). The furnace one stays because it carries rollback
|
|
101
102
|
// bookkeeping the generic sweep does not, and runs after it so the
|
|
102
103
|
// ownership checks see a settled tree.
|
|
103
104
|
.then(() => forceReleaseHeldLocksForSignal())
|
|
104
105
|
.then(() => forceReleaseFurnaceLocksForActiveOperations())
|
|
106
|
+
// The run log's held partial line and queued writes do not survive
|
|
107
|
+
// `process.exit`. The command's own `finally` that would close it is
|
|
108
|
+
// racing this handler and usually loses. Best-effort like the log
|
|
109
|
+
// itself: a diagnostic must never keep the process from exiting.
|
|
110
|
+
.then(() => closeActiveRunLog().catch(() => undefined))
|
|
105
111
|
.finally(() => {
|
|
106
112
|
exitAfterStdioFlush(exitCode);
|
|
107
113
|
});
|
|
@@ -114,7 +120,7 @@ main().catch((error) => {
|
|
|
114
120
|
exitAfterStdioFlush(error.exitCode);
|
|
115
121
|
return;
|
|
116
122
|
}
|
|
117
|
-
//
|
|
123
|
+
// Unexpected: withErrorHandling should have thrown a CommandError.
|
|
118
124
|
console.error('Fatal error:', error);
|
|
119
125
|
exitAfterStdioFlush(1);
|
|
120
126
|
});
|
package/dist/build-info.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.
|
|
4
|
-
"commit": "
|
|
5
|
-
"shortCommit": "
|
|
3
|
+
"version": "0.46.1",
|
|
4
|
+
"commit": "821990fd7d076a205f37618055c0a01a95180aed",
|
|
5
|
+
"shortCommit": "821990fd7d07",
|
|
6
6
|
"dirty": false,
|
|
7
7
|
"dirtyHash": null,
|
|
8
|
-
"buildTime": "2026-09-
|
|
8
|
+
"buildTime": "2026-09-05T22:29:34.415Z"
|
|
9
9
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { FireForgeError } from './errors/base.js';
|
|
2
|
+
/**
|
|
3
|
+
* Stable machine-readable tag for an error class, for the `--json` envelope.
|
|
4
|
+
*
|
|
5
|
+
* Derived from the class name rather than hand-mapped: a new error class gets
|
|
6
|
+
* a sensible tag automatically, and the mapping cannot drift out of sync with
|
|
7
|
+
* the taxonomy. `ConfigNotFoundError` becomes `config-not-found`.
|
|
8
|
+
*
|
|
9
|
+
* @param error - The error being rendered
|
|
10
|
+
* @returns A kebab-case tag with the `Error` suffix stripped
|
|
11
|
+
*/
|
|
12
|
+
export declare function machineErrorCode(error: FireForgeError): string;
|
|
13
|
+
/**
|
|
14
|
+
* Whether the invocation asked for machine-readable output.
|
|
15
|
+
*
|
|
16
|
+
* Reading the flag from argv is blunt but exact: if the invocation asked for
|
|
17
|
+
* machine output, stdout belongs to the payload from the first byte, before
|
|
18
|
+
* commander has parsed anything.
|
|
19
|
+
*
|
|
20
|
+
* @param argv - Process argv (defaults to `process.argv`)
|
|
21
|
+
* @returns True when `--json` or `--raw` is present
|
|
22
|
+
*/
|
|
23
|
+
export declare function wantsMachineOutput(argv?: readonly string[]): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Converts a `CommanderError` thrown out of `parseAsync` into the exit
|
|
26
|
+
* contract, and rethrows anything else untouched.
|
|
27
|
+
*
|
|
28
|
+
* `--help` and `--version` also travel through `exitOverride()` (codes
|
|
29
|
+
* `commander.helpDisplayed` / `commander.version`, exit 0): commander has
|
|
30
|
+
* already written their output, so those simply return. So does
|
|
31
|
+
* `commander.help`: a command group invoked with no subcommand (`fireforge`,
|
|
32
|
+
* `fireforge tree`), for which commander prints the group's help and would
|
|
33
|
+
* exit 1. That is an informational invocation rather than a wrong flag.
|
|
34
|
+
* `patch`, `token` and `furnace` already answer it with help and exit 0
|
|
35
|
+
* through an explicit action, and the groups without one must not exit 8 (or
|
|
36
|
+
* leak commander's `(outputHelp)` placeholder into a `--json` envelope)
|
|
37
|
+
* merely for lacking it. A genuine usage error has already had its message
|
|
38
|
+
* written to stderr by commander. It becomes exit 8, and under `--json` it
|
|
39
|
+
* also gets the standard refusal envelope on stdout so a scripted consumer
|
|
40
|
+
* sees a parseable failure.
|
|
41
|
+
*
|
|
42
|
+
* @param error - Whatever `parseAsync` rejected with
|
|
43
|
+
* @param machineOutput - Whether the invocation asked for `--json`/`--raw`
|
|
44
|
+
* @throws CommandError carrying `INVALID_ARGUMENT` for a usage error
|
|
45
|
+
*/
|
|
46
|
+
export declare function handleParseError(error: unknown, machineOutput: boolean): void;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* Maps commander's own parse failures onto the FireForge exit-code contract.
|
|
4
|
+
*
|
|
5
|
+
* Commander terminates the process itself on a usage error (unknown option,
|
|
6
|
+
* missing argument, unknown command) with exit 1, which contradicts the
|
|
7
|
+
* documented `INVALID_ARGUMENT` (8) in `docs/exit-codes.md` and bypasses the
|
|
8
|
+
* `--json` refusal envelope because no action (and therefore no
|
|
9
|
+
* `withErrorHandling` wrapper) ever runs. `createProgram` installs
|
|
10
|
+
* `exitOverride()` so those failures surface as a thrown `CommanderError`,
|
|
11
|
+
* and `main` routes them through here.
|
|
12
|
+
*/
|
|
13
|
+
import { CommanderError } from 'commander';
|
|
14
|
+
import { CommandError, FireForgeError, InvalidArgumentError } from './errors/base.js';
|
|
15
|
+
import { emitMachineError } from './utils/machine-output.js';
|
|
16
|
+
/**
|
|
17
|
+
* Stable machine-readable tag for an error class, for the `--json` envelope.
|
|
18
|
+
*
|
|
19
|
+
* Derived from the class name rather than hand-mapped: a new error class gets
|
|
20
|
+
* a sensible tag automatically, and the mapping cannot drift out of sync with
|
|
21
|
+
* the taxonomy. `ConfigNotFoundError` becomes `config-not-found`.
|
|
22
|
+
*
|
|
23
|
+
* @param error - The error being rendered
|
|
24
|
+
* @returns A kebab-case tag with the `Error` suffix stripped
|
|
25
|
+
*/
|
|
26
|
+
export function machineErrorCode(error) {
|
|
27
|
+
return error.name
|
|
28
|
+
.replace(/Error$/, '')
|
|
29
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
30
|
+
.toLowerCase();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Whether the invocation asked for machine-readable output.
|
|
34
|
+
*
|
|
35
|
+
* Reading the flag from argv is blunt but exact: if the invocation asked for
|
|
36
|
+
* machine output, stdout belongs to the payload from the first byte, before
|
|
37
|
+
* commander has parsed anything.
|
|
38
|
+
*
|
|
39
|
+
* @param argv - Process argv (defaults to `process.argv`)
|
|
40
|
+
* @returns True when `--json` or `--raw` is present
|
|
41
|
+
*/
|
|
42
|
+
export function wantsMachineOutput(argv = process.argv) {
|
|
43
|
+
return argv.includes('--json') || argv.includes('--raw');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Converts a `CommanderError` thrown out of `parseAsync` into the exit
|
|
47
|
+
* contract, and rethrows anything else untouched.
|
|
48
|
+
*
|
|
49
|
+
* `--help` and `--version` also travel through `exitOverride()` (codes
|
|
50
|
+
* `commander.helpDisplayed` / `commander.version`, exit 0): commander has
|
|
51
|
+
* already written their output, so those simply return. So does
|
|
52
|
+
* `commander.help`: a command group invoked with no subcommand (`fireforge`,
|
|
53
|
+
* `fireforge tree`), for which commander prints the group's help and would
|
|
54
|
+
* exit 1. That is an informational invocation rather than a wrong flag.
|
|
55
|
+
* `patch`, `token` and `furnace` already answer it with help and exit 0
|
|
56
|
+
* through an explicit action, and the groups without one must not exit 8 (or
|
|
57
|
+
* leak commander's `(outputHelp)` placeholder into a `--json` envelope)
|
|
58
|
+
* merely for lacking it. A genuine usage error has already had its message
|
|
59
|
+
* written to stderr by commander. It becomes exit 8, and under `--json` it
|
|
60
|
+
* also gets the standard refusal envelope on stdout so a scripted consumer
|
|
61
|
+
* sees a parseable failure.
|
|
62
|
+
*
|
|
63
|
+
* @param error - Whatever `parseAsync` rejected with
|
|
64
|
+
* @param machineOutput - Whether the invocation asked for `--json`/`--raw`
|
|
65
|
+
* @throws CommandError carrying `INVALID_ARGUMENT` for a usage error
|
|
66
|
+
*/
|
|
67
|
+
export function handleParseError(error, machineOutput) {
|
|
68
|
+
if (!(error instanceof CommanderError)) {
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
if (error.exitCode === 0 || error.code === 'commander.help') {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// Commander's message carries its own `error: ` prefix. Strip it so the
|
|
75
|
+
// envelope text matches how every other refusal reads.
|
|
76
|
+
const usage = new InvalidArgumentError(error.message.replace(/^error:\s*/, ''));
|
|
77
|
+
if (machineOutput) {
|
|
78
|
+
emitMachineError(machineErrorCode(usage), usage.message, usage.code);
|
|
79
|
+
}
|
|
80
|
+
throw new CommandError(usage.code);
|
|
81
|
+
}
|
package/dist/src/cli.d.ts
CHANGED
|
@@ -6,13 +6,18 @@ import { Command } from 'commander';
|
|
|
6
6
|
* We treat this as a clean exit.
|
|
7
7
|
*/
|
|
8
8
|
export declare function installBrokenPipeHandler(): void;
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* Removes the broken-pipe handler installed for CLI tests.
|
|
11
|
+
*
|
|
12
|
+
* @internal Exported only so tests can reach it. It is not part of the
|
|
13
|
+
* public surface.
|
|
14
|
+
*/
|
|
10
15
|
export declare function resetBrokenPipeHandlerForTests(): void;
|
|
11
16
|
/**
|
|
12
17
|
* Gets the project root directory.
|
|
13
18
|
* Walks up from the current working directory until a fireforge.json is found.
|
|
14
19
|
* Throws a {@link ConfigNotFoundError} (code: CONFIG_ERROR) when no
|
|
15
|
-
* fireforge.json is found within the walk depth limit
|
|
20
|
+
* fireforge.json is found within the walk depth limit. The error is
|
|
16
21
|
* user-facing so `withErrorHandling` can print the guidance without
|
|
17
22
|
* the stack dump that a plain `Error` would trigger.
|
|
18
23
|
*/
|
package/dist/src/cli.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
3
|
import { dirname, join, resolve } from 'node:path';
|
|
4
4
|
import { Command, Help } from 'commander';
|
|
5
|
+
import { handleParseError, machineErrorCode, wantsMachineOutput } from './cli-usage-error.js';
|
|
5
6
|
import { COMMAND_MANIFEST } from './commands/manifest.js';
|
|
6
7
|
import { runTreeGuardHook } from './core/tree-guard.js';
|
|
7
8
|
import { CancellationError, CommandError, FireForgeError, InternalInvariantError, } from './errors/base.js';
|
|
@@ -32,27 +33,11 @@ function getBrokenPipeHandler(state) {
|
|
|
32
33
|
state[brokenPipeListenerKey] = handler;
|
|
33
34
|
return handler;
|
|
34
35
|
}
|
|
35
|
-
/**
|
|
36
|
-
* Stable machine-readable tag for an error class, for the `--json` envelope.
|
|
37
|
-
*
|
|
38
|
-
* Derived from the class name rather than hand-mapped: a new error class gets
|
|
39
|
-
* a sensible tag automatically, and the mapping cannot drift out of sync with
|
|
40
|
-
* the taxonomy. `ConfigNotFoundError` becomes `config-not-found`.
|
|
41
|
-
*
|
|
42
|
-
* @param error - The error being rendered
|
|
43
|
-
* @returns A kebab-case tag with the `Error` suffix stripped
|
|
44
|
-
*/
|
|
45
|
-
function machineErrorCode(error) {
|
|
46
|
-
return error.name
|
|
47
|
-
.replace(/Error$/, '')
|
|
48
|
-
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
49
|
-
.toLowerCase();
|
|
50
|
-
}
|
|
51
36
|
/**
|
|
52
37
|
* Prints an error's `cause` chain under `--verbose`.
|
|
53
38
|
*
|
|
54
|
-
* Nine error classes declare a `cause` and twenty-two throw sites pass one
|
|
55
|
-
*
|
|
39
|
+
* Nine error classes declare a `cause` and twenty-two throw sites pass one.
|
|
40
|
+
* Without this the underlying git stderr, errno or parse failure never
|
|
56
41
|
* reaches the operator, because a `FireForgeError` renders as its
|
|
57
42
|
* `userMessage` and stops.
|
|
58
43
|
*
|
|
@@ -93,7 +78,12 @@ export function installBrokenPipeHandler() {
|
|
|
93
78
|
process.stderr.on('error', handleStreamError);
|
|
94
79
|
state[brokenPipeInstalledKey] = true;
|
|
95
80
|
}
|
|
96
|
-
/**
|
|
81
|
+
/**
|
|
82
|
+
* Removes the broken-pipe handler installed for CLI tests.
|
|
83
|
+
*
|
|
84
|
+
* @internal Exported only so tests can reach it. It is not part of the
|
|
85
|
+
* public surface.
|
|
86
|
+
*/
|
|
97
87
|
export function resetBrokenPipeHandlerForTests() {
|
|
98
88
|
const state = getProcessState();
|
|
99
89
|
const handleStreamError = state[brokenPipeListenerKey];
|
|
@@ -108,14 +98,14 @@ export function resetBrokenPipeHandlerForTests() {
|
|
|
108
98
|
* Maximum number of directory levels to walk when searching for
|
|
109
99
|
* `fireforge.json`. `dirname()` walking is pure string manipulation and
|
|
110
100
|
* cannot cycle (the `parent === current` check already terminates at the
|
|
111
|
-
* root)
|
|
101
|
+
* root). This cap only bounds the cost on pathologically deep paths.
|
|
112
102
|
*/
|
|
113
103
|
const MAX_PROJECT_ROOT_WALK_DEPTH = 50;
|
|
114
104
|
/**
|
|
115
105
|
* Gets the project root directory.
|
|
116
106
|
* Walks up from the current working directory until a fireforge.json is found.
|
|
117
107
|
* Throws a {@link ConfigNotFoundError} (code: CONFIG_ERROR) when no
|
|
118
|
-
* fireforge.json is found within the walk depth limit
|
|
108
|
+
* fireforge.json is found within the walk depth limit. The error is
|
|
119
109
|
* user-facing so `withErrorHandling` can print the guidance without
|
|
120
110
|
* the stack dump that a plain `Error` would trigger.
|
|
121
111
|
*/
|
|
@@ -143,15 +133,15 @@ export function getProjectRoot() {
|
|
|
143
133
|
*/
|
|
144
134
|
export function withErrorHandling(handler) {
|
|
145
135
|
return async (...args) => {
|
|
146
|
-
// Rule 3 of docs/machine-output.md: machine mode engages
|
|
147
|
-
// output. Anything that throws on the way in
|
|
148
|
-
// `getProjectRoot`'s ConfigNotFoundError
|
|
136
|
+
// Rule 3 of docs/machine-output.md: machine mode engages before any
|
|
137
|
+
// output. Anything that throws on the way in (most visibly
|
|
138
|
+
// `getProjectRoot`'s ConfigNotFoundError) would otherwise render a
|
|
149
139
|
// clack-styled block to stdout and leave a `--json` consumer with
|
|
150
140
|
// un-parseable output. Reading the flag from argv is blunt but exact: if
|
|
151
141
|
// the invocation asked for machine output, stdout belongs to the payload
|
|
152
142
|
// from the first byte.
|
|
153
|
-
const
|
|
154
|
-
if (
|
|
143
|
+
const machineOutput = wantsMachineOutput();
|
|
144
|
+
if (machineOutput) {
|
|
155
145
|
setMachineOutputMode(true);
|
|
156
146
|
}
|
|
157
147
|
try {
|
|
@@ -166,9 +156,9 @@ export function withErrorHandling(handler) {
|
|
|
166
156
|
}
|
|
167
157
|
if (error instanceof CancellationError) {
|
|
168
158
|
cancel('Operation cancelled');
|
|
169
|
-
// 130 (128+SIGINT) is the conventional "user interrupted" code
|
|
170
|
-
// scripts/CI can distinguish a
|
|
171
|
-
//
|
|
159
|
+
// 130 (128+SIGINT) is the conventional "user interrupted" code, so
|
|
160
|
+
// scripts/CI can distinguish a prompt cancellation from a real
|
|
161
|
+
// failure (which exits 1).
|
|
172
162
|
throw new CommandError(ExitCode.USER_CANCELLED);
|
|
173
163
|
}
|
|
174
164
|
// An invariant failure is the one FireForgeError whose stack is part
|
|
@@ -189,9 +179,9 @@ export function withErrorHandling(handler) {
|
|
|
189
179
|
logError(error.userMessage);
|
|
190
180
|
printCauseChain(error);
|
|
191
181
|
// Not when a payload already owns stdout: `status --json --fail-on`
|
|
192
|
-
// writes its full document and
|
|
182
|
+
// writes its full document and then refuses, and appending an
|
|
193
183
|
// envelope would make that two JSON documents.
|
|
194
|
-
if (
|
|
184
|
+
if (machineOutput && !isStdoutSealed()) {
|
|
195
185
|
emitMachineError(machineErrorCode(error), error.message, error.code);
|
|
196
186
|
}
|
|
197
187
|
throw new CommandError(error.code);
|
|
@@ -205,9 +195,9 @@ export function withErrorHandling(handler) {
|
|
|
205
195
|
}
|
|
206
196
|
finally {
|
|
207
197
|
// Central machine-mode and stdout-seal reset. Commands leave both
|
|
208
|
-
//
|
|
198
|
+
// engaged while an error propagates (a mid-throw restore would route
|
|
209
199
|
// the styled error to stdout, corrupting the `--json`/`--raw` payload
|
|
210
|
-
// stream or displacing the FIREFORGE-VERDICT line)
|
|
200
|
+
// stream or displacing the FIREFORGE-VERDICT line). The reset happens
|
|
211
201
|
// here, after logError has picked its stream, so no state leaks into a
|
|
212
202
|
// subsequent in-process invocation.
|
|
213
203
|
setMachineOutputMode(false);
|
|
@@ -255,9 +245,9 @@ function buildGroupedHelpFormatter(manifest) {
|
|
|
255
245
|
return formatHelpLine(term, desc, termWidth, helpWidth);
|
|
256
246
|
});
|
|
257
247
|
// -V/--version is handled in main() before commander parses (a real
|
|
258
|
-
// root-level `.version()` option would claim `--version`
|
|
248
|
+
// root-level `.version()` option would claim `--version` anywhere in
|
|
259
249
|
// argv under commander's default parsing, breaking subcommand flags
|
|
260
|
-
// like `source set --version <v>`)
|
|
250
|
+
// like `source set --version <v>`). Advertise it here so root help
|
|
261
251
|
// stays truthful.
|
|
262
252
|
optionLines.unshift(formatHelpLine('-V, --version', 'output the version number', termWidth, helpWidth));
|
|
263
253
|
if (optionLines.length > 0) {
|
|
@@ -339,6 +329,11 @@ export function createProgram() {
|
|
|
339
329
|
const program = new Command();
|
|
340
330
|
program
|
|
341
331
|
.name('fireforge')
|
|
332
|
+
// Usage errors must not let commander call process.exit(1) itself: the
|
|
333
|
+
// documented code is INVALID_ARGUMENT (8) and `--json` owes a refusal
|
|
334
|
+
// envelope. Installed before any subcommand registers, because
|
|
335
|
+
// `.command()` copies the override into the child at creation time.
|
|
336
|
+
.exitOverride()
|
|
342
337
|
.description('A build tool for customizing Firefox')
|
|
343
338
|
.option('-v, --verbose', 'Enable debug output')
|
|
344
339
|
.option('--ignore-corrupt-tree-marker', 'Run even when .fireforge/tree.json exists but cannot be parsed. Without this the tree guard refuses, because an unreadable marker leaves it unknown whether this is a snapshot or the primary tree.')
|
|
@@ -348,9 +343,9 @@ export function createProgram() {
|
|
|
348
343
|
setVerbose(true);
|
|
349
344
|
}
|
|
350
345
|
})
|
|
351
|
-
// Verification-tree guard: when the cwd resolves into a
|
|
352
|
-
//
|
|
353
|
-
//
|
|
346
|
+
// Verification-tree guard: when the cwd resolves into a tree snapshot,
|
|
347
|
+
// refuse mutating commands before their action runs. One hook covers
|
|
348
|
+
// every command regardless of how the cwd got there.
|
|
354
349
|
.hook('preAction', async (thisCommand, actionCommand) => {
|
|
355
350
|
await runTreeGuardHook(thisCommand.name(), actionCommand);
|
|
356
351
|
});
|
|
@@ -365,7 +360,7 @@ export function createProgram() {
|
|
|
365
360
|
// Uniform `--wait-lock`: scripted sequences blanket-append the flag, and a
|
|
366
361
|
// subcommand that rejects it with "unknown option" kills the sequence with
|
|
367
362
|
// a usage error instead of a lock message. Applied after registration so it
|
|
368
|
-
// covers every subcommand at every depth
|
|
363
|
+
// covers every subcommand at every depth. Commands that already declare the
|
|
369
364
|
// honoring flag keep it untouched.
|
|
370
365
|
ensureWaitLockOptionEverywhere(program);
|
|
371
366
|
return program;
|
|
@@ -374,13 +369,13 @@ export function createProgram() {
|
|
|
374
369
|
* Main CLI entry point.
|
|
375
370
|
*/
|
|
376
371
|
export async function main() {
|
|
377
|
-
// Root-level --version/-V handling.
|
|
378
|
-
//
|
|
379
|
-
//
|
|
380
|
-
//
|
|
381
|
-
//
|
|
382
|
-
//
|
|
383
|
-
//
|
|
372
|
+
// Root-level --version/-V handling. This is not a commander `.version()`
|
|
373
|
+
// option, because under commander's default (non-positional) parsing a
|
|
374
|
+
// root version option claims `--version` anywhere in argv and hijacks
|
|
375
|
+
// subcommand flags like `source set --version <v>`. The rule here: when no
|
|
376
|
+
// subcommand was given, any -V/--version among the root flags prints the
|
|
377
|
+
// version, so `fireforge --verbose --version` works and
|
|
378
|
+
// `fireforge source set --version 152` is untouched.
|
|
384
379
|
const userArgs = process.argv.slice(2);
|
|
385
380
|
const hasSubcommand = userArgs.some((arg) => !arg.startsWith('-'));
|
|
386
381
|
if (!hasSubcommand && userArgs.some((arg) => arg === '--version' || arg === '-V')) {
|
|
@@ -388,5 +383,10 @@ export async function main() {
|
|
|
388
383
|
return;
|
|
389
384
|
}
|
|
390
385
|
const program = createProgram();
|
|
391
|
-
|
|
386
|
+
try {
|
|
387
|
+
await program.parseAsync(process.argv);
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
handleParseError(error, wantsMachineOutput());
|
|
391
|
+
}
|
|
392
392
|
}
|
|
@@ -13,7 +13,8 @@ export function detectBootstrapIssues(output) {
|
|
|
13
13
|
const hasTraceback = /traceback \(most recent call last\):/i.test(normalized);
|
|
14
14
|
const has403 = /\bhttp(?:\s+error)?\s*403\b/i.test(normalized) || /\b403\b.*forbidden/i.test(normalized);
|
|
15
15
|
if (has403) {
|
|
16
|
-
// The traceback is just the stack trace from the HTTP error
|
|
16
|
+
// The traceback is just the stack trace from the HTTP error, so report
|
|
17
|
+
// it once.
|
|
17
18
|
issues.push('sdk-fetch-403');
|
|
18
19
|
}
|
|
19
20
|
else if (hasTraceback) {
|
|
@@ -10,7 +10,6 @@ import { ExitCode } from '../errors/codes.js';
|
|
|
10
10
|
import { error, info, intro, outro, warn } from '../utils/logger.js';
|
|
11
11
|
import { detectBootstrapIssues, runPostBootstrapChecks, } from './bootstrap-checks.js';
|
|
12
12
|
import { reportDoctorResults } from './doctor.js';
|
|
13
|
-
import { resolveDoctorSeverity } from './doctor-check-core.js';
|
|
14
13
|
/** One sentence per detected issue, keyed by the scanner's own tags. */
|
|
15
14
|
const BOOTSTRAP_FAILURE_SENTENCES = {
|
|
16
15
|
'python-traceback': 'Bootstrap emitted a Python traceback.',
|
|
@@ -24,7 +23,7 @@ const BOOTSTRAP_FAILURE_SENTENCES = {
|
|
|
24
23
|
function buildBootstrapFailureMessage(output) {
|
|
25
24
|
// Delegates detection to the canonical scanner rather than keeping a
|
|
26
25
|
// second copy of its six regexes. The copies had already disagreed: this
|
|
27
|
-
// one reported a traceback
|
|
26
|
+
// one reported a traceback and a 403 separately, while
|
|
28
27
|
// `detectBootstrapIssues` collapses them, because a bootstrap traceback
|
|
29
28
|
// accompanying a 403 is just the stack trace from that HTTP error.
|
|
30
29
|
const issues = detectBootstrapIssues(output).map((issue) => BOOTSTRAP_FAILURE_SENTENCES[issue]);
|
|
@@ -68,7 +67,7 @@ export async function bootstrapCommand(projectRoot) {
|
|
|
68
67
|
// Shares one resolver with reportDoctorResults so the two consumers of
|
|
69
68
|
// this same array cannot drift apart on how a check's severity is
|
|
70
69
|
// derived.
|
|
71
|
-
const hasErrors = checks.some((c) =>
|
|
70
|
+
const hasErrors = checks.some((c) => c.severity === 'error');
|
|
72
71
|
info('');
|
|
73
72
|
if (hasErrors) {
|
|
74
73
|
warn('Bootstrap completed with issues:');
|
|
@@ -80,7 +79,7 @@ export async function bootstrapCommand(projectRoot) {
|
|
|
80
79
|
if (hasErrors) {
|
|
81
80
|
outro('Build dependencies installed with errors');
|
|
82
81
|
// Propagate the failure (mirroring doctor's exit-code handling)
|
|
83
|
-
// instead of exiting 0
|
|
82
|
+
// instead of exiting 0. CI gating on bootstrap used to proceed to a
|
|
84
83
|
// build that could not succeed because error-severity check results
|
|
85
84
|
// were discarded here.
|
|
86
85
|
return checksExitCode;
|
|
@@ -13,6 +13,7 @@ import { buildHarnessCrashMessage } from '../core/test-harness-crash.js';
|
|
|
13
13
|
import { formatToolchainMismatchMessage, runToolchainPreflight, } from '../core/toolchain-preflight.js';
|
|
14
14
|
import { GeneralError, InvalidArgumentError } from '../errors/base.js';
|
|
15
15
|
import { AmbiguousBuildArtifactsError, BuildError } from '../errors/build.js';
|
|
16
|
+
import { elapsedSince } from '../utils/elapsed.js';
|
|
16
17
|
import { toError } from '../utils/errors.js';
|
|
17
18
|
import { checkDiskSpace } from '../utils/fs.js';
|
|
18
19
|
import { error, info, intro, outro, spinner, verbose, warn } from '../utils/logger.js';
|
|
@@ -29,9 +30,9 @@ function parseJobCount(value) {
|
|
|
29
30
|
* Patches `mozinfo.json` under the active obj-* directory so its recorded
|
|
30
31
|
* paths match the current engine checkout, then runs `mach configure` to
|
|
31
32
|
* regenerate every other generated path alongside it. Throws with the
|
|
32
|
-
* original mismatch guidance when the rewriter refuses to proceed
|
|
33
|
-
*
|
|
34
|
-
*
|
|
33
|
+
* original mismatch guidance when the rewriter refuses to proceed. That
|
|
34
|
+
* covers the unsafe cases, so the operator still gets the correct fallback
|
|
35
|
+
* recovery instruction.
|
|
35
36
|
*/
|
|
36
37
|
async function rewriteAndReconfigure(engineDir, objDir, mismatchMessage) {
|
|
37
38
|
const rewriteSpinner = spinner('Rewriting mozinfo.json paths...');
|
|
@@ -200,7 +201,7 @@ async function runBuildCommandBody(projectRoot, options) {
|
|
|
200
201
|
// and fail fast naming `fireforge bootstrap` instead of dying ~8s into
|
|
201
202
|
// configure with mach's "./mach bootstrap" remediation text. Fail-soft by
|
|
202
203
|
// design: only a definitively parsed minimum vs a definitively probed host
|
|
203
|
-
// version can fail here
|
|
204
|
+
// version can fail here. Anything uncertain proceeds to mach, where the
|
|
204
205
|
// mach-error-hints translator still names the right remedy.
|
|
205
206
|
const toolchainMismatches = await runToolchainPreflight(paths.engine);
|
|
206
207
|
if (toolchainMismatches.length > 0) {
|
|
@@ -216,7 +217,7 @@ async function runBuildCommandBody(projectRoot, options) {
|
|
|
216
217
|
// Safe-relocation rewrite path: patch mozinfo.json paths in place so
|
|
217
218
|
// `mach configure` can regenerate the backend without scrubbing the
|
|
218
219
|
// whole obj tree. The rewriter refuses anything that is not a pure
|
|
219
|
-
// prefix-move
|
|
220
|
+
// prefix-move. On refusal we surface the refusal reason alongside
|
|
220
221
|
// the original mismatch guidance and abort.
|
|
221
222
|
await rewriteAndReconfigure(paths.engine, buildCheck.objDir, mismatchMessage);
|
|
222
223
|
}
|
|
@@ -274,7 +275,7 @@ async function runBuildCommandBody(projectRoot, options) {
|
|
|
274
275
|
// overlapping `fireforge build` / `fireforge build --ui` commands
|
|
275
276
|
// against the same engine tree serialise instead of racing through the
|
|
276
277
|
// same obj-*. A `build --ui` launched during an in-progress full build
|
|
277
|
-
// otherwise hits `No rule to make target 'XUL'` in mach
|
|
278
|
+
// otherwise hits `No rule to make target 'XUL'` in mach, the
|
|
278
279
|
// downstream consequence of an incomplete backend, with no clue that a
|
|
279
280
|
// concurrent build caused it. The lock turns the second invocation's
|
|
280
281
|
// failure into an explicit refusal naming the holder PID.
|
|
@@ -288,10 +289,7 @@ async function runBuildCommandBody(projectRoot, options) {
|
|
|
288
289
|
catch (error) {
|
|
289
290
|
throw new BuildError('Build process failed to start', options.ui ? 'mach build faster' : 'mach build', error instanceof Error ? error : undefined);
|
|
290
291
|
}
|
|
291
|
-
const
|
|
292
|
-
const minutes = Math.floor(duration / 60000);
|
|
293
|
-
const seconds = Math.floor((duration % 60000) / 1000);
|
|
294
|
-
const timeStr = minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;
|
|
292
|
+
const timeStr = elapsedSince(startTime);
|
|
295
293
|
if (result.exitCode !== 0) {
|
|
296
294
|
error(`Build failed after ${timeStr}`);
|
|
297
295
|
const machCommand = options.ui ? 'mach build faster' : 'mach build';
|
|
@@ -315,9 +313,10 @@ async function runBuildCommandBody(projectRoot, options) {
|
|
|
315
313
|
// Matching only (1) leaves operators on the (2) path seeing mach's own
|
|
316
314
|
// "Configure complete!" and "run |mach build|" lines unexplained between
|
|
317
315
|
// mach's "Your build was successful!" and FireForge's "Build completed in
|
|
318
|
-
// Xm Ys" outro
|
|
319
|
-
// annotation, emitted
|
|
320
|
-
// terminal line is the explanation
|
|
316
|
+
// Xm Ys" outro, a contradictory tail. Both shapes route through the same
|
|
317
|
+
// annotation, emitted before FireForge's outro so the operator's last
|
|
318
|
+
// terminal line is the explanation instead of the confusing mach guard
|
|
319
|
+
// text.
|
|
321
320
|
const staleConfigurePatterns = [
|
|
322
321
|
/config\.status is out of date/i,
|
|
323
322
|
/Config object not found by mach\.[\s\S]*Configure complete!/i,
|
|
@@ -331,10 +330,12 @@ async function runBuildCommandBody(projectRoot, options) {
|
|
|
331
330
|
}
|
|
332
331
|
// Warn-only post-build audit: surfaces silent packaging drops (files
|
|
333
332
|
// edited in engine/ but never registered for packaging) against the
|
|
334
|
-
// previous-build baseline. Never fails the build
|
|
333
|
+
// previous-build baseline. Never fails the build. The worst case is a
|
|
335
334
|
// warning an operator chooses to investigate.
|
|
336
335
|
try {
|
|
337
|
-
await auditBuildArtifacts(projectRoot, paths.engine, previousBaseline
|
|
336
|
+
await auditBuildArtifacts(projectRoot, paths.engine, previousBaseline, {
|
|
337
|
+
...(config.buildAudit?.unpackaged ? { unpackaged: config.buildAudit.unpackaged } : {}),
|
|
338
|
+
});
|
|
338
339
|
}
|
|
339
340
|
catch (auditError) {
|
|
340
341
|
verbose(`Audit skipped: ${toError(auditError).message}`);
|
|
@@ -346,14 +347,23 @@ async function runBuildCommandBody(projectRoot, options) {
|
|
|
346
347
|
outro(`Build completed in ${timeStr}!`);
|
|
347
348
|
}
|
|
348
349
|
/**
|
|
349
|
-
* Persists the full-coverage baseline
|
|
350
|
+
* Persists the full-coverage baseline. A failed write never fails the build.
|
|
350
351
|
* `--ui` is a `mach build faster`, so it is recorded as such: its `jar.mn`
|
|
351
352
|
* fingerprints are carried forward from the previous baseline rather than
|
|
352
353
|
* refreshed, which is why that baseline is threaded through.
|
|
353
354
|
*/
|
|
354
355
|
async function recordFullBuildBaseline(projectRoot, engineDir, binaryName, ui, previousBaseline) {
|
|
355
356
|
try {
|
|
356
|
-
await writeBuildBaseline(
|
|
357
|
+
await writeBuildBaseline({
|
|
358
|
+
projectRoot,
|
|
359
|
+
engineDir,
|
|
360
|
+
binaryName,
|
|
361
|
+
testPackagingCoverage: 'full',
|
|
362
|
+
previousBaseline,
|
|
363
|
+
recordedBy: ui ? 'fireforge build --ui' : 'fireforge build',
|
|
364
|
+
staticComponentsHandling: 'auto',
|
|
365
|
+
buildKind: ui ? 'faster' : 'full',
|
|
366
|
+
});
|
|
357
367
|
}
|
|
358
368
|
catch (baselineError) {
|
|
359
369
|
verbose(`Could not persist build baseline: ${toError(baselineError).message}`);
|