@hominis/fireforge 0.43.1 → 0.44.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +153 -0
- package/README.md +3 -3
- 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 +13 -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-patch-manifest.d.ts +8 -0
- package/dist/src/commands/doctor-patch-manifest.js +155 -0
- 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.d.ts +1 -1
- package/dist/src/commands/doctor.js +64 -96
- 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 +15 -10
- 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 +14 -17
- 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 +48 -37
- 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 +39 -36
- 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-mutate.js +20 -19
- 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 +16 -13
- package/dist/src/core/furnace-apply-helpers.d.ts +7 -7
- package/dist/src/core/furnace-apply-helpers.js +30 -21
- 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 +21 -9
- package/dist/src/core/git-base.js +24 -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 +57 -71
- 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 +41 -20
- 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 +57 -6
- package/dist/src/core/patch-manifest-consistency.js +111 -40
- package/dist/src/core/patch-manifest-files-affected.d.ts +43 -0
- package/dist/src/core/patch-manifest-files-affected.js +77 -0
- 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-manifest.d.ts +2 -1
- package/dist/src/core/patch-manifest.js +2 -1
- 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 +66 -14
- 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 +29 -13
- package/dist/src/core/token-docs.d.ts +2 -0
- package/dist/src/core/token-docs.js +3 -1
- 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 +28 -6
- 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 +68 -43
- 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 +15 -9
- 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 +111 -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 +3 -3
- 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
|
@@ -70,6 +70,7 @@ export async function readBuildBaseline(projectRoot) {
|
|
|
70
70
|
* engine HEAD SHA (or an empty string when the engine has no HEAD yet) and
|
|
71
71
|
* the current binaryName. Caller is responsible for only invoking this
|
|
72
72
|
* after the build exit code was zero.
|
|
73
|
+
*
|
|
73
74
|
* @param projectRoot - Root directory of the project
|
|
74
75
|
* @param engineDir - Path to the engine directory
|
|
75
76
|
* @param binaryName - Current `binaryName` from fireforge.json
|
|
@@ -85,10 +86,10 @@ export async function readBuildBaseline(projectRoot) {
|
|
|
85
86
|
* @param staticComponentsHandling - `'auto'` (default) refreshes the
|
|
86
87
|
* static-components anchor whenever the coverage claim is `'full'` or
|
|
87
88
|
* absent. `'refresh'` records it even for a scoped coverage claim whose
|
|
88
|
-
* implementation escalated to a full build. `'carry-forward'` always
|
|
89
|
-
* `--extend-coverage`, whose union
|
|
90
|
-
* while the build that produced it was still a
|
|
91
|
-
* faster` that did not rebake the compiled table.
|
|
89
|
+
* implementation escalated to a full build. `'carry-forward'` always
|
|
90
|
+
* keeps the previous anchor: needed by `--extend-coverage`, whose union
|
|
91
|
+
* can EVALUATE to `'full'` while the build that produced it was still a
|
|
92
|
+
* scoped `mach build faster` that did not rebake the compiled table.
|
|
92
93
|
*/
|
|
93
94
|
export async function writeBuildBaseline(projectRoot, engineDir, binaryName, testPackagingCoverage, previousBaseline, recordedBy, staticComponentsHandling = 'auto') {
|
|
94
95
|
let engineHeadSha = '';
|
|
@@ -128,17 +129,16 @@ export async function writeBuildBaseline(projectRoot, engineDir, binaryName, tes
|
|
|
128
129
|
await writeJson(getBuildBaselinePath(projectRoot), baseline);
|
|
129
130
|
}
|
|
130
131
|
/**
|
|
131
|
-
* Reads the current engine workdir and computes a SHA-256 fingerprint
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* are new since the baseline) are genuinely stale.
|
|
132
|
+
* Reads the current engine workdir and computes a SHA-256 fingerprint for
|
|
133
|
+
* every packageable path that is either modified against HEAD or untracked.
|
|
134
|
+
* The stale-build preflight (`checkStaleBuildForTest`) compares the live
|
|
135
|
+
* fingerprint for each packageable-dirty file to the baseline's entry: a
|
|
136
|
+
* matching hash means the build already saw this exact content, a differing
|
|
137
|
+
* or new one means the file is genuinely stale.
|
|
138
138
|
*
|
|
139
|
-
* Returns `undefined` on any git failure so a broken probe never
|
|
140
|
-
*
|
|
141
|
-
*
|
|
139
|
+
* Returns `undefined` on any git failure so a broken probe never corrupts
|
|
140
|
+
* the on-disk baseline with `{}`; the stale-check then falls back to a
|
|
141
|
+
* path-only comparison.
|
|
142
142
|
*/
|
|
143
143
|
async function collectPackageableFingerprints(engineDir) {
|
|
144
144
|
return collectDirtyFingerprints(engineDir, isPackageablePath, 'packageable fingerprint');
|
|
@@ -1,20 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Loud guard against silently reverting UNEXPORTED engine drift.
|
|
3
3
|
*
|
|
4
|
-
* `build-prepare` rewrites engine files from FireForge-owned sources
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* passed on the hybrid capture. Only a hand-run grep of the patch body
|
|
12
|
-
* caught it.
|
|
13
|
-
*
|
|
14
|
-
* The `setupBranding` half of this class was closed in `31fdf744` (the
|
|
15
|
-
* branding writer preserves unmanaged lines). The general shape — any
|
|
16
|
-
* build-prepare overwrite destroying local drift that no patch records —
|
|
17
|
-
* stayed silent, and silence is what made the hybrid capture possible.
|
|
4
|
+
* `build-prepare` rewrites engine files from FireForge-owned sources before
|
|
5
|
+
* every build: the branding tree, every Furnace-managed component, and
|
|
6
|
+
* `mozconfig`. On a multi-session checkout that is a silent destructive
|
|
7
|
+
* write — one session edits a file in `engine/` while another holds the
|
|
8
|
+
* engine lock, the lock-holder's build rewrites it back to its patch
|
|
9
|
+
* baseline, and the editing session's later `re-export --wait-lock`
|
|
10
|
+
* captures a HYBRID file that every gate then passes.
|
|
18
11
|
*
|
|
19
12
|
* This guard runs BEFORE the writes, classifies the engine's dirty files
|
|
20
13
|
* with the same classifier `fireforge status` uses, and reports the ones
|
|
@@ -2,20 +2,13 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Loud guard against silently reverting UNEXPORTED engine drift.
|
|
4
4
|
*
|
|
5
|
-
* `build-prepare` rewrites engine files from FireForge-owned sources
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* passed on the hybrid capture. Only a hand-run grep of the patch body
|
|
13
|
-
* caught it.
|
|
14
|
-
*
|
|
15
|
-
* The `setupBranding` half of this class was closed in `31fdf744` (the
|
|
16
|
-
* branding writer preserves unmanaged lines). The general shape — any
|
|
17
|
-
* build-prepare overwrite destroying local drift that no patch records —
|
|
18
|
-
* stayed silent, and silence is what made the hybrid capture possible.
|
|
5
|
+
* `build-prepare` rewrites engine files from FireForge-owned sources before
|
|
6
|
+
* every build: the branding tree, every Furnace-managed component, and
|
|
7
|
+
* `mozconfig`. On a multi-session checkout that is a silent destructive
|
|
8
|
+
* write — one session edits a file in `engine/` while another holds the
|
|
9
|
+
* engine lock, the lock-holder's build rewrites it back to its patch
|
|
10
|
+
* baseline, and the editing session's later `re-export --wait-lock`
|
|
11
|
+
* captures a HYBRID file that every gate then passes.
|
|
19
12
|
*
|
|
20
13
|
* This guard runs BEFORE the writes, classifies the engine's dirty files
|
|
21
14
|
* with the same classifier `fireforge status` uses, and reports the ones
|
|
@@ -66,20 +59,17 @@ function isOverwrittenByBuildPrepare(file, binaryName, furnacePrefixes) {
|
|
|
66
59
|
* expanding collapsed untracked directories on the way.
|
|
67
60
|
*
|
|
68
61
|
* Git reports a WHOLLY untracked directory as a single `?? dir/` entry
|
|
69
|
-
* rather than listing the files under it. A directory entry has no
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* while `status --unmanaged` (which expands) reported the same tree
|
|
75
|
-
* clean. Expanding here is what makes the two agree by construction.
|
|
62
|
+
* rather than listing the files under it. A directory entry has no content
|
|
63
|
+
* to compare, so `classifyFiles` matches it against neither a patch body nor
|
|
64
|
+
* the pristine baseline and buckets it `unmanaged` — an at-risk
|
|
65
|
+
* classification. Expanding here is what keeps this guard and
|
|
66
|
+
* `status --unmanaged`, which expands, agreeing by construction.
|
|
76
67
|
*
|
|
77
|
-
* Expansion is scoped to build-prepare-owned prefixes on both sides of
|
|
78
|
-
*
|
|
79
|
-
* (`components/` when `components/custom/` is Furnace-managed) is
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* expansion cap on a tree whose owned prefixes are small.
|
|
68
|
+
* Expansion is scoped to build-prepare-owned prefixes on both sides of the
|
|
69
|
+
* walk: a collapsed directory that merely CONTAINS an owned prefix
|
|
70
|
+
* (`components/` when `components/custom/` is Furnace-managed) is rewritten
|
|
71
|
+
* to the owned prefixes beneath it, so the enumeration never walks an
|
|
72
|
+
* unrelated subtree and never trips the per-directory expansion cap.
|
|
83
73
|
*/
|
|
84
74
|
async function collectOverwrittenEntries(engineDir, status, binaryName, furnacePrefixes) {
|
|
85
75
|
const ownedPrefixes = buildPrepareOwnedPrefixes(binaryName, furnacePrefixes);
|
|
@@ -37,8 +37,8 @@ export declare function requiresFullBuildForIncrementalTest(path: string): boole
|
|
|
37
37
|
* Describes an exit code in the shell's 128+N signal convention. Truncated
|
|
38
38
|
* configure/build logs with a signal-shaped exit (e.g. 144 = 128+16, SIGURG
|
|
39
39
|
* on macOS) are environmental interruptions, not compiler failures — naming
|
|
40
|
-
* that in the failure text saves the operator a fruitless log hunt
|
|
41
|
-
|
|
40
|
+
* that in the failure text saves the operator a fruitless log hunt.
|
|
41
|
+
* Returns undefined for codes <= 128 (regular failures) and
|
|
42
42
|
* for codes past the conventional signal range, so callers append nothing.
|
|
43
43
|
*/
|
|
44
44
|
export declare function describeSignalShapedExit(exitCode: number): string | undefined;
|
|
@@ -44,8 +44,8 @@ function extractMachConfigureError(result) {
|
|
|
44
44
|
* Describes an exit code in the shell's 128+N signal convention. Truncated
|
|
45
45
|
* configure/build logs with a signal-shaped exit (e.g. 144 = 128+16, SIGURG
|
|
46
46
|
* on macOS) are environmental interruptions, not compiler failures — naming
|
|
47
|
-
* that in the failure text saves the operator a fruitless log hunt
|
|
48
|
-
|
|
47
|
+
* that in the failure text saves the operator a fruitless log hunt.
|
|
48
|
+
* Returns undefined for codes <= 128 (regular failures) and
|
|
49
49
|
* for codes past the conventional signal range, so callers append nothing.
|
|
50
50
|
*/
|
|
51
51
|
export function describeSignalShapedExit(exitCode) {
|
|
@@ -94,10 +94,10 @@ export function isBackendInvalidatingFile(path) {
|
|
|
94
94
|
*
|
|
95
95
|
* Every write `prepareBuildEnvironment` performs — branding, Furnace
|
|
96
96
|
* components, `mozconfig` — rewrites engine files from a FireForge-owned
|
|
97
|
-
* source. Content recorded in neither a patch body nor the pristine
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
97
|
+
* source. Content recorded in neither a patch body nor the pristine baseline
|
|
98
|
+
* is destroyed by that, and on a multi-session checkout the destruction is
|
|
99
|
+
* what lets a later re-export capture a half-reverted hybrid that every gate
|
|
100
|
+
* then passes.
|
|
101
101
|
*
|
|
102
102
|
* @param projectRoot - Project root
|
|
103
103
|
* @param config - Loaded FireForge config
|
|
@@ -190,9 +190,8 @@ export async function prepareBuildEnvironment(projectRoot, paths, config, option
|
|
|
190
190
|
// project license through so `buildConfigureScriptContent` /
|
|
191
191
|
// `buildBrandPropertiesContent` / `buildBrandFtlContent` stamp the
|
|
192
192
|
// generated files with a matching SPDX header — otherwise `patch-lint`
|
|
193
|
-
// flags them with `missing-license-header` on every subsequent export
|
|
194
|
-
//
|
|
195
|
-
// fork's first export failed `lint` on its own generated branding).
|
|
193
|
+
// flags them with `missing-license-header` on every subsequent export when
|
|
194
|
+
// the project is not MPL-2.0.
|
|
196
195
|
const brandingConfig = {
|
|
197
196
|
name: config.name,
|
|
198
197
|
vendor: config.vendor,
|
|
@@ -18,21 +18,16 @@ function cloneConfigDocument(config) {
|
|
|
18
18
|
return cloned;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
21
|
+
* The error every sentinel-segment refusal raises. Only the MESSAGE lives
|
|
22
|
+
* here: the comparison itself is spelled inline at each write site, because
|
|
23
|
+
* that is what both a reader and CodeQL's `js/prototype-pollution-utility`
|
|
24
|
+
* barrier detection need — the latter is not interprocedural, so a check
|
|
25
|
+
* hidden behind a helper leaves the descent below looking unguarded.
|
|
26
26
|
*/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
throw new ConfigError(`Config key "${key}" contains a reserved segment "${part}". ` +
|
|
32
|
-
'Segments "__proto__", "constructor", and "prototype" are not permitted ' +
|
|
33
|
-
'because they would mutate the object prototype chain.');
|
|
34
|
-
}
|
|
35
|
-
}
|
|
27
|
+
function sentinelSegmentError(key, part) {
|
|
28
|
+
return new ConfigError(`Config key "${key}" contains a reserved segment "${part}". ` +
|
|
29
|
+
'Segments "__proto__", "constructor", and "prototype" are not permitted ' +
|
|
30
|
+
'because they would mutate the object prototype chain.');
|
|
36
31
|
}
|
|
37
32
|
function getOrCreateChildRecord(parent, key) {
|
|
38
33
|
const existing = parent[key];
|
|
@@ -45,21 +40,27 @@ function getOrCreateChildRecord(parent, key) {
|
|
|
45
40
|
}
|
|
46
41
|
export function mutateConfig(config, key, value, skipValidation = false) {
|
|
47
42
|
const parts = key.split('.');
|
|
48
|
-
// Reject prototype-chain sentinel segments before any write so
|
|
49
|
-
// `--force` cannot be used to mutate Object.prototype. This guard must
|
|
50
|
-
// run against the original key parts, not any subset — the final leaf
|
|
51
|
-
// assignment `current[lastPart] = value` would otherwise stay vulnerable.
|
|
52
|
-
assertNoSentinelSegments(key, parts);
|
|
53
43
|
const raw = cloneConfigDocument(config);
|
|
44
|
+
// Every segment is checked at the point it is USED as a property name —
|
|
45
|
+
// the descent below and the leaf assignment — rather than once up front,
|
|
46
|
+
// so `--force` cannot be used to mutate Object.prototype and neither write
|
|
47
|
+
// can drift out from behind the guard. `raw` is a private clone, so a
|
|
48
|
+
// refusal here has mutated nothing the caller can observe.
|
|
54
49
|
let current = raw;
|
|
55
50
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
56
51
|
const part = parts[i];
|
|
57
52
|
if (part === undefined)
|
|
58
53
|
continue;
|
|
54
|
+
if (part === '__proto__' || part === 'constructor' || part === 'prototype') {
|
|
55
|
+
throw sentinelSegmentError(key, part);
|
|
56
|
+
}
|
|
59
57
|
current = getOrCreateChildRecord(current, part);
|
|
60
58
|
}
|
|
61
59
|
const lastPart = parts[parts.length - 1];
|
|
62
60
|
if (lastPart !== undefined) {
|
|
61
|
+
if (lastPart === '__proto__' || lastPart === 'constructor' || lastPart === 'prototype') {
|
|
62
|
+
throw sentinelSegmentError(key, lastPart);
|
|
63
|
+
}
|
|
63
64
|
current[lastPart] = value;
|
|
64
65
|
}
|
|
65
66
|
if (!skipValidation) {
|
|
@@ -3,10 +3,14 @@
|
|
|
3
3
|
* Project state file management (.fireforge/state.json).
|
|
4
4
|
*/
|
|
5
5
|
import { ConfigError } from '../errors/config.js';
|
|
6
|
+
import { BUILD_MODES } from '../types/config.js';
|
|
6
7
|
import { toError } from '../utils/errors.js';
|
|
7
8
|
import { pathExists, readJson, writeJson } from '../utils/fs.js';
|
|
8
9
|
import { warn } from '../utils/logger.js';
|
|
9
10
|
import { isObject, isString } from '../utils/validation.js';
|
|
11
|
+
import { makeEnumGuard } from '../utils/validation.js';
|
|
12
|
+
/** Narrows an arbitrary string to a {@link BuildMode}. */
|
|
13
|
+
const isBuildMode = makeEnumGuard(BUILD_MODES);
|
|
10
14
|
import { getProjectPaths } from './config-paths.js';
|
|
11
15
|
import { quarantineStateFile, withStateFileLock } from './state-file.js';
|
|
12
16
|
function sanitizeProjectState(data) {
|
|
@@ -36,11 +40,15 @@ function sanitizeProjectState(data) {
|
|
|
36
40
|
issues.push(`field "${key}" must be a string`);
|
|
37
41
|
continue;
|
|
38
42
|
}
|
|
39
|
-
if (key === 'buildMode' && !['dev', 'debug', 'release'].includes(value)) {
|
|
40
|
-
issues.push('field "buildMode" must be one of: dev, debug, release');
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
43
|
if (key === 'buildMode') {
|
|
44
|
+
// Validate and assign in ONE block so the predicate's narrowing reaches
|
|
45
|
+
// the assignment. Split across two `key === 'buildMode'` guards,
|
|
46
|
+
// TypeScript cannot correlate them and the assignment needed a cast —
|
|
47
|
+
// which is what let the untyped allowlist drift from the union.
|
|
48
|
+
if (!isBuildMode(value)) {
|
|
49
|
+
issues.push(`field "buildMode" must be one of: ${BUILD_MODES.join(', ')}`);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
44
52
|
state.buildMode = value;
|
|
45
53
|
}
|
|
46
54
|
else {
|
|
@@ -6,7 +6,7 @@ import { ConfigError } from '../errors/config.js';
|
|
|
6
6
|
import { verbose } from '../utils/logger.js';
|
|
7
7
|
import { parseObject } from '../utils/parse.js';
|
|
8
8
|
import { isContainedRelativePath, isExplicitAbsolutePath } from '../utils/paths.js';
|
|
9
|
-
import { isObject, isValidAppId, isValidFirefoxCandidate, isValidFirefoxVersion, isValidProjectLicense, PROJECT_LICENSES,
|
|
9
|
+
import { describeProductVersionIncompatibility, FIREFOX_PRODUCTS, isObject, isValidAppId, isValidFirefoxCandidate, isValidFirefoxProduct, isValidFirefoxVersion, isValidProjectLicense, PROJECT_LICENSES, } from '../utils/validation.js';
|
|
10
10
|
import { SUPPORTED_CONFIG_ROOT_KEYS } from './config-paths.js';
|
|
11
11
|
import { parsePatchPolicyBlock } from './config-validate-patch-policy.js';
|
|
12
12
|
import { parseExternalToolchainsBlock, parseTestBlock } from './config-validate-test-toolchains.js';
|
|
@@ -68,12 +68,15 @@ function parseFirefoxBlock(rec) {
|
|
|
68
68
|
throw new ConfigError('Config field "firefox.version" must be a valid Firefox version (e.g., "145.0")');
|
|
69
69
|
}
|
|
70
70
|
const firefoxProduct = requireConfigString(firefoxRec, 'product', 'firefox.product');
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
// Uses the shared guard rather than a fourth copy of the member list. This
|
|
72
|
+
// is the fireforge.json READ path: a product added to the union but not to
|
|
73
|
+
// the copy that used to live here would have been silently rejected from
|
|
74
|
+
// every project config.
|
|
75
|
+
if (!isValidFirefoxProduct(firefoxProduct)) {
|
|
76
|
+
throw new ConfigError(`Config field "firefox.product" must be one of: ${FIREFOX_PRODUCTS.join(', ')}`);
|
|
74
77
|
}
|
|
75
78
|
// Cross-field validation: product and version must be compatible
|
|
76
|
-
const compatError =
|
|
79
|
+
const compatError = describeProductVersionIncompatibility(firefoxVersion, firefoxProduct);
|
|
77
80
|
if (compatError) {
|
|
78
81
|
throw new ConfigError(compatError);
|
|
79
82
|
}
|
|
@@ -66,13 +66,10 @@ export declare function writeConfigDocument(root: string, config: FireForgeConfi
|
|
|
66
66
|
/**
|
|
67
67
|
* Runs an operation while holding a sidecar lock on `fireforge.json`.
|
|
68
68
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* `0`, but only one change survived. This helper turns the same
|
|
74
|
-
* read-modify-write sequence into a serialised operation so a concurrent
|
|
75
|
-
* writer now waits for the lock rather than racing on the document.
|
|
69
|
+
* Two concurrent `fireforge config <key> <value>` invocations each run
|
|
70
|
+
* load → mutate → writeJson against the same document; without this lock the
|
|
71
|
+
* second rename lands after the first and silently drops the first writer's
|
|
72
|
+
* key, with both commands exiting 0.
|
|
76
73
|
*
|
|
77
74
|
* Reads (`loadConfig`, `loadRawConfigDocument`) stay lock-free: writers
|
|
78
75
|
* always use `writeJson`'s atomic temp-file + rename, so a reader observes
|
|
@@ -81,7 +78,7 @@ export declare function writeConfigDocument(root: string, config: FireForgeConfi
|
|
|
81
78
|
*
|
|
82
79
|
* The lock is a sidecar directory `${config}.fireforge-config.lock`, and
|
|
83
80
|
* `withFileLock` handles stale-lock recovery (PID-alive probe, age-based
|
|
84
|
-
* fallback)
|
|
81
|
+
* fallback), so a crashed writer does not permanently block future writes.
|
|
85
82
|
*
|
|
86
83
|
* @param root - Root directory of the project
|
|
87
84
|
* @param operation - Async function to run while holding the lock
|
package/dist/src/core/config.js
CHANGED
|
@@ -26,14 +26,8 @@ export { validateConfig } from './config-validate.js';
|
|
|
26
26
|
* Config-file existence probe.
|
|
27
27
|
*
|
|
28
28
|
* Uses {@link pathExistsStrict} deliberately: a permission error probing
|
|
29
|
-
* `fireforge.json` must propagate rather than read as "no config here",
|
|
30
|
-
* is what plain `pathExists` would report.
|
|
31
|
-
*
|
|
32
|
-
* The `fsUtils as typeof fsUtils & { pathExistsStrict?: … }` cast this
|
|
33
|
-
* replaced re-declared a real, non-optional export as optional so a partial
|
|
34
|
-
* `vi.mock` of `utils/fs.js` would fall back to `pathExists` — production code
|
|
35
|
-
* shaped around a test double, and shaped around the *wrong* function, since
|
|
36
|
-
* the two differ precisely on whether EACCES propagates.
|
|
29
|
+
* `fireforge.json` must propagate rather than read as "no config here",
|
|
30
|
+
* which is what plain `pathExists` would report.
|
|
37
31
|
*/
|
|
38
32
|
async function configPathExists(path) {
|
|
39
33
|
return fsUtils.pathExistsStrict(path);
|
|
@@ -134,13 +128,10 @@ export async function writeConfigDocument(root, config) {
|
|
|
134
128
|
/**
|
|
135
129
|
* Runs an operation while holding a sidecar lock on `fireforge.json`.
|
|
136
130
|
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* `0`, but only one change survived. This helper turns the same
|
|
142
|
-
* read-modify-write sequence into a serialised operation so a concurrent
|
|
143
|
-
* writer now waits for the lock rather than racing on the document.
|
|
131
|
+
* Two concurrent `fireforge config <key> <value>` invocations each run
|
|
132
|
+
* load → mutate → writeJson against the same document; without this lock the
|
|
133
|
+
* second rename lands after the first and silently drops the first writer's
|
|
134
|
+
* key, with both commands exiting 0.
|
|
144
135
|
*
|
|
145
136
|
* Reads (`loadConfig`, `loadRawConfigDocument`) stay lock-free: writers
|
|
146
137
|
* always use `writeJson`'s atomic temp-file + rename, so a reader observes
|
|
@@ -149,7 +140,7 @@ export async function writeConfigDocument(root, config) {
|
|
|
149
140
|
*
|
|
150
141
|
* The lock is a sidecar directory `${config}.fireforge-config.lock`, and
|
|
151
142
|
* `withFileLock` handles stale-lock recovery (PID-alive probe, age-based
|
|
152
|
-
* fallback)
|
|
143
|
+
* fallback), so a crashed writer does not permanently block future writes.
|
|
153
144
|
*
|
|
154
145
|
* @param root - Root directory of the project
|
|
155
146
|
* @param operation - Async function to run while holding the lock
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `test --build/--build-only --extend-coverage`: unions the
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* `test --build/--build-only --extend-coverage`: unions the requested paths
|
|
3
|
+
* into the recorded `testPackagingCoverage` instead of replacing it, under
|
|
4
|
+
* an anchor guard.
|
|
5
5
|
*
|
|
6
|
-
* Coverage REPLACES by default for a documented
|
|
7
|
-
*
|
|
6
|
+
* Coverage REPLACES by default for a reason documented in
|
|
7
|
+
* `build-baseline-types.ts`: every baseline write refreshes
|
|
8
8
|
* `packageableFingerprints` for ALL dirty packageable paths, so a blind
|
|
9
9
|
* union would whitewash an earlier scope's edited fixtures while
|
|
10
10
|
* `obj-*`/`_tests/` still holds that scope's stale staging. Extending is
|
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
*
|
|
15
15
|
* 1. engine HEAD is unchanged — every committed edit is excluded;
|
|
16
16
|
* 2. every path the previous baseline fingerprinted still hashes to the
|
|
17
|
-
* recorded digest
|
|
18
|
-
* Files that became dirty SINCE that build are fine:
|
|
19
|
-
* whole-tree `mach build faster` repackages `dist/` and
|
|
17
|
+
* recorded digest, so the earlier scope's staging inputs are
|
|
18
|
+
* byte-identical. Files that became dirty SINCE that build are fine:
|
|
19
|
+
* the current whole-tree `mach build faster` repackages `dist/` and
|
|
20
|
+
* vouches for them;
|
|
20
21
|
* 3. the generated `engine/mozconfig` is unchanged. Engine HEAD does not
|
|
21
22
|
* cover this — the mozconfig is regenerated from project-side
|
|
22
23
|
* `configs/*.mozconfig` templates plus `fireforge.json` on every build,
|
|
@@ -29,8 +30,8 @@
|
|
|
29
30
|
* fixtures under previously covered paths (plain test files, manifests
|
|
30
31
|
* `isPackageablePath` rejects) are invisible to check 2. Editing one
|
|
31
32
|
* uncommitted between two builds leaves the earlier scope's `_tests/`
|
|
32
|
-
* staging stale while extend still vouches for it. Plain REPLACE has no
|
|
33
|
-
*
|
|
33
|
+
* staging stale while extend still vouches for it. Plain REPLACE has no such
|
|
34
|
+
* window, because the earlier scope simply stops being covered.
|
|
34
35
|
*/
|
|
35
36
|
import { type BuildBaseline, type TestPackagingCoverage } from './build-baseline-types.js';
|
|
36
37
|
/** Why `--extend-coverage` could not union onto the recorded claim. */
|
|
@@ -62,9 +63,10 @@ export declare function checkExtendCoverageAnchor(engineDir: string, previousBas
|
|
|
62
63
|
*/
|
|
63
64
|
export declare function checkExtendMozconfigAnchor(engineDir: string, previousBaseline: BuildBaseline | undefined): Promise<ExtendAnchorResult>;
|
|
64
65
|
/**
|
|
65
|
-
* Unions the newly built paths onto the recorded claim. A `'full'` claim
|
|
66
|
-
*
|
|
67
|
-
*
|
|
66
|
+
* Unions the newly built paths onto the recorded claim. A `'full'` claim, or
|
|
67
|
+
* an absent one (which means full), stays `'full'` — it already covers
|
|
68
|
+
* everything.
|
|
69
|
+
*
|
|
68
70
|
* @param previous - Coverage recorded by the previous build
|
|
69
71
|
* @param requested - Normalized request paths this build packaged
|
|
70
72
|
*/
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
/**
|
|
3
|
-
* `test --build/--build-only --extend-coverage`: unions the
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* `test --build/--build-only --extend-coverage`: unions the requested paths
|
|
4
|
+
* into the recorded `testPackagingCoverage` instead of replacing it, under
|
|
5
|
+
* an anchor guard.
|
|
6
6
|
*
|
|
7
|
-
* Coverage REPLACES by default for a documented
|
|
8
|
-
*
|
|
7
|
+
* Coverage REPLACES by default for a reason documented in
|
|
8
|
+
* `build-baseline-types.ts`: every baseline write refreshes
|
|
9
9
|
* `packageableFingerprints` for ALL dirty packageable paths, so a blind
|
|
10
10
|
* union would whitewash an earlier scope's edited fixtures while
|
|
11
11
|
* `obj-*`/`_tests/` still holds that scope's stale staging. Extending is
|
|
@@ -15,9 +15,10 @@
|
|
|
15
15
|
*
|
|
16
16
|
* 1. engine HEAD is unchanged — every committed edit is excluded;
|
|
17
17
|
* 2. every path the previous baseline fingerprinted still hashes to the
|
|
18
|
-
* recorded digest
|
|
19
|
-
* Files that became dirty SINCE that build are fine:
|
|
20
|
-
* whole-tree `mach build faster` repackages `dist/` and
|
|
18
|
+
* recorded digest, so the earlier scope's staging inputs are
|
|
19
|
+
* byte-identical. Files that became dirty SINCE that build are fine:
|
|
20
|
+
* the current whole-tree `mach build faster` repackages `dist/` and
|
|
21
|
+
* vouches for them;
|
|
21
22
|
* 3. the generated `engine/mozconfig` is unchanged. Engine HEAD does not
|
|
22
23
|
* cover this — the mozconfig is regenerated from project-side
|
|
23
24
|
* `configs/*.mozconfig` templates plus `fireforge.json` on every build,
|
|
@@ -30,8 +31,8 @@
|
|
|
30
31
|
* fixtures under previously covered paths (plain test files, manifests
|
|
31
32
|
* `isPackageablePath` rejects) are invisible to check 2. Editing one
|
|
32
33
|
* uncommitted between two builds leaves the earlier scope's `_tests/`
|
|
33
|
-
* staging stale while extend still vouches for it. Plain REPLACE has no
|
|
34
|
-
*
|
|
34
|
+
* staging stale while extend still vouches for it. Plain REPLACE has no such
|
|
35
|
+
* window, because the earlier scope simply stops being covered.
|
|
35
36
|
*/
|
|
36
37
|
import { createHash } from 'node:crypto';
|
|
37
38
|
import { readFile } from 'node:fs/promises';
|
|
@@ -106,9 +107,10 @@ export async function checkExtendMozconfigAnchor(engineDir, previousBaseline) {
|
|
|
106
107
|
return { ok: true };
|
|
107
108
|
}
|
|
108
109
|
/**
|
|
109
|
-
* Unions the newly built paths onto the recorded claim. A `'full'` claim
|
|
110
|
-
*
|
|
111
|
-
*
|
|
110
|
+
* Unions the newly built paths onto the recorded claim. A `'full'` claim, or
|
|
111
|
+
* an absent one (which means full), stays `'full'` — it already covers
|
|
112
|
+
* everything.
|
|
113
|
+
*
|
|
112
114
|
* @param previous - Coverage recorded by the previous build
|
|
113
115
|
* @param requested - Normalized request paths this build packaged
|
|
114
116
|
*/
|
|
@@ -49,8 +49,16 @@ export interface DestructiveOpInput {
|
|
|
49
49
|
/** Structural conflicts that should block the operation unless `unsafeOverride`. */
|
|
50
50
|
conflicts?: ConflictReport | null;
|
|
51
51
|
}
|
|
52
|
-
/**
|
|
53
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Outcome of the destructive-operation contract.
|
|
54
|
+
*
|
|
55
|
+
* `'declined'` means the operator answered "no" — a successful run that
|
|
56
|
+
* chose not to proceed, so callers return normally and the process exits 0.
|
|
57
|
+
* An INTERRUPT (Esc / Ctrl+C) is not represented here: it throws
|
|
58
|
+
* {@link CancellationError} and exits 130. Collapsing the two would make an
|
|
59
|
+
* interrupted prompt indistinguishable from a declined one.
|
|
60
|
+
*/
|
|
61
|
+
export type DestructiveOpResult = 'proceed' | 'dry-run' | 'declined';
|
|
54
62
|
/**
|
|
55
63
|
* Inputs to {@link appendHistory}. Entries are appended as one JSON record
|
|
56
64
|
* per line. Callers should only append after a mutation succeeds so
|
|
@@ -68,6 +76,21 @@ export interface HistoryEntry {
|
|
|
68
76
|
/** Result: `'ok'` on success; other strings describe failure. */
|
|
69
77
|
result: string;
|
|
70
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* True when BOTH standard handles are real TTYs, i.e. an interactive prompt
|
|
81
|
+
* can actually be answered.
|
|
82
|
+
*
|
|
83
|
+
* Named for the condition rather than for confirmation specifically: many
|
|
84
|
+
* call sites gate a `text()` / `multiselect()` input prompt or a mode
|
|
85
|
+
* switch, not a destructive confirmation.
|
|
86
|
+
*
|
|
87
|
+
* Node types `isTTY` as `boolean`, but at runtime it is `true | undefined`
|
|
88
|
+
* (absent when the handle is not a TTY). Unusual harnesses (vitest stdio
|
|
89
|
+
* capture, CI spawners, mocked pipes) can also leave it unset on only one
|
|
90
|
+
* handle, so every falsy variant — false, undefined, a null-patched mock —
|
|
91
|
+
* must route to the non-interactive path.
|
|
92
|
+
*/
|
|
93
|
+
export declare function stdioIsInteractive(): boolean;
|
|
71
94
|
/**
|
|
72
95
|
* UP-FRONT non-interactive refusal for a command that will end at
|
|
73
96
|
* {@link confirmDestructive}.
|
|
@@ -78,8 +101,7 @@ export interface HistoryEntry {
|
|
|
78
101
|
* --create` that is minutes of work before a scripted run learns it needed
|
|
79
102
|
* `--yes`, and the failure reads as an obscure late error rather than a
|
|
80
103
|
* usage problem. Calling this at command entry turns it into a usage
|
|
81
|
-
* refusal that names the flag
|
|
82
|
-
* `move-files --create` / `--description` refusal.
|
|
104
|
+
* refusal that names the flag.
|
|
83
105
|
*
|
|
84
106
|
* A `--yes` or `--dry-run` run never prompts, so neither is refused.
|
|
85
107
|
*
|
|
@@ -95,14 +117,14 @@ export declare function assertConfirmationAvailable(operation: string, options:
|
|
|
95
117
|
* Executes the destructive-operation contract: summary → conflict refusal →
|
|
96
118
|
* dry-run / force / prompt / non-TTY refusal.
|
|
97
119
|
*
|
|
98
|
-
* Returns the decision for the caller to act on; callers must not execute
|
|
99
|
-
* mutation when the result is `'dry-run'` or `'
|
|
100
|
-
* {@link appendHistory} only after the mutation succeeds (never on dry-run
|
|
101
|
-
*
|
|
120
|
+
* Returns the decision for the caller to act on; callers must not execute
|
|
121
|
+
* the mutation when the result is `'dry-run'` or `'declined'`, and must call
|
|
122
|
+
* {@link appendHistory} only after the mutation succeeds (never on dry-run
|
|
123
|
+
* or decline).
|
|
102
124
|
*
|
|
103
125
|
* @param input - Operation description, flags, and optional conflict report
|
|
104
126
|
* @returns `'proceed'` to execute, `'dry-run'` to skip execution, or
|
|
105
|
-
* `'
|
|
127
|
+
* `'declined'` when the user declined the prompt
|
|
106
128
|
*/
|
|
107
129
|
export declare function confirmDestructive(input: DestructiveOpInput): Promise<DestructiveOpResult>;
|
|
108
130
|
/**
|