@hominis/fireforge 0.43.1 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +126 -0
- package/README.md +10 -1
- package/dist/bin/fireforge.d.ts +4 -9
- package/dist/bin/fireforge.js +42 -40
- package/dist/build-info.json +4 -4
- package/dist/src/cli.js +74 -8
- package/dist/src/commands/bootstrap.js +17 -20
- package/dist/src/commands/build.js +25 -32
- package/dist/src/commands/config.js +34 -41
- package/dist/src/commands/discard.js +8 -9
- package/dist/src/commands/doctor-check-core.d.ts +4 -18
- package/dist/src/commands/doctor-check-core.js +8 -35
- package/dist/src/commands/doctor-external-toolchains.js +2 -2
- package/dist/src/commands/doctor-furnace-config-sync.d.ts +18 -0
- package/dist/src/commands/{doctor-furnace-manifest-sync.js → doctor-furnace-config-sync.js} +27 -26
- package/dist/src/commands/doctor-furnace-jar.d.ts +7 -9
- package/dist/src/commands/doctor-furnace-jar.js +7 -9
- package/dist/src/commands/doctor-furnace.js +21 -24
- package/dist/src/commands/doctor-orphaned-harness.d.ts +16 -20
- package/dist/src/commands/doctor-orphaned-harness.js +18 -44
- package/dist/src/commands/doctor-post-rebase-audit.d.ts +2 -0
- package/dist/src/commands/{doctor/post-rebase-audit.js → doctor-post-rebase-audit.js} +3 -3
- package/dist/src/commands/doctor-working-tree.d.ts +10 -12
- package/dist/src/commands/doctor-working-tree.js +11 -18
- package/dist/src/commands/doctor.js +35 -53
- package/dist/src/commands/download.js +32 -48
- package/dist/src/commands/export-all.js +29 -33
- package/dist/src/commands/export-flow.js +6 -6
- package/dist/src/commands/export-placement-conflicts.js +10 -9
- package/dist/src/commands/export-placement-gate.js +5 -5
- package/dist/src/commands/export-shared.d.ts +30 -33
- package/dist/src/commands/export-shared.js +45 -43
- package/dist/src/commands/export.js +21 -27
- package/dist/src/commands/furnace/apply.js +14 -23
- package/dist/src/commands/furnace/chrome-doc-remove.js +14 -21
- package/dist/src/commands/furnace/chrome-doc-templates.d.ts +23 -23
- package/dist/src/commands/furnace/chrome-doc-templates.js +23 -23
- package/dist/src/commands/furnace/chrome-doc-tests.js +26 -29
- package/dist/src/commands/furnace/chrome-doc.d.ts +16 -17
- package/dist/src/commands/furnace/chrome-doc.js +31 -41
- package/dist/src/commands/furnace/create-browser-test.d.ts +4 -4
- package/dist/src/commands/furnace/create-browser-test.js +8 -8
- package/dist/src/commands/furnace/create-mochikit.d.ts +6 -7
- package/dist/src/commands/furnace/create-mochikit.js +8 -9
- package/dist/src/commands/furnace/create-readback.d.ts +12 -13
- package/dist/src/commands/furnace/create-readback.js +12 -13
- package/dist/src/commands/furnace/create-templates.d.ts +22 -28
- package/dist/src/commands/furnace/create-templates.js +35 -30
- package/dist/src/commands/furnace/create-xpcshell.js +2 -2
- package/dist/src/commands/furnace/create.js +33 -23
- package/dist/src/commands/furnace/deploy.js +16 -24
- package/dist/src/commands/furnace/diff.js +9 -9
- package/dist/src/commands/furnace/init.js +33 -36
- package/dist/src/commands/furnace/override.js +23 -25
- package/dist/src/commands/furnace/preview.js +47 -67
- package/dist/src/commands/furnace/refresh.js +12 -16
- package/dist/src/commands/furnace/remove-mutations.d.ts +3 -6
- package/dist/src/commands/furnace/remove-mutations.js +9 -16
- package/dist/src/commands/furnace/remove-state.js +1 -1
- package/dist/src/commands/furnace/remove.js +33 -38
- package/dist/src/commands/furnace/rename-xpcshell.d.ts +8 -11
- package/dist/src/commands/furnace/rename-xpcshell.js +8 -11
- package/dist/src/commands/furnace/rename.js +59 -69
- package/dist/src/commands/furnace/scan.js +19 -33
- package/dist/src/commands/furnace/status.js +12 -9
- package/dist/src/commands/furnace/sync.js +9 -16
- package/dist/src/commands/furnace/validate.js +20 -20
- package/dist/src/commands/import.js +42 -35
- package/dist/src/commands/lint-per-patch.js +15 -10
- package/dist/src/commands/lint-per-run-checkjs.d.ts +13 -13
- package/dist/src/commands/lint-per-run-checkjs.js +13 -13
- package/dist/src/commands/lint-report.js +6 -7
- package/dist/src/commands/lint.d.ts +15 -16
- package/dist/src/commands/lint.js +86 -102
- package/dist/src/commands/package.js +6 -11
- package/dist/src/commands/patch/compact.js +1 -1
- package/dist/src/commands/patch/delete.js +24 -33
- package/dist/src/commands/patch/index.d.ts +5 -6
- package/dist/src/commands/patch/index.js +10 -12
- package/dist/src/commands/patch/lint-ignore.js +14 -13
- package/dist/src/commands/patch/move-files-create.d.ts +6 -6
- package/dist/src/commands/patch/move-files-create.js +8 -8
- package/dist/src/commands/patch/move-files-into.d.ts +6 -6
- package/dist/src/commands/patch/move-files-into.js +8 -8
- package/dist/src/commands/patch/patch-context.d.ts +2 -3
- package/dist/src/commands/patch/patch-context.js +2 -3
- package/dist/src/commands/patch/rename.d.ts +10 -11
- package/dist/src/commands/patch/rename.js +11 -12
- package/dist/src/commands/patch/reorder.js +8 -9
- package/dist/src/commands/patch/split-plan.js +1 -1
- package/dist/src/commands/patch/split.d.ts +8 -10
- package/dist/src/commands/patch/split.js +9 -11
- package/dist/src/commands/patch/staged-dependency-validate.js +8 -8
- package/dist/src/commands/patch/staged-dependency.js +7 -3
- package/dist/src/commands/patch/tier.d.ts +9 -9
- package/dist/src/commands/patch/tier.js +18 -15
- package/dist/src/commands/re-export-adjacent.js +9 -8
- package/dist/src/commands/re-export-bulk-scan.d.ts +9 -9
- package/dist/src/commands/re-export-bulk-scan.js +22 -21
- package/dist/src/commands/re-export-drift.js +10 -10
- package/dist/src/commands/re-export-files.d.ts +6 -7
- package/dist/src/commands/re-export-files.js +34 -44
- package/dist/src/commands/re-export-lint.d.ts +10 -13
- package/dist/src/commands/re-export-lint.js +16 -14
- package/dist/src/commands/re-export-options.d.ts +6 -6
- package/dist/src/commands/re-export-options.js +6 -6
- package/dist/src/commands/re-export-register.d.ts +4 -10
- package/dist/src/commands/re-export-register.js +5 -11
- package/dist/src/commands/re-export-scan.js +1 -1
- package/dist/src/commands/re-export-single.d.ts +3 -3
- package/dist/src/commands/re-export-single.js +33 -25
- package/dist/src/commands/re-export.js +13 -21
- package/dist/src/commands/rebase/abort.js +3 -3
- package/dist/src/commands/rebase/confirm.js +2 -1
- package/dist/src/commands/rebase/continue.d.ts +1 -1
- package/dist/src/commands/rebase/continue.js +14 -9
- package/dist/src/commands/rebase/index.js +11 -11
- package/dist/src/commands/rebase/patch-loop.d.ts +7 -1
- package/dist/src/commands/rebase/patch-loop.js +60 -39
- package/dist/src/commands/rebase/summary.js +1 -1
- package/dist/src/commands/register.js +5 -7
- package/dist/src/commands/reset.js +2 -1
- package/dist/src/commands/resolve.d.ts +16 -13
- package/dist/src/commands/resolve.js +30 -33
- package/dist/src/commands/run.js +33 -35
- package/dist/src/commands/setup-support.js +15 -19
- package/dist/src/commands/setup.js +13 -9
- package/dist/src/commands/status-check.d.ts +6 -6
- package/dist/src/commands/status-json.d.ts +6 -6
- package/dist/src/commands/status-json.js +5 -0
- package/dist/src/commands/status-output.d.ts +5 -5
- package/dist/src/commands/status-output.js +6 -6
- package/dist/src/commands/status-ownership.d.ts +16 -14
- package/dist/src/commands/status-ownership.js +16 -14
- package/dist/src/commands/status.js +42 -34
- package/dist/src/commands/test-build-phase.js +26 -13
- package/dist/src/commands/test-diagnose.js +44 -44
- package/dist/src/commands/test-register.js +1 -0
- package/dist/src/commands/test-run.d.ts +14 -16
- package/dist/src/commands/test-run.js +21 -13
- package/dist/src/commands/test-stale-gate.d.ts +15 -16
- package/dist/src/commands/test-stale-gate.js +15 -16
- package/dist/src/commands/test-verdict.d.ts +20 -3
- package/dist/src/commands/test-verdict.js +30 -0
- package/dist/src/commands/test.js +83 -76
- package/dist/src/commands/token-coverage.js +3 -4
- package/dist/src/commands/token.js +16 -18
- package/dist/src/commands/tree.js +47 -31
- package/dist/src/commands/typecheck.d.ts +10 -12
- package/dist/src/commands/typecheck.js +24 -27
- package/dist/src/commands/verify.js +13 -15
- package/dist/src/commands/watch.js +21 -23
- package/dist/src/commands/wire.js +52 -62
- package/dist/src/core/ast-utils.d.ts +8 -7
- package/dist/src/core/ast-utils.js +8 -7
- package/dist/src/core/branding.d.ts +9 -14
- package/dist/src/core/branding.js +7 -11
- package/dist/src/core/browser-wire.d.ts +1 -1
- package/dist/src/core/browser-wire.js +14 -19
- package/dist/src/core/build-audit-platform.js +25 -33
- package/dist/src/core/build-audit-registration.js +17 -25
- package/dist/src/core/build-audit-resolve.d.ts +15 -17
- package/dist/src/core/build-audit-resolve.js +27 -33
- package/dist/src/core/build-audit-transforms.js +18 -19
- package/dist/src/core/build-audit.js +28 -42
- package/dist/src/core/build-baseline-types.d.ts +29 -35
- package/dist/src/core/build-baseline.d.ts +5 -4
- package/dist/src/core/build-baseline.js +14 -14
- package/dist/src/core/build-overwrite-guard.d.ts +7 -14
- package/dist/src/core/build-overwrite-guard.js +17 -27
- package/dist/src/core/build-prepare.d.ts +2 -2
- package/dist/src/core/build-prepare.js +8 -9
- package/dist/src/core/config-state.js +12 -4
- package/dist/src/core/config-validate.js +8 -5
- package/dist/src/core/config.d.ts +5 -8
- package/dist/src/core/config.js +7 -16
- package/dist/src/core/coverage-extend.d.ts +15 -13
- package/dist/src/core/coverage-extend.js +15 -13
- package/dist/src/core/destructive.d.ts +31 -9
- package/dist/src/core/destructive.js +29 -26
- package/dist/src/core/diff-hunks.js +10 -12
- package/dist/src/core/discard-baseline.d.ts +8 -8
- package/dist/src/core/discard-baseline.js +16 -15
- package/dist/src/core/display-state.d.ts +12 -14
- package/dist/src/core/display-state.js +12 -14
- package/dist/src/core/engine-changes.d.ts +2 -4
- package/dist/src/core/engine-changes.js +2 -4
- package/dist/src/core/engine-precondition.d.ts +28 -13
- package/dist/src/core/engine-precondition.js +25 -10
- package/dist/src/core/engine-session-lock.d.ts +47 -21
- package/dist/src/core/engine-session-lock.js +168 -33
- package/dist/src/core/export-moved-code-shape.d.ts +10 -10
- package/dist/src/core/export-moved-code-shape.js +10 -10
- package/dist/src/core/file-lock.d.ts +62 -5
- package/dist/src/core/file-lock.js +196 -59
- package/dist/src/core/firefox-cache.js +1 -3
- package/dist/src/core/firefox-extract.js +10 -14
- package/dist/src/core/firefox.d.ts +7 -5
- package/dist/src/core/firefox.js +4 -5
- package/dist/src/core/furnace-apply-dry-run.d.ts +2 -2
- package/dist/src/core/furnace-apply-dry-run.js +3 -2
- package/dist/src/core/furnace-apply-ftl.d.ts +7 -9
- package/dist/src/core/furnace-apply-ftl.js +12 -12
- package/dist/src/core/furnace-apply-helpers.d.ts +7 -7
- package/dist/src/core/furnace-apply-helpers.js +19 -16
- package/dist/src/core/furnace-apply-overwrite-warn.d.ts +8 -9
- package/dist/src/core/furnace-apply-overwrite-warn.js +8 -9
- package/dist/src/core/furnace-apply-undeploy-actions.d.ts +3 -4
- package/dist/src/core/furnace-apply-undeploy-actions.js +3 -4
- package/dist/src/core/furnace-apply.d.ts +5 -8
- package/dist/src/core/furnace-apply.js +19 -24
- package/dist/src/core/furnace-checksum-utils.d.ts +14 -0
- package/dist/src/core/furnace-checksum-utils.js +16 -0
- package/dist/src/core/furnace-config.d.ts +21 -30
- package/dist/src/core/furnace-config.js +32 -54
- package/dist/src/core/furnace-constants.d.ts +8 -0
- package/dist/src/core/furnace-constants.js +10 -2
- package/dist/src/core/furnace-css-fragments.d.ts +5 -5
- package/dist/src/core/furnace-css-fragments.js +5 -5
- package/dist/src/core/furnace-jsconfig.d.ts +11 -12
- package/dist/src/core/furnace-jsconfig.js +11 -12
- package/dist/src/core/furnace-marker.d.ts +7 -8
- package/dist/src/core/furnace-marker.js +7 -8
- package/dist/src/core/furnace-operation.d.ts +31 -0
- package/dist/src/core/furnace-operation.js +54 -17
- package/dist/src/core/furnace-precondition.d.ts +61 -0
- package/dist/src/core/furnace-precondition.js +67 -0
- package/dist/src/core/furnace-registration-remove.d.ts +5 -6
- package/dist/src/core/furnace-registration-remove.js +6 -7
- package/dist/src/core/furnace-registration-validate.d.ts +13 -0
- package/dist/src/core/furnace-registration-validate.js +20 -1
- package/dist/src/core/furnace-registration.d.ts +5 -6
- package/dist/src/core/furnace-registration.js +10 -12
- package/dist/src/core/furnace-rollback.js +7 -7
- package/dist/src/core/furnace-scanner.d.ts +1 -0
- package/dist/src/core/furnace-scanner.js +1 -2
- package/dist/src/core/furnace-stale-export.d.ts +10 -10
- package/dist/src/core/furnace-stale-export.js +10 -10
- package/dist/src/core/furnace-state-persist.d.ts +6 -8
- package/dist/src/core/furnace-state-persist.js +6 -8
- package/dist/src/core/furnace-validate-accessibility.d.ts +22 -0
- package/dist/src/core/furnace-validate-accessibility.js +310 -1
- package/dist/src/core/furnace-validate-compatibility.js +141 -1
- package/dist/src/core/furnace-validate-helpers.d.ts +5 -116
- package/dist/src/core/furnace-validate-helpers.js +0 -491
- package/dist/src/core/furnace-validate-registration.d.ts +7 -0
- package/dist/src/core/furnace-validate-registration.js +115 -41
- package/dist/src/core/furnace-validate.d.ts +16 -0
- package/dist/src/core/furnace-validate.js +188 -145
- package/dist/src/core/furnace-version-drift.d.ts +10 -11
- package/dist/src/core/furnace-version-drift.js +10 -11
- package/dist/src/core/git-base.d.ts +7 -9
- package/dist/src/core/git-base.js +7 -9
- package/dist/src/core/git-diff.d.ts +20 -9
- package/dist/src/core/git-diff.js +148 -63
- package/dist/src/core/git-file-ops.d.ts +19 -19
- package/dist/src/core/git-file-ops.js +19 -19
- package/dist/src/core/git-readonly-index.d.ts +53 -19
- package/dist/src/core/git-readonly-index.js +75 -31
- package/dist/src/core/git-status.d.ts +5 -6
- package/dist/src/core/git-status.js +5 -6
- package/dist/src/core/git.d.ts +9 -10
- package/dist/src/core/git.js +54 -70
- package/dist/src/core/license-headers.d.ts +17 -23
- package/dist/src/core/license-headers.js +17 -23
- package/dist/src/core/mach-build-artifacts.d.ts +9 -9
- package/dist/src/core/mach-build-artifacts.js +57 -19
- package/dist/src/core/mach-error-hints.js +42 -29
- package/dist/src/core/mach-known-noise-filter.d.ts +15 -16
- package/dist/src/core/mach-known-noise-filter.js +18 -20
- package/dist/src/core/mach-mozconfig.d.ts +14 -0
- package/dist/src/core/mach-mozconfig.js +30 -0
- package/dist/src/core/mach-resource-shim.d.ts +43 -58
- package/dist/src/core/mach-resource-shim.js +50 -67
- package/dist/src/core/mach.d.ts +37 -41
- package/dist/src/core/mach.js +50 -51
- package/dist/src/core/marionette-port.d.ts +36 -1
- package/dist/src/core/marionette-port.js +96 -31
- package/dist/src/core/marionette-preflight.d.ts +8 -12
- package/dist/src/core/marionette-preflight.js +86 -52
- package/dist/src/core/mochitest-server-port.d.ts +42 -0
- package/dist/src/core/mochitest-server-port.js +119 -0
- package/dist/src/core/module-resolution-preflight.d.ts +9 -11
- package/dist/src/core/module-resolution-preflight.js +9 -11
- package/dist/src/core/moz-manifest-helpers.d.ts +79 -0
- package/dist/src/core/moz-manifest-helpers.js +163 -0
- package/dist/src/core/{manifest-register.d.ts → moz-manifest-register.d.ts} +1 -1
- package/dist/src/core/{manifest-register.js → moz-manifest-register.js} +13 -28
- package/dist/src/core/{manifest-rules.d.ts → moz-manifest-rules.d.ts} +10 -1
- package/dist/src/core/{manifest-rules.js → moz-manifest-rules.js} +31 -24
- package/dist/src/core/{manifest-tokenizers.d.ts → moz-manifest-tokenizers.d.ts} +3 -5
- package/dist/src/core/{manifest-tokenizers.js → moz-manifest-tokenizers.js} +9 -12
- package/dist/src/core/ownership-table.d.ts +14 -16
- package/dist/src/core/ownership-table.js +14 -16
- package/dist/src/core/parser-fallback.d.ts +15 -1
- package/dist/src/core/parser-fallback.js +22 -3
- package/dist/src/core/patch-apply-fuzz.d.ts +10 -12
- package/dist/src/core/patch-apply-fuzz.js +15 -18
- package/dist/src/core/patch-apply.d.ts +13 -34
- package/dist/src/core/patch-apply.js +16 -76
- package/dist/src/core/patch-artifact-normalize.d.ts +13 -15
- package/dist/src/core/patch-artifact-normalize.js +13 -15
- package/dist/src/core/patch-export-metadata.d.ts +12 -2
- package/dist/src/core/patch-export-metadata.js +13 -4
- package/dist/src/core/patch-export-update.d.ts +13 -1
- package/dist/src/core/patch-export-update.js +25 -8
- package/dist/src/core/patch-export.d.ts +15 -8
- package/dist/src/core/patch-export.js +10 -11
- package/dist/src/core/patch-files.d.ts +5 -6
- package/dist/src/core/patch-files.js +5 -6
- package/dist/src/core/patch-identifier-suggest.d.ts +7 -12
- package/dist/src/core/patch-identifier-suggest.js +14 -19
- package/dist/src/core/patch-lint-binary.d.ts +51 -0
- package/dist/src/core/patch-lint-binary.js +39 -0
- package/dist/src/core/{lint-cache.d.ts → patch-lint-cache.d.ts} +5 -5
- package/dist/src/core/{lint-cache.js → patch-lint-cache.js} +21 -23
- package/dist/src/core/patch-lint-checkjs.d.ts +16 -16
- package/dist/src/core/patch-lint-checkjs.js +16 -16
- package/dist/src/core/patch-lint-chrome-jsdoc.d.ts +6 -9
- package/dist/src/core/patch-lint-chrome-jsdoc.js +10 -14
- package/dist/src/core/patch-lint-creators.d.ts +8 -8
- package/dist/src/core/patch-lint-creators.js +8 -8
- package/dist/src/core/patch-lint-cross.d.ts +17 -20
- package/dist/src/core/patch-lint-cross.js +16 -16
- package/dist/src/core/patch-lint-css.d.ts +3 -5
- package/dist/src/core/patch-lint-css.js +17 -22
- package/dist/src/core/patch-lint-diff-tag.d.ts +14 -16
- package/dist/src/core/patch-lint-diff-tag.js +14 -16
- package/dist/src/core/patch-lint-jsdoc.d.ts +7 -8
- package/dist/src/core/patch-lint-jsdoc.js +26 -19
- package/dist/src/core/patch-lint-mozbuild.js +20 -20
- package/dist/src/core/patch-lint-observer.d.ts +7 -7
- package/dist/src/core/patch-lint-observer.js +7 -7
- package/dist/src/core/patch-lint.d.ts +38 -29
- package/dist/src/core/patch-lint.js +89 -121
- package/dist/src/core/patch-lock.d.ts +1 -1
- package/dist/src/core/patch-lock.js +45 -9
- package/dist/src/core/patch-manifest-consistency.d.ts +2 -1
- package/dist/src/core/patch-manifest-consistency.js +25 -27
- package/dist/src/core/patch-manifest-io.js +14 -18
- package/dist/src/core/patch-manifest-resolve.d.ts +9 -12
- package/dist/src/core/patch-manifest-resolve.js +9 -12
- package/dist/src/core/patch-manifest-validate.d.ts +6 -1
- package/dist/src/core/patch-manifest-validate.js +25 -13
- package/dist/src/core/patch-parse.d.ts +24 -13
- package/dist/src/core/patch-parse.js +19 -14
- package/dist/src/core/patch-policy.d.ts +2 -2
- package/dist/src/core/patch-policy.js +2 -2
- package/dist/src/core/patch-registration-refs.d.ts +7 -8
- package/dist/src/core/patch-registration-refs.js +9 -9
- package/dist/src/core/process-cpu-time.d.ts +12 -0
- package/dist/src/core/process-cpu-time.js +52 -0
- package/dist/src/core/rebase-session.d.ts +38 -26
- package/dist/src/core/rebase-session.js +55 -28
- package/dist/src/core/register-browser-content.js +9 -74
- package/dist/src/core/{register-test-manifest.js → register-browser-test.js} +7 -42
- package/dist/src/core/register-module.js +10 -43
- package/dist/src/core/register-scaffold.d.ts +8 -8
- package/dist/src/core/register-scaffold.js +10 -10
- package/dist/src/core/register-shared-css.d.ts +9 -12
- package/dist/src/core/register-shared-css.js +17 -87
- package/dist/src/core/register-xpcshell-test.d.ts +6 -7
- package/dist/src/core/register-xpcshell-test.js +7 -8
- package/dist/src/core/shared-ftl.js +12 -4
- package/dist/src/core/state-file.d.ts +45 -0
- package/dist/src/core/state-file.js +34 -0
- package/dist/src/core/status-binary.d.ts +18 -11
- package/dist/src/core/status-binary.js +19 -12
- package/dist/src/core/status-classify.d.ts +30 -36
- package/dist/src/core/status-classify.js +21 -26
- package/dist/src/core/test-changed-prefs.d.ts +30 -0
- package/dist/src/core/test-changed-prefs.js +78 -0
- package/dist/src/core/test-harness-crash.d.ts +25 -63
- package/dist/src/core/test-harness-crash.js +121 -142
- package/dist/src/core/test-harness-signature.d.ts +18 -0
- package/dist/src/core/test-harness-signature.js +13 -0
- package/dist/src/core/test-path-scope.d.ts +12 -15
- package/dist/src/core/test-path-scope.js +15 -18
- package/dist/src/core/test-stale-check.d.ts +17 -17
- package/dist/src/core/test-stale-check.js +50 -43
- package/dist/src/core/test-stall-triage.d.ts +51 -0
- package/dist/src/core/test-stall-triage.js +126 -0
- package/dist/src/core/token-category.js +5 -7
- package/dist/src/core/token-coverage.js +9 -9
- package/dist/src/core/token-dark-mode.d.ts +9 -11
- package/dist/src/core/token-dark-mode.js +9 -11
- package/dist/src/core/token-docs.d.ts +2 -0
- package/dist/src/core/token-docs.js +2 -0
- package/dist/src/core/token-manager.d.ts +10 -2
- package/dist/src/core/token-manager.js +17 -8
- package/dist/src/core/token-scaffold.d.ts +7 -7
- package/dist/src/core/token-scaffold.js +7 -7
- package/dist/src/core/token-variant.d.ts +4 -4
- package/dist/src/core/token-variant.js +4 -4
- package/dist/src/core/toolchain-preflight.d.ts +20 -21
- package/dist/src/core/toolchain-preflight.js +28 -31
- package/dist/src/core/tree-guard.js +12 -2
- package/dist/src/core/tree-store.d.ts +41 -27
- package/dist/src/core/tree-store.js +63 -42
- package/dist/src/core/typecheck-shim.d.ts +23 -24
- package/dist/src/core/typecheck-shim.js +23 -24
- package/dist/src/core/typecheck.js +8 -8
- package/dist/src/core/wire-destroy.d.ts +3 -3
- package/dist/src/core/wire-destroy.js +7 -15
- package/dist/src/core/wire-dom-fragment.d.ts +9 -17
- package/dist/src/core/wire-dom-fragment.js +11 -44
- package/dist/src/core/wire-init.d.ts +2 -3
- package/dist/src/core/wire-init.js +8 -19
- package/dist/src/core/wire-subscript.d.ts +2 -3
- package/dist/src/core/wire-subscript.js +4 -13
- package/dist/src/core/wire-utils.d.ts +7 -8
- package/dist/src/core/wire-utils.js +7 -8
- package/dist/src/core/xpcshell-appdir.d.ts +38 -45
- package/dist/src/core/xpcshell-appdir.js +38 -45
- package/dist/src/errors/base.d.ts +37 -16
- package/dist/src/errors/base.js +37 -16
- package/dist/src/errors/build.d.ts +13 -1
- package/dist/src/errors/build.js +14 -2
- package/dist/src/errors/codes.d.ts +16 -0
- package/dist/src/errors/codes.js +16 -0
- package/dist/src/errors/furnace.d.ts +4 -4
- package/dist/src/errors/git.d.ts +6 -10
- package/dist/src/errors/git.js +6 -10
- package/dist/src/errors/patch.d.ts +7 -7
- package/dist/src/errors/patch.js +7 -7
- package/dist/src/errors/rebase.d.ts +4 -4
- package/dist/src/errors/rebase.js +4 -4
- package/dist/src/index.d.ts +7 -1
- package/dist/src/index.js +5 -0
- package/dist/src/types/commands/index.d.ts +2 -2
- package/dist/src/types/commands/options.d.ts +88 -70
- package/dist/src/types/commands/patches.d.ts +24 -34
- package/dist/src/types/commands/project.d.ts +5 -34
- package/dist/src/types/config.d.ts +25 -23
- package/dist/src/types/config.js +6 -1
- package/dist/src/types/furnace.d.ts +37 -13
- package/dist/src/types/furnace.js +19 -1
- package/dist/src/types/index.d.ts +3 -3
- package/dist/src/utils/build-info.d.ts +7 -8
- package/dist/src/utils/build-info.js +12 -11
- package/dist/src/utils/errors.d.ts +6 -8
- package/dist/src/utils/errors.js +6 -8
- package/dist/src/utils/logger.d.ts +27 -10
- package/dist/src/utils/logger.js +28 -16
- package/dist/src/utils/machine-output.d.ts +12 -0
- package/dist/src/utils/machine-output.js +33 -0
- package/dist/src/utils/options.d.ts +31 -14
- package/dist/src/utils/options.js +86 -30
- package/dist/src/utils/paths.d.ts +10 -8
- package/dist/src/utils/paths.js +10 -8
- package/dist/src/utils/platform.d.ts +0 -25
- package/dist/src/utils/platform.js +1 -42
- package/dist/src/utils/process-group.d.ts +9 -4
- package/dist/src/utils/process-group.js +19 -5
- package/dist/src/utils/process.d.ts +42 -7
- package/dist/src/utils/process.js +44 -17
- package/dist/src/utils/ps-duration.d.ts +31 -0
- package/dist/src/utils/ps-duration.js +70 -0
- package/dist/src/utils/regex.d.ts +9 -10
- package/dist/src/utils/regex.js +9 -10
- package/dist/src/utils/validation.d.ts +58 -28
- package/dist/src/utils/validation.js +60 -33
- package/package.json +2 -2
- package/dist/src/commands/doctor/post-rebase-audit.d.ts +0 -2
- package/dist/src/commands/doctor-furnace-manifest-sync.d.ts +0 -18
- package/dist/src/core/manifest-helpers.d.ts +0 -38
- package/dist/src/core/manifest-helpers.js +0 -120
- /package/dist/src/core/{lint-projection.d.ts → patch-lint-projection.d.ts} +0 -0
- /package/dist/src/core/{lint-projection.js → patch-lint-projection.js} +0 -0
- /package/dist/src/core/{register-test-manifest.d.ts → register-browser-test.d.ts} +0 -0
|
@@ -5,14 +5,15 @@ import { auditBuildArtifacts } from '../core/build-audit.js';
|
|
|
5
5
|
import { readBuildBaseline, writeBuildBaseline } from '../core/build-baseline.js';
|
|
6
6
|
import { describeSignalShapedExit, prepareBuildEnvironment } from '../core/build-prepare.js';
|
|
7
7
|
import { getProjectPaths, loadConfig } from '../core/config.js';
|
|
8
|
+
import { assertEngineExists } from '../core/engine-precondition.js';
|
|
8
9
|
import { withEngineSessionLock } from '../core/engine-session-lock.js';
|
|
9
10
|
import { attemptMozinfoRewrite, build, buildArtifactMismatchMessage, buildUI, hasBuildArtifacts, hasRunnableBundle, runMach, withBuildLock, } from '../core/mach.js';
|
|
10
11
|
import { buildHarnessCrashMessage } from '../core/test-harness-crash.js';
|
|
11
12
|
import { formatToolchainMismatchMessage, runToolchainPreflight, } from '../core/toolchain-preflight.js';
|
|
12
|
-
import { GeneralError } from '../errors/base.js';
|
|
13
|
+
import { GeneralError, InvalidArgumentError } from '../errors/base.js';
|
|
13
14
|
import { AmbiguousBuildArtifactsError, BuildError } from '../errors/build.js';
|
|
14
15
|
import { toError } from '../utils/errors.js';
|
|
15
|
-
import { checkDiskSpace
|
|
16
|
+
import { checkDiskSpace } from '../utils/fs.js';
|
|
16
17
|
import { error, info, intro, outro, spinner, verbose, warn } from '../utils/logger.js';
|
|
17
18
|
import { addWaitLockOption, pickDefined, resolveWaitLockSeconds } from '../utils/options.js';
|
|
18
19
|
import { isPositiveInteger } from '../utils/validation.js';
|
|
@@ -68,7 +69,7 @@ function resolveJobCount(options, configJobs) {
|
|
|
68
69
|
return undefined;
|
|
69
70
|
}
|
|
70
71
|
if (!isPositiveInteger(jobs)) {
|
|
71
|
-
throw new
|
|
72
|
+
throw new InvalidArgumentError('Build jobs must be a positive integer', '--jobs');
|
|
72
73
|
}
|
|
73
74
|
return jobs;
|
|
74
75
|
}
|
|
@@ -176,16 +177,13 @@ export async function buildCommand(projectRoot, options) {
|
|
|
176
177
|
// Disk space pre-flight: a full Firefox build can be ~20 GB
|
|
177
178
|
await checkDiskSpace(projectRoot, 20 * 1024 * 1024 * 1024, warn);
|
|
178
179
|
// Check if engine exists
|
|
179
|
-
|
|
180
|
-
throw new GeneralError('Firefox source not found. Run "fireforge download" first.');
|
|
181
|
-
}
|
|
180
|
+
await assertEngineExists(paths.engine);
|
|
182
181
|
// Toolchain preflight: compare the minimums the tree itself declares
|
|
183
|
-
// (cbindgen / rust) against the host binaries mach configure will
|
|
184
|
-
//
|
|
185
|
-
//
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
// can fail here; anything uncertain proceeds to mach, where the
|
|
182
|
+
// (cbindgen / rust) against the host binaries mach configure will resolve,
|
|
183
|
+
// and fail fast naming `fireforge bootstrap` instead of dying ~8s into
|
|
184
|
+
// configure with mach's "./mach bootstrap" remediation text. Fail-soft by
|
|
185
|
+
// design: only a definitively parsed minimum vs a definitively probed host
|
|
186
|
+
// version can fail here; anything uncertain proceeds to mach, where the
|
|
189
187
|
// mach-error-hints translator still names the right remedy.
|
|
190
188
|
const toolchainMismatches = await runToolchainPreflight(paths.engine);
|
|
191
189
|
if (toolchainMismatches.length > 0) {
|
|
@@ -257,13 +255,12 @@ export async function buildCommand(projectRoot, options) {
|
|
|
257
255
|
try {
|
|
258
256
|
// Hold the per-project build lock across the mach invocation so two
|
|
259
257
|
// overlapping `fireforge build` / `fireforge build --ui` commands
|
|
260
|
-
// against the same engine tree serialise instead of racing through
|
|
261
|
-
//
|
|
262
|
-
//
|
|
263
|
-
//
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
// refusal naming the holder PID.
|
|
258
|
+
// against the same engine tree serialise instead of racing through the
|
|
259
|
+
// same obj-*. A `build --ui` launched during an in-progress full build
|
|
260
|
+
// otherwise hits `No rule to make target 'XUL'` in mach — the
|
|
261
|
+
// downstream consequence of an incomplete backend, with no clue that a
|
|
262
|
+
// concurrent build caused it. The lock turns the second invocation's
|
|
263
|
+
// failure into an explicit refusal naming the holder PID.
|
|
267
264
|
result = await withBuildLock(projectRoot, async () => {
|
|
268
265
|
if (options.ui) {
|
|
269
266
|
return buildUI(paths.engine);
|
|
@@ -290,24 +287,20 @@ export async function buildCommand(projectRoot, options) {
|
|
|
290
287
|
: '';
|
|
291
288
|
throw new BuildError(crashPreamble + buildFailureDiagnostics(result, paths.engine, buildCheck.objDir, machCommand), machCommand);
|
|
292
289
|
}
|
|
293
|
-
// Tool-managed branding edits that land on `browser/moz.configure`
|
|
294
|
-
//
|
|
295
|
-
//
|
|
296
|
-
// completed cleanly:
|
|
290
|
+
// Tool-managed branding edits that land on `browser/moz.configure` before
|
|
291
|
+
// the build cause mach's post-build guard to print one of two banners that
|
|
292
|
+
// read like build failures even though the build completed cleanly:
|
|
297
293
|
//
|
|
298
294
|
// 1) "config.status is out of date with respect to ..."
|
|
299
295
|
// 2) "Config object not found by mach. / Configure complete! /
|
|
300
296
|
// Be sure to run |mach build| to pick up any changes."
|
|
301
297
|
//
|
|
302
|
-
//
|
|
303
|
-
//
|
|
304
|
-
//
|
|
305
|
-
//
|
|
306
|
-
//
|
|
307
|
-
//
|
|
308
|
-
// through the same annotation, emitted BEFORE FireForge's outro so
|
|
309
|
-
// the operator's last terminal line is the explanation, not the
|
|
310
|
-
// confusing mach guard text.
|
|
298
|
+
// Matching only (1) leaves operators on the (2) path seeing mach's own
|
|
299
|
+
// "Configure complete!" and "run |mach build|" lines unexplained between
|
|
300
|
+
// mach's "Your build was successful!" and FireForge's "Build completed in
|
|
301
|
+
// Xm Ys" outro — a contradictory tail. Both shapes route through the same
|
|
302
|
+
// annotation, emitted BEFORE FireForge's outro so the operator's last
|
|
303
|
+
// terminal line is the explanation, not the confusing mach guard text.
|
|
311
304
|
const staleConfigurePatterns = [
|
|
312
305
|
/config\.status is out of date/i,
|
|
313
306
|
/Config object not found by mach\.[\s\S]*Configure complete!/i,
|
|
@@ -91,10 +91,10 @@ export async function configCommand(projectRoot, key, value, options = {}) {
|
|
|
91
91
|
if (value === undefined) {
|
|
92
92
|
// Get mode — read the raw document rather than the validated config so
|
|
93
93
|
// keys persisted via `fireforge config <key> --force` remain readable.
|
|
94
|
-
// `validateConfig` builds a typed clone containing only the known
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
//
|
|
94
|
+
// `validateConfig` builds a typed clone containing only the known schema
|
|
95
|
+
// fields, so relying on it here would hide forced-write keys and surface
|
|
96
|
+
// "Unknown config key" even though the key sits plainly inside
|
|
97
|
+
// fireforge.json.
|
|
98
98
|
const rawConfig = await loadRawConfigDocument(projectRoot);
|
|
99
99
|
const currentValue = getNestedValue(rawConfig, key);
|
|
100
100
|
if (currentValue === undefined) {
|
|
@@ -124,43 +124,36 @@ export async function configCommand(projectRoot, key, value, options = {}) {
|
|
|
124
124
|
let unchanged;
|
|
125
125
|
try {
|
|
126
126
|
// Serialise the read → mutate → write round-trip behind the sidecar
|
|
127
|
-
// config lock so two concurrent `fireforge config` invocations
|
|
127
|
+
// config lock so two concurrent `fireforge config` invocations cannot
|
|
128
128
|
// each read the pre-state, mutate their own copy, and clobber each
|
|
129
|
-
// other on write
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
// were never enough on their own — the lost update happens before
|
|
134
|
-
// the rename, inside the read-modify step. Readers stay lock-free
|
|
135
|
-
// (see `withConfigFileLock` docstring).
|
|
129
|
+
// other on write — both exiting 0 with one key silently lost. Atomic
|
|
130
|
+
// file writes (temp + rename) are not enough on their own: the lost
|
|
131
|
+
// update happens before the rename, inside the read-modify step.
|
|
132
|
+
// Readers stay lock-free (see `withConfigFileLock`).
|
|
136
133
|
unchanged = await withConfigFileLock(projectRoot, async () => {
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
-
// through `
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
// the raw on-disk document so forced-keys round-trip the same
|
|
145
|
-
// as known keys.
|
|
134
|
+
// Short-circuit when the new value matches the current on-disk
|
|
135
|
+
// value. Running every set through `mutateConfig` + `writeConfig`
|
|
136
|
+
// round-trips through `JSON.stringify` and rewrites the file even
|
|
137
|
+
// when nothing changed semantically, reordering top-level keys
|
|
138
|
+
// (`license`, `markerComment`, …) on every harmless re-set. The
|
|
139
|
+
// check uses the raw on-disk document so forced keys round-trip the
|
|
140
|
+
// same as known keys.
|
|
146
141
|
const rawConfig = await loadRawConfigDocument(projectRoot);
|
|
147
142
|
const currentValue = getNestedValue(rawConfig, key);
|
|
148
143
|
if (deepEqual(currentValue, parsedValue)) {
|
|
149
144
|
return true;
|
|
150
145
|
}
|
|
151
|
-
// `--force` is
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
//
|
|
155
|
-
// skip validation for genuinely unknown key paths.
|
|
146
|
+
// `--force` is an escape hatch for *unknown* keys; it must not also
|
|
147
|
+
// let the user write a structurally invalid value for a *known* key.
|
|
148
|
+
// Strict validation applies whenever the key is listed in
|
|
149
|
+
// SUPPORTED_CONFIG_PATHS, regardless of --force.
|
|
156
150
|
//
|
|
157
151
|
// BOTH branches seed the mutation from the raw on-disk document.
|
|
158
|
-
//
|
|
159
|
-
// `validateConfig
|
|
160
|
-
//
|
|
161
|
-
//
|
|
162
|
-
//
|
|
163
|
-
// branch's comment described this exact hazard for its own path).
|
|
152
|
+
// Round-tripping the known-key branch through `loadConfig` →
|
|
153
|
+
// `validateConfig` builds a typed clone containing only the known
|
|
154
|
+
// schema fields, so any ordinary `fireforge config <key> <value>`
|
|
155
|
+
// would silently drop every previously --force-written key from
|
|
156
|
+
// fireforge.json.
|
|
164
157
|
if (options.force && !keyIsKnown) {
|
|
165
158
|
const updatedConfig = mutateConfig(rawConfig, key, parsedValue, true);
|
|
166
159
|
await writeConfigDocument(projectRoot, updatedConfig);
|
|
@@ -181,10 +174,10 @@ export async function configCommand(projectRoot, key, value, options = {}) {
|
|
|
181
174
|
catch (error) {
|
|
182
175
|
// Only value/validation problems are the user's "invalid value".
|
|
183
176
|
// Lock-acquisition timeouts and I/O failures must keep their own
|
|
184
|
-
// types
|
|
185
|
-
// "<key>"`
|
|
186
|
-
//
|
|
187
|
-
//
|
|
177
|
+
// types and messages — re-labelling a lock timeout as `Invalid value
|
|
178
|
+
// for "<key>"` points diagnosis at the value (and returns the wrong
|
|
179
|
+
// exit-code class) when the real problem is a concurrent fireforge
|
|
180
|
+
// process holding the config lock.
|
|
188
181
|
if (error instanceof ConfigError) {
|
|
189
182
|
throw new InvalidArgumentError(`Invalid value for "${key}": ${toError(error).message}`, key);
|
|
190
183
|
}
|
|
@@ -200,11 +193,11 @@ export async function configCommand(projectRoot, key, value, options = {}) {
|
|
|
200
193
|
outro('');
|
|
201
194
|
}
|
|
202
195
|
/**
|
|
203
|
-
* Structural equality check covering the shapes
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
196
|
+
* Structural equality check covering the shapes `fireforge config` accepts:
|
|
197
|
+
* primitives (strings, numbers, booleans), `null`, arrays of primitives, and
|
|
198
|
+
* nested objects. Used to short-circuit no-op writes — when the parsed value
|
|
199
|
+
* matches the current on-disk value, the mutate + write step is skipped
|
|
200
|
+
* entirely.
|
|
208
201
|
*/
|
|
209
202
|
function deepEqual(a, b) {
|
|
210
203
|
if (a === b)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { confirm } from '@clack/prompts';
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import { getProjectPaths } from '../core/config.js';
|
|
5
|
+
import { stdioIsInteractive } from '../core/destructive.js';
|
|
5
6
|
import { applyDiscardBaseline, describeConflictWarning, describeDiscardBaseline, describeDiscardOutcome, planDiscardBaselines, planUpstreamDiscards, summarizeDiscardBaselines, } from '../core/discard-baseline.js';
|
|
6
7
|
import { assertEngineGitReady } from '../core/engine-precondition.js';
|
|
7
8
|
import { collectFurnaceManagedPrefixes } from '../core/furnace-config.js';
|
|
@@ -18,7 +19,7 @@ import { pickDefined } from '../utils/options.js';
|
|
|
18
19
|
async function confirmDiscard(message, hint, options) {
|
|
19
20
|
if (options.yes || options.dryRun)
|
|
20
21
|
return true;
|
|
21
|
-
const isInteractive =
|
|
22
|
+
const isInteractive = stdioIsInteractive();
|
|
22
23
|
if (!isInteractive) {
|
|
23
24
|
throw new InvalidArgumentError('Interactive confirmation not available. Use --yes flag to discard without confirmation.', hint);
|
|
24
25
|
}
|
|
@@ -130,14 +131,12 @@ export async function discardCommand(projectRoot, file, options = {}) {
|
|
|
130
131
|
const statusEntries = await expandUntrackedDirectoryEntries(paths.engine, await getWorkingTreeStatus(paths.engine));
|
|
131
132
|
const statusEntry = statusEntries.find((entry) => entry.file === file || entry.originalPath === file);
|
|
132
133
|
// Directory recursion fallback: when the explicit path does not match a
|
|
133
|
-
// single status entry but DOES correspond to one or more entries below
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
//
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
-
// back to non-FireForge cleanup commands. Match against the
|
|
140
|
-
// directory-with-trailing-slash form so a path like `foo/bar` doesn't
|
|
134
|
+
// single status entry but DOES correspond to one or more entries below it,
|
|
135
|
+
// treat the input as a directory and discard everything inside. Otherwise
|
|
136
|
+
// `discard <dir> --yes` fails with "no changes to discard" even though
|
|
137
|
+
// `status --unmanaged` lists files under that directory, forcing the
|
|
138
|
+
// operator to discard each file individually. Match against the
|
|
139
|
+
// directory-with-trailing-slash form so a path like `foo/bar` does not
|
|
141
140
|
// accidentally match `foo/bar2/file`.
|
|
142
141
|
if (!statusEntry) {
|
|
143
142
|
// Normalize the operator's input once: `discard foo/` (or `foo//`) must
|
|
@@ -88,29 +88,15 @@ export interface DoctorCheckDefinition {
|
|
|
88
88
|
fix?: string;
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
91
|
-
* Resolves a {@link DoctorCheck} to its effective severity
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* 1. `severity`, when present, is authoritative — regardless of `passed`.
|
|
96
|
-
* 2. Without `severity`, `passed: false` is an error unless `warning: true`
|
|
97
|
-
* downgrades it to a warning.
|
|
98
|
-
*
|
|
99
|
-
* This is the single implementation on purpose. Before 0.41.0 there were two
|
|
100
|
-
* and they disagreed on exactly one cell: `reportDoctorResults` consulted
|
|
101
|
-
* `warning` only inside the `passed === true` branch, so the documented
|
|
102
|
-
* downgrade produced an error and a non-zero doctor exit, while
|
|
103
|
-
* `bootstrap.ts` — reading the same array one line earlier — classified it as
|
|
104
|
-
* a warning. No in-tree producer emitted that combination (`failure()` always
|
|
105
|
-
* sets `severity: 'error'`), so the contradiction was latent rather than
|
|
106
|
-
* observable; the interface is exported, so the next hand-rolled check would
|
|
107
|
-
* have hit it.
|
|
91
|
+
* Resolves a {@link DoctorCheck} to its effective severity. `severity` is the
|
|
92
|
+
* single source of truth; this exists so every consumer of a
|
|
93
|
+
* `DoctorCheck[]` reads it the same way.
|
|
108
94
|
*/
|
|
109
95
|
export declare function resolveDoctorSeverity(check: DoctorCheck): 'ok' | 'warning' | 'error';
|
|
110
96
|
/**
|
|
111
97
|
* Builds a DoctorCheck object representing a successful "OK" check.
|
|
112
98
|
*/
|
|
113
|
-
export declare function ok(name: string): DoctorCheck;
|
|
99
|
+
export declare function ok(name: string, message?: string): DoctorCheck;
|
|
114
100
|
/**
|
|
115
101
|
* Builds a DoctorCheck object representing a warning result.
|
|
116
102
|
*/
|
|
@@ -5,55 +5,28 @@
|
|
|
5
5
|
* these symbols without creating cycles through `doctor.ts`.
|
|
6
6
|
*/
|
|
7
7
|
/**
|
|
8
|
-
* Resolves a {@link DoctorCheck} to its effective severity
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* 1. `severity`, when present, is authoritative — regardless of `passed`.
|
|
13
|
-
* 2. Without `severity`, `passed: false` is an error unless `warning: true`
|
|
14
|
-
* downgrades it to a warning.
|
|
15
|
-
*
|
|
16
|
-
* This is the single implementation on purpose. Before 0.41.0 there were two
|
|
17
|
-
* and they disagreed on exactly one cell: `reportDoctorResults` consulted
|
|
18
|
-
* `warning` only inside the `passed === true` branch, so the documented
|
|
19
|
-
* downgrade produced an error and a non-zero doctor exit, while
|
|
20
|
-
* `bootstrap.ts` — reading the same array one line earlier — classified it as
|
|
21
|
-
* a warning. No in-tree producer emitted that combination (`failure()` always
|
|
22
|
-
* sets `severity: 'error'`), so the contradiction was latent rather than
|
|
23
|
-
* observable; the interface is exported, so the next hand-rolled check would
|
|
24
|
-
* have hit it.
|
|
8
|
+
* Resolves a {@link DoctorCheck} to its effective severity. `severity` is the
|
|
9
|
+
* single source of truth; this exists so every consumer of a
|
|
10
|
+
* `DoctorCheck[]` reads it the same way.
|
|
25
11
|
*/
|
|
26
12
|
export function resolveDoctorSeverity(check) {
|
|
27
|
-
|
|
28
|
-
return check.severity;
|
|
29
|
-
}
|
|
30
|
-
if (check.warning) {
|
|
31
|
-
return 'warning';
|
|
32
|
-
}
|
|
33
|
-
return check.passed ? 'ok' : 'error';
|
|
13
|
+
return check.severity;
|
|
34
14
|
}
|
|
35
15
|
/**
|
|
36
16
|
* Builds a DoctorCheck object representing a successful "OK" check.
|
|
37
17
|
*/
|
|
38
|
-
export function ok(name) {
|
|
39
|
-
return { name,
|
|
18
|
+
export function ok(name, message = 'OK') {
|
|
19
|
+
return { name, severity: 'ok', message };
|
|
40
20
|
}
|
|
41
21
|
/**
|
|
42
22
|
* Builds a DoctorCheck object representing a warning result.
|
|
43
23
|
*/
|
|
44
24
|
export function warning(name, message, fix) {
|
|
45
|
-
return {
|
|
46
|
-
name,
|
|
47
|
-
passed: true,
|
|
48
|
-
severity: 'warning',
|
|
49
|
-
warning: true,
|
|
50
|
-
message,
|
|
51
|
-
...(fix ? { fix } : {}),
|
|
52
|
-
};
|
|
25
|
+
return { name, severity: 'warning', message, ...(fix ? { fix } : {}) };
|
|
53
26
|
}
|
|
54
27
|
/**
|
|
55
28
|
* Builds a DoctorCheck object representing a failure result.
|
|
56
29
|
*/
|
|
57
30
|
export function failure(name, message, fix) {
|
|
58
|
-
return { name,
|
|
31
|
+
return { name, severity: 'error', message, ...(fix ? { fix } : {}) };
|
|
59
32
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { isAbsolute, resolve } from 'node:path';
|
|
3
3
|
import { pathExists } from '../utils/fs.js';
|
|
4
4
|
import { exec, findExecutable } from '../utils/process.js';
|
|
5
|
-
import { failure, warning } from './doctor-check-core.js';
|
|
5
|
+
import { failure, ok, warning } from './doctor-check-core.js';
|
|
6
6
|
async function resolveDeclaredTool(projectRoot, tool) {
|
|
7
7
|
if (tool.path !== undefined) {
|
|
8
8
|
const candidate = isAbsolute(tool.path) ? tool.path : resolve(projectRoot, tool.path);
|
|
@@ -32,7 +32,7 @@ async function runExternalToolchainChecks(ctx) {
|
|
|
32
32
|
const label = `External toolchain: ${toolchain.name}/${tool.name}`;
|
|
33
33
|
const found = await resolveDeclaredTool(ctx.projectRoot, tool);
|
|
34
34
|
if (found !== undefined) {
|
|
35
|
-
rows.push(
|
|
35
|
+
rows.push(ok(label, `OK (${found})`));
|
|
36
36
|
continue;
|
|
37
37
|
}
|
|
38
38
|
const required = tool.required !== false;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Furnace config sync" doctor check.
|
|
3
|
+
*
|
|
4
|
+
* Surfaces orphaned component directories on disk whose names are missing
|
|
5
|
+
* from `furnace.json` — typically the concurrent-override race, where two
|
|
6
|
+
* parallel `furnace override` commands both leave their directory on disk
|
|
7
|
+
* but only the second reaches `writeFurnaceConfig`. Under
|
|
8
|
+
* `--repair-furnace`, override orphans are re-registered from the
|
|
9
|
+
* `override.json` sidecar the command wrote during the copy phase; custom
|
|
10
|
+
* orphans are listed for the operator to either re-run `furnace create`
|
|
11
|
+
* against or delete manually, because custom components have no similar
|
|
12
|
+
* persisted metadata.
|
|
13
|
+
*
|
|
14
|
+
* Lives in a sibling module to keep `doctor-furnace.ts` under the per-file
|
|
15
|
+
* LOC budget.
|
|
16
|
+
*/
|
|
17
|
+
import type { DoctorCheckDefinition } from './doctor-check-core.js';
|
|
18
|
+
export declare const furnaceConfigSyncCheck: DoctorCheckDefinition;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
/**
|
|
3
|
-
* "Furnace
|
|
3
|
+
* "Furnace config sync" doctor check.
|
|
4
4
|
*
|
|
5
5
|
* Surfaces orphaned component directories on disk whose names are missing
|
|
6
|
-
* from `furnace.json
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
6
|
+
* from `furnace.json` — typically the concurrent-override race, where two
|
|
7
|
+
* parallel `furnace override` commands both leave their directory on disk
|
|
8
|
+
* but only the second reaches `writeFurnaceConfig`. Under
|
|
9
|
+
* `--repair-furnace`, override orphans are re-registered from the
|
|
10
|
+
* `override.json` sidecar the command wrote during the copy phase; custom
|
|
11
|
+
* orphans are listed for the operator to either re-run `furnace create`
|
|
12
|
+
* against or delete manually, because custom components have no similar
|
|
13
|
+
* persisted metadata.
|
|
14
14
|
*
|
|
15
|
-
* Lives in a sibling module to keep `doctor-furnace.ts` under the
|
|
16
|
-
*
|
|
15
|
+
* Lives in a sibling module to keep `doctor-furnace.ts` under the per-file
|
|
16
|
+
* LOC budget.
|
|
17
17
|
*/
|
|
18
18
|
import { readdir, rmdir } from 'node:fs/promises';
|
|
19
19
|
import { join } from 'node:path';
|
|
@@ -43,12 +43,13 @@ async function listComponentDirs(dir) {
|
|
|
43
43
|
}
|
|
44
44
|
async function recoverOverrideConfig(overrideDir, name) {
|
|
45
45
|
// `furnace override` writes `override.json` alongside the copied files.
|
|
46
|
-
// That sidecar is enough to reconstruct the furnace.json entry lost to
|
|
47
|
-
//
|
|
48
|
-
// outer-snapshot config
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
// the
|
|
46
|
+
// That sidecar is enough to reconstruct the furnace.json entry lost to a
|
|
47
|
+
// concurrent-write race, where the second override writes back the
|
|
48
|
+
// outer-snapshot config and drops the sibling write's addition.
|
|
49
|
+
//
|
|
50
|
+
// No `pathExists` precheck: it collapses "absent" and "unreadable" into
|
|
51
|
+
// the same `false`, and both outcomes lead here anyway — a missing file
|
|
52
|
+
// lands in the catch below with the same `undefined` result.
|
|
52
53
|
const sidecarPath = join(overrideDir, name, 'override.json');
|
|
53
54
|
try {
|
|
54
55
|
const raw = await readJson(sidecarPath);
|
|
@@ -148,12 +149,12 @@ async function repairOrphans(projectRoot, orphans) {
|
|
|
148
149
|
return outcome;
|
|
149
150
|
const lockPath = getFurnaceLockPath(projectRoot);
|
|
150
151
|
// One catch covers four distinct phases; naming the one that failed keeps
|
|
151
|
-
// the report honest — a lock timeout
|
|
152
|
+
// the report honest — a lock timeout otherwise renders as "failed while
|
|
152
153
|
// writing furnace.json", the phase least likely to have been reached.
|
|
153
154
|
// Held in an object rather than two `let`s: the lock callback mutates them
|
|
154
155
|
// from inside a closure, and TS's control-flow analysis does not propagate
|
|
155
|
-
// that through the call — it would narrow both to their initial literals
|
|
156
|
-
// the catch below.
|
|
156
|
+
// that through the call — it would narrow both to their initial literals
|
|
157
|
+
// in the catch below.
|
|
157
158
|
const progress = { phase: 'waiting for the furnace lock', persisted: false };
|
|
158
159
|
try {
|
|
159
160
|
await withFileLock(lockPath, async () => {
|
|
@@ -246,8 +247,8 @@ async function deleteEmptyCustomOrphans(projectRoot, freshConfig, customNames, o
|
|
|
246
247
|
}
|
|
247
248
|
}
|
|
248
249
|
}
|
|
249
|
-
export const
|
|
250
|
-
name: 'Furnace
|
|
250
|
+
export const furnaceConfigSyncCheck = {
|
|
251
|
+
name: 'Furnace config sync',
|
|
251
252
|
dependsOn: ['Furnace configuration'],
|
|
252
253
|
skipIf: (ctx) => !ctx.furnaceConfigExists || !ctx.furnaceConfig,
|
|
253
254
|
run: async (ctx) => {
|
|
@@ -258,15 +259,15 @@ export const furnaceManifestSyncCheck = {
|
|
|
258
259
|
const overrideCount = orphans.overrides.length;
|
|
259
260
|
const customCount = orphans.customNames.length;
|
|
260
261
|
if (overrideCount === 0 && customCount === 0) {
|
|
261
|
-
return ok('Furnace
|
|
262
|
+
return ok('Furnace config sync');
|
|
262
263
|
}
|
|
263
264
|
const summary = formatOrphanSummary(orphans);
|
|
264
265
|
if (!ctx.options.repairFurnace) {
|
|
265
|
-
return warning('Furnace
|
|
266
|
+
return warning('Furnace config sync', summary, 'Run "fireforge doctor --repair-furnace" to re-register override orphans from their override.json sidecars (custom orphans are listed for manual follow-up).');
|
|
266
267
|
}
|
|
267
268
|
const repairResult = await repairOrphans(ctx.projectRoot, orphans);
|
|
268
269
|
if (repairResult.repairError) {
|
|
269
|
-
return failure('Furnace
|
|
270
|
+
return failure('Furnace config sync', `Repair failed ${repairResult.repairError}`, 'Fix the underlying error and retry the doctor command.');
|
|
270
271
|
}
|
|
271
272
|
const customRepair = repairResult;
|
|
272
273
|
const { restored, unrecoverable, reconciled } = repairResult;
|
|
@@ -288,7 +289,7 @@ export const furnaceManifestSyncCheck = {
|
|
|
288
289
|
const customErrorDetail = customRepair.errors.length > 0
|
|
289
290
|
? ` Could not inspect or delete ${customRepair.errors.length} custom orphan ${customRepair.errors.length === 1 ? 'directory' : 'directories'} (${customRepair.errors.join('; ')}).`
|
|
290
291
|
: '';
|
|
291
|
-
return warning('Furnace
|
|
292
|
+
return warning('Furnace config sync', `${restoreDetail}${unrecoverableDetail}${customDetail}${retainedCustomDetail}${customErrorDetail}${reconciledDetail}`.trim() ||
|
|
292
293
|
'Nothing to repair (orphans surfaced but all were already recoverable).');
|
|
293
294
|
},
|
|
294
295
|
};
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `doctor` check for stale furnace jar.mn registrations
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* of `doctor-furnace.ts` to keep that file within the line budget.
|
|
2
|
+
* `doctor` check for stale furnace jar.mn registrations: a component-file
|
|
3
|
+
* rename can leave the old toolkit jar.mn line pointing at the deleted file,
|
|
4
|
+
* failing every build at packaging. Split out of `doctor-furnace.ts` to keep
|
|
5
|
+
* that file within the line budget.
|
|
7
6
|
*/
|
|
8
7
|
import type { DoctorCheckDefinition } from './doctor-check-core.js';
|
|
9
8
|
/**
|
|
10
9
|
* "Furnace jar.mn registrations" check: detect widget registration lines
|
|
11
|
-
* pointing at component files that no longer exist in the workspace
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* report: doctor --repair-furnace reported success without pruning).
|
|
10
|
+
* pointing at component files that no longer exist in the workspace,
|
|
11
|
+
* typically left by a rename. These break `mach build` at packaging;
|
|
12
|
+
* `--repair-furnace` prunes them.
|
|
15
13
|
*/
|
|
16
14
|
export declare const furnaceStaleJarRegistrationCheck: DoctorCheckDefinition;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
/**
|
|
3
|
-
* `doctor` check for stale furnace jar.mn registrations
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* of `doctor-furnace.ts` to keep that file within the line budget.
|
|
3
|
+
* `doctor` check for stale furnace jar.mn registrations: a component-file
|
|
4
|
+
* rename can leave the old toolkit jar.mn line pointing at the deleted file,
|
|
5
|
+
* failing every build at packaging. Split out of `doctor-furnace.ts` to keep
|
|
6
|
+
* that file within the line budget.
|
|
8
7
|
*/
|
|
9
8
|
import { getFurnacePaths } from '../core/furnace-config.js';
|
|
10
9
|
import { findStaleJarMnEntries, pruneStaleJarMnEntries } from '../core/furnace-registration.js';
|
|
@@ -12,10 +11,9 @@ import { toError } from '../utils/errors.js';
|
|
|
12
11
|
import { failure, ok, warning } from './doctor-check-core.js';
|
|
13
12
|
/**
|
|
14
13
|
* "Furnace jar.mn registrations" check: detect widget registration lines
|
|
15
|
-
* pointing at component files that no longer exist in the workspace
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* report: doctor --repair-furnace reported success without pruning).
|
|
14
|
+
* pointing at component files that no longer exist in the workspace,
|
|
15
|
+
* typically left by a rename. These break `mach build` at packaging;
|
|
16
|
+
* `--repair-furnace` prunes them.
|
|
19
17
|
*/
|
|
20
18
|
export const furnaceStaleJarRegistrationCheck = {
|
|
21
19
|
name: 'Furnace jar.mn registrations',
|