@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
|
@@ -17,12 +17,11 @@ import { resolvePatchOwnedChromeScripts, resolvePatchOwnedSysMjs, resolvePatchOw
|
|
|
17
17
|
// Cross-patch lint re-exports
|
|
18
18
|
// ---------------------------------------------------------------------------
|
|
19
19
|
//
|
|
20
|
-
// The cross-patch lint infrastructure (queue context builder,
|
|
21
|
-
// creation and forward-import rules, ignore marker) lives in
|
|
22
|
-
// `patch-lint-cross.ts` so the per-patch and cross-patch rule bodies
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
// import from a single module.
|
|
20
|
+
// The cross-patch lint infrastructure (queue context builder,
|
|
21
|
+
// duplicate-creation and forward-import rules, ignore marker) lives in
|
|
22
|
+
// `patch-lint-cross.ts` so the per-patch and cross-patch rule bodies each
|
|
23
|
+
// stay within the per-file line budget. The public surface is re-exported
|
|
24
|
+
// from `patch-lint-reexports.ts` so callers keep importing from one module.
|
|
26
25
|
export * from './patch-lint-reexports.js';
|
|
27
26
|
// The CSS rule bodies live in `patch-lint-css.ts` (same per-file-budget
|
|
28
27
|
// split as the other rule families); re-export the imported binding so
|
|
@@ -38,10 +37,10 @@ const FILE_SIZE_THRESHOLDS = {
|
|
|
38
37
|
};
|
|
39
38
|
/**
|
|
40
39
|
* Counts the lines of `content` the way `wc -l` reports them: a trailing
|
|
41
|
-
* newline terminates the last line rather than starting an empty extra
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
40
|
+
* newline terminates the last line rather than starting an empty extra one.
|
|
41
|
+
* A naive `split('\n').length` over-counts by one for any content ending in
|
|
42
|
+
* `\n` (the common case), making the size rules fire one line early against
|
|
43
|
+
* the operator's own `wc -l` measurement.
|
|
45
44
|
*/
|
|
46
45
|
function countContentLines(content) {
|
|
47
46
|
const lines = content.split('\n');
|
|
@@ -94,50 +93,39 @@ const PATCH_LINE_THRESHOLDS = {
|
|
|
94
93
|
* Branding patches have a legitimate reason to be large: they include
|
|
95
94
|
* every locale's `brand.ftl`, copied upstream CSS/PNG assets, and the
|
|
96
95
|
* fork-specific `configure.sh` / `brand.properties` under a single
|
|
97
|
-
* `browser/branding/<name>/` subtree.
|
|
96
|
+
* `browser/branding/<name>/` subtree.
|
|
98
97
|
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* Both data points need to surface as a soft `notice` rather than a
|
|
107
|
-
* `warning`, since they represent the *minimum* branding diff. The
|
|
108
|
-
* pre-2026-04-25 calibration {3000/8000/20000} put 15904 firmly in the
|
|
109
|
-
* `warning` band, contradicting the docstring's "loud but not
|
|
110
|
-
* actionable" intent. The current calibration moves the warning band
|
|
111
|
-
* above the eval baseline (with ~13% headroom) and the error band to
|
|
112
|
-
* roughly 2× the baseline — reaching `error` strongly suggests
|
|
113
|
-
* non-branding work is bundled in.
|
|
98
|
+
* Calibrated against a fresh-fork branding export, which lands around
|
|
99
|
+
* 15–16k lines (localized brand.ftl across many locales + SVG path data +
|
|
100
|
+
* copied upstream CSS). That is the MINIMUM branding diff, so it must
|
|
101
|
+
* surface as a soft `notice` rather than a `warning`: the warning band
|
|
102
|
+
* sits above it with ~13% headroom, and the error band at roughly 2× the
|
|
103
|
+
* baseline, where non-branding work is probably bundled in.
|
|
114
104
|
*
|
|
115
105
|
* Permissive thresholds are safe because the *gate* into this tier is
|
|
116
|
-
* narrow
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
* cannot accidentally land here.
|
|
106
|
+
* narrow: auto-detect requires every file under `browser/branding/` plus a
|
|
107
|
+
* tight registration allowlist, or an explicit `PatchMetadata.tier:
|
|
108
|
+
* "branding"` opt-in. A non-branding patch cannot accidentally land here.
|
|
120
109
|
*/
|
|
121
110
|
branding: { notice: 8000, warning: 18000, error: 30000 },
|
|
122
111
|
};
|
|
123
112
|
/**
|
|
124
|
-
* File-count thresholds for the `large-patch-files` rule, mirroring the
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
113
|
+
* File-count thresholds for the `large-patch-files` rule, mirroring the tier
|
|
114
|
+
* shape of {@link PATCH_LINE_THRESHOLDS}. A single warning-only threshold
|
|
115
|
+
* per tier is intentional — file count expresses scope, not blast radius,
|
|
116
|
+
* and there is no error band that would block export.
|
|
128
117
|
*
|
|
129
118
|
* The branding tier sits well above the typical floor because branding
|
|
130
|
-
* patches inherently span many files: PNG/ICO icon assets in 7+ sizes,
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
* on a genuinely bloated patch.
|
|
119
|
+
* patches inherently span many files: PNG/ICO icon assets in 7+ sizes, MSIX
|
|
120
|
+
* manifests, channel-specific configs, locale `.ftl` files, Windows/macOS
|
|
121
|
+
* launcher resources. A fresh-fork branding bundle is around 56 files, so 60
|
|
122
|
+
* leaves headroom for additional channels/locales while still firing on a
|
|
123
|
+
* genuinely bloated patch.
|
|
136
124
|
*
|
|
137
|
-
* Test tier matches general because a test-only patch rarely touches
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
125
|
+
* Test tier matches general because a test-only patch rarely touches many
|
|
126
|
+
* files (a single regression test usually adds 1–3 fixtures); the elevation
|
|
127
|
+
* in {@link PATCH_LINE_THRESHOLDS.test} addresses big table-driven test
|
|
128
|
+
* bodies, not file fan-out.
|
|
141
129
|
*/
|
|
142
130
|
const PATCH_FILES_THRESHOLDS = {
|
|
143
131
|
general: 5,
|
|
@@ -145,29 +133,25 @@ const PATCH_FILES_THRESHOLDS = {
|
|
|
145
133
|
branding: 60,
|
|
146
134
|
};
|
|
147
135
|
/**
|
|
148
|
-
* Shared remedy sentence for the over-budget findings
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
* emission sites — the wording cannot drift.
|
|
136
|
+
* Shared remedy sentence for the over-budget findings. Both places an
|
|
137
|
+
* operator stands when a patch outgrows its budget must name the sanctioned
|
|
138
|
+
* one-transaction way out, or they reach for the wrong tools first. One
|
|
139
|
+
* constant, four emission sites, so the wording cannot drift.
|
|
153
140
|
*/
|
|
154
141
|
const SPLIT_HINT = 'Consider splitting into smaller, focused patches — ' +
|
|
155
142
|
'"fireforge patch move-files <from> <to> --file <path> --create --order <n>" ' +
|
|
156
143
|
'moves files into a new patch in one transaction.';
|
|
157
144
|
/**
|
|
158
145
|
* Fixed allowlist of non-branding sibling paths that real-world Firefox
|
|
159
|
-
* branding patches legitimately need to touch to register the new
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
* `browser/moz.configure`
|
|
163
|
-
*
|
|
164
|
-
* required every file to live under `browser/branding/`. This
|
|
165
|
-
* allowlist stays intentionally narrow — additions require a real
|
|
166
|
-
* operator data point, not a speculative expansion. Add new entries
|
|
167
|
-
* only when a genuine branding patch cannot be expressed without a
|
|
168
|
-
* specific registration sibling.
|
|
146
|
+
* branding patches legitimately need to touch to register the new branding
|
|
147
|
+
* flavor with the top-level configure. A predicate requiring every file to
|
|
148
|
+
* live under `browser/branding/` drops a branding patch that also touches
|
|
149
|
+
* `browser/moz.configure` — the canonical registration point — into the
|
|
150
|
+
* general lint tier.
|
|
169
151
|
*
|
|
170
|
-
*
|
|
152
|
+
* Intentionally narrow: add entries only when a genuine branding patch
|
|
153
|
+
* cannot be expressed without a specific registration sibling. Pinned
|
|
154
|
+
* against ESR 140.x conventions at time of writing.
|
|
171
155
|
*/
|
|
172
156
|
const BRANDING_REGISTRATION_FILES = new Set([
|
|
173
157
|
'browser/moz.configure',
|
|
@@ -235,33 +219,31 @@ function isBrowserChromeTestFile(file) {
|
|
|
235
219
|
/**
|
|
236
220
|
* Bare assertion-call detection for the `test-needs-assertion` floor.
|
|
237
221
|
*
|
|
238
|
-
* Each alternative must sit at a call boundary: preceded by something that
|
|
239
|
-
* not an identifier character, `.`, `#`, or `-`.
|
|
240
|
-
* `strippedContent.includes(tok)` over
|
|
241
|
-
* `
|
|
242
|
-
*
|
|
243
|
-
* `promiseIsDeeply(` contains `isDeeply(
|
|
244
|
-
* any such call
|
|
245
|
-
* catch.
|
|
222
|
+
* Each alternative must sit at a call boundary: preceded by something that
|
|
223
|
+
* is not an identifier character, `.`, `#`, or `-`. A plain
|
|
224
|
+
* `strippedContent.includes(tok)` over `Assert.`, `ok(`, `is(`, `isnot(`,
|
|
225
|
+
* `isDeeply(` lets any identifier merely *ending* in one satisfy the gate —
|
|
226
|
+
* `this.axis(3)` contains `is(`, `book(` contains `ok(`,
|
|
227
|
+
* `promiseIsDeeply(` contains `isDeeply(` — so an assertion-free smoke test
|
|
228
|
+
* using any such call clears the floor.
|
|
246
229
|
*
|
|
247
|
-
* The namespaced arm must name a member
|
|
248
|
-
* its dot alone
|
|
249
|
-
*
|
|
250
|
-
* `SimpleTest.
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
230
|
+
* The namespaced arm must name a member AND a call. Matching the namespace
|
|
231
|
+
* and its dot alone re-opens the same hole from the other side:
|
|
232
|
+
* `SimpleTest` is mostly *harness* API, so `SimpleTest.finish()`,
|
|
233
|
+
* `SimpleTest.waitForExplicitFinish()` and `SimpleTest.requestCompleteLog()`
|
|
234
|
+
* would each clear the floor on their own — the exact calls an
|
|
235
|
+
* assertion-free smoke test contains. The enumeration below is the
|
|
236
|
+
* mochitest/xpcshell assertion surface both namespaces share, and it is what
|
|
237
|
+
* the user-facing message names.
|
|
255
238
|
*
|
|
256
|
-
* Two qualified spellings of the bare four
|
|
257
|
-
* globals ARE window properties) and an optional-chained `win?.ok(...)
|
|
258
|
-
*
|
|
239
|
+
* Two qualified spellings of the bare four also count: `window.ok(...)` (the
|
|
240
|
+
* globals ARE window properties) and an optional-chained `win?.ok(...)`;
|
|
241
|
+
* blocking those flags tests whose only assertions are real as
|
|
259
242
|
* assertion-free. `SpecialPowers.ok(` stays excluded — that is API surface,
|
|
260
243
|
* not an assertion.
|
|
261
244
|
*
|
|
262
|
-
* Deliberately
|
|
263
|
-
*
|
|
264
|
-
* proof.
|
|
245
|
+
* Deliberately textual, not AST-based: this runs over patch bodies rather
|
|
246
|
+
* than resolvable sources, and the surrounding rule is a floor, not a proof.
|
|
265
247
|
*/
|
|
266
248
|
const ASSERTION_MEMBERS = [
|
|
267
249
|
'ok',
|
|
@@ -318,22 +300,18 @@ export function commentStyleForFile(file) {
|
|
|
318
300
|
* Accepted shapes, in order:
|
|
319
301
|
* - the project's own header for the file's comment style;
|
|
320
302
|
* - under `browser/branding/`, ANY recognised license header in the
|
|
321
|
-
* matching style: the setup-generated branding directory is copied
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
* GPL-2.0-or-later;
|
|
303
|
+
* matching style: the setup-generated branding directory is copied from
|
|
304
|
+
* Firefox's `unofficial` template and arrives with Mozilla MPL-2.0
|
|
305
|
+
* headers — legitimate for copyright purposes (the assets are Mozilla's)
|
|
306
|
+
* even when the fork's own code is 0BSD / EUPL-1.2 / GPL-2.0-or-later;
|
|
326
307
|
* - on an MPL-2.0 project, any recognised header in the matching style;
|
|
327
308
|
* - the verbatim upstream MPL-2.0 block header (`/* … *\/`, optionally
|
|
328
|
-
* behind a leading editor-directive comment) REGARDLESS of the
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
* still needed a patch-level lintIgnore. Only the block form is
|
|
335
|
-
* accepted — the `// `-style MPL header is FireForge-generated, not
|
|
336
|
-
* upstream provenance — and `hash`-style files (FTL) stay excluded
|
|
309
|
+
* behind a leading editor-directive comment) REGARDLESS of the project
|
|
310
|
+
* license, on any file whose comment syntax is the block form (JS and
|
|
311
|
+
* CSS): a file copied from the Firefox tree legitimately keeps Mozilla's
|
|
312
|
+
* header for provenance in an EUPL/GPL/0BSD project too. Only the block
|
|
313
|
+
* form is accepted — the `// `-style MPL header is FireForge-generated,
|
|
314
|
+
* not upstream provenance — and `hash`-style files (FTL) stay excluded
|
|
337
315
|
* because `/* … *\/` is not a comment there.
|
|
338
316
|
*
|
|
339
317
|
* @param file - Engine-relative path of the new file
|
|
@@ -588,16 +566,15 @@ export function lintPatchSize(filesAffected, lineCount, patchTier) {
|
|
|
588
566
|
const issues = [];
|
|
589
567
|
// Tier selection: test > branding > general. Tests keep their elevated
|
|
590
568
|
// thresholds because a big regression test is legitimate (table-driven
|
|
591
|
-
// harnesses run into the thousands of lines). Branding patches get
|
|
592
|
-
//
|
|
593
|
-
//
|
|
594
|
-
//
|
|
595
|
-
//
|
|
596
|
-
//
|
|
597
|
-
//
|
|
598
|
-
//
|
|
599
|
-
//
|
|
600
|
-
// disagree about which tier applies.
|
|
569
|
+
// harnesses run into the thousands of lines). Branding patches get their
|
|
570
|
+
// own tier so a first export of setup-generated branding does not fire the
|
|
571
|
+
// general hard limit — see `PATCH_LINE_THRESHOLDS.branding` and
|
|
572
|
+
// `PATCH_FILES_THRESHOLDS.branding` above. An explicit `patchTier` opt-in
|
|
573
|
+
// forces branding even when `isBrandingOnlyPatch` cannot reach the patch's
|
|
574
|
+
// actual shape (a branding patch that also touches a non-allowlisted
|
|
575
|
+
// sibling like a vendor-specific icon resource). Both checks read off the
|
|
576
|
+
// same decision so the file-count and line-count rules cannot disagree
|
|
577
|
+
// about which tier applies.
|
|
601
578
|
const decision = resolvePatchSizeTier(filesAffected, patchTier);
|
|
602
579
|
const fileThreshold = decision.tier === 'test'
|
|
603
580
|
? PATCH_FILES_THRESHOLDS.test
|
|
@@ -687,23 +664,14 @@ export async function lintModifiedFileHeaders(repoDir, affectedFiles, newFiles)
|
|
|
687
664
|
* @param affectedFiles - File paths (relative to repoDir) affected by the patch
|
|
688
665
|
* @param diffContent - Raw unified diff string
|
|
689
666
|
* @param config - Project configuration
|
|
690
|
-
* @param
|
|
691
|
-
*
|
|
692
|
-
*
|
|
693
|
-
*
|
|
694
|
-
* manifest, etc.) can opt out of a specific rule without reaching for the
|
|
695
|
-
* blunt `--skip-lint` hammer. Not mutated by this function.
|
|
696
|
-
* @param patchTier - Optional explicit tier override, threaded from
|
|
697
|
-
* `PatchMetadata.tier`. When `"branding"` forces the branding
|
|
698
|
-
* thresholds on the `large-patch-lines` rule. Callers with a
|
|
699
|
-
* per-patch manifest context (re-export, per-patch lint) should
|
|
700
|
-
* pass this; aggregate-mode callers without a specific patch
|
|
701
|
-
* context skip it and fall through to auto-detection.
|
|
702
|
-
* @param options - Optional behaviour switches; see
|
|
703
|
-
* {@link LintExportedPatchOptions}.
|
|
667
|
+
* @param options - Optional context and behaviour switches; see
|
|
668
|
+
* {@link LintExportedPatchOptions}. Every optional input lives here
|
|
669
|
+
* rather than in a positional tail: four of the five call sites had to
|
|
670
|
+
* pass `undefined` placeholders to reach the one member they wanted.
|
|
704
671
|
* @returns Array of all lint issues found
|
|
705
672
|
*/
|
|
706
|
-
export async function lintExportedPatch(repoDir, affectedFiles, diffContent, config,
|
|
673
|
+
export async function lintExportedPatch(repoDir, affectedFiles, diffContent, config, options) {
|
|
674
|
+
const { patchQueueCtx, ignoreChecks, patchTier } = options ?? {};
|
|
707
675
|
const newFiles = detectNewFilesInDiff(diffContent);
|
|
708
676
|
const { textLines: lineCount } = countNonBinaryDiffLines(diffContent);
|
|
709
677
|
const patchOwnedFiles = resolvePatchOwnedSysMjs(newFiles, patchQueueCtx);
|
|
@@ -6,7 +6,7 @@ export interface PatchDirectoryLockOptions {
|
|
|
6
6
|
* Wait up to this many seconds for the patch directory lock instead of the
|
|
7
7
|
* default ~30 s budget. Enables exponential poll backoff (100 ms → 2 s)
|
|
8
8
|
* and a holder-identified progress line roughly every 5 s. `undefined`
|
|
9
|
-
*
|
|
9
|
+
* keeps the default.
|
|
10
10
|
*/
|
|
11
11
|
waitLockSeconds?: number | undefined;
|
|
12
12
|
/** Command name recorded in the lock's owner metadata for holder diagnostics. */
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Filesystem-based lock for serializing patch directory mutations.
|
|
4
4
|
*/
|
|
5
5
|
import { join } from 'node:path';
|
|
6
|
-
import { FireForgeError } from '../errors/base.js';
|
|
6
|
+
import { CommandError, FireForgeError } from '../errors/base.js';
|
|
7
7
|
import { PatchError } from '../errors/patch.js';
|
|
8
8
|
import { assert } from '../utils/assert.js';
|
|
9
9
|
import { toError } from '../utils/errors.js';
|
|
@@ -56,7 +56,24 @@ export async function assertPatchDirectoryLockHeld(patchesDir, context) {
|
|
|
56
56
|
export async function withPatchDirectoryLock(patchesDir, operation, options = {}) {
|
|
57
57
|
const lockDir = join(patchesDir, PATCH_DIRECTORY_LOCK);
|
|
58
58
|
const { waitLockSeconds, command } = options;
|
|
59
|
-
|
|
59
|
+
// Tag whatever the BODY throws so the catch below can tell it apart from a
|
|
60
|
+
// lock-acquire/release failure. Narrowing by origin rather than by error
|
|
61
|
+
// shape is what "the rewrap is for lock I/O" actually means: an errno test
|
|
62
|
+
// would still reclassify an EACCES raised while the body writes a .patch
|
|
63
|
+
// file, and a class test cannot see a bare `new Error` from a body at all.
|
|
64
|
+
let bodyFailure;
|
|
65
|
+
let bodyThrew = false;
|
|
66
|
+
const trackedOperation = async () => {
|
|
67
|
+
try {
|
|
68
|
+
return await operation();
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
bodyThrew = true;
|
|
72
|
+
bodyFailure = error;
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
return withFileLock(lockDir, trackedOperation, {
|
|
60
77
|
...(waitLockSeconds !== undefined
|
|
61
78
|
? {
|
|
62
79
|
timeoutMs: waitLockSeconds * 1000,
|
|
@@ -71,12 +88,12 @@ export async function withPatchDirectoryLock(patchesDir, operation, options = {}
|
|
|
71
88
|
...(command !== undefined
|
|
72
89
|
? { ownerMetadata: [`command=${command}`, `started=${new Date().toISOString()}`] }
|
|
73
90
|
: {}),
|
|
74
|
-
// Reason first, remedy second. The remedy is waiting, not
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
91
|
+
// Reason first, remedy second. The remedy is waiting, not deleting: bulk
|
|
92
|
+
// exports/re-exports legitimately hold this lock for minutes, and
|
|
93
|
+
// FireForge reaps genuinely stale locks on its own — advice to `rm -rf`
|
|
94
|
+
// while a holder is alive destroys a live lock. The leading sentence is
|
|
95
|
+
// a message contract; extend, do not reword. withFileLock appends the
|
|
96
|
+
// holder identification.
|
|
80
97
|
onTimeoutMessage: `Timed out waiting for another FireForge command mutating ${patchesDir}.\n` +
|
|
81
98
|
`Pass --wait-lock [seconds] to wait longer (bare --wait-lock waits up to 60 seconds). ` +
|
|
82
99
|
`FireForge removes genuinely stale locks automatically; only if no other fireforge ` +
|
|
@@ -84,9 +101,28 @@ export async function withPatchDirectoryLock(patchesDir, operation, options = {}
|
|
|
84
101
|
onStaleLockMessage: (ageMs) => `Removing stale patch lock (age: ${Math.round(ageMs / 1000)}s). ` +
|
|
85
102
|
'A previous fireforge process may have crashed.',
|
|
86
103
|
}).catch((error) => {
|
|
104
|
+
// The body's own failures are never ours to reclassify. Rewrapping them
|
|
105
|
+
// reports an EACCES writing patches.json, a postcondition failure from
|
|
106
|
+
// renumberPatchesInManifest, or a plain TypeError from a FireForge bug
|
|
107
|
+
// as a "Patch Error" carrying three fixed remedies about Firefox-version
|
|
108
|
+
// compatibility and `fireforge reset` — none of which apply. Worse,
|
|
109
|
+
// src/cli.ts prints a stack only for non-FireForgeError throwables, so
|
|
110
|
+
// the rewrap moves real bugs into the branch that discards their stack.
|
|
111
|
+
if (bodyThrew && error === bodyFailure) {
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
87
114
|
if (error instanceof FireForgeError) {
|
|
88
115
|
throw error;
|
|
89
116
|
}
|
|
90
|
-
|
|
117
|
+
// CommandError is the one class in src/errors/ that does NOT extend
|
|
118
|
+
// FireForgeError: it is the sentinel carrying an already-rendered exit
|
|
119
|
+
// code to the entrypoint. The `instanceof FireForgeError` guard above
|
|
120
|
+
// misses it, so without this the exit code was replaced by PATCH_ERROR.
|
|
121
|
+
if (error instanceof CommandError) {
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
// What remains is a genuine failure to acquire or release the lock.
|
|
125
|
+
const cause = toError(error);
|
|
126
|
+
throw new PatchError(cause.message, undefined, cause);
|
|
91
127
|
});
|
|
92
128
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Manifest consistency checks and rebuild/recovery operations.
|
|
3
3
|
*/
|
|
4
4
|
import type { PatchesManifest } from '../types/commands/index.js';
|
|
5
|
+
import type { PatchDirectoryLockOptions } from './patch-lock.js';
|
|
5
6
|
/** Consistency issue codes for manifest validation. */
|
|
6
7
|
export interface PatchManifestConsistencyIssue {
|
|
7
8
|
code: 'manifest-invalid' | 'manifest-missing' | 'missing-patch-file' | 'untracked-patch-file' | 'files-affected-mismatch' | 'duplicate-manifest-entry';
|
|
@@ -14,6 +15,16 @@ export interface PatchManifestConsistencyIssue {
|
|
|
14
15
|
* @returns Consistency issues between manifest metadata and on-disk patch files
|
|
15
16
|
*/
|
|
16
17
|
export declare function validatePatchesManifestConsistency(patchesDir: string): Promise<PatchManifestConsistencyIssue[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Recovery hint for an unrepaired consistency failure.
|
|
20
|
+
*
|
|
21
|
+
* Drift that is only in `filesAffected` is a derived value disagreeing with
|
|
22
|
+
* the diff it describes, and the narrow repair fixes exactly that. Naming the
|
|
23
|
+
* whole-manifest rebuild for it — as this hint used to, unconditionally — puts
|
|
24
|
+
* an operator one keystroke from rewriting every row in the manifest to
|
|
25
|
+
* correct one list.
|
|
26
|
+
*/
|
|
27
|
+
export declare function recommendManifestRepair(issues: readonly PatchManifestConsistencyIssue[]): string;
|
|
17
28
|
/**
|
|
18
29
|
* Summary of a {@link rebuildPatchesManifest} run. `recoveredFilenames`
|
|
19
30
|
* lists patches whose manifest entry was reconstructed from filename,
|
|
@@ -24,21 +35,61 @@ export declare function validatePatchesManifestConsistency(patchesDir: string):
|
|
|
24
35
|
* invented vs which was restored.
|
|
25
36
|
*/
|
|
26
37
|
export interface RebuildPatchesManifestResult {
|
|
27
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Rebuilt manifest, ready to be re-applied by callers. Persisted unless
|
|
40
|
+
* the run was a dry run — see {@link RebuildPatchesManifestResult.written}.
|
|
41
|
+
*/
|
|
28
42
|
manifest: PatchesManifest;
|
|
29
43
|
/**
|
|
30
44
|
* Filenames whose manifest entry had no pre-existing metadata to
|
|
31
45
|
* preserve — every descriptive field on these entries is inferred.
|
|
32
46
|
*/
|
|
33
47
|
recoveredFilenames: string[];
|
|
48
|
+
/**
|
|
49
|
+
* Filenames that had a manifest entry but no patch file on disk, so the
|
|
50
|
+
* row was dropped. Discarding these silently is how a manifest quietly
|
|
51
|
+
* loses rows an operator still expected to be there.
|
|
52
|
+
*/
|
|
53
|
+
droppedFilenames: string[];
|
|
54
|
+
/** False when the run was a dry run and patches.json was left untouched. */
|
|
55
|
+
written: boolean;
|
|
56
|
+
}
|
|
57
|
+
/** Options for {@link rebuildPatchesManifest}. */
|
|
58
|
+
export interface RebuildPatchesManifestOptions extends PatchDirectoryLockOptions {
|
|
59
|
+
/**
|
|
60
|
+
* Proceed even when patches.json exists but cannot be parsed, in which case
|
|
61
|
+
* there is no existing metadata to preserve and every descriptive field on
|
|
62
|
+
* every entry is invented. Refused without this flag — see
|
|
63
|
+
* {@link rebuildPatchesManifest}.
|
|
64
|
+
*/
|
|
65
|
+
allowMetadataLoss?: boolean;
|
|
66
|
+
/** Compute the rebuilt manifest without writing it. */
|
|
67
|
+
dryRun?: boolean;
|
|
34
68
|
}
|
|
35
69
|
/**
|
|
36
70
|
* Rebuilds patches.json from the patch files currently present on disk.
|
|
37
|
-
*
|
|
38
|
-
*
|
|
71
|
+
*
|
|
72
|
+
* This is a MERGE, not a from-scratch rebuild: only `filesAffected` and
|
|
73
|
+
* `order` are recomputed from the patch files, and every other field on an
|
|
74
|
+
* existing entry is carried forward untouched. Entries with no pre-existing
|
|
75
|
+
* metadata are recovered from filename structure, patch contents, and file
|
|
76
|
+
* mtimes.
|
|
77
|
+
*
|
|
78
|
+
* Refuses when patches.json exists but cannot be parsed, because that is the
|
|
79
|
+
* one case where nothing can be carried forward and the "merge" silently
|
|
80
|
+
* becomes a whole-manifest reinvention. Pass `allowMetadataLoss` to accept it.
|
|
81
|
+
*
|
|
39
82
|
* @param patchesDir - Path to the patches directory
|
|
40
83
|
* @param fallbackSourceEsrVersion - source version to use for recovered legacy entries
|
|
41
|
-
* @
|
|
42
|
-
*
|
|
84
|
+
* @param options - Lock options plus `allowMetadataLoss` / `dryRun`
|
|
85
|
+
* @returns {@link RebuildPatchesManifestResult} — the rebuilt manifest, the
|
|
86
|
+
* filenames that were reconstructed from generic defaults, and the rows
|
|
87
|
+
* dropped because their patch file is gone.
|
|
88
|
+
*/
|
|
89
|
+
export declare function rebuildPatchesManifest(patchesDir: string, fallbackSourceEsrVersion: string, options?: RebuildPatchesManifestOptions): Promise<RebuildPatchesManifestResult>;
|
|
90
|
+
/**
|
|
91
|
+
* Canonical form of a `filesAffected` list: deduplicated and sorted, so a
|
|
92
|
+
* comparison between a declared list and one extracted from a patch body is
|
|
93
|
+
* about membership rather than ordering.
|
|
43
94
|
*/
|
|
44
|
-
export declare function
|
|
95
|
+
export declare function normalizeAffectedFiles(files: string[]): string[];
|