@hominis/fireforge 0.45.0 → 0.46.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +409 -446
- package/dist/bin/fireforge.d.ts +1 -1
- package/dist/bin/fireforge.js +21 -15
- package/dist/build-info.json +4 -4
- package/dist/src/cli-usage-error.d.ts +46 -0
- package/dist/src/cli-usage-error.js +81 -0
- package/dist/src/cli.d.ts +7 -2
- package/dist/src/cli.js +47 -47
- package/dist/src/commands/bootstrap-checks.js +2 -1
- package/dist/src/commands/bootstrap.js +3 -4
- package/dist/src/commands/build.js +27 -17
- package/dist/src/commands/config.js +9 -9
- package/dist/src/commands/destructive-decision.d.ts +19 -0
- package/dist/src/commands/destructive-decision.js +31 -0
- package/dist/src/commands/discard.js +5 -5
- package/dist/src/commands/doctor-check-core.d.ts +4 -10
- package/dist/src/commands/doctor-check-core.js +0 -8
- package/dist/src/commands/doctor-external-toolchains.js +2 -2
- package/dist/src/commands/doctor-furnace-config-sync.d.ts +2 -2
- package/dist/src/commands/doctor-furnace-config-sync.js +20 -20
- package/dist/src/commands/doctor-furnace-jar.d.ts +1 -1
- package/dist/src/commands/doctor-furnace-jar.js +1 -1
- package/dist/src/commands/doctor-furnace.js +22 -22
- package/dist/src/commands/doctor-orphaned-harness.d.ts +10 -17
- package/dist/src/commands/doctor-orphaned-harness.js +14 -23
- package/dist/src/commands/doctor-patch-manifest.d.ts +2 -1
- package/dist/src/commands/doctor-patch-manifest.js +7 -6
- package/dist/src/commands/doctor-post-rebase-audit.js +3 -3
- package/dist/src/commands/doctor-source-pin.d.ts +12 -12
- package/dist/src/commands/doctor-source-pin.js +14 -14
- package/dist/src/commands/doctor-working-tree.d.ts +3 -3
- package/dist/src/commands/doctor-working-tree.js +3 -3
- package/dist/src/commands/doctor.d.ts +3 -1
- package/dist/src/commands/doctor.js +15 -16
- package/dist/src/commands/download.js +50 -37
- package/dist/src/commands/export-all.js +29 -12
- package/dist/src/commands/export-flow.d.ts +5 -5
- package/dist/src/commands/export-flow.js +29 -59
- package/dist/src/commands/export-placement-conflicts.d.ts +3 -3
- package/dist/src/commands/export-placement-conflicts.js +12 -12
- package/dist/src/commands/export-placement-gate.d.ts +2 -2
- package/dist/src/commands/export-placement-gate.js +7 -13
- package/dist/src/commands/export-placement-policy.d.ts +1 -1
- package/dist/src/commands/export-placement-policy.js +4 -6
- package/dist/src/commands/export-shared.d.ts +51 -32
- package/dist/src/commands/export-shared.js +17 -32
- package/dist/src/commands/export.js +14 -5
- package/dist/src/commands/furnace/apply.js +16 -16
- package/dist/src/commands/furnace/authoring-config.d.ts +13 -0
- package/dist/src/commands/furnace/authoring-config.js +19 -0
- package/dist/src/commands/furnace/chrome-doc-remove.d.ts +1 -1
- package/dist/src/commands/furnace/chrome-doc-remove.js +2 -2
- package/dist/src/commands/furnace/chrome-doc-templates.d.ts +14 -14
- package/dist/src/commands/furnace/chrome-doc-templates.js +17 -17
- package/dist/src/commands/furnace/chrome-doc-tests.d.ts +2 -2
- package/dist/src/commands/furnace/chrome-doc-tests.js +4 -4
- package/dist/src/commands/furnace/chrome-doc.d.ts +8 -8
- package/dist/src/commands/furnace/chrome-doc.js +18 -18
- package/dist/src/commands/furnace/create-browser-test.d.ts +1 -1
- package/dist/src/commands/furnace/create-browser-test.js +7 -12
- package/dist/src/commands/furnace/create-dry-run.d.ts +4 -4
- package/dist/src/commands/furnace/create-dry-run.js +6 -9
- package/dist/src/commands/furnace/create-features.d.ts +2 -2
- package/dist/src/commands/furnace/create-features.js +2 -2
- package/dist/src/commands/furnace/create-mochikit.d.ts +4 -4
- package/dist/src/commands/furnace/create-mochikit.js +7 -7
- package/dist/src/commands/furnace/create-templates.d.ts +31 -15
- package/dist/src/commands/furnace/create-templates.js +20 -19
- package/dist/src/commands/furnace/create-xpcshell.d.ts +5 -5
- package/dist/src/commands/furnace/create-xpcshell.js +8 -8
- package/dist/src/commands/furnace/create.d.ts +1 -1
- package/dist/src/commands/furnace/create.js +35 -29
- package/dist/src/commands/furnace/deploy.js +15 -6
- package/dist/src/commands/furnace/diff.js +7 -7
- package/dist/src/commands/furnace/index.js +1 -1
- package/dist/src/commands/furnace/init.js +17 -16
- package/dist/src/commands/furnace/list.js +2 -2
- package/dist/src/commands/furnace/override.d.ts +1 -1
- package/dist/src/commands/furnace/override.js +43 -34
- package/dist/src/commands/furnace/preview.js +17 -17
- package/dist/src/commands/furnace/refresh.js +15 -7
- package/dist/src/commands/furnace/remove-mutations.d.ts +9 -10
- package/dist/src/commands/furnace/remove-mutations.js +19 -19
- package/dist/src/commands/furnace/remove-state.d.ts +1 -1
- package/dist/src/commands/furnace/remove-state.js +1 -1
- package/dist/src/commands/furnace/remove.js +4 -8
- package/dist/src/commands/furnace/rename-browser-test.js +10 -15
- package/dist/src/commands/furnace/rename-xpcshell.d.ts +2 -2
- package/dist/src/commands/furnace/rename-xpcshell.js +3 -3
- package/dist/src/commands/furnace/rename.js +36 -36
- package/dist/src/commands/furnace/scan.js +3 -3
- package/dist/src/commands/furnace/status.js +19 -16
- package/dist/src/commands/furnace/sync.js +6 -6
- package/dist/src/commands/furnace/test-file-name.d.ts +28 -0
- package/dist/src/commands/furnace/test-file-name.js +39 -0
- package/dist/src/commands/furnace/validate.js +11 -12
- package/dist/src/commands/furnace/validation-output.d.ts +21 -9
- package/dist/src/commands/furnace/validation-output.js +3 -8
- package/dist/src/commands/import.js +22 -29
- package/dist/src/commands/lint-per-patch.d.ts +2 -2
- package/dist/src/commands/lint-per-patch.js +27 -12
- package/dist/src/commands/lint-per-run-checkjs.d.ts +14 -15
- package/dist/src/commands/lint-per-run-checkjs.js +14 -15
- package/dist/src/commands/lint-report.d.ts +3 -3
- package/dist/src/commands/lint-report.js +4 -4
- package/dist/src/commands/lint.d.ts +5 -4
- package/dist/src/commands/lint.js +36 -36
- package/dist/src/commands/manifest.d.ts +4 -4
- package/dist/src/commands/manifest.js +1 -1
- package/dist/src/commands/package.js +4 -6
- package/dist/src/commands/patch/compact.d.ts +2 -2
- package/dist/src/commands/patch/compact.js +19 -20
- package/dist/src/commands/patch/delete.d.ts +1 -1
- package/dist/src/commands/patch/delete.js +23 -33
- package/dist/src/commands/patch/entry-projection.d.ts +13 -0
- package/dist/src/commands/patch/entry-projection.js +24 -0
- package/dist/src/commands/patch/lint-ignore.d.ts +3 -12
- package/dist/src/commands/patch/lint-ignore.js +33 -44
- package/dist/src/commands/patch/move-files-create.d.ts +2 -2
- package/dist/src/commands/patch/move-files-create.js +29 -15
- package/dist/src/commands/patch/move-files-into.d.ts +2 -2
- package/dist/src/commands/patch/move-files-into.js +41 -37
- package/dist/src/commands/patch/move-files.js +5 -14
- package/dist/src/commands/patch/patch-context.d.ts +1 -1
- package/dist/src/commands/patch/rename.d.ts +4 -4
- package/dist/src/commands/patch/rename.js +35 -49
- package/dist/src/commands/patch/reorder.js +35 -48
- package/dist/src/commands/patch/split-plan.d.ts +7 -8
- package/dist/src/commands/patch/split-plan.js +10 -13
- package/dist/src/commands/patch/split.d.ts +2 -2
- package/dist/src/commands/patch/split.js +50 -48
- package/dist/src/commands/patch/staged-dependency-validate.d.ts +1 -1
- package/dist/src/commands/patch/staged-dependency-validate.js +3 -3
- package/dist/src/commands/patch/staged-dependency.d.ts +1 -1
- package/dist/src/commands/patch/staged-dependency.js +22 -28
- package/dist/src/commands/patch/tier.d.ts +2 -2
- package/dist/src/commands/patch/tier.js +20 -30
- package/dist/src/commands/patch-rename-map.d.ts +19 -0
- package/dist/src/commands/patch-rename-map.js +36 -0
- package/dist/src/commands/pending-resolution.d.ts +15 -0
- package/dist/src/commands/pending-resolution.js +25 -0
- package/dist/src/commands/re-export-adjacent.d.ts +25 -3
- package/dist/src/commands/re-export-adjacent.js +40 -24
- package/dist/src/commands/re-export-bulk-scan.d.ts +3 -3
- package/dist/src/commands/re-export-bulk-scan.js +23 -27
- package/dist/src/commands/re-export-drift.d.ts +10 -10
- package/dist/src/commands/re-export-drift.js +33 -33
- package/dist/src/commands/re-export-files.d.ts +2 -3
- package/dist/src/commands/re-export-files.js +52 -44
- package/dist/src/commands/re-export-lint.d.ts +29 -30
- package/dist/src/commands/re-export-lint.js +36 -29
- package/dist/src/commands/re-export-options.d.ts +1 -1
- package/dist/src/commands/re-export-options.js +1 -1
- package/dist/src/commands/re-export-register.d.ts +1 -1
- package/dist/src/commands/re-export-register.js +1 -1
- package/dist/src/commands/re-export-scan.d.ts +1 -1
- package/dist/src/commands/re-export-scan.js +12 -9
- package/dist/src/commands/re-export-single.d.ts +23 -4
- package/dist/src/commands/re-export-single.js +39 -31
- package/dist/src/commands/re-export.js +35 -17
- package/dist/src/commands/rebase/abort.js +9 -14
- package/dist/src/commands/rebase/continue.js +20 -19
- package/dist/src/commands/rebase/index.d.ts +1 -1
- package/dist/src/commands/rebase/index.js +5 -5
- package/dist/src/commands/rebase/patch-loop.d.ts +2 -2
- package/dist/src/commands/rebase/patch-loop.js +20 -24
- package/dist/src/commands/register.js +5 -5
- package/dist/src/commands/reset.js +1 -1
- package/dist/src/commands/resolve.d.ts +2 -2
- package/dist/src/commands/resolve.js +21 -13
- package/dist/src/commands/run.d.ts +0 -13
- package/dist/src/commands/run.js +38 -51
- package/dist/src/commands/setup-support.d.ts +16 -4
- package/dist/src/commands/setup-support.js +20 -20
- package/dist/src/commands/setup.js +4 -10
- package/dist/src/commands/source.js +9 -2
- package/dist/src/commands/status-check.d.ts +3 -3
- package/dist/src/commands/status-check.js +6 -6
- package/dist/src/commands/status-json.d.ts +14 -13
- package/dist/src/commands/status-json.js +9 -8
- package/dist/src/commands/status-output.d.ts +3 -3
- package/dist/src/commands/status-output.js +5 -5
- package/dist/src/commands/status-ownership.d.ts +3 -3
- package/dist/src/commands/status-ownership.js +3 -3
- package/dist/src/commands/status.js +25 -26
- package/dist/src/commands/test-build-phase.d.ts +3 -3
- package/dist/src/commands/test-build-phase.js +48 -24
- package/dist/src/commands/test-diagnose.d.ts +1 -1
- package/dist/src/commands/test-diagnose.js +20 -20
- package/dist/src/commands/test-modes.d.ts +4 -4
- package/dist/src/commands/test-modes.js +4 -5
- package/dist/src/commands/test-register.js +5 -3
- package/dist/src/commands/test-run.d.ts +11 -11
- package/dist/src/commands/test-run.js +40 -33
- package/dist/src/commands/test-stale-gate.d.ts +12 -12
- package/dist/src/commands/test-stale-gate.js +17 -17
- package/dist/src/commands/test-verdict.d.ts +19 -5
- package/dist/src/commands/test-verdict.js +26 -11
- package/dist/src/commands/test.d.ts +3 -3
- package/dist/src/commands/test.js +73 -36
- package/dist/src/commands/token-coverage.js +3 -3
- package/dist/src/commands/token-list.d.ts +26 -0
- package/dist/src/commands/token-list.js +153 -0
- package/dist/src/commands/token.js +26 -10
- package/dist/src/commands/tree.js +26 -21
- package/dist/src/commands/typecheck.d.ts +6 -6
- package/dist/src/commands/typecheck.js +16 -16
- package/dist/src/commands/verify.d.ts +3 -3
- package/dist/src/commands/verify.js +10 -10
- package/dist/src/commands/watch.js +11 -11
- package/dist/src/commands/wire.js +17 -16
- package/dist/src/core/ast-utils.d.ts +7 -7
- package/dist/src/core/ast-utils.js +8 -8
- package/dist/src/core/branding.d.ts +5 -12
- package/dist/src/core/branding.js +6 -5
- package/dist/src/core/browser-wire.d.ts +1 -1
- package/dist/src/core/browser-wire.js +10 -7
- package/dist/src/core/build-audit-platform.d.ts +32 -3
- package/dist/src/core/build-audit-platform.js +153 -13
- package/dist/src/core/build-audit-registration.d.ts +5 -5
- package/dist/src/core/build-audit-registration.js +10 -9
- package/dist/src/core/build-audit-resolve.d.ts +5 -5
- package/dist/src/core/build-audit-resolve.js +6 -6
- package/dist/src/core/build-audit-skip.d.ts +57 -0
- package/dist/src/core/build-audit-skip.js +112 -0
- package/dist/src/core/build-audit-transforms.d.ts +2 -2
- package/dist/src/core/build-audit-transforms.js +3 -3
- package/dist/src/core/build-audit.d.ts +21 -8
- package/dist/src/core/build-audit.js +142 -40
- package/dist/src/core/build-baseline-types.d.ts +19 -18
- package/dist/src/core/build-baseline-types.js +1 -1
- package/dist/src/core/build-baseline.d.ts +48 -31
- package/dist/src/core/build-baseline.js +20 -43
- package/dist/src/core/build-jar-escalation.d.ts +8 -8
- package/dist/src/core/build-jar-escalation.js +18 -17
- package/dist/src/core/build-overwrite-guard.d.ts +4 -4
- package/dist/src/core/build-overwrite-guard.js +14 -14
- package/dist/src/core/build-prepare.d.ts +4 -12
- package/dist/src/core/build-prepare.js +22 -26
- package/dist/src/core/config-mutate.js +4 -4
- package/dist/src/core/config-paths.d.ts +2 -6
- package/dist/src/core/config-paths.js +4 -2
- package/dist/src/core/config-state.d.ts +0 -6
- package/dist/src/core/config-state.js +3 -21
- package/dist/src/core/config-validate-build-audit.d.ts +8 -0
- package/dist/src/core/config-validate-build-audit.js +80 -0
- package/dist/src/core/config-validate-file-size.d.ts +1 -1
- package/dist/src/core/config-validate-file-size.js +3 -3
- package/dist/src/core/config-validate-patch-policy.d.ts +2 -2
- package/dist/src/core/config-validate-patch-policy.js +3 -3
- package/dist/src/core/config-validate-test-toolchains.d.ts +2 -2
- package/dist/src/core/config-validate-test-toolchains.js +4 -5
- package/dist/src/core/config-validate.js +22 -12
- package/dist/src/core/config.d.ts +12 -12
- package/dist/src/core/config.js +21 -25
- package/dist/src/core/coverage-extend.d.ts +16 -16
- package/dist/src/core/coverage-extend.js +20 -20
- package/dist/src/core/destructive.d.ts +14 -14
- package/dist/src/core/destructive.js +9 -9
- package/dist/src/core/diff-hunks.d.ts +2 -2
- package/dist/src/core/diff-hunks.js +7 -7
- package/dist/src/core/discard-baseline.d.ts +10 -10
- package/dist/src/core/discard-baseline.js +22 -23
- package/dist/src/core/display-state.d.ts +11 -11
- package/dist/src/core/display-state.js +12 -12
- package/dist/src/core/engine-changes.d.ts +2 -2
- package/dist/src/core/engine-changes.js +2 -2
- package/dist/src/core/engine-precondition.d.ts +5 -13
- package/dist/src/core/engine-precondition.js +5 -10
- package/dist/src/core/engine-session-lock.d.ts +18 -18
- package/dist/src/core/engine-session-lock.js +50 -54
- package/dist/src/core/export-moved-code-shape.d.ts +7 -7
- package/dist/src/core/export-moved-code-shape.js +10 -10
- package/dist/src/core/file-lock-owner.d.ts +103 -0
- package/dist/src/core/file-lock-owner.js +259 -0
- package/dist/src/core/file-lock.d.ts +14 -19
- package/dist/src/core/file-lock.js +90 -128
- package/dist/src/core/firefox-cache.d.ts +13 -1
- package/dist/src/core/firefox-cache.js +61 -36
- package/dist/src/core/firefox-download.d.ts +15 -0
- package/dist/src/core/firefox-download.js +38 -22
- package/dist/src/core/firefox-extract.d.ts +8 -7
- package/dist/src/core/firefox-extract.js +45 -27
- package/dist/src/core/firefox.d.ts +34 -36
- package/dist/src/core/firefox.js +13 -44
- package/dist/src/core/furnace-apply-dry-run.d.ts +1 -6
- package/dist/src/core/furnace-apply-dry-run.js +2 -8
- package/dist/src/core/furnace-apply-ftl.d.ts +5 -5
- package/dist/src/core/furnace-apply-ftl.js +8 -8
- package/dist/src/core/furnace-apply-helpers.d.ts +9 -20
- package/dist/src/core/furnace-apply-helpers.js +28 -39
- package/dist/src/core/furnace-apply-output.js +1 -1
- package/dist/src/core/furnace-apply-overwrite-warn.d.ts +9 -9
- package/dist/src/core/furnace-apply-overwrite-warn.js +13 -11
- package/dist/src/core/furnace-apply-undeploy-actions.d.ts +1 -1
- package/dist/src/core/furnace-apply-undeploy-actions.js +1 -1
- package/dist/src/core/furnace-apply.d.ts +4 -4
- package/dist/src/core/furnace-apply.js +50 -29
- package/dist/src/core/furnace-checksum-utils.d.ts +5 -5
- package/dist/src/core/furnace-checksum-utils.js +5 -5
- package/dist/src/core/furnace-config-custom.d.ts +1 -1
- package/dist/src/core/furnace-config-custom.js +2 -2
- package/dist/src/core/furnace-config-order.js +1 -1
- package/dist/src/core/furnace-config-tokens.d.ts +3 -3
- package/dist/src/core/furnace-config-tokens.js +3 -3
- package/dist/src/core/furnace-config-validate.js +2 -2
- package/dist/src/core/furnace-config.d.ts +5 -5
- package/dist/src/core/furnace-config.js +40 -53
- package/dist/src/core/furnace-constants.d.ts +6 -6
- package/dist/src/core/furnace-constants.js +9 -8
- package/dist/src/core/furnace-css-fragments.d.ts +6 -6
- package/dist/src/core/furnace-css-fragments.js +11 -11
- package/dist/src/core/furnace-dir-entry.d.ts +20 -0
- package/dist/src/core/furnace-dir-entry.js +21 -0
- package/dist/src/core/furnace-jsconfig.d.ts +7 -7
- package/dist/src/core/furnace-jsconfig.js +22 -20
- package/dist/src/core/furnace-operation.d.ts +22 -19
- package/dist/src/core/furnace-operation.js +38 -34
- package/dist/src/core/furnace-precondition.d.ts +10 -10
- package/dist/src/core/furnace-precondition.js +8 -8
- package/dist/src/core/furnace-refresh.d.ts +18 -6
- package/dist/src/core/furnace-refresh.js +5 -8
- package/dist/src/core/furnace-registration-ast.d.ts +2 -3
- package/dist/src/core/furnace-registration-ast.js +9 -12
- package/dist/src/core/furnace-registration-remove.d.ts +4 -4
- package/dist/src/core/furnace-registration-remove.js +6 -6
- package/dist/src/core/furnace-registration-validate.d.ts +2 -2
- package/dist/src/core/furnace-registration-validate.js +2 -2
- package/dist/src/core/furnace-registration.d.ts +7 -6
- package/dist/src/core/furnace-registration.js +29 -36
- package/dist/src/core/furnace-rollback.d.ts +1 -1
- package/dist/src/core/furnace-rollback.js +5 -5
- package/dist/src/core/furnace-scanner.js +3 -6
- package/dist/src/core/furnace-stale-export.d.ts +17 -16
- package/dist/src/core/furnace-stale-export.js +16 -15
- package/dist/src/core/furnace-staleness.d.ts +2 -2
- package/dist/src/core/furnace-staleness.js +2 -2
- package/dist/src/core/furnace-state-persist.d.ts +12 -12
- package/dist/src/core/furnace-state-persist.js +10 -10
- package/dist/src/core/furnace-step-errors.d.ts +6 -6
- package/dist/src/core/furnace-step-errors.js +6 -6
- package/dist/src/core/furnace-validate-accessibility.js +14 -14
- package/dist/src/core/furnace-validate-compatibility.js +9 -9
- package/dist/src/core/furnace-validate-registration.d.ts +2 -2
- package/dist/src/core/furnace-validate-registration.js +18 -20
- package/dist/src/core/furnace-validate-structure.d.ts +1 -1
- package/dist/src/core/furnace-validate-structure.js +4 -4
- package/dist/src/core/furnace-validate.js +9 -9
- package/dist/src/core/furnace-version-drift.d.ts +5 -5
- package/dist/src/core/furnace-version-drift.js +5 -5
- package/dist/src/core/git-base.d.ts +6 -4
- package/dist/src/core/git-base.js +29 -7
- package/dist/src/core/git-diff-new-file.d.ts +40 -0
- package/dist/src/core/git-diff-new-file.js +119 -0
- package/dist/src/core/git-diff.d.ts +13 -13
- package/dist/src/core/git-diff.js +121 -189
- package/dist/src/core/git-file-ops.d.ts +6 -13
- package/dist/src/core/git-file-ops.js +11 -35
- package/dist/src/core/git-readonly-index.d.ts +12 -14
- package/dist/src/core/git-readonly-index.js +12 -16
- package/dist/src/core/git-status.d.ts +9 -2
- package/dist/src/core/git-status.js +23 -11
- package/dist/src/core/git.d.ts +3 -9
- package/dist/src/core/git.js +28 -57
- package/dist/src/core/harness-orphans.d.ts +17 -17
- package/dist/src/core/harness-orphans.js +28 -27
- package/dist/src/core/history-log.d.ts +19 -0
- package/dist/src/core/history-log.js +29 -0
- package/dist/src/core/license-headers.d.ts +19 -18
- package/dist/src/core/license-headers.js +29 -28
- package/dist/src/core/mach-build-artifacts.d.ts +21 -21
- package/dist/src/core/mach-build-artifacts.js +23 -23
- package/dist/src/core/mach-error-hints.d.ts +5 -10
- package/dist/src/core/mach-error-hints.js +14 -14
- package/dist/src/core/mach-known-noise-filter.d.ts +42 -38
- package/dist/src/core/mach-known-noise-filter.js +57 -56
- package/dist/src/core/mach-mozconfig.d.ts +6 -6
- package/dist/src/core/mach-mozconfig.js +17 -16
- package/dist/src/core/mach-python.d.ts +3 -0
- package/dist/src/core/mach-python.js +13 -7
- package/dist/src/core/mach-resource-shim.d.ts +24 -12
- package/dist/src/core/mach-resource-shim.js +124 -21
- package/dist/src/core/mach.d.ts +59 -73
- package/dist/src/core/mach.js +47 -115
- package/dist/src/core/marionette-port.d.ts +15 -30
- package/dist/src/core/marionette-port.js +46 -89
- package/dist/src/core/marionette-preflight.d.ts +6 -6
- package/dist/src/core/marionette-preflight.js +32 -50
- package/dist/src/core/markdown-table.d.ts +9 -9
- package/dist/src/core/markdown-table.js +14 -14
- package/dist/src/core/mochitest-server-port.d.ts +8 -8
- package/dist/src/core/mochitest-server-port.js +17 -17
- package/dist/src/core/module-resolution-preflight.d.ts +8 -8
- package/dist/src/core/module-resolution-preflight.js +11 -11
- package/dist/src/core/moz-manifest-helpers.d.ts +7 -7
- package/dist/src/core/moz-manifest-helpers.js +7 -7
- package/dist/src/core/moz-manifest-register.d.ts +1 -1
- package/dist/src/core/moz-manifest-register.js +2 -2
- package/dist/src/core/moz-manifest-rules.js +46 -42
- package/dist/src/core/moz-manifest-tokenizers.js +1 -1
- package/dist/src/core/ownership-table.d.ts +5 -5
- package/dist/src/core/ownership-table.js +7 -7
- package/dist/src/core/parser-fallback.d.ts +3 -3
- package/dist/src/core/parser-fallback.js +3 -3
- package/dist/src/core/patch-apply-fuzz.d.ts +5 -5
- package/dist/src/core/patch-apply-fuzz.js +13 -13
- package/dist/src/core/patch-apply.d.ts +13 -14
- package/dist/src/core/patch-apply.js +36 -42
- package/dist/src/core/patch-export-coverage.d.ts +0 -9
- package/dist/src/core/patch-export-coverage.js +1 -30
- package/dist/src/core/patch-export-update.d.ts +21 -4
- package/dist/src/core/patch-export-update.js +7 -6
- package/dist/src/core/patch-export.d.ts +20 -30
- package/dist/src/core/patch-export.js +55 -77
- package/dist/src/core/patch-files.d.ts +0 -4
- package/dist/src/core/patch-files.js +0 -11
- package/dist/src/core/patch-identifier-suggest.d.ts +1 -1
- package/dist/src/core/patch-identifier-suggest.js +4 -4
- package/dist/src/core/patch-lint-binary.d.ts +12 -18
- package/dist/src/core/patch-lint-cache.d.ts +18 -2
- package/dist/src/core/patch-lint-cache.js +16 -19
- package/dist/src/core/patch-lint-checkjs.d.ts +55 -38
- package/dist/src/core/patch-lint-checkjs.js +78 -64
- package/dist/src/core/patch-lint-chrome-jsdoc.d.ts +8 -9
- package/dist/src/core/patch-lint-chrome-jsdoc.js +10 -11
- package/dist/src/core/patch-lint-creators.d.ts +5 -9
- package/dist/src/core/patch-lint-creators.js +3 -3
- package/dist/src/core/patch-lint-cross.d.ts +27 -19
- package/dist/src/core/patch-lint-cross.js +67 -110
- package/dist/src/core/patch-lint-css.d.ts +1 -1
- package/dist/src/core/patch-lint-css.js +15 -11
- package/dist/src/core/patch-lint-diff-tag.d.ts +5 -5
- package/dist/src/core/patch-lint-diff-tag.js +5 -5
- package/dist/src/core/patch-lint-diff.d.ts +4 -4
- package/dist/src/core/patch-lint-diff.js +4 -4
- package/dist/src/core/patch-lint-file-size.d.ts +3 -3
- package/dist/src/core/patch-lint-file-size.js +6 -6
- package/dist/src/core/patch-lint-forward-registration.d.ts +58 -0
- package/dist/src/core/patch-lint-forward-registration.js +210 -0
- package/dist/src/core/patch-lint-jsdoc.d.ts +2 -2
- package/dist/src/core/patch-lint-jsdoc.js +46 -46
- package/dist/src/core/patch-lint-module-registration.d.ts +3 -9
- package/dist/src/core/patch-lint-module-registration.js +1 -1
- package/dist/src/core/patch-lint-mozbuild.d.ts +1 -1
- package/dist/src/core/patch-lint-mozbuild.js +10 -10
- package/dist/src/core/patch-lint-observer.d.ts +3 -3
- package/dist/src/core/patch-lint-observer.js +7 -7
- package/dist/src/core/patch-lint-ownership.d.ts +6 -6
- package/dist/src/core/patch-lint-ownership.js +6 -6
- package/dist/src/core/patch-lint-prettier.d.ts +6 -6
- package/dist/src/core/patch-lint-prettier.js +7 -7
- package/dist/src/core/patch-lint-queue-types.d.ts +60 -0
- package/dist/src/core/patch-lint-queue-types.js +12 -0
- package/dist/src/core/patch-lint-staged-registration.d.ts +61 -0
- package/dist/src/core/patch-lint-staged-registration.js +90 -0
- package/dist/src/core/patch-lint-unmanaged-companion.d.ts +23 -23
- package/dist/src/core/patch-lint-unmanaged-companion.js +26 -26
- package/dist/src/core/patch-lint.d.ts +41 -35
- package/dist/src/core/patch-lint.js +52 -49
- package/dist/src/core/patch-lock.d.ts +1 -1
- package/dist/src/core/patch-lock.js +11 -11
- package/dist/src/core/patch-manifest-consistency.d.ts +7 -7
- package/dist/src/core/patch-manifest-consistency.js +16 -17
- package/dist/src/core/patch-manifest-files-affected.d.ts +1 -1
- package/dist/src/core/patch-manifest-files-affected.js +3 -3
- package/dist/src/core/patch-manifest-io.d.ts +14 -14
- package/dist/src/core/patch-manifest-io.js +35 -34
- package/dist/src/core/patch-manifest-query.d.ts +1 -1
- package/dist/src/core/patch-manifest-query.js +4 -4
- package/dist/src/core/patch-manifest-resolve.d.ts +5 -5
- package/dist/src/core/patch-manifest-resolve.js +7 -7
- package/dist/src/core/patch-manifest-validate.js +3 -3
- package/dist/src/core/patch-manifest.d.ts +2 -2
- package/dist/src/core/patch-manifest.js +2 -2
- package/dist/src/core/patch-parse.d.ts +32 -21
- package/dist/src/core/patch-parse.js +40 -15
- package/dist/src/core/patch-policy.js +15 -27
- package/dist/src/core/patch-registration-refs.d.ts +4 -4
- package/dist/src/core/patch-registration-refs.js +7 -7
- package/dist/src/core/patch-source-metadata.d.ts +1 -3
- package/dist/src/core/patch-source-metadata.js +0 -4
- package/dist/src/core/patch-transform.d.ts +8 -16
- package/dist/src/core/patch-transform.js +13 -23
- package/dist/src/core/process-cpu-time.d.ts +1 -1
- package/dist/src/core/process-cpu-time.js +6 -6
- package/dist/src/core/rebase-session.d.ts +9 -15
- package/dist/src/core/rebase-session.js +13 -25
- package/dist/src/core/register-browser-content.js +3 -2
- package/dist/src/core/register-browser-test.js +2 -1
- package/dist/src/core/register-module.js +2 -1
- package/dist/src/core/register-result.d.ts +1 -1
- package/dist/src/core/register-result.js +1 -1
- package/dist/src/core/register-scaffold.d.ts +2 -2
- package/dist/src/core/register-scaffold.js +8 -7
- package/dist/src/core/register-shared-css.d.ts +3 -3
- package/dist/src/core/register-shared-css.js +6 -5
- package/dist/src/core/register-xpcshell-test.d.ts +2 -2
- package/dist/src/core/register-xpcshell-test.js +2 -2
- package/dist/src/core/run-log-redact.d.ts +38 -0
- package/dist/src/core/run-log-redact.js +69 -0
- package/dist/src/core/run-log.d.ts +21 -10
- package/dist/src/core/run-log.js +76 -27
- package/dist/src/core/shared-ftl.d.ts +2 -2
- package/dist/src/core/shared-ftl.js +6 -6
- package/dist/src/core/signal-critical.d.ts +2 -2
- package/dist/src/core/signal-critical.js +4 -6
- package/dist/src/core/smoke-patterns.d.ts +5 -6
- package/dist/src/core/smoke-patterns.js +15 -20
- package/dist/src/core/state-file.d.ts +15 -4
- package/dist/src/core/state-file.js +14 -1
- package/dist/src/core/status-binary.d.ts +8 -8
- package/dist/src/core/status-binary.js +12 -12
- package/dist/src/core/status-classify.d.ts +17 -17
- package/dist/src/core/status-classify.js +13 -12
- package/dist/src/core/test-changed-prefs.d.ts +12 -12
- package/dist/src/core/test-changed-prefs.js +40 -25
- package/dist/src/core/test-harness-crash.d.ts +39 -39
- package/dist/src/core/test-harness-crash.js +69 -69
- package/dist/src/core/test-harness-output.d.ts +7 -7
- package/dist/src/core/test-harness-output.js +7 -7
- package/dist/src/core/test-harness-verdict-notes.d.ts +13 -14
- package/dist/src/core/test-harness-verdict-notes.js +4 -4
- package/dist/src/core/test-path-scope.d.ts +8 -8
- package/dist/src/core/test-path-scope.js +11 -11
- package/dist/src/core/test-stale-check.d.ts +22 -23
- package/dist/src/core/test-stale-check.js +31 -30
- package/dist/src/core/test-stale-symlink.d.ts +1 -1
- package/dist/src/core/test-stale-symlink.js +1 -1
- package/dist/src/core/test-stall-triage.d.ts +9 -9
- package/dist/src/core/test-stall-triage.js +22 -22
- package/dist/src/core/test-xpcshell-retry.d.ts +26 -7
- package/dist/src/core/test-xpcshell-retry.js +14 -11
- package/dist/src/core/token-category.d.ts +35 -2
- package/dist/src/core/token-category.js +67 -58
- package/dist/src/core/token-coverage.js +4 -5
- package/dist/src/core/token-dark-mode.d.ts +9 -9
- package/dist/src/core/token-dark-mode.js +13 -25
- package/dist/src/core/token-docs.d.ts +1 -1
- package/dist/src/core/token-inventory.d.ts +56 -0
- package/dist/src/core/token-inventory.js +109 -0
- package/dist/src/core/token-manager.d.ts +4 -4
- package/dist/src/core/token-manager.js +22 -22
- package/dist/src/core/token-scaffold.d.ts +4 -4
- package/dist/src/core/token-scaffold.js +4 -4
- package/dist/src/core/token-variant.d.ts +14 -14
- package/dist/src/core/token-variant.js +52 -53
- package/dist/src/core/toolchain-preflight.d.ts +15 -15
- package/dist/src/core/toolchain-preflight.js +23 -23
- package/dist/src/core/tree-cow.d.ts +3 -5
- package/dist/src/core/tree-cow.js +8 -8
- package/dist/src/core/tree-guard.d.ts +3 -3
- package/dist/src/core/tree-guard.js +23 -23
- package/dist/src/core/tree-store.d.ts +15 -15
- package/dist/src/core/tree-store.js +39 -38
- package/dist/src/core/typecheck-shim.d.ts +16 -15
- package/dist/src/core/typecheck-shim.js +26 -25
- package/dist/src/core/typecheck.d.ts +12 -12
- package/dist/src/core/typecheck.js +33 -33
- package/dist/src/core/wire-destroy.d.ts +2 -2
- package/dist/src/core/wire-destroy.js +5 -5
- package/dist/src/core/wire-dom-fragment.d.ts +3 -3
- package/dist/src/core/wire-dom-fragment.js +12 -23
- package/dist/src/core/wire-init.d.ts +2 -2
- package/dist/src/core/wire-init.js +7 -7
- package/dist/src/core/wire-subscript.d.ts +1 -1
- package/dist/src/core/wire-subscript.js +3 -3
- package/dist/src/core/wire-utils.d.ts +9 -9
- package/dist/src/core/wire-utils.js +16 -28
- package/dist/src/core/xpcshell-appdir.d.ts +20 -20
- package/dist/src/core/xpcshell-appdir.js +28 -30
- package/dist/src/core/xpcshell-profile-dir.d.ts +3 -3
- package/dist/src/core/xpcshell-profile-dir.js +7 -7
- package/dist/src/errors/base.d.ts +69 -16
- package/dist/src/errors/base.js +95 -26
- package/dist/src/errors/build.d.ts +6 -6
- package/dist/src/errors/build.js +26 -34
- package/dist/src/errors/codes.d.ts +10 -10
- package/dist/src/errors/codes.js +10 -10
- package/dist/src/errors/config.d.ts +0 -14
- package/dist/src/errors/config.js +13 -34
- package/dist/src/errors/download.d.ts +13 -0
- package/dist/src/errors/download.js +53 -24
- package/dist/src/errors/furnace.d.ts +2 -2
- package/dist/src/errors/furnace.js +8 -9
- package/dist/src/errors/git.d.ts +9 -9
- package/dist/src/errors/git.js +21 -31
- package/dist/src/errors/patch.d.ts +3 -3
- package/dist/src/errors/patch.js +11 -13
- package/dist/src/errors/rebase.d.ts +1 -1
- package/dist/src/errors/rebase.js +8 -8
- package/dist/src/errors/run.d.ts +1 -1
- package/dist/src/errors/run.js +1 -1
- package/dist/src/index.d.ts +4 -4
- package/dist/src/index.js +4 -4
- package/dist/src/types/commands/options.d.ts +155 -200
- package/dist/src/types/commands/patches.d.ts +19 -19
- package/dist/src/types/commands/project.d.ts +3 -3
- package/dist/src/types/config.d.ts +52 -19
- package/dist/src/types/furnace.d.ts +17 -17
- package/dist/src/types/index.d.ts +0 -1
- package/dist/src/types/json.d.ts +3 -3
- package/dist/src/types/json.js +2 -2
- package/dist/src/types/typecheck.d.ts +3 -3
- package/dist/src/utils/assert.d.ts +4 -16
- package/dist/src/utils/assert.js +7 -24
- package/dist/src/utils/build-info.d.ts +6 -6
- package/dist/src/utils/build-info.js +6 -6
- package/dist/src/utils/child-env.d.ts +7 -6
- package/dist/src/utils/child-env.js +5 -5
- package/dist/src/utils/concurrency.d.ts +2 -2
- package/dist/src/utils/concurrency.js +2 -2
- package/dist/src/utils/elapsed.js +10 -1
- package/dist/src/utils/errors.d.ts +8 -8
- package/dist/src/utils/errors.js +8 -8
- package/dist/src/utils/fs.d.ts +1 -1
- package/dist/src/utils/fs.js +15 -20
- package/dist/src/utils/hash.d.ts +12 -0
- package/dist/src/utils/hash.js +16 -0
- package/dist/src/utils/line-dispatch.d.ts +15 -0
- package/dist/src/utils/line-dispatch.js +48 -0
- package/dist/src/utils/logger.d.ts +4 -4
- package/dist/src/utils/logger.js +11 -11
- package/dist/src/utils/machine-output.js +2 -2
- package/dist/src/utils/options.d.ts +14 -20
- package/dist/src/utils/options.js +26 -27
- package/dist/src/utils/package-root.js +5 -14
- package/dist/src/utils/paths.d.ts +4 -4
- package/dist/src/utils/paths.js +4 -4
- package/dist/src/utils/platform.d.ts +0 -4
- package/dist/src/utils/process-group.d.ts +10 -9
- package/dist/src/utils/process-group.js +37 -36
- package/dist/src/utils/process.d.ts +70 -55
- package/dist/src/utils/process.js +129 -179
- package/dist/src/utils/ps-duration.d.ts +4 -4
- package/dist/src/utils/ps-duration.js +9 -9
- package/dist/src/utils/regex.d.ts +4 -4
- package/dist/src/utils/regex.js +7 -7
- package/dist/src/utils/sleep.d.ts +26 -0
- package/dist/src/utils/sleep.js +31 -0
- package/dist/src/utils/stdio-drain.d.ts +7 -7
- package/dist/src/utils/stdio-drain.js +8 -8
- package/dist/src/utils/validation.d.ts +12 -49
- package/dist/src/utils/validation.js +26 -36
- package/docs/README.md +2 -2
- package/docs/configuration.md +163 -69
- package/docs/exit-codes.md +66 -49
- package/docs/furnace.md +20 -19
- package/docs/lifecycle-invariants.md +414 -247
- package/docs/machine-output.md +58 -34
- package/docs/patch-workflow.md +48 -44
- package/docs/run-logs.md +72 -28
- package/docs/testing.md +105 -98
- package/docs/verification-trees.md +23 -22
- package/package.json +7 -6
- package/dist/src/commands/rebase.d.ts +0 -4
- package/dist/src/commands/rebase.js +0 -5
- package/dist/src/core/patch-artifact-normalize.d.ts +0 -21
- package/dist/src/core/patch-artifact-normalize.js +0 -24
- package/dist/src/core/patch-lint-reexports.d.ts +0 -7
- package/dist/src/core/patch-lint-reexports.js +0 -8
- package/dist/src/core/wire-targets.d.ts +0 -7
- package/dist/src/core/wire-targets.js +0 -8
|
@@ -2,9 +2,19 @@ import type { PatchCategory, PatchesManifest, PatchInfo, PatchMetadata } from '.
|
|
|
2
2
|
import type { FireForgeConfig } from '../types/config.js';
|
|
3
3
|
import { type SupersedeCoverageDetail } from './patch-export-coverage.js';
|
|
4
4
|
import type { PatchDirectoryLockOptions } from './patch-lock.js';
|
|
5
|
-
export { findAllPatchesForFiles, findAllPatchesForFilesWithDetails,
|
|
5
|
+
export { findAllPatchesForFiles, findAllPatchesForFilesWithDetails, } from './patch-export-coverage.js';
|
|
6
6
|
export { mutatePatchMetadata, updatePatchMetadata } from './patch-export-metadata.js';
|
|
7
7
|
export { updatePatchAndMetadata } from './patch-export-update.js';
|
|
8
|
+
/**
|
|
9
|
+
* Projects the planning subset out of a wider export input (commit input,
|
|
10
|
+
* dry-run preview input): the fields `planExport` /
|
|
11
|
+
* `computeExportPlanUnderLock` read. Optional fields are copied only when
|
|
12
|
+
* present so the plan input never carries explicit `undefined` keys, which
|
|
13
|
+
* would otherwise leak into the written metadata via spread. The commit
|
|
14
|
+
* path and the dry-run preview both go through this one projection so
|
|
15
|
+
* they cannot drift field by field.
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildPlanExportInput(input: PlanExportInput): PlanExportInput;
|
|
8
18
|
/**
|
|
9
19
|
* Gets the next patch number for a new patch.
|
|
10
20
|
* @param patchesDir - Path to the patches directory
|
|
@@ -23,7 +33,7 @@ export declare function getNextPatchNumber(patchesDir: string): Promise<string>;
|
|
|
23
33
|
export declare function sanitizeName(name: string): string;
|
|
24
34
|
/**
|
|
25
35
|
* Strips a leading `NNN-<category>-` prefix from a sanitized name slug.
|
|
26
|
-
* Operators frequently pass the
|
|
36
|
+
* Operators frequently pass the desired filename stem to `--name`
|
|
27
37
|
* (`--name 203-ui-foo --category ui`), which would otherwise double-prefix
|
|
28
38
|
* into `203-ui-203-ui-foo.patch`. The filename builders prepend the order
|
|
29
39
|
* and category themselves, so a matching prefix in the name is always
|
|
@@ -35,7 +45,7 @@ export declare function stripRedundantCategoryPrefix(sanitizedName: string, cate
|
|
|
35
45
|
* Sanitizes a patch name and drops redundant category/full-stem prefixes.
|
|
36
46
|
*
|
|
37
47
|
* A single trailing `.patch` extension is stripped before sanitisation:
|
|
38
|
-
* operators frequently pass a full patch
|
|
48
|
+
* operators frequently pass a full patch filename where a name is expected
|
|
39
49
|
* (`move-files <from> 348-ui-foo.patch --create`, `rename --to foo.patch`),
|
|
40
50
|
* and slugging the extension produces double-suffixed `...-patch.patch`
|
|
41
51
|
* files. A name that deliberately ends in a literal `-patch` slug segment
|
|
@@ -91,26 +101,6 @@ export interface CommitExportedPatchResult {
|
|
|
91
101
|
* to filename allocation or supersede detection lands in both automatically.
|
|
92
102
|
*/
|
|
93
103
|
export declare function commitExportedPatch(input: CommitExportedPatchInput): Promise<CommitExportedPatchResult>;
|
|
94
|
-
/**
|
|
95
|
-
* Parses a patch filename to extract order, category, and name.
|
|
96
|
-
* Supports both new format (001-category-name.patch) and legacy (001-name.patch).
|
|
97
|
-
*/
|
|
98
|
-
export declare function parseFilename(filename: string): {
|
|
99
|
-
order: number;
|
|
100
|
-
category: PatchCategory | null;
|
|
101
|
-
name: string;
|
|
102
|
-
};
|
|
103
|
-
/**
|
|
104
|
-
* Finds an existing patch that contains the specified file.
|
|
105
|
-
* Returns the most recent (highest order) patch if multiple exist.
|
|
106
|
-
* @param patchesDir - Path to the patches directory
|
|
107
|
-
* @param filePath - File path to search for
|
|
108
|
-
* @returns The patch info and metadata, or null if not found
|
|
109
|
-
*/
|
|
110
|
-
export declare function findExistingPatchForFile(patchesDir: string, filePath: string): Promise<{
|
|
111
|
-
patch: PatchInfo;
|
|
112
|
-
metadata: PatchMetadata;
|
|
113
|
-
} | null>;
|
|
114
104
|
/**
|
|
115
105
|
* Updates the content of a patch file.
|
|
116
106
|
* @param patchPath - Path to the patch file
|
|
@@ -125,7 +115,7 @@ export declare function updatePatch(patchPath: string, newContent: string): Prom
|
|
|
125
115
|
* Dry-run and the real write both go through {@link computeExportPlanUnderLock}
|
|
126
116
|
* so their filename allocation, supersede detection, and projected
|
|
127
117
|
* post-write manifest cannot drift. `planExport` exposes the rich coverage
|
|
128
|
-
* form for preview rendering
|
|
118
|
+
* form for preview rendering. {@link commitExportedPatch} consumes the bare
|
|
129
119
|
* `PatchInfo[]` form of the same underlying data.
|
|
130
120
|
*/
|
|
131
121
|
export interface ExportPlan {
|
|
@@ -155,13 +145,13 @@ export interface PlanExportInput {
|
|
|
155
145
|
/**
|
|
156
146
|
* Optional `PatchMetadata.tier` opt-in carried from the CLI flag.
|
|
157
147
|
* Only `"branding"` is currently recognised. When provided the field
|
|
158
|
-
* is written into the new patch's metadata
|
|
148
|
+
* is written into the new patch's metadata. When absent the field
|
|
159
149
|
* stays unset and tier resolution falls back to auto-detection.
|
|
160
150
|
*/
|
|
161
151
|
tier?: 'branding';
|
|
162
152
|
/**
|
|
163
153
|
* Optional `PatchMetadata.lintIgnore` carried from the CLI flag.
|
|
164
|
-
* Empty arrays are treated as "field absent"
|
|
154
|
+
* Empty arrays are treated as "field absent": the validator only
|
|
165
155
|
* preserves the field when it has at least one entry.
|
|
166
156
|
*/
|
|
167
157
|
lintIgnore?: string[];
|
|
@@ -169,16 +159,16 @@ export interface PlanExportInput {
|
|
|
169
159
|
config?: FireForgeConfig;
|
|
170
160
|
}
|
|
171
161
|
/**
|
|
172
|
-
* Read-only planning function
|
|
162
|
+
* Read-only planning function. Computes everything a real export would
|
|
173
163
|
* do without writing anything to disk. Takes the patch directory lock
|
|
174
164
|
* briefly, runs {@link computeExportPlanUnderLock}, releases the lock,
|
|
175
165
|
* and returns the plan for preview rendering.
|
|
176
166
|
*
|
|
177
167
|
* Shares {@link computeExportPlanUnderLock} with {@link commitExportedPatch}
|
|
178
168
|
* so the dry-run preview cannot drift from the real write. The real write
|
|
179
|
-
* path does
|
|
180
|
-
* between dry-run and commit, which would stale the filename allocation)
|
|
181
|
-
*
|
|
169
|
+
* path does not reuse a prior plan object (another export may have landed
|
|
170
|
+
* between dry-run and commit, which would stale the filename allocation).
|
|
171
|
+
* It re-runs the same helper under a fresh lock. The guarantee is "same
|
|
182
172
|
* code, possibly different data," not "same plan object."
|
|
183
173
|
*/
|
|
184
174
|
export declare function planExport(input: PlanExportInput): Promise<ExportPlan>;
|
|
@@ -3,17 +3,39 @@ import { join } from 'node:path';
|
|
|
3
3
|
import { toError } from '../utils/errors.js';
|
|
4
4
|
import { pathExists, readText, removeFile, writeText } from '../utils/fs.js';
|
|
5
5
|
import { warn } from '../utils/logger.js';
|
|
6
|
-
import { PATCH_CATEGORIES } from '../utils/validation.js';
|
|
7
6
|
import { discoverPatches, withPatchDirectoryLock } from './patch-apply.js';
|
|
8
|
-
import { normalizePatchArtifact } from './patch-artifact-normalize.js';
|
|
9
7
|
import { findAllPatchesForFilesWithDetails, } from './patch-export-coverage.js';
|
|
10
|
-
import { addPatchToManifest,
|
|
11
|
-
import { requirePatchOrder } from './patch-parse.js';
|
|
8
|
+
import { addPatchToManifest, loadPatchesManifestForWrite, PATCHES_MANIFEST, savePatchesManifest, } from './patch-manifest.js';
|
|
9
|
+
import { formatPatchOrder, requirePatchOrder } from './patch-parse.js';
|
|
12
10
|
import { allocatePolicyOrder, enforcePatchPolicy } from './patch-policy.js';
|
|
13
|
-
export { findAllPatchesForFiles, findAllPatchesForFilesWithDetails,
|
|
11
|
+
export { findAllPatchesForFiles, findAllPatchesForFilesWithDetails, } from './patch-export-coverage.js';
|
|
14
12
|
import { escapeRegex } from '../utils/regex.js';
|
|
15
13
|
export { mutatePatchMetadata, updatePatchMetadata } from './patch-export-metadata.js';
|
|
16
14
|
export { updatePatchAndMetadata } from './patch-export-update.js';
|
|
15
|
+
/**
|
|
16
|
+
* Projects the planning subset out of a wider export input (commit input,
|
|
17
|
+
* dry-run preview input): the fields `planExport` /
|
|
18
|
+
* `computeExportPlanUnderLock` read. Optional fields are copied only when
|
|
19
|
+
* present so the plan input never carries explicit `undefined` keys, which
|
|
20
|
+
* would otherwise leak into the written metadata via spread. The commit
|
|
21
|
+
* path and the dry-run preview both go through this one projection so
|
|
22
|
+
* they cannot drift field by field.
|
|
23
|
+
*/
|
|
24
|
+
export function buildPlanExportInput(input) {
|
|
25
|
+
return {
|
|
26
|
+
patchesDir: input.patchesDir,
|
|
27
|
+
category: input.category,
|
|
28
|
+
name: input.name,
|
|
29
|
+
description: input.description,
|
|
30
|
+
filesAffected: input.filesAffected,
|
|
31
|
+
sourceEsrVersion: input.sourceEsrVersion,
|
|
32
|
+
...(input.sourceProduct !== undefined ? { sourceProduct: input.sourceProduct } : {}),
|
|
33
|
+
...(input.sourceVersion !== undefined ? { sourceVersion: input.sourceVersion } : {}),
|
|
34
|
+
...(input.tier !== undefined ? { tier: input.tier } : {}),
|
|
35
|
+
...(input.lintIgnore !== undefined ? { lintIgnore: input.lintIgnore } : {}),
|
|
36
|
+
...(input.config !== undefined ? { config: input.config } : {}),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
17
39
|
/**
|
|
18
40
|
* Gets the next patch number for a new patch.
|
|
19
41
|
* @param patchesDir - Path to the patches directory
|
|
@@ -49,7 +71,7 @@ export function sanitizeName(name) {
|
|
|
49
71
|
}
|
|
50
72
|
/**
|
|
51
73
|
* Strips a leading `NNN-<category>-` prefix from a sanitized name slug.
|
|
52
|
-
* Operators frequently pass the
|
|
74
|
+
* Operators frequently pass the desired filename stem to `--name`
|
|
53
75
|
* (`--name 203-ui-foo --category ui`), which would otherwise double-prefix
|
|
54
76
|
* into `203-ui-203-ui-foo.patch`. The filename builders prepend the order
|
|
55
77
|
* and category themselves, so a matching prefix in the name is always
|
|
@@ -78,7 +100,7 @@ export function stripRedundantCategoryPrefix(sanitizedName, category) {
|
|
|
78
100
|
* Sanitizes a patch name and drops redundant category/full-stem prefixes.
|
|
79
101
|
*
|
|
80
102
|
* A single trailing `.patch` extension is stripped before sanitisation:
|
|
81
|
-
* operators frequently pass a full patch
|
|
103
|
+
* operators frequently pass a full patch filename where a name is expected
|
|
82
104
|
* (`move-files <from> 348-ui-foo.patch --create`, `rename --to foo.patch`),
|
|
83
105
|
* and slugging the extension produces double-suffixed `...-patch.patch`
|
|
84
106
|
* files. A name that deliberately ends in a literal `-patch` slug segment
|
|
@@ -110,19 +132,7 @@ export async function getNextPatchFilename(patchesDir, category, name) {
|
|
|
110
132
|
*/
|
|
111
133
|
export async function commitExportedPatch(input) {
|
|
112
134
|
return withPatchDirectoryLock(input.patchesDir, async () => {
|
|
113
|
-
const plan = await computeExportPlanUnderLock(
|
|
114
|
-
patchesDir: input.patchesDir,
|
|
115
|
-
category: input.category,
|
|
116
|
-
name: input.name,
|
|
117
|
-
description: input.description,
|
|
118
|
-
filesAffected: input.filesAffected,
|
|
119
|
-
sourceEsrVersion: input.sourceEsrVersion,
|
|
120
|
-
...(input.sourceProduct !== undefined ? { sourceProduct: input.sourceProduct } : {}),
|
|
121
|
-
...(input.sourceVersion !== undefined ? { sourceVersion: input.sourceVersion } : {}),
|
|
122
|
-
...(input.tier !== undefined ? { tier: input.tier } : {}),
|
|
123
|
-
...(input.lintIgnore !== undefined ? { lintIgnore: input.lintIgnore } : {}),
|
|
124
|
-
...(input.config !== undefined ? { config: input.config } : {}),
|
|
125
|
-
});
|
|
135
|
+
const plan = await computeExportPlanUnderLock(buildPlanExportInput(input));
|
|
126
136
|
if (input.config !== undefined) {
|
|
127
137
|
enforcePatchPolicy({
|
|
128
138
|
config: input.config,
|
|
@@ -140,7 +150,20 @@ export async function commitExportedPatch(input) {
|
|
|
140
150
|
}
|
|
141
151
|
}
|
|
142
152
|
try {
|
|
143
|
-
|
|
153
|
+
// Patch bodies are written byte-for-byte as git produced them, including the
|
|
154
|
+
// single-space rendering of a blank context line.
|
|
155
|
+
//
|
|
156
|
+
// Do not add a whitespace-trimming pass here or at any other write site.
|
|
157
|
+
// Stripping marker lines whose payload is pure whitespace (`/^[ +-]\s+$/` →
|
|
158
|
+
// bare marker) corrupts real content: Firefox sources contain whitespace-only
|
|
159
|
+
// lines, so a ` `/`-` line whose payload was two spaces no longer matches the
|
|
160
|
+
// pristine tree and the freshly exported patch fails `git apply --check`,
|
|
161
|
+
// while a `+` line silently changes what the patch produces. The repository
|
|
162
|
+
// whitespace check already exempts `patches/*.patch`
|
|
163
|
+
// (scripts/check-worktree-whitespace.mjs), and the byte-fidelity contract is
|
|
164
|
+
// pinned end-to-end by `git-diff-latin1-roundtrip.test.ts` and
|
|
165
|
+
// `re-export.integration.test.ts`.
|
|
166
|
+
await writeText(patchPath, input.diff);
|
|
144
167
|
await addPatchToManifest(input.patchesDir, plan.metadata, plan.supersededPatches.map((p) => p.filename));
|
|
145
168
|
for (const oldPatch of plan.supersededPatches) {
|
|
146
169
|
await removeFile(oldPatch.path);
|
|
@@ -188,70 +211,25 @@ export async function commitExportedPatch(input) {
|
|
|
188
211
|
};
|
|
189
212
|
}, input.lockOptions ?? {});
|
|
190
213
|
}
|
|
191
|
-
/**
|
|
192
|
-
* Parses a patch filename to extract order, category, and name.
|
|
193
|
-
* Supports both new format (001-category-name.patch) and legacy (001-name.patch).
|
|
194
|
-
*/
|
|
195
|
-
export function parseFilename(filename) {
|
|
196
|
-
// New format: 001-ui-sidebar.patch
|
|
197
|
-
const newMatch = /^(\d+)-([a-z]+)-(.+)\.patch$/.exec(filename);
|
|
198
|
-
if (newMatch?.[1] && newMatch[2] && newMatch[3]) {
|
|
199
|
-
const orderStr = newMatch[1];
|
|
200
|
-
const category = newMatch[2];
|
|
201
|
-
const name = newMatch[3];
|
|
202
|
-
if (PATCH_CATEGORIES.includes(category)) {
|
|
203
|
-
return {
|
|
204
|
-
order: parseInt(orderStr, 10),
|
|
205
|
-
category,
|
|
206
|
-
name,
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
// Legacy format: 001-name.patch
|
|
211
|
-
const legacyMatch = /^(\d+)-(.+)\.patch$/.exec(filename);
|
|
212
|
-
if (legacyMatch?.[1] && legacyMatch[2]) {
|
|
213
|
-
return {
|
|
214
|
-
order: parseInt(legacyMatch[1], 10),
|
|
215
|
-
category: null,
|
|
216
|
-
name: legacyMatch[2],
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
return { order: Infinity, category: null, name: filename };
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Finds an existing patch that contains the specified file.
|
|
223
|
-
* Returns the most recent (highest order) patch if multiple exist.
|
|
224
|
-
* @param patchesDir - Path to the patches directory
|
|
225
|
-
* @param filePath - File path to search for
|
|
226
|
-
* @returns The patch info and metadata, or null if not found
|
|
227
|
-
*/
|
|
228
|
-
export async function findExistingPatchForFile(patchesDir, filePath) {
|
|
229
|
-
const affectingPatches = await findPatchesAffectingFile(patchesDir, filePath);
|
|
230
|
-
if (affectingPatches.length === 0) {
|
|
231
|
-
return null;
|
|
232
|
-
}
|
|
233
|
-
// Return the most recent (highest order) patch
|
|
234
|
-
return affectingPatches[affectingPatches.length - 1] ?? null;
|
|
235
|
-
}
|
|
236
214
|
/**
|
|
237
215
|
* Updates the content of a patch file.
|
|
238
216
|
* @param patchPath - Path to the patch file
|
|
239
217
|
* @param newContent - New patch content
|
|
240
218
|
*/
|
|
241
219
|
export async function updatePatch(patchPath, newContent) {
|
|
242
|
-
await writeText(patchPath,
|
|
220
|
+
await writeText(patchPath, newContent);
|
|
243
221
|
}
|
|
244
222
|
/**
|
|
245
|
-
* Internal planning helper.
|
|
246
|
-
* caller must already hold it
|
|
223
|
+
* Internal planning helper. It does not take the patch directory lock (the
|
|
224
|
+
* caller must already hold it), because the two public entry points
|
|
247
225
|
* ({@link planExport} and {@link commitExportedPatch}) each take their own
|
|
248
226
|
* lock for the full operation. Sharing this single pure computation is how
|
|
249
|
-
* dry-run previews and real writes stay in lockstep
|
|
250
|
-
*
|
|
227
|
+
* dry-run previews and real writes stay in lockstep, instead of relying on
|
|
228
|
+
* parallel implementations that can drift.
|
|
251
229
|
*/
|
|
252
230
|
async function computeExportPlanUnderLock(input) {
|
|
253
231
|
// ForWrite: a corrupt manifest read as null here would produce a
|
|
254
|
-
// manifestAfter containing
|
|
232
|
+
// manifestAfter containing only the new patch. Committing that plan
|
|
255
233
|
// wipes the queue metadata, and the rollback path would then delete
|
|
256
234
|
// patches.json entirely because manifestBefore looked absent.
|
|
257
235
|
const manifestBefore = await loadPatchesManifestForWrite(input.patchesDir);
|
|
@@ -259,7 +237,7 @@ async function computeExportPlanUnderLock(input) {
|
|
|
259
237
|
? allocatePolicyOrder(input.config, manifestBefore?.patches ?? [], input.category)
|
|
260
238
|
: null;
|
|
261
239
|
const patchFilename = policyOrder !== null
|
|
262
|
-
? `${
|
|
240
|
+
? `${formatPatchOrder(policyOrder)}-${input.category}-${patchNameSlug(input.name, input.category)}.patch`
|
|
263
241
|
: await getNextPatchFilename(input.patchesDir, input.category, input.name);
|
|
264
242
|
const patchPath = join(input.patchesDir, patchFilename);
|
|
265
243
|
const metadata = {
|
|
@@ -302,16 +280,16 @@ async function computeExportPlanUnderLock(input) {
|
|
|
302
280
|
};
|
|
303
281
|
}
|
|
304
282
|
/**
|
|
305
|
-
* Read-only planning function
|
|
283
|
+
* Read-only planning function. Computes everything a real export would
|
|
306
284
|
* do without writing anything to disk. Takes the patch directory lock
|
|
307
285
|
* briefly, runs {@link computeExportPlanUnderLock}, releases the lock,
|
|
308
286
|
* and returns the plan for preview rendering.
|
|
309
287
|
*
|
|
310
288
|
* Shares {@link computeExportPlanUnderLock} with {@link commitExportedPatch}
|
|
311
289
|
* so the dry-run preview cannot drift from the real write. The real write
|
|
312
|
-
* path does
|
|
313
|
-
* between dry-run and commit, which would stale the filename allocation)
|
|
314
|
-
*
|
|
290
|
+
* path does not reuse a prior plan object (another export may have landed
|
|
291
|
+
* between dry-run and commit, which would stale the filename allocation).
|
|
292
|
+
* It re-runs the same helper under a fresh lock. The guarantee is "same
|
|
315
293
|
* code, possibly different data," not "same plan object."
|
|
316
294
|
*/
|
|
317
295
|
export async function planExport(input) {
|
|
@@ -3,10 +3,6 @@ import type { PatchInfo } from '../types/commands/index.js';
|
|
|
3
3
|
export declare function discoverPatches(patchesDir: string): Promise<PatchInfo[]>;
|
|
4
4
|
/** Counts the patch files currently present in a patch directory. */
|
|
5
5
|
export declare function countPatches(patchesDir: string): Promise<number>;
|
|
6
|
-
/** Checks whether a patch creates a new file rather than modifying an existing one. */
|
|
7
|
-
export declare function isNewFilePatch(patchPath: string): Promise<boolean>;
|
|
8
|
-
/** Returns the first target file path referenced by a patch, if any. */
|
|
9
|
-
export declare function getTargetFileFromPatch(patchPath: string): Promise<string | null>;
|
|
10
6
|
/**
|
|
11
7
|
* Returns all target file paths referenced by a multi-file patch.
|
|
12
8
|
*
|
|
@@ -24,17 +24,6 @@ export async function countPatches(patchesDir) {
|
|
|
24
24
|
const patches = await discoverPatches(patchesDir);
|
|
25
25
|
return patches.length;
|
|
26
26
|
}
|
|
27
|
-
/** Checks whether a patch creates a new file rather than modifying an existing one. */
|
|
28
|
-
export async function isNewFilePatch(patchPath) {
|
|
29
|
-
const content = await readText(patchPath);
|
|
30
|
-
return content.includes('new file mode') && content.includes('--- /dev/null');
|
|
31
|
-
}
|
|
32
|
-
/** Returns the first target file path referenced by a patch, if any. */
|
|
33
|
-
export async function getTargetFileFromPatch(patchPath) {
|
|
34
|
-
const content = await readText(patchPath);
|
|
35
|
-
const match = /^\+\+\+ b\/(.+)$/m.exec(content);
|
|
36
|
-
return match?.[1] ?? null;
|
|
37
|
-
}
|
|
38
27
|
/**
|
|
39
28
|
* Returns all target file paths referenced by a multi-file patch.
|
|
40
29
|
*
|
|
@@ -15,6 +15,6 @@ import type { PatchMetadata } from '../types/commands/index.js';
|
|
|
15
15
|
* Formats the user-facing "patch not found" error message used by
|
|
16
16
|
* `patch delete`, `patch reorder`, `patch tier`, and
|
|
17
17
|
* `patch lint-ignore`. Returns a single string suitable for the
|
|
18
|
-
* `InvalidArgumentError` body
|
|
18
|
+
* `InvalidArgumentError` body, never the full queue enumeration.
|
|
19
19
|
*/
|
|
20
20
|
export declare function formatPatchNotFoundError(identifier: string, patches: readonly PatchMetadata[]): string;
|
|
@@ -22,7 +22,7 @@ const MIN_PREFIX_MATCH_LENGTH = 4;
|
|
|
22
22
|
const SUGGESTION_LIMIT = 3;
|
|
23
23
|
/**
|
|
24
24
|
* Computes the Levenshtein edit distance between two strings. Used by
|
|
25
|
-
* `formatPatchNotFoundError` to rank candidate identifiers
|
|
25
|
+
* `formatPatchNotFoundError` to rank candidate identifiers. The small
|
|
26
26
|
* upper bound on input lengths (filenames, ordinals, names) makes the
|
|
27
27
|
* O(m*n) implementation trivially fast.
|
|
28
28
|
*/
|
|
@@ -87,13 +87,13 @@ function rankSuggestions(identifier, candidates) {
|
|
|
87
87
|
return candidates
|
|
88
88
|
.map((candidate) => {
|
|
89
89
|
const lower = candidate.toLowerCase();
|
|
90
|
-
// Prefix relation in
|
|
90
|
+
// Prefix relation in either direction is a stronger signal than edit
|
|
91
91
|
// distance and is not bounded by it: a partial ordinal or an
|
|
92
92
|
// abbreviated slug ("ui-foo" for "002-ui-foo.patch") is many edits away
|
|
93
93
|
// from the full identifier yet is obviously the intended target.
|
|
94
94
|
// `lower.startsWith(needle)`: the operator typed an abbreviation of a
|
|
95
95
|
// real identifier. The reverse relation is only meaningful when the
|
|
96
|
-
// candidate is substantial
|
|
96
|
+
// candidate is substantial. Otherwise the single-character ordinal
|
|
97
97
|
// "9" would "match" every input starting with a 9.
|
|
98
98
|
const prefixMatch = needle.length >= MIN_PREFIX_MATCH_LENGTH &&
|
|
99
99
|
(lower.startsWith(needle) ||
|
|
@@ -115,7 +115,7 @@ function rankSuggestions(identifier, candidates) {
|
|
|
115
115
|
* Formats the user-facing "patch not found" error message used by
|
|
116
116
|
* `patch delete`, `patch reorder`, `patch tier`, and
|
|
117
117
|
* `patch lint-ignore`. Returns a single string suitable for the
|
|
118
|
-
* `InvalidArgumentError` body
|
|
118
|
+
* `InvalidArgumentError` body, never the full queue enumeration.
|
|
119
119
|
*/
|
|
120
120
|
export function formatPatchNotFoundError(identifier, patches) {
|
|
121
121
|
const accepted = collectAcceptedIdentifiers(patches);
|
|
@@ -2,39 +2,33 @@
|
|
|
2
2
|
* Queue-wide lint for binary patch bodies that cannot recreate their file.
|
|
3
3
|
*
|
|
4
4
|
* `git diff` has two ways to render a binary change. `git diff --binary`
|
|
5
|
-
* emits a `GIT binary patch` section carrying the literal/delta payload
|
|
6
|
-
* that body can be replayed by `git apply`. Plain `git diff` emits only
|
|
7
|
-
* informational `Binary files a/x and b/x differ`, which records
|
|
8
|
-
* bytes changed and carries none of them.
|
|
5
|
+
* emits a `GIT binary patch` section carrying the literal/delta payload,
|
|
6
|
+
* and that body can be replayed by `git apply`. Plain `git diff` emits only
|
|
7
|
+
* the informational `Binary files a/x and b/x differ`, which records that
|
|
8
|
+
* the bytes changed and carries none of them.
|
|
9
9
|
*
|
|
10
10
|
* The stub form is dangerous rather than merely lossy because it still
|
|
11
11
|
* carries a correct `index <old>..<new>` line. Every identity-shaped check in
|
|
12
|
-
* the codebase
|
|
12
|
+
* the codebase (worktree classification, foreign-drift detection) keys on
|
|
13
13
|
* that hash, matches it against the live file, and concludes the patch is
|
|
14
14
|
* backed. So a queue can hold a patch that provably cannot rebuild its own
|
|
15
15
|
* file while every gate reports green, and the loss surfaces only at the next
|
|
16
16
|
* clean-room apply. This rule is the one check that reads the body itself and
|
|
17
17
|
* fails closed, whichever command wrote it.
|
|
18
18
|
*
|
|
19
|
-
* Body-only
|
|
19
|
+
* Body-only: it needs no engine checkout, so it runs anywhere the
|
|
20
20
|
* queue context is available and never pulls an engine dependency into the
|
|
21
21
|
* cross-patch lint graph.
|
|
22
22
|
*/
|
|
23
23
|
import type { PatchLintIssue } from '../types/commands/index.js';
|
|
24
|
+
import type { PatchQueueBodyEntry, PatchQueueView } from './patch-lint-queue-types.js';
|
|
24
25
|
/**
|
|
25
|
-
*
|
|
26
|
-
* than importing `
|
|
27
|
-
* this module back
|
|
28
|
-
* `dpdm` clean
|
|
26
|
+
* Queue view accepted by {@link lintPatchQueueBinaryBodies}. Described
|
|
27
|
+
* structurally rather than by importing `PatchQueueContext` from
|
|
28
|
+
* `patch-lint-cross.ts`, which imports this module back. The shared leaf
|
|
29
|
+
* type keeps the dependency edge one-way and `dpdm` clean.
|
|
29
30
|
*/
|
|
30
|
-
|
|
31
|
-
filename: string;
|
|
32
|
-
diff: string;
|
|
33
|
-
}
|
|
34
|
-
/** Queue view accepted by {@link lintPatchQueueBinaryBodies}. */
|
|
35
|
-
interface BinaryBodyQueueContext {
|
|
36
|
-
entries: readonly BinaryBodyQueueEntry[];
|
|
37
|
-
}
|
|
31
|
+
type BinaryBodyQueueContext = PatchQueueView<PatchQueueBodyEntry>;
|
|
38
32
|
/** Lint check identifier emitted by {@link lintPatchQueueBinaryBodies}. */
|
|
39
33
|
export declare const BINARY_BODY_CHECK = "binary-body-not-reconstructable";
|
|
40
34
|
/**
|
|
@@ -53,10 +53,26 @@ export interface CachedPerPatchLint {
|
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
55
|
* Returns the cached lint payload for a patch when the stored key still
|
|
56
|
-
* matches
|
|
56
|
+
* matches and the entry was computed under the same lint-ignore waiver set.
|
|
57
57
|
* A waiver change makes a replayed verdict actively wrong, so the waiver set
|
|
58
58
|
* is compared explicitly rather than trusted to the key.
|
|
59
59
|
*/
|
|
60
60
|
export declare function getCachedPerPatchLintIssues(cache: PerPatchLintCacheFile, patchFilename: string, key: string, lintIgnore?: Iterable<string>): CachedPerPatchLint | undefined;
|
|
61
|
+
export interface SetCachedPerPatchLintIssuesInput {
|
|
62
|
+
/** Cache file to mutate in place. */
|
|
63
|
+
cache: PerPatchLintCacheFile;
|
|
64
|
+
/** Patch the payload belongs to, and also the cache entry key. */
|
|
65
|
+
patchFilename: string;
|
|
66
|
+
/** Fingerprint the payload is valid for. */
|
|
67
|
+
key: string;
|
|
68
|
+
/** Reported issues, stored as copies. */
|
|
69
|
+
issues: PatchLintIssue[];
|
|
70
|
+
/** Issues suppressed by `lintIgnore`, stored as copies. */
|
|
71
|
+
suppressed: PatchLintIssue[];
|
|
72
|
+
/** Line count the run measured. */
|
|
73
|
+
lineCount: number;
|
|
74
|
+
/** Suppression ids in force for the run, normalized on store. */
|
|
75
|
+
lintIgnore?: Iterable<string> | undefined;
|
|
76
|
+
}
|
|
61
77
|
/** Stores the per-patch lint payload after a successful lint calculation. */
|
|
62
|
-
export declare function setCachedPerPatchLintIssues(
|
|
78
|
+
export declare function setCachedPerPatchLintIssues(input: SetCachedPerPatchLintIssuesInput): void;
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
-
import { createHash } from 'node:crypto';
|
|
3
2
|
import { readFile } from 'node:fs/promises';
|
|
4
3
|
import { join, resolve } from 'node:path';
|
|
5
4
|
import { pathExists, readJson, writeJson } from '../utils/fs.js';
|
|
5
|
+
import { sha256Hex } from '../utils/hash.js';
|
|
6
6
|
import { getPackageVersion } from '../utils/package-root.js';
|
|
7
7
|
import { getFurnacePaths } from './furnace-config.js';
|
|
8
8
|
import { git } from './git-base.js';
|
|
9
9
|
import { collectNewFileCreatorsByPath } from './patch-lint.js';
|
|
10
10
|
// Schema 2: entries additionally carry the lintIgnore-suppressed issues and
|
|
11
11
|
// the measured non-binary line count, so a warm run can report waived size
|
|
12
|
-
// measurements identically to a cold one
|
|
13
|
-
//
|
|
12
|
+
// measurements identically to a cold one. A cache hit must never surface
|
|
13
|
+
// less than a fresh lint.
|
|
14
14
|
// Schema 3: the key additionally content-hashes the
|
|
15
15
|
// `patchLint.checkJsTestShim` file exactly as `checkJsExtraShim`'s already
|
|
16
|
-
// was
|
|
16
|
+
// was. Without it, editing the test shim in place replays every cached
|
|
17
17
|
// verdict.
|
|
18
|
-
// Schema 4: each entry
|
|
18
|
+
// Schema 4: each entry records the lint-ignore waiver set that produced it,
|
|
19
19
|
// and a lookup whose effective waiver set differs is refused even when the
|
|
20
20
|
// key matches. The key already hashes `patch.lintIgnore`, so this is
|
|
21
21
|
// belt-and-braces on purpose: a waiver change is the one mutation that makes
|
|
22
|
-
// a replayed verdict actively
|
|
22
|
+
// a replayed verdict actively wrong (an operator writes a waiver, re-runs,
|
|
23
23
|
// and is shown the finding they just waived), and the class must not depend
|
|
24
24
|
// on every future key input staying complete. Bumping the schema also
|
|
25
25
|
// discards every pre-4 entry, which is itself the cure for a cache that
|
|
@@ -42,10 +42,6 @@ function stableJson(value) {
|
|
|
42
42
|
.map(([key, item]) => `${JSON.stringify(key)}:${stableJson(item)}`)
|
|
43
43
|
.join(',')}}`;
|
|
44
44
|
}
|
|
45
|
-
/** Computes a SHA-256 hex digest for text or binary content. */
|
|
46
|
-
function sha256Hex(content) {
|
|
47
|
-
return createHash('sha256').update(content).digest('hex');
|
|
48
|
-
}
|
|
49
45
|
/** Computes a stable SHA-256 digest for JSON-compatible data. */
|
|
50
46
|
function stableHash(value) {
|
|
51
47
|
return sha256Hex(stableJson(value));
|
|
@@ -100,7 +96,7 @@ function buildOwnershipFingerprint(files, ctx) {
|
|
|
100
96
|
export async function buildPerPatchLintCacheKey(input) {
|
|
101
97
|
// Hash in parallel, then insert in sorted order. The sort is load-bearing:
|
|
102
98
|
// `stableHash` below serialises this record, so insertion order is part of
|
|
103
|
-
// the cache key
|
|
99
|
+
// the cache key, and assigning as results land would make the key
|
|
104
100
|
// nondeterministic.
|
|
105
101
|
const sortedFiles = [...input.existingFiles].sort((a, b) => a.localeCompare(b));
|
|
106
102
|
const hashes = await Promise.all(sortedFiles.map((file) => fileHash(join(input.engineDir, file))));
|
|
@@ -114,8 +110,8 @@ export async function buildPerPatchLintCacheKey(input) {
|
|
|
114
110
|
const shimHashOf = async (shimPath) => shimPath === undefined
|
|
115
111
|
? null
|
|
116
112
|
: { path: shimPath, hash: await fileHash(resolve(input.projectRoot, shimPath)) };
|
|
117
|
-
// Both shims feed compiled checkJs programs, so both are content-hashed
|
|
118
|
-
//
|
|
113
|
+
// Both shims feed compiled checkJs programs, so both are content-hashed.
|
|
114
|
+
// The config block alone only carries their paths, and an in-place edit
|
|
119
115
|
// must invalidate the programs it feeds.
|
|
120
116
|
const [extraShim, testShim] = await Promise.all([
|
|
121
117
|
shimHashOf(input.config.patchLint?.checkJsExtraShim),
|
|
@@ -125,9 +121,9 @@ export async function buildPerPatchLintCacheKey(input) {
|
|
|
125
121
|
cacheSchemaVersion: LINT_CACHE_SCHEMA_VERSION,
|
|
126
122
|
engineHeadSha: input.engineHeadSha ?? null,
|
|
127
123
|
lintImplementationVersion: LINT_IMPLEMENTATION_VERSION,
|
|
128
|
-
//
|
|
129
|
-
//
|
|
130
|
-
//
|
|
124
|
+
// The plain semver, not the +g<sha> build identity: that identity
|
|
125
|
+
// churns every commit at the same version and would invalidate the
|
|
126
|
+
// cache for no correctness gain.
|
|
131
127
|
packageVersion: input.packageVersion ?? getPackageVersion(),
|
|
132
128
|
patchFile: await fileHash(join(input.patchesDir, input.patch.filename)),
|
|
133
129
|
patchMetadata: normalizePatchMetadata(input.patch),
|
|
@@ -181,7 +177,7 @@ export async function loadPerPatchLintCache(projectRoot) {
|
|
|
181
177
|
}
|
|
182
178
|
catch {
|
|
183
179
|
// Any unreadable or malformed cache file is treated as a cold cache. The
|
|
184
|
-
// cache is a pure optimisation, so discarding it is always safe
|
|
180
|
+
// cache is a pure optimisation, so discarding it is always safe. The
|
|
185
181
|
// alternative is failing lint over a corrupt sidecar.
|
|
186
182
|
return createEmptyPerPatchLintCache();
|
|
187
183
|
}
|
|
@@ -203,7 +199,7 @@ function normalizeLintIgnoreSet(lintIgnore) {
|
|
|
203
199
|
}
|
|
204
200
|
/**
|
|
205
201
|
* Returns the cached lint payload for a patch when the stored key still
|
|
206
|
-
* matches
|
|
202
|
+
* matches and the entry was computed under the same lint-ignore waiver set.
|
|
207
203
|
* A waiver change makes a replayed verdict actively wrong, so the waiver set
|
|
208
204
|
* is compared explicitly rather than trusted to the key.
|
|
209
205
|
*/
|
|
@@ -223,7 +219,8 @@ export function getCachedPerPatchLintIssues(cache, patchFilename, key, lintIgnor
|
|
|
223
219
|
};
|
|
224
220
|
}
|
|
225
221
|
/** Stores the per-patch lint payload after a successful lint calculation. */
|
|
226
|
-
export function setCachedPerPatchLintIssues(
|
|
222
|
+
export function setCachedPerPatchLintIssues(input) {
|
|
223
|
+
const { cache, patchFilename, key, issues, suppressed, lineCount, lintIgnore } = input;
|
|
227
224
|
cache.entries[patchFilename] = {
|
|
228
225
|
key,
|
|
229
226
|
patchFilename,
|