@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
|
@@ -1,30 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Toolchain-minimum awareness for Firefox source hops.
|
|
3
3
|
*
|
|
4
|
-
* When `fireforge download --force` moves the engine to a new Firefox
|
|
5
|
-
*
|
|
6
|
-
* frequently move with it — and the first `fireforge build` then dies a
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
4
|
+
* When `fireforge download --force` moves the engine to a new Firefox MAJOR
|
|
5
|
+
* version, the tree's declared toolchain minimums (cbindgen, Rust)
|
|
6
|
+
* frequently move with it — and the first `fireforge build` then dies a few
|
|
7
|
+
* seconds into `mach configure` with a message whose remediation text names
|
|
8
|
+
* `./mach bootstrap`, the wrong tool for a FireForge-managed repo (e.g.
|
|
9
|
+
* `ERROR: cbindgen version 0.29.1 is too old. At least version 0.29.4 is
|
|
10
|
+
* required.`).
|
|
11
11
|
*
|
|
12
12
|
* Two layers:
|
|
13
|
-
* 1. {@link formatMajorVersionHopNotice} — a post-download nudge when
|
|
14
|
-
*
|
|
15
|
-
* 2. {@link runToolchainPreflight} — a cheap pre-build probe comparing
|
|
16
|
-
*
|
|
13
|
+
* 1. {@link formatMajorVersionHopNotice} — a post-download nudge when the
|
|
14
|
+
* downloaded major differs from the previously downloaded one.
|
|
15
|
+
* 2. {@link runToolchainPreflight} — a cheap pre-build probe comparing the
|
|
16
|
+
* minimums the tree itself declares against the host binaries
|
|
17
17
|
* `mach configure` will resolve, probing configure's own candidate
|
|
18
|
-
* order: env override first, then the `~/.mozbuild` state-directory
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* failure downstream.
|
|
18
|
+
* order: env override first, then the `~/.mozbuild` state-directory copy
|
|
19
|
+
* bootstrap installs, then PATH. Probing env-or-PATH alone blocks builds
|
|
20
|
+
* whose current tool lives in the state dir behind a stale PATH copy.
|
|
21
|
+
* Deliberately FAIL-SOFT: it reports a mismatch only when a minimum was
|
|
22
|
+
* positively parsed AND at least one candidate resolved AND every
|
|
23
|
+
* resolved candidate is definitively lower. Any uncertainty (file moved
|
|
24
|
+
* upstream, unparseable output, no candidate found) skips silently — the
|
|
25
|
+
* mach-error-hints translator still catches the real configure failure
|
|
26
|
+
* downstream.
|
|
28
27
|
*/
|
|
29
28
|
/** Tools the preflight knows how to probe. */
|
|
30
29
|
export type ToolchainTool = 'cbindgen' | 'rustc';
|
|
@@ -2,30 +2,29 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Toolchain-minimum awareness for Firefox source hops.
|
|
4
4
|
*
|
|
5
|
-
* When `fireforge download --force` moves the engine to a new Firefox
|
|
6
|
-
*
|
|
7
|
-
* frequently move with it — and the first `fireforge build` then dies a
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
5
|
+
* When `fireforge download --force` moves the engine to a new Firefox MAJOR
|
|
6
|
+
* version, the tree's declared toolchain minimums (cbindgen, Rust)
|
|
7
|
+
* frequently move with it — and the first `fireforge build` then dies a few
|
|
8
|
+
* seconds into `mach configure` with a message whose remediation text names
|
|
9
|
+
* `./mach bootstrap`, the wrong tool for a FireForge-managed repo (e.g.
|
|
10
|
+
* `ERROR: cbindgen version 0.29.1 is too old. At least version 0.29.4 is
|
|
11
|
+
* required.`).
|
|
12
12
|
*
|
|
13
13
|
* Two layers:
|
|
14
|
-
* 1. {@link formatMajorVersionHopNotice} — a post-download nudge when
|
|
15
|
-
*
|
|
16
|
-
* 2. {@link runToolchainPreflight} — a cheap pre-build probe comparing
|
|
17
|
-
*
|
|
14
|
+
* 1. {@link formatMajorVersionHopNotice} — a post-download nudge when the
|
|
15
|
+
* downloaded major differs from the previously downloaded one.
|
|
16
|
+
* 2. {@link runToolchainPreflight} — a cheap pre-build probe comparing the
|
|
17
|
+
* minimums the tree itself declares against the host binaries
|
|
18
18
|
* `mach configure` will resolve, probing configure's own candidate
|
|
19
|
-
* order: env override first, then the `~/.mozbuild` state-directory
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* failure downstream.
|
|
19
|
+
* order: env override first, then the `~/.mozbuild` state-directory copy
|
|
20
|
+
* bootstrap installs, then PATH. Probing env-or-PATH alone blocks builds
|
|
21
|
+
* whose current tool lives in the state dir behind a stale PATH copy.
|
|
22
|
+
* Deliberately FAIL-SOFT: it reports a mismatch only when a minimum was
|
|
23
|
+
* positively parsed AND at least one candidate resolved AND every
|
|
24
|
+
* resolved candidate is definitively lower. Any uncertainty (file moved
|
|
25
|
+
* upstream, unparseable output, no candidate found) skips silently — the
|
|
26
|
+
* mach-error-hints translator still catches the real configure failure
|
|
27
|
+
* downstream.
|
|
29
28
|
*/
|
|
30
29
|
import { execFile } from 'node:child_process';
|
|
31
30
|
import { homedir } from 'node:os';
|
|
@@ -61,16 +60,14 @@ const MINIMUM_DECLARATIONS = {
|
|
|
61
60
|
/**
|
|
62
61
|
* How each tool's host binary is resolved and its version parsed.
|
|
63
62
|
*
|
|
64
|
-
* `stateDirRelPaths` are the mach-state-directory locations
|
|
65
|
-
* bootstrap` (via mozboot) installs the tool to. mach's configure
|
|
66
|
-
* the state directory BEFORE the PATH candidates
|
|
67
|
-
* toolchain search path lists `~/.mozbuild/cbindgen/
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* (field report: PATH 0.29.1 vs mozbuild 0.29.4, minimum 0.29.4). Rust
|
|
73
|
-
* has no state-dir install — rustup owns it — so its list is empty.
|
|
63
|
+
* `stateDirRelPaths` are the mach-state-directory locations
|
|
64
|
+
* `fireforge bootstrap` (via mozboot) installs the tool to. mach's configure
|
|
65
|
+
* tries the state directory BEFORE the PATH candidates —
|
|
66
|
+
* bindgen.configure's toolchain search path lists `~/.mozbuild/cbindgen/
|
|
67
|
+
* cbindgen` first — so the probe must too. Probing only env-or-PATH fails a
|
|
68
|
+
* build configure would have accepted whenever an old `~/.cargo/bin/
|
|
69
|
+
* cbindgen` shadows a current bootstrap-installed copy. Rust has no
|
|
70
|
+
* state-dir install — rustup owns it — so its list is empty.
|
|
74
71
|
*/
|
|
75
72
|
const HOST_PROBES = {
|
|
76
73
|
// `mach configure` honours the CBINDGEN env option (bindgen.configure's
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import { existsSync } from 'node:fs';
|
|
16
16
|
import { dirname, join, resolve } from 'node:path';
|
|
17
17
|
import { GeneralError } from '../errors/base.js';
|
|
18
|
-
import { getTreeMarkerPath,
|
|
18
|
+
import { getTreeMarkerPath, readTreeMarker, } from './tree-store.js';
|
|
19
19
|
/**
|
|
20
20
|
* Per-command verdicts. `allowed` runs unconditionally; `refused` never
|
|
21
21
|
* runs in a tree; `conditional` consults `TREE_CONDITIONAL_CHECKS` with
|
|
@@ -135,7 +135,7 @@ export async function runTreeGuardHook(rootCommandName, actionCommand) {
|
|
|
135
135
|
let current = resolve(process.cwd());
|
|
136
136
|
for (let depth = 0; depth < 50; depth++) {
|
|
137
137
|
if (existsSync(join(current, 'fireforge.json'))) {
|
|
138
|
-
return { root: current, state: await
|
|
138
|
+
return { root: current, state: await readTreeMarker(current) };
|
|
139
139
|
}
|
|
140
140
|
const parent = dirname(current);
|
|
141
141
|
if (parent === current)
|
|
@@ -153,6 +153,16 @@ export async function runTreeGuardHook(rootCommandName, actionCommand) {
|
|
|
153
153
|
// evidence that we cannot tell. Treating it as "not a tree" would grant the
|
|
154
154
|
// full mutating command set to a snapshot on the strength of a file that
|
|
155
155
|
// failed to parse, which is exactly backwards for a default-deny guard.
|
|
156
|
+
// A marker from a NEWER FireForge is not damaged, so the corrupt branch's
|
|
157
|
+
// remedies — recreate the tree, delete the stray marker — are actively
|
|
158
|
+
// wrong for it. Refuse with the upgrade instruction instead, and do NOT
|
|
159
|
+
// offer --ignore-corrupt-tree-marker: proceeding would mean acting on a
|
|
160
|
+
// marker whose fields this build does not understand.
|
|
161
|
+
if (state.kind === 'unsupported') {
|
|
162
|
+
if (TREE_COMMAND_VERDICTS[commandName] === 'allowed')
|
|
163
|
+
return;
|
|
164
|
+
throw new GeneralError(`Refusing "${[commandName, ...subcommands].join(' ')}": ${state.reason}`);
|
|
165
|
+
}
|
|
156
166
|
if (state.kind === 'corrupt') {
|
|
157
167
|
if (options['ignoreCorruptTreeMarker'] === true)
|
|
158
168
|
return;
|
|
@@ -33,13 +33,13 @@ export declare function withTreeLifecycleLock<T>(primaryRoot: string, operation:
|
|
|
33
33
|
* Outcome of reading a tree marker.
|
|
34
34
|
*
|
|
35
35
|
* The three states must stay distinct because they carry opposite safety
|
|
36
|
-
* meanings. `absent` means "this directory is not a tree", which is what
|
|
37
|
-
* every mutating command run. `corrupt` means "this directory claims to
|
|
38
|
-
* tree but we cannot read the claim" — collapsing it into `absent` (as
|
|
39
|
-
* `undefined` return does) hands a snapshot the full mutating command
|
|
40
|
-
* the strength of a file we failed to parse, inverting
|
|
41
|
-
* default-deny design. Deleting one field from a marker
|
|
42
|
-
* `reset` inside a clone.
|
|
36
|
+
* meanings. `absent` means "this directory is not a tree", which is what
|
|
37
|
+
* lets every mutating command run. `corrupt` means "this directory claims to
|
|
38
|
+
* be a tree but we cannot read the claim" — collapsing it into `absent` (as
|
|
39
|
+
* a bare `undefined` return does) hands a snapshot the full mutating command
|
|
40
|
+
* set on the strength of a file we failed to parse, inverting
|
|
41
|
+
* `tree-guard.ts`'s default-deny design. Deleting one field from a marker is
|
|
42
|
+
* enough to make `reset` runnable inside a clone.
|
|
43
43
|
*/
|
|
44
44
|
export type TreeMarkerRead = {
|
|
45
45
|
kind: 'absent';
|
|
@@ -49,31 +49,45 @@ export type TreeMarkerRead = {
|
|
|
49
49
|
} | {
|
|
50
50
|
kind: 'corrupt';
|
|
51
51
|
reason: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Written by a NEWER FireForge. Distinct from `corrupt` because the remedy
|
|
55
|
+
* is the opposite: upgrade, do not delete.
|
|
56
|
+
*/
|
|
57
|
+
| {
|
|
58
|
+
kind: 'unsupported';
|
|
59
|
+
reason: string;
|
|
52
60
|
};
|
|
53
61
|
/** Absolute path of a root's tree marker. */
|
|
54
62
|
export declare function getTreeMarkerPath(root: string): string;
|
|
55
63
|
/**
|
|
56
64
|
* Reads the tree marker for a project root, distinguishing "not a tree" from
|
|
57
|
-
* "a tree whose marker we could not read". Callers that make a safety
|
|
58
|
-
* (the guard hook, the no-nesting refusal) must use this rather
|
|
59
|
-
* {@link
|
|
65
|
+
* "a tree whose marker we could not read". Callers that make a safety
|
|
66
|
+
* decision (the guard hook, the no-nesting refusal) must use this rather
|
|
67
|
+
* than {@link tryReadTreeMarker}.
|
|
60
68
|
*
|
|
61
69
|
* Only ENOENT/ENOTDIR mean `absent`: any other probe failure (EACCES on the
|
|
62
70
|
* `.fireforge` directory, EIO, …) reports `corrupt`, because "we cannot read
|
|
63
71
|
* the marker" is not evidence that there is no marker — a `pathExists`
|
|
64
|
-
* pre-check
|
|
65
|
-
*
|
|
72
|
+
* pre-check classifies a tree with an unreadable `.fireforge` as `absent`
|
|
73
|
+
* and hands it the full mutating command set.
|
|
66
74
|
*/
|
|
67
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Naming convention for state-file readers:
|
|
77
|
+
* - `readX(): Promise<XRead>` — the TRI-STATE read: absent, corrupt, or
|
|
78
|
+
* valid.
|
|
79
|
+
* - `tryReadX(): Promise<X | undefined>` — collapses absent and corrupt.
|
|
80
|
+
*/
|
|
81
|
+
export declare function readTreeMarker(root: string): Promise<TreeMarkerRead>;
|
|
68
82
|
/**
|
|
69
83
|
* Reads the tree marker for a project root, or undefined when it is absent
|
|
70
84
|
* OR unreadable.
|
|
71
85
|
*
|
|
72
86
|
* For display and best-effort paths only (`tree list` renders an unreadable
|
|
73
87
|
* marker as staleness 'unknown'). Anything that decides whether a mutation may
|
|
74
|
-
* proceed must call {@link
|
|
88
|
+
* proceed must call {@link readTreeMarker} and handle `corrupt`.
|
|
75
89
|
*/
|
|
76
|
-
export declare function
|
|
90
|
+
export declare function tryReadTreeMarker(root: string): Promise<TreeMarker | undefined>;
|
|
77
91
|
/**
|
|
78
92
|
* Refuses a build-less in-tree `test` when the objdir preflight found is not
|
|
79
93
|
* the one this tree's marker vouched for as rewritten-and-reconfigured. A
|
|
@@ -92,18 +106,18 @@ export declare function computePrimaryFingerprint(primaryRoot: string): Promise<
|
|
|
92
106
|
/** Validates a tree name: one path segment, no traversal. */
|
|
93
107
|
export declare function assertValidTreeName(name: string): void;
|
|
94
108
|
/**
|
|
95
|
-
* Materialises the tree at `treeRoot` from `primaryRoot` using
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* touches metadata for millions of
|
|
101
|
-
* that objdir is included
|
|
102
|
-
* refuses symlinked or engine-escaping objdirs
|
|
103
|
-
* rewritten to the tree
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
109
|
+
* Materialises the tree at `treeRoot` from `primaryRoot` using `capability`
|
|
110
|
+
* ('none' = plain copy, already gated on --force-copy by the caller).
|
|
111
|
+
*
|
|
112
|
+
* The engine is cloned one TOP-LEVEL entry at a time so unwanted `obj-*`
|
|
113
|
+
* directories are never traversed or materialised — on a Firefox tree, even
|
|
114
|
+
* CoW-cloning and then deleting an objdir touches metadata for millions of
|
|
115
|
+
* build outputs. With `withObjdir` exactly that objdir is included (after
|
|
116
|
+
* {@link assertCloneSafeObjdir} refuses symlinked or engine-escaping objdirs
|
|
117
|
+
* before any copying), rewritten to the tree, and reconfigured in-tree via
|
|
118
|
+
* the caller-supplied `reconfigure` hook. A fresh `.fireforge/` is created
|
|
119
|
+
* with only `state.json` (when present), the last-build baseline (withObjdir
|
|
120
|
+
* only), and the tree marker.
|
|
107
121
|
*/
|
|
108
122
|
export declare function cloneTree(args: {
|
|
109
123
|
primaryRoot: string;
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { createHash } from 'node:crypto';
|
|
15
15
|
import { existsSync } from 'node:fs';
|
|
16
|
-
import { lstat, readdir, readFile, realpath, rm } from 'node:fs/promises';
|
|
16
|
+
import { cp, lstat, mkdir, readdir, readFile, realpath, rm } from 'node:fs/promises';
|
|
17
17
|
import { basename, join, resolve, sep } from 'node:path';
|
|
18
18
|
import { GeneralError } from '../errors/base.js';
|
|
19
19
|
import { mapWithConcurrency } from '../utils/concurrency.js';
|
|
@@ -26,6 +26,7 @@ import { LOCK_PID_FILE, withFileLock } from './file-lock.js';
|
|
|
26
26
|
import { git } from './git-base.js';
|
|
27
27
|
import { getAllDiff } from './git-diff.js';
|
|
28
28
|
import { attemptMozinfoRewrite } from './mach-build-artifacts.js';
|
|
29
|
+
import { checkDocumentVersion, describeNewerDocument } from './state-file.js';
|
|
29
30
|
import { cloneEntry } from './tree-cow.js';
|
|
30
31
|
const TREE_MARKER_FILENAME = 'tree.json';
|
|
31
32
|
const TREES_DIRNAME = 'trees';
|
|
@@ -56,16 +57,18 @@ export async function withTreeLifecycleLock(primaryRoot, operation) {
|
|
|
56
57
|
/**
|
|
57
58
|
* Validates every field of a tree marker.
|
|
58
59
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* reaches a user-facing refusal message
|
|
60
|
+
* Checking only `schemaVersion` and `name` and asserting the rest is not
|
|
61
|
+
* enough: the unvalidated fields are consumed unguarded. `primaryRoot`
|
|
62
|
+
* reaches a user-facing refusal message in `tree-guard.ts`, and
|
|
62
63
|
* `engineHead`/`patchesFingerprint` feed the staleness compare, where an
|
|
63
64
|
* `undefined` from a truncated marker reports every tree as stale.
|
|
64
65
|
*/
|
|
66
|
+
/** Schema version this build writes and understands. */
|
|
67
|
+
const TREE_MARKER_SCHEMA_VERSION = 1;
|
|
65
68
|
function isTreeMarker(value) {
|
|
66
69
|
if (!isObject(value))
|
|
67
70
|
return false;
|
|
68
|
-
return (value['schemaVersion'] ===
|
|
71
|
+
return (value['schemaVersion'] === TREE_MARKER_SCHEMA_VERSION &&
|
|
69
72
|
typeof value['name'] === 'string' &&
|
|
70
73
|
typeof value['primaryRoot'] === 'string' &&
|
|
71
74
|
typeof value['createdAt'] === 'string' &&
|
|
@@ -82,20 +85,39 @@ export function getTreeMarkerPath(root) {
|
|
|
82
85
|
}
|
|
83
86
|
/**
|
|
84
87
|
* Reads the tree marker for a project root, distinguishing "not a tree" from
|
|
85
|
-
* "a tree whose marker we could not read". Callers that make a safety
|
|
86
|
-
* (the guard hook, the no-nesting refusal) must use this rather
|
|
87
|
-
* {@link
|
|
88
|
+
* "a tree whose marker we could not read". Callers that make a safety
|
|
89
|
+
* decision (the guard hook, the no-nesting refusal) must use this rather
|
|
90
|
+
* than {@link tryReadTreeMarker}.
|
|
88
91
|
*
|
|
89
92
|
* Only ENOENT/ENOTDIR mean `absent`: any other probe failure (EACCES on the
|
|
90
93
|
* `.fireforge` directory, EIO, …) reports `corrupt`, because "we cannot read
|
|
91
94
|
* the marker" is not evidence that there is no marker — a `pathExists`
|
|
92
|
-
* pre-check
|
|
93
|
-
*
|
|
95
|
+
* pre-check classifies a tree with an unreadable `.fireforge` as `absent`
|
|
96
|
+
* and hands it the full mutating command set.
|
|
94
97
|
*/
|
|
95
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Naming convention for state-file readers:
|
|
100
|
+
* - `readX(): Promise<XRead>` — the TRI-STATE read: absent, corrupt, or
|
|
101
|
+
* valid.
|
|
102
|
+
* - `tryReadX(): Promise<X | undefined>` — collapses absent and corrupt.
|
|
103
|
+
*/
|
|
104
|
+
export async function readTreeMarker(root) {
|
|
96
105
|
const markerPath = getTreeMarkerPath(root);
|
|
97
106
|
try {
|
|
98
107
|
const raw = await readJson(markerPath);
|
|
108
|
+
// Version FIRST, and reported distinctly. Folding the schemaVersion
|
|
109
|
+
// check into `isTreeMarker` makes a marker from a NEWER FireForge read
|
|
110
|
+
// as "missing or mistypes a required field" — and `tree-guard.ts` is
|
|
111
|
+
// default-deny on corrupt, so the operator is locked out of every
|
|
112
|
+
// mutating command inside the tree by a message claiming the file is
|
|
113
|
+
// malformed when it is merely newer.
|
|
114
|
+
const version = checkDocumentVersion(raw, 'schemaVersion', TREE_MARKER_SCHEMA_VERSION);
|
|
115
|
+
if (version.kind === 'newer') {
|
|
116
|
+
return {
|
|
117
|
+
kind: 'unsupported',
|
|
118
|
+
reason: describeNewerDocument('tree marker', version.found, TREE_MARKER_SCHEMA_VERSION),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
99
121
|
if (!isTreeMarker(raw)) {
|
|
100
122
|
verbose(`Malformed tree marker at ${markerPath}`);
|
|
101
123
|
return { kind: 'corrupt', reason: 'the marker is missing or mistypes a required field' };
|
|
@@ -116,10 +138,10 @@ export async function readTreeMarkerState(root) {
|
|
|
116
138
|
*
|
|
117
139
|
* For display and best-effort paths only (`tree list` renders an unreadable
|
|
118
140
|
* marker as staleness 'unknown'). Anything that decides whether a mutation may
|
|
119
|
-
* proceed must call {@link
|
|
141
|
+
* proceed must call {@link readTreeMarker} and handle `corrupt`.
|
|
120
142
|
*/
|
|
121
|
-
export async function
|
|
122
|
-
const state = await
|
|
143
|
+
export async function tryReadTreeMarker(root) {
|
|
144
|
+
const state = await readTreeMarker(root);
|
|
123
145
|
return state.kind === 'valid' ? state.marker : undefined;
|
|
124
146
|
}
|
|
125
147
|
/**
|
|
@@ -131,7 +153,7 @@ export async function readTreeMarker(root) {
|
|
|
131
153
|
* No-op outside a tree; a corrupt marker is already refused by the guard.
|
|
132
154
|
*/
|
|
133
155
|
export async function assertObjdirMatchesTreeMarker(projectRoot, objDir) {
|
|
134
|
-
const state = await
|
|
156
|
+
const state = await readTreeMarker(projectRoot);
|
|
135
157
|
if (state.kind !== 'valid' || state.marker.clonedObjdir === undefined)
|
|
136
158
|
return;
|
|
137
159
|
if (objDir !== state.marker.clonedObjdir) {
|
|
@@ -235,22 +257,21 @@ async function assertCloneSafeObjdir(engineDir, objDir, role) {
|
|
|
235
257
|
}
|
|
236
258
|
}
|
|
237
259
|
/**
|
|
238
|
-
* Materialises the tree at `treeRoot` from `primaryRoot` using
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
* touches metadata for millions of
|
|
244
|
-
* that objdir is included
|
|
245
|
-
* refuses symlinked or engine-escaping objdirs
|
|
246
|
-
* rewritten to the tree
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
260
|
+
* Materialises the tree at `treeRoot` from `primaryRoot` using `capability`
|
|
261
|
+
* ('none' = plain copy, already gated on --force-copy by the caller).
|
|
262
|
+
*
|
|
263
|
+
* The engine is cloned one TOP-LEVEL entry at a time so unwanted `obj-*`
|
|
264
|
+
* directories are never traversed or materialised — on a Firefox tree, even
|
|
265
|
+
* CoW-cloning and then deleting an objdir touches metadata for millions of
|
|
266
|
+
* build outputs. With `withObjdir` exactly that objdir is included (after
|
|
267
|
+
* {@link assertCloneSafeObjdir} refuses symlinked or engine-escaping objdirs
|
|
268
|
+
* before any copying), rewritten to the tree, and reconfigured in-tree via
|
|
269
|
+
* the caller-supplied `reconfigure` hook. A fresh `.fireforge/` is created
|
|
270
|
+
* with only `state.json` (when present), the last-build baseline (withObjdir
|
|
271
|
+
* only), and the tree marker.
|
|
250
272
|
*/
|
|
251
273
|
export async function cloneTree(args) {
|
|
252
274
|
const { primaryRoot, treeRoot, name, capability, createdAt, withObjdir } = args;
|
|
253
|
-
const { mkdir, cp } = await import('node:fs/promises');
|
|
254
275
|
if (withObjdir) {
|
|
255
276
|
// Refuse a symlinked/escaping primary objdir BEFORE any copying: the
|
|
256
277
|
// clone would carry the symlink and every later write would land in
|
|
@@ -303,7 +324,7 @@ export async function cloneTree(args) {
|
|
|
303
324
|
}
|
|
304
325
|
const { engineHead, engineFingerprint, patchesFingerprint } = await computePrimaryFingerprint(primaryRoot);
|
|
305
326
|
const marker = {
|
|
306
|
-
schemaVersion:
|
|
327
|
+
schemaVersion: TREE_MARKER_SCHEMA_VERSION,
|
|
307
328
|
name,
|
|
308
329
|
primaryRoot,
|
|
309
330
|
createdAt,
|
|
@@ -352,7 +373,7 @@ export async function listTrees(primaryRoot) {
|
|
|
352
373
|
if (name.endsWith('.lock'))
|
|
353
374
|
continue;
|
|
354
375
|
const path = join(treesDir, name);
|
|
355
|
-
const marker = await
|
|
376
|
+
const marker = await tryReadTreeMarker(path);
|
|
356
377
|
if (!marker) {
|
|
357
378
|
entries.push({ name, path, createdAt: '(no marker)', staleness: 'unknown' });
|
|
358
379
|
continue;
|
|
@@ -376,19 +397,19 @@ export async function listTrees(primaryRoot) {
|
|
|
376
397
|
* file-lock internals.
|
|
377
398
|
*
|
|
378
399
|
* Liveness comes from the shared {@link isProcessAlive}, which treats EPERM
|
|
379
|
-
* as alive.
|
|
380
|
-
*
|
|
381
|
-
*
|
|
400
|
+
* as alive. Returning `false` for EPERM lets a tree whose build lock is held
|
|
401
|
+
* by a live process running under a different uid pass the guard below and
|
|
402
|
+
* get `rm -rf`'d mid-build.
|
|
382
403
|
*
|
|
383
|
-
* The `unknown` state is not
|
|
384
|
-
*
|
|
385
|
-
* write failure as non-fatal — so every acquisition passes through a window
|
|
386
|
-
* which the lock is genuinely held and has no readable PID, and a
|
|
387
|
-
* full filesystem leaves it that way for the lock's whole life.
|
|
388
|
-
* as `free`
|
|
389
|
-
* build. `file-lock.ts` reaches the same conclusion for
|
|
390
|
-
* recovery, where an unreadable PID falls back to an age-only
|
|
391
|
-
* than assuming the lock is abandoned.
|
|
404
|
+
* The `unknown` state is not theoretical. `withFileLock` takes the lock by
|
|
405
|
+
* creating the directory and only *then* writes the owner file, treating a
|
|
406
|
+
* write failure as non-fatal — so every acquisition passes through a window
|
|
407
|
+
* in which the lock is genuinely held and has no readable PID, and a
|
|
408
|
+
* read-only or full filesystem leaves it that way for the lock's whole life.
|
|
409
|
+
* Reporting that as `free` lets `removeTree` recursively delete a tree out
|
|
410
|
+
* from under a live build. `file-lock.ts` reaches the same conclusion for
|
|
411
|
+
* its own stale recovery, where an unreadable PID falls back to an age-only
|
|
412
|
+
* heuristic rather than assuming the lock is abandoned.
|
|
392
413
|
*/
|
|
393
414
|
async function inspectTreeLock(lockPath) {
|
|
394
415
|
if (!existsSync(lockPath))
|
|
@@ -40,13 +40,12 @@ export declare const TEST_HARNESS_SHIM = "\n// \u2500\u2500 FireForge test-harne
|
|
|
40
40
|
export declare const SUPPRESSED_DIAGNOSTIC_CODES: ReadonlySet<number>;
|
|
41
41
|
/**
|
|
42
42
|
* Undefined-free-identifier codes, split out of
|
|
43
|
-
* {@link SUPPRESSED_DIAGNOSTIC_CODES}.
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* `extraShim`, or per-run via the `'off'` setting).
|
|
43
|
+
* {@link SUPPRESSED_DIAGNOSTIC_CODES}. Suppressing them unconditionally lets
|
|
44
|
+
* a module reference a name with no import or declaration anywhere and still
|
|
45
|
+
* typecheck with 0 errors, so the failure surfaces as a runtime
|
|
46
|
+
* `ReferenceError`. Both flows report these at a configurable severity
|
|
47
|
+
* (default `'warning'`: visible without breaking gates; genuine shim gaps
|
|
48
|
+
* are silenced by adding the global to `extraShim`, or per-run via `'off'`).
|
|
50
49
|
*/
|
|
51
50
|
export declare const UNDEFINED_IDENTIFIER_CODES: ReadonlySet<number>;
|
|
52
51
|
/** Hint appended to reported undefined-identifier diagnostics. */
|
|
@@ -61,25 +60,25 @@ export interface ComposedShim {
|
|
|
61
60
|
extraShimAppended: boolean;
|
|
62
61
|
}
|
|
63
62
|
/**
|
|
64
|
-
* Composes the synthetic shim source by concatenating the built-in
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* so they are not silently dropped at the synthetic shim path.
|
|
63
|
+
* Composes the synthetic shim source by concatenating the built-in Firefox
|
|
64
|
+
* globals shim with the contents of an optional user-supplied `.d.ts` file.
|
|
65
|
+
* The user file is appended verbatim — the augment direction is intentional
|
|
66
|
+
* (declarations later in concat order augment earlier ones), so a project
|
|
67
|
+
* that wants to refine `Services` with a more specific type can do so in the
|
|
68
|
+
* extra shim, and members can be ADDED to the structured globals by merging
|
|
69
|
+
* their interfaces (`interface ChromeUtilsShim { newMember(): any }` — see
|
|
70
|
+
* the module doc comment). Any triple-slash `/// <reference path="…">`
|
|
71
|
+
* directives inside the extra shim are inlined (resolved against the extra
|
|
72
|
+
* shim's own directory) so they are not silently dropped at the synthetic
|
|
73
|
+
* shim path.
|
|
76
74
|
*
|
|
77
|
-
* Missing extra-shim files raise a clear error rather than failing
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
75
|
+
* Missing extra-shim files raise a clear error rather than failing silently
|
|
76
|
+
* with a confusing "type not found" downstream — this is the one
|
|
77
|
+
* config-driven path where a user typo in `fireforge.json` produces a
|
|
78
|
+
* runtime error, so it needs to be unmistakable.
|
|
81
79
|
*
|
|
82
|
-
* @param projectRoot - Absolute project root, used to resolve the relative
|
|
80
|
+
* @param projectRoot - Absolute project root, used to resolve the relative
|
|
81
|
+
* shim path
|
|
83
82
|
* @param extraShimPath - Optional project-relative path to an extra `.d.ts`
|
|
84
83
|
*/
|
|
85
84
|
export declare function composeShimSource(projectRoot: string, extraShimPath: string | undefined): Promise<ComposedShim>;
|
|
@@ -189,13 +189,12 @@ export const SUPPRESSED_DIAGNOSTIC_CODES = new Set([
|
|
|
189
189
|
]);
|
|
190
190
|
/**
|
|
191
191
|
* Undefined-free-identifier codes, split out of
|
|
192
|
-
* {@link SUPPRESSED_DIAGNOSTIC_CODES}.
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
* `extraShim`, or per-run via the `'off'` setting).
|
|
192
|
+
* {@link SUPPRESSED_DIAGNOSTIC_CODES}. Suppressing them unconditionally lets
|
|
193
|
+
* a module reference a name with no import or declaration anywhere and still
|
|
194
|
+
* typecheck with 0 errors, so the failure surfaces as a runtime
|
|
195
|
+
* `ReferenceError`. Both flows report these at a configurable severity
|
|
196
|
+
* (default `'warning'`: visible without breaking gates; genuine shim gaps
|
|
197
|
+
* are silenced by adding the global to `extraShim`, or per-run via `'off'`).
|
|
199
198
|
*/
|
|
200
199
|
export const UNDEFINED_IDENTIFIER_CODES = new Set([
|
|
201
200
|
2304, // Cannot find name '{0}'.
|
|
@@ -242,25 +241,25 @@ async function inlineTripleSlashReferences(source, baseDir, seen) {
|
|
|
242
241
|
return out.join('\n');
|
|
243
242
|
}
|
|
244
243
|
/**
|
|
245
|
-
* Composes the synthetic shim source by concatenating the built-in
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
* so they are not silently dropped at the synthetic shim path.
|
|
244
|
+
* Composes the synthetic shim source by concatenating the built-in Firefox
|
|
245
|
+
* globals shim with the contents of an optional user-supplied `.d.ts` file.
|
|
246
|
+
* The user file is appended verbatim — the augment direction is intentional
|
|
247
|
+
* (declarations later in concat order augment earlier ones), so a project
|
|
248
|
+
* that wants to refine `Services` with a more specific type can do so in the
|
|
249
|
+
* extra shim, and members can be ADDED to the structured globals by merging
|
|
250
|
+
* their interfaces (`interface ChromeUtilsShim { newMember(): any }` — see
|
|
251
|
+
* the module doc comment). Any triple-slash `/// <reference path="…">`
|
|
252
|
+
* directives inside the extra shim are inlined (resolved against the extra
|
|
253
|
+
* shim's own directory) so they are not silently dropped at the synthetic
|
|
254
|
+
* shim path.
|
|
257
255
|
*
|
|
258
|
-
* Missing extra-shim files raise a clear error rather than failing
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
*
|
|
256
|
+
* Missing extra-shim files raise a clear error rather than failing silently
|
|
257
|
+
* with a confusing "type not found" downstream — this is the one
|
|
258
|
+
* config-driven path where a user typo in `fireforge.json` produces a
|
|
259
|
+
* runtime error, so it needs to be unmistakable.
|
|
262
260
|
*
|
|
263
|
-
* @param projectRoot - Absolute project root, used to resolve the relative
|
|
261
|
+
* @param projectRoot - Absolute project root, used to resolve the relative
|
|
262
|
+
* shim path
|
|
264
263
|
* @param extraShimPath - Optional project-relative path to an extra `.d.ts`
|
|
265
264
|
*/
|
|
266
265
|
export async function composeShimSource(projectRoot, extraShimPath) {
|
|
@@ -89,8 +89,8 @@ export async function runTypecheck(projectRoot, cfg) {
|
|
|
89
89
|
// override (a path, or `null` to opt out) when present, else the shared
|
|
90
90
|
// top-level extraShim. A project that narrows `lib`/`types` can opt out of
|
|
91
91
|
// a Gecko-lib shim hub that another project needs, so the composed shim is
|
|
92
|
-
//
|
|
93
|
-
// resolved extraShim path so projects sharing a shim
|
|
92
|
+
// not injected identically everywhere. Compositions are cached by the
|
|
93
|
+
// resolved extraShim path so projects sharing a shim do not recompose it.
|
|
94
94
|
const shimCache = new Map();
|
|
95
95
|
const composeForProject = async (extraShim) => {
|
|
96
96
|
const key = extraShim ?? '';
|
|
@@ -222,12 +222,12 @@ async function runTypecheckForProject(ts, projectRoot, projectPath, shimSource,
|
|
|
222
222
|
noEmit: true,
|
|
223
223
|
allowJs: parsed.options.allowJs ?? true,
|
|
224
224
|
checkJs: parsed.options.checkJs ?? true,
|
|
225
|
-
// No incremental sidecar, ever. A user jsconfig under `engine/` that
|
|
226
|
-
//
|
|
227
|
-
//
|
|
228
|
-
//
|
|
229
|
-
//
|
|
230
|
-
//
|
|
225
|
+
// No incremental sidecar, ever. A user jsconfig under `engine/` that sets
|
|
226
|
+
// `incremental` (or names a `tsBuildInfoFile`) would have this command
|
|
227
|
+
// drop a `.tsbuildinfo` inside the primary engine checkout — a second
|
|
228
|
+
// writer that invalidates a concurrent `fireforge test`'s engine
|
|
229
|
+
// fingerprint. This command emits nothing, so the sidecar buys nothing
|
|
230
|
+
// either.
|
|
231
231
|
incremental: false,
|
|
232
232
|
// skipLibCheck is not forced; the user owns it via their jsconfig.
|
|
233
233
|
};
|