@hominis/fireforge 0.44.4 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +120 -0
- package/dist/bin/fireforge.js +6 -0
- 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 +5 -1
- package/dist/src/cli.js +20 -21
- package/dist/src/commands/bootstrap.js +1 -2
- package/dist/src/commands/build.js +15 -6
- package/dist/src/commands/destructive-decision.d.ts +19 -0
- package/dist/src/commands/destructive-decision.js +31 -0
- package/dist/src/commands/doctor-check-core.d.ts +0 -6
- package/dist/src/commands/doctor-check-core.js +0 -8
- package/dist/src/commands/doctor-orphaned-harness.d.ts +0 -6
- package/dist/src/commands/doctor-orphaned-harness.js +4 -12
- package/dist/src/commands/doctor-post-rebase-audit.js +1 -1
- package/dist/src/commands/doctor-source-pin.d.ts +29 -0
- package/dist/src/commands/doctor-source-pin.js +81 -0
- package/dist/src/commands/doctor.d.ts +2 -0
- package/dist/src/commands/doctor.js +9 -8
- package/dist/src/commands/download.js +35 -24
- package/dist/src/commands/export-all.js +21 -4
- package/dist/src/commands/export-flow.js +15 -60
- package/dist/src/commands/export-placement-conflicts.js +3 -3
- package/dist/src/commands/export-placement-gate.js +2 -8
- package/dist/src/commands/export-placement-policy.js +3 -5
- package/dist/src/commands/export-shared.d.ts +42 -23
- package/dist/src/commands/export-shared.js +4 -19
- package/dist/src/commands/export.js +10 -1
- 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.js +1 -1
- package/dist/src/commands/furnace/create-browser-test.js +3 -8
- package/dist/src/commands/furnace/create-dry-run.js +2 -5
- package/dist/src/commands/furnace/create-templates.d.ts +17 -1
- package/dist/src/commands/furnace/create-templates.js +2 -1
- package/dist/src/commands/furnace/create.js +25 -19
- package/dist/src/commands/furnace/deploy.js +11 -2
- package/dist/src/commands/furnace/init.js +2 -1
- package/dist/src/commands/furnace/override.js +28 -19
- package/dist/src/commands/furnace/refresh.js +9 -1
- package/dist/src/commands/furnace/remove-mutations.d.ts +6 -7
- package/dist/src/commands/furnace/remove-mutations.js +0 -1
- package/dist/src/commands/furnace/remove.js +2 -6
- package/dist/src/commands/furnace/rename-browser-test.js +1 -7
- package/dist/src/commands/furnace/rename.js +29 -29
- package/dist/src/commands/furnace/status.js +12 -9
- 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/validation-output.d.ts +21 -9
- package/dist/src/commands/furnace/validation-output.js +3 -8
- package/dist/src/commands/import.js +2 -9
- package/dist/src/commands/lint-per-patch.d.ts +2 -2
- package/dist/src/commands/lint-per-patch.js +19 -4
- package/dist/src/commands/lint-per-run-checkjs.d.ts +2 -2
- package/dist/src/commands/lint.d.ts +2 -1
- package/dist/src/commands/lint.js +1 -1
- package/dist/src/commands/manifest.js +1 -1
- package/dist/src/commands/package.js +2 -4
- package/dist/src/commands/patch/compact.js +14 -15
- package/dist/src/commands/patch/delete.js +15 -25
- 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 +0 -8
- package/dist/src/commands/patch/lint-ignore.js +19 -29
- package/dist/src/commands/patch/move-files-create.js +24 -10
- package/dist/src/commands/patch/move-files-into.js +38 -37
- package/dist/src/commands/patch/move-files.js +4 -13
- package/dist/src/commands/patch/rename.js +27 -41
- package/dist/src/commands/patch/reorder.js +25 -38
- package/dist/src/commands/patch/split-plan.d.ts +4 -5
- package/dist/src/commands/patch/split-plan.js +4 -11
- package/dist/src/commands/patch/split.js +45 -43
- package/dist/src/commands/patch/staged-dependency.js +16 -22
- package/dist/src/commands/patch/tier.js +15 -25
- 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 +32 -2
- package/dist/src/commands/re-export-adjacent.js +51 -10
- package/dist/src/commands/re-export-bulk-scan.js +6 -10
- package/dist/src/commands/re-export-drift.d.ts +8 -0
- package/dist/src/commands/re-export-drift.js +65 -4
- package/dist/src/commands/re-export-files.d.ts +2 -3
- package/dist/src/commands/re-export-files.js +38 -32
- package/dist/src/commands/re-export-lint.d.ts +3 -4
- package/dist/src/commands/re-export-lint.js +9 -2
- package/dist/src/commands/re-export-options.js +19 -5
- package/dist/src/commands/re-export-register.js +5 -1
- package/dist/src/commands/re-export-scan.js +8 -8
- package/dist/src/commands/re-export-single.d.ts +22 -3
- package/dist/src/commands/re-export-single.js +19 -11
- package/dist/src/commands/re-export.js +44 -27
- package/dist/src/commands/rebase/abort.js +3 -8
- package/dist/src/commands/rebase/continue.js +12 -12
- package/dist/src/commands/rebase/index.js +2 -2
- package/dist/src/commands/rebase/patch-loop.d.ts +2 -2
- package/dist/src/commands/rebase/patch-loop.js +2 -7
- package/dist/src/commands/resolve.js +18 -10
- package/dist/src/commands/run.d.ts +0 -13
- package/dist/src/commands/run.js +12 -25
- package/dist/src/commands/setup-support.d.ts +16 -4
- package/dist/src/commands/setup-support.js +16 -16
- package/dist/src/commands/setup.js +3 -9
- package/dist/src/commands/source.js +8 -1
- package/dist/src/commands/status-check.js +2 -2
- package/dist/src/commands/status-output.js +2 -2
- package/dist/src/commands/status.js +3 -4
- package/dist/src/commands/test-build-phase.d.ts +2 -2
- package/dist/src/commands/test-build-phase.js +33 -8
- package/dist/src/commands/test-diagnose.js +14 -5
- package/dist/src/commands/test-modes.d.ts +2 -2
- package/dist/src/commands/test-modes.js +0 -1
- package/dist/src/commands/test-register.js +6 -3
- package/dist/src/commands/test-run.js +29 -21
- package/dist/src/commands/test-stale-gate.js +8 -5
- package/dist/src/commands/test-verdict.d.ts +16 -2
- package/dist/src/commands/test-verdict.js +18 -3
- package/dist/src/commands/test.js +51 -7
- 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 +17 -1
- package/dist/src/commands/tree.js +7 -2
- package/dist/src/commands/typecheck.js +9 -9
- package/dist/src/commands/wire.js +4 -3
- package/dist/src/core/branding.d.ts +0 -7
- package/dist/src/core/branding.js +3 -2
- package/dist/src/core/browser-wire.js +6 -3
- package/dist/src/core/build-audit-platform.d.ts +29 -0
- package/dist/src/core/build-audit-platform.js +140 -0
- package/dist/src/core/build-audit-registration.js +3 -2
- 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.d.ts +15 -2
- package/dist/src/core/build-audit.js +154 -12
- package/dist/src/core/build-baseline.d.ts +45 -28
- package/dist/src/core/build-baseline.js +6 -29
- package/dist/src/core/build-jar-escalation.d.ts +64 -0
- package/dist/src/core/build-jar-escalation.js +128 -0
- package/dist/src/core/build-overwrite-guard.js +1 -1
- package/dist/src/core/build-prepare.d.ts +5 -2
- package/dist/src/core/build-prepare.js +34 -6
- 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 +1 -19
- 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 +12 -0
- package/dist/src/core/config-validate-file-size.js +65 -0
- 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 +20 -3
- package/dist/src/core/config.d.ts +2 -2
- package/dist/src/core/config.js +11 -15
- package/dist/src/core/coverage-extend.js +4 -4
- package/dist/src/core/discard-baseline.js +7 -7
- package/dist/src/core/engine-precondition.d.ts +1 -9
- package/dist/src/core/engine-precondition.js +3 -8
- package/dist/src/core/engine-session-lock.js +13 -17
- package/dist/src/core/export-moved-code-shape.js +2 -2
- 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 +2 -7
- package/dist/src/core/file-lock.js +40 -91
- package/dist/src/core/firefox-cache.d.ts +13 -1
- package/dist/src/core/firefox-cache.js +59 -34
- package/dist/src/core/firefox-download.d.ts +15 -0
- package/dist/src/core/firefox-download.js +37 -21
- package/dist/src/core/firefox-extract.d.ts +6 -5
- package/dist/src/core/firefox-extract.js +36 -18
- package/dist/src/core/firefox.d.ts +30 -32
- package/dist/src/core/firefox.js +5 -36
- package/dist/src/core/furnace-apply-dry-run.d.ts +1 -6
- package/dist/src/core/furnace-apply-dry-run.js +1 -7
- package/dist/src/core/furnace-apply-helpers.d.ts +0 -11
- package/dist/src/core/furnace-apply-helpers.js +8 -19
- package/dist/src/core/furnace-apply-overwrite-warn.js +4 -2
- package/dist/src/core/furnace-apply.d.ts +1 -1
- package/dist/src/core/furnace-apply.js +30 -10
- package/dist/src/core/furnace-config.d.ts +1 -1
- package/dist/src/core/furnace-config.js +23 -36
- package/dist/src/core/furnace-constants.js +3 -2
- 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-operation.d.ts +2 -0
- package/dist/src/core/furnace-operation.js +3 -1
- package/dist/src/core/furnace-refresh.d.ts +18 -6
- package/dist/src/core/furnace-refresh.js +3 -6
- package/dist/src/core/furnace-registration-ast.d.ts +0 -1
- package/dist/src/core/furnace-registration-ast.js +0 -3
- package/dist/src/core/furnace-registration.d.ts +2 -1
- package/dist/src/core/furnace-registration.js +22 -29
- package/dist/src/core/furnace-scanner.js +3 -6
- package/dist/src/core/furnace-state-persist.d.ts +2 -2
- package/dist/src/core/furnace-validate-registration.js +5 -7
- package/dist/src/core/git-base.d.ts +3 -1
- package/dist/src/core/git-base.js +25 -3
- 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 +9 -9
- package/dist/src/core/git-diff.js +88 -157
- package/dist/src/core/git-file-ops.d.ts +0 -7
- package/dist/src/core/git-file-ops.js +4 -28
- package/dist/src/core/git-readonly-index.d.ts +0 -2
- package/dist/src/core/git-readonly-index.js +0 -4
- package/dist/src/core/git-status.d.ts +7 -0
- package/dist/src/core/git-status.js +21 -9
- package/dist/src/core/git.d.ts +0 -6
- package/dist/src/core/git.js +14 -43
- package/dist/src/core/harness-orphans.d.ts +73 -0
- package/dist/src/core/harness-orphans.js +187 -0
- package/dist/src/core/history-log.d.ts +19 -0
- package/dist/src/core/history-log.js +29 -0
- package/dist/src/core/mach-error-hints.d.ts +0 -5
- package/dist/src/core/mach-error-hints.js +1 -1
- package/dist/src/core/mach-known-noise-filter.d.ts +25 -3
- package/dist/src/core/mach-known-noise-filter.js +31 -10
- package/dist/src/core/mach-mozconfig.js +2 -1
- package/dist/src/core/mach-python.d.ts +2 -0
- package/dist/src/core/mach-python.js +12 -7
- package/dist/src/core/mach-resource-shim.d.ts +13 -1
- package/dist/src/core/mach-resource-shim.js +112 -9
- package/dist/src/core/mach.d.ts +46 -53
- package/dist/src/core/mach.js +31 -83
- package/dist/src/core/marionette-port.d.ts +0 -17
- package/dist/src/core/marionette-port.js +12 -58
- package/dist/src/core/marionette-preflight.js +9 -27
- package/dist/src/core/mochitest-server-port.js +3 -3
- package/dist/src/core/moz-manifest-rules.js +37 -33
- package/dist/src/core/patch-apply-fuzz.js +4 -4
- package/dist/src/core/patch-apply.d.ts +4 -5
- package/dist/src/core/patch-apply.js +55 -32
- 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 +18 -1
- package/dist/src/core/patch-export-update.js +4 -3
- package/dist/src/core/patch-export.d.ts +11 -21
- package/dist/src/core/patch-export.js +44 -66
- package/dist/src/core/patch-files.d.ts +0 -4
- package/dist/src/core/patch-files.js +0 -11
- package/dist/src/core/patch-lint-binary.d.ts +6 -12
- package/dist/src/core/patch-lint-cache.d.ts +17 -1
- package/dist/src/core/patch-lint-cache.js +3 -6
- package/dist/src/core/patch-lint-checkjs.d.ts +33 -16
- package/dist/src/core/patch-lint-checkjs.js +43 -25
- package/dist/src/core/patch-lint-creators.d.ts +2 -6
- package/dist/src/core/patch-lint-cross.d.ts +16 -8
- package/dist/src/core/patch-lint-cross.js +49 -92
- package/dist/src/core/patch-lint-css.js +10 -6
- package/dist/src/core/patch-lint-file-size.d.ts +52 -0
- package/dist/src/core/patch-lint-file-size.js +53 -0
- 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.js +36 -36
- package/dist/src/core/patch-lint-module-registration.d.ts +2 -8
- package/dist/src/core/patch-lint-prettier.d.ts +36 -0
- package/dist/src/core/patch-lint-prettier.js +126 -0
- 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 +106 -0
- package/dist/src/core/patch-lint-unmanaged-companion.js +214 -0
- package/dist/src/core/patch-lint.d.ts +14 -9
- package/dist/src/core/patch-lint.js +27 -27
- package/dist/src/core/patch-lock.js +3 -3
- package/dist/src/core/patch-manifest-io.js +8 -7
- package/dist/src/core/patch-parse.d.ts +19 -8
- package/dist/src/core/patch-parse.js +25 -0
- package/dist/src/core/patch-policy.js +15 -27
- 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 +21 -8
- package/dist/src/core/patch-transform.js +38 -10
- package/dist/src/core/process-cpu-time.js +1 -1
- package/dist/src/core/rebase-session.d.ts +2 -8
- package/dist/src/core/rebase-session.js +5 -17
- 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-scaffold.js +5 -4
- package/dist/src/core/register-shared-css.js +2 -1
- 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 +13 -2
- package/dist/src/core/run-log.js +67 -18
- package/dist/src/core/signal-critical.js +2 -4
- package/dist/src/core/smoke-patterns.d.ts +0 -1
- package/dist/src/core/smoke-patterns.js +18 -11
- package/dist/src/core/state-file.d.ts +12 -1
- package/dist/src/core/state-file.js +14 -1
- package/dist/src/core/status-classify.js +2 -1
- package/dist/src/core/test-changed-prefs.js +26 -11
- package/dist/src/core/test-harness-crash.js +61 -48
- package/dist/src/core/test-harness-verdict-notes.d.ts +55 -0
- package/dist/src/core/test-harness-verdict-notes.js +48 -0
- package/dist/src/core/test-stale-check.d.ts +23 -8
- package/dist/src/core/test-stale-check.js +77 -4
- package/dist/src/core/test-stall-triage.js +37 -19
- 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 +33 -0
- package/dist/src/core/token-category.js +56 -48
- package/dist/src/core/token-dark-mode.js +2 -14
- 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 +1 -1
- package/dist/src/core/token-manager.js +1 -1
- package/dist/src/core/token-variant.js +21 -22
- package/dist/src/core/toolchain-preflight.js +1 -1
- package/dist/src/core/tree-cow.d.ts +0 -2
- package/dist/src/core/tree-cow.js +2 -2
- package/dist/src/core/tree-store.js +4 -5
- package/dist/src/core/typecheck.js +2 -2
- package/dist/src/core/wire-dom-fragment.js +6 -17
- package/dist/src/core/wire-utils.js +5 -17
- package/dist/src/core/xpcshell-appdir.js +2 -4
- package/dist/src/errors/base.d.ts +53 -1
- package/dist/src/errors/base.js +79 -11
- package/dist/src/errors/build.d.ts +28 -0
- package/dist/src/errors/build.js +51 -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.js +8 -9
- package/dist/src/errors/git.d.ts +8 -8
- package/dist/src/errors/git.js +20 -30
- package/dist/src/errors/patch.js +8 -10
- package/dist/src/errors/rebase.js +7 -7
- package/dist/src/types/commands/options.d.ts +96 -123
- package/dist/src/types/commands/patches.d.ts +17 -6
- package/dist/src/types/config.d.ts +75 -2
- package/dist/src/types/index.d.ts +0 -1
- package/dist/src/utils/assert.d.ts +3 -15
- package/dist/src/utils/assert.js +1 -18
- package/dist/src/utils/build-info.d.ts +1 -1
- package/dist/src/utils/child-env.d.ts +2 -1
- package/dist/src/utils/elapsed.js +10 -1
- package/dist/src/utils/fs.d.ts +4 -2
- package/dist/src/utils/fs.js +11 -14
- 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/options.d.ts +1 -7
- package/dist/src/utils/options.js +6 -7
- package/dist/src/utils/package-root.js +3 -12
- package/dist/src/utils/platform.d.ts +0 -4
- package/dist/src/utils/process-group.d.ts +2 -1
- package/dist/src/utils/process-group.js +20 -19
- package/dist/src/utils/process.d.ts +40 -26
- package/dist/src/utils/process.js +115 -166
- package/dist/src/utils/ps-duration.js +3 -3
- package/dist/src/utils/sleep.d.ts +26 -0
- package/dist/src/utils/sleep.js +31 -0
- package/dist/src/utils/validation.d.ts +2 -38
- package/dist/src/utils/validation.js +7 -16
- package/docs/configuration.md +136 -1
- package/docs/exit-codes.md +34 -20
- package/docs/lifecycle-invariants.md +18 -12
- package/docs/machine-output.md +31 -8
- package/docs/patch-workflow.md +2 -1
- package/docs/run-logs.md +44 -4
- package/docs/testing.md +70 -11
- package/package.json +8 -7
- 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
|
@@ -18,18 +18,7 @@ import { escapeRegex } from '../../utils/regex.js';
|
|
|
18
18
|
import { updateBrowserChromeTestContent } from './rename-browser-test.js';
|
|
19
19
|
import { rekeyStateChecksums, renameComponentFileName, updateConfigForCustomRename, updateConfigForOverrideRename, } from './rename-helpers.js';
|
|
20
20
|
import { renameXpcshellTestFiles } from './rename-xpcshell.js';
|
|
21
|
-
|
|
22
|
-
* Derives the test file name for a component, matching the convention used by
|
|
23
|
-
* `furnace create --with-tests`.
|
|
24
|
-
*/
|
|
25
|
-
function deriveTestFileName(componentName, binaryName) {
|
|
26
|
-
const strippedName = componentName.startsWith('moz-') ? componentName.slice(4) : componentName;
|
|
27
|
-
const withoutBinaryPrefix = strippedName.startsWith(binaryName + '-')
|
|
28
|
-
? strippedName.slice(binaryName.length + 1)
|
|
29
|
-
: strippedName;
|
|
30
|
-
const underscored = withoutBinaryPrefix.replace(/-/g, '_');
|
|
31
|
-
return `browser_${binaryName}_${underscored}.js`;
|
|
32
|
-
}
|
|
21
|
+
import { browserTestFileName } from './test-file-name.js';
|
|
33
22
|
/**
|
|
34
23
|
* Renames test files created by `furnace create --with-tests` in the engine
|
|
35
24
|
* test directory. Best-effort: failures are logged as warnings but do not
|
|
@@ -44,8 +33,8 @@ async function renameTestFiles(engineDir, projectRoot, oldName, newName, journal
|
|
|
44
33
|
return; // Cannot determine test paths without config.
|
|
45
34
|
}
|
|
46
35
|
const binaryName = forgeConfig.binaryName;
|
|
47
|
-
const oldTestFileName =
|
|
48
|
-
const newTestFileName =
|
|
36
|
+
const oldTestFileName = browserTestFileName(oldName, binaryName);
|
|
37
|
+
const newTestFileName = browserTestFileName(newName, binaryName);
|
|
49
38
|
const testDir = join(engineDir, 'browser/base/content/test', binaryName);
|
|
50
39
|
if (!(await pathExists(testDir)))
|
|
51
40
|
return;
|
|
@@ -259,7 +248,15 @@ async function performRenameMutations(args) {
|
|
|
259
248
|
if (isCustom && config.custom[newName]?.register && (await pathExists(args.engineDir))) {
|
|
260
249
|
const ftlDir = resolveFtlDir(config.ftlBasePath);
|
|
261
250
|
const isLocalized = config.custom[newName].localized;
|
|
262
|
-
await updateEngineRegistrations(
|
|
251
|
+
await updateEngineRegistrations({
|
|
252
|
+
engineDir: args.engineDir,
|
|
253
|
+
oldName,
|
|
254
|
+
newName,
|
|
255
|
+
newDir,
|
|
256
|
+
ftlDir,
|
|
257
|
+
isLocalized,
|
|
258
|
+
journal,
|
|
259
|
+
});
|
|
263
260
|
}
|
|
264
261
|
// 4. Re-key furnace-state.json checksums from old name to new name
|
|
265
262
|
await rekeyStateChecksums(args.projectRoot, componentType, oldName, newName);
|
|
@@ -323,7 +320,14 @@ async function performRenameMutations(args) {
|
|
|
323
320
|
}
|
|
324
321
|
});
|
|
325
322
|
}
|
|
326
|
-
|
|
323
|
+
/**
|
|
324
|
+
* Re-points the engine-side registrations (customElements.js, jar.mn, and
|
|
325
|
+
* the localized `.ftl` entries) from the old tag name to the new one.
|
|
326
|
+
*
|
|
327
|
+
* @param options - See {@link UpdateEngineRegistrationsOptions}
|
|
328
|
+
*/
|
|
329
|
+
async function updateEngineRegistrations(options) {
|
|
330
|
+
const { engineDir, oldName, newName, newDir, ftlDir, isLocalized, journal } = options;
|
|
327
331
|
const customElementsPath = join(engineDir, 'toolkit/content/customElements.js');
|
|
328
332
|
const jarMnPath = join(engineDir, 'toolkit/content/jar.mn');
|
|
329
333
|
if (await pathExists(customElementsPath)) {
|
|
@@ -396,15 +400,15 @@ export async function furnaceRenameCommand(projectRoot, oldName, newName) {
|
|
|
396
400
|
if (newName in config.custom || newName in config.overrides || config.stock.includes(newName)) {
|
|
397
401
|
throw new FurnaceError(`A component named "${newName}" already exists in furnace.json.`, newName);
|
|
398
402
|
}
|
|
399
|
-
|
|
400
|
-
//
|
|
401
|
-
//
|
|
402
|
-
// live under `components/
|
|
403
|
-
// `
|
|
404
|
-
//
|
|
405
|
-
//
|
|
406
|
-
//
|
|
407
|
-
//
|
|
403
|
+
// The furnace-state key is singular (`custom` / `override`, derived
|
|
404
|
+
// inside performRenameMutations); the on-disk directory label differs —
|
|
405
|
+
// custom components live under `components/custom/` (singular) while
|
|
406
|
+
// overrides live under `components/overrides/` (plural). Appending an
|
|
407
|
+
// `s` to the state key produces the wrong label `components/customs/`
|
|
408
|
+
// for custom components and is correct for overrides only by
|
|
409
|
+
// coincidence. `componentDirLabel` centralises the pick so every
|
|
410
|
+
// operator-facing string names the directory that actually exists on
|
|
411
|
+
// disk.
|
|
408
412
|
const componentDirLabel = isCustom ? 'custom' : 'overrides';
|
|
409
413
|
const baseDir = isCustom ? furnacePaths.customDir : furnacePaths.overridesDir;
|
|
410
414
|
const oldDir = join(baseDir, oldName);
|
|
@@ -419,11 +423,7 @@ export async function furnaceRenameCommand(projectRoot, oldName, newName) {
|
|
|
419
423
|
projectRoot,
|
|
420
424
|
oldName,
|
|
421
425
|
newName,
|
|
422
|
-
oldDir,
|
|
423
426
|
newDir,
|
|
424
|
-
isCustom,
|
|
425
|
-
componentType,
|
|
426
|
-
config,
|
|
427
427
|
furnaceConfigPath: furnacePaths.furnaceConfig,
|
|
428
428
|
furnacePaths,
|
|
429
429
|
engineDir: paths.engine,
|
|
@@ -11,15 +11,10 @@ import { pathExists } from '../../utils/fs.js';
|
|
|
11
11
|
import { info, intro, note, outro, warn } from '../../utils/logger.js';
|
|
12
12
|
/**
|
|
13
13
|
* Displays detailed status for a single Furnace component, including registration drift.
|
|
14
|
-
* @param
|
|
15
|
-
* @param config - Loaded Furnace configuration
|
|
16
|
-
* @param state - Loaded furnace state, for applied/engine checksums
|
|
17
|
-
* @param projectRoot - Root directory of the project
|
|
18
|
-
* @param paths - Resolved project paths
|
|
19
|
-
* @param furnacePaths - Resolved Furnace-specific paths
|
|
20
|
-
* @param ftlDir - Engine-relative directory localized components deploy their `.ftl` into
|
|
14
|
+
* @param options - See {@link DetailedComponentStatusOptions}
|
|
21
15
|
*/
|
|
22
|
-
async function showDetailedComponentStatus(
|
|
16
|
+
async function showDetailedComponentStatus(options) {
|
|
17
|
+
const { name, config, state, projectRoot, paths, furnacePaths, ftlDir } = options;
|
|
23
18
|
const customConfig = config.custom[name];
|
|
24
19
|
const overrideConfig = config.overrides[name];
|
|
25
20
|
if (!customConfig && !overrideConfig && !config.stock.includes(name)) {
|
|
@@ -113,7 +108,15 @@ export async function furnaceStatusCommand(projectRoot, name) {
|
|
|
113
108
|
const furnacePaths = getFurnacePaths(projectRoot);
|
|
114
109
|
const ftlDir = resolveFtlDir(config.ftlBasePath);
|
|
115
110
|
if (name) {
|
|
116
|
-
await showDetailedComponentStatus(
|
|
111
|
+
await showDetailedComponentStatus({
|
|
112
|
+
name,
|
|
113
|
+
config,
|
|
114
|
+
state,
|
|
115
|
+
projectRoot,
|
|
116
|
+
paths,
|
|
117
|
+
furnacePaths,
|
|
118
|
+
ftlDir,
|
|
119
|
+
});
|
|
117
120
|
return;
|
|
118
121
|
}
|
|
119
122
|
// Surface a pendingRepair marker before the normal summary so it cannot
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derives the underscored stem a component's generated test files are named
|
|
3
|
+
* after.
|
|
4
|
+
*
|
|
5
|
+
* Five modules (`create-browser-test`, `create-dry-run`, `remove`, `rename`,
|
|
6
|
+
* `rename-browser-test`) had each inlined this three-step transform. The steps
|
|
7
|
+
* are not arbitrary and must agree exactly, or `furnace rename` and
|
|
8
|
+
* `furnace remove` compute a different filename than `furnace create` wrote
|
|
9
|
+
* and silently leave the old test behind:
|
|
10
|
+
*
|
|
11
|
+
* 1. drop the upstream `moz-` custom-element prefix, which never appears in a
|
|
12
|
+
* test filename;
|
|
13
|
+
* 2. drop a leading `<binaryName>-`, because the test directory is already
|
|
14
|
+
* named after the binary and the prefix would be doubled;
|
|
15
|
+
* 3. underscore the remaining dashes, matching mozilla-central's
|
|
16
|
+
* `browser_*.js` convention.
|
|
17
|
+
* @param componentName - Custom-element name, e.g. `moz-mybrowser-sidebar`.
|
|
18
|
+
* @param binaryName - Configured binary name, e.g. `mybrowser`.
|
|
19
|
+
* @returns The stem, e.g. `sidebar`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function deriveTestStem(componentName: string, binaryName: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Builds the browser-chrome test filename for a component.
|
|
24
|
+
* @param componentName - Custom-element name.
|
|
25
|
+
* @param binaryName - Configured binary name.
|
|
26
|
+
* @returns The filename, e.g. `browser_mybrowser_sidebar.js`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function browserTestFileName(componentName: string, binaryName: string): string;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* Derives the underscored stem a component's generated test files are named
|
|
4
|
+
* after.
|
|
5
|
+
*
|
|
6
|
+
* Five modules (`create-browser-test`, `create-dry-run`, `remove`, `rename`,
|
|
7
|
+
* `rename-browser-test`) had each inlined this three-step transform. The steps
|
|
8
|
+
* are not arbitrary and must agree exactly, or `furnace rename` and
|
|
9
|
+
* `furnace remove` compute a different filename than `furnace create` wrote
|
|
10
|
+
* and silently leave the old test behind:
|
|
11
|
+
*
|
|
12
|
+
* 1. drop the upstream `moz-` custom-element prefix, which never appears in a
|
|
13
|
+
* test filename;
|
|
14
|
+
* 2. drop a leading `<binaryName>-`, because the test directory is already
|
|
15
|
+
* named after the binary and the prefix would be doubled;
|
|
16
|
+
* 3. underscore the remaining dashes, matching mozilla-central's
|
|
17
|
+
* `browser_*.js` convention.
|
|
18
|
+
* @param componentName - Custom-element name, e.g. `moz-mybrowser-sidebar`.
|
|
19
|
+
* @param binaryName - Configured binary name, e.g. `mybrowser`.
|
|
20
|
+
* @returns The stem, e.g. `sidebar`.
|
|
21
|
+
*/
|
|
22
|
+
export function deriveTestStem(componentName, binaryName) {
|
|
23
|
+
const withoutMozPrefix = componentName.startsWith('moz-')
|
|
24
|
+
? componentName.slice(4)
|
|
25
|
+
: componentName;
|
|
26
|
+
const withoutBinaryPrefix = withoutMozPrefix.startsWith(`${binaryName}-`)
|
|
27
|
+
? withoutMozPrefix.slice(binaryName.length + 1)
|
|
28
|
+
: withoutMozPrefix;
|
|
29
|
+
return withoutBinaryPrefix.replace(/-/g, '_');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Builds the browser-chrome test filename for a component.
|
|
33
|
+
* @param componentName - Custom-element name.
|
|
34
|
+
* @param binaryName - Configured binary name.
|
|
35
|
+
* @returns The filename, e.g. `browser_mybrowser_sidebar.js`.
|
|
36
|
+
*/
|
|
37
|
+
export function browserTestFileName(componentName, binaryName) {
|
|
38
|
+
return `browser_${binaryName}_${deriveTestStem(componentName, binaryName)}.js`;
|
|
39
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FurnacePaths } from '../../core/furnace-config.js';
|
|
2
2
|
import type { DryRunAction, FurnaceConfig, ValidationIssue } from '../../types/furnace.js';
|
|
3
3
|
import { type SpinnerHandle } from '../../utils/logger.js';
|
|
4
4
|
/**
|
|
@@ -16,15 +16,27 @@ export type ValidationResult = {
|
|
|
16
16
|
componentCount: number;
|
|
17
17
|
skippedValidationCount: number;
|
|
18
18
|
};
|
|
19
|
+
export interface RunDeployValidationOptions {
|
|
20
|
+
/** Active spinner handle for progress display. */
|
|
21
|
+
validateSpinner: SpinnerHandle;
|
|
22
|
+
/** Optional component name (validates all if omitted). */
|
|
23
|
+
name: string | undefined;
|
|
24
|
+
/** Loaded Furnace configuration. */
|
|
25
|
+
config: FurnaceConfig;
|
|
26
|
+
/** Resolved Furnace workspace paths. */
|
|
27
|
+
furnacePaths: FurnacePaths;
|
|
28
|
+
/** Names of components whose apply step failed. */
|
|
29
|
+
failedComponents: Set<string>;
|
|
30
|
+
/** Whether deploy is running in dry-run mode. */
|
|
31
|
+
isDryRun: boolean;
|
|
32
|
+
/** Root directory of the project. */
|
|
33
|
+
projectRoot: string;
|
|
34
|
+
/** Projected actions of a dry run, used to filter projected issues. */
|
|
35
|
+
dryRunActions?: DryRunAction[] | undefined;
|
|
36
|
+
}
|
|
19
37
|
/**
|
|
20
38
|
* Runs the validation phase of a furnace deploy, checking all or a single component.
|
|
21
|
-
* @param
|
|
22
|
-
* @param name - Optional component name (validates all if omitted)
|
|
23
|
-
* @param config - Loaded Furnace configuration
|
|
24
|
-
* @param furnacePaths - Resolved Furnace workspace paths
|
|
25
|
-
* @param failedComponents - Names of components whose apply step failed
|
|
26
|
-
* @param isDryRun - Whether deploy is running in dry-run mode
|
|
27
|
-
* @param projectRoot - Root directory of the project
|
|
39
|
+
* @param options - See {@link RunDeployValidationOptions}
|
|
28
40
|
* @returns Validation counts, or `done: true` if the caller should early-return
|
|
29
41
|
*/
|
|
30
|
-
export declare function runDeployValidation(
|
|
42
|
+
export declare function runDeployValidation(options: RunDeployValidationOptions): Promise<ValidationResult>;
|
|
@@ -56,16 +56,11 @@ function resolveNamedValidationTarget(name, config, furnacePaths) {
|
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
58
|
* Runs the validation phase of a furnace deploy, checking all or a single component.
|
|
59
|
-
* @param
|
|
60
|
-
* @param name - Optional component name (validates all if omitted)
|
|
61
|
-
* @param config - Loaded Furnace configuration
|
|
62
|
-
* @param furnacePaths - Resolved Furnace workspace paths
|
|
63
|
-
* @param failedComponents - Names of components whose apply step failed
|
|
64
|
-
* @param isDryRun - Whether deploy is running in dry-run mode
|
|
65
|
-
* @param projectRoot - Root directory of the project
|
|
59
|
+
* @param options - See {@link RunDeployValidationOptions}
|
|
66
60
|
* @returns Validation counts, or `done: true` if the caller should early-return
|
|
67
61
|
*/
|
|
68
|
-
export async function runDeployValidation(
|
|
62
|
+
export async function runDeployValidation(options) {
|
|
63
|
+
const { validateSpinner, name, config, furnacePaths, failedComponents, isDryRun, projectRoot, dryRunActions, } = options;
|
|
69
64
|
let totalErrors = 0;
|
|
70
65
|
let totalWarnings = 0;
|
|
71
66
|
let componentCount = 0;
|
|
@@ -437,16 +437,9 @@ export function registerImport(program, { getProjectRoot, withErrorHandling }) {
|
|
|
437
437
|
// prompt, so a scripted import can run unattended while the integrity
|
|
438
438
|
// refusal stays armed — which is the guard you actually want in CI.
|
|
439
439
|
.option('-y, --yes', 'Answer the drift prompt non-interactively. Unlike --force, this does NOT waive the patch-integrity gate.')
|
|
440
|
-
.option('--until <patch>', 'Apply patches only up to and including this patch
|
|
441
|
-
.option('--stop-at <patch>', 'Alias for --until')
|
|
440
|
+
.option('--until <patch>', 'Apply patches only up to and including this patch')
|
|
442
441
|
.option('--dry-run', 'Preview which patches would be applied without modifying the engine')
|
|
443
442
|
.action(withErrorHandling(async (options) => {
|
|
444
|
-
|
|
445
|
-
const merged = { ...options };
|
|
446
|
-
if (merged.until === undefined && merged.stopAt !== undefined) {
|
|
447
|
-
merged.until = merged.stopAt;
|
|
448
|
-
}
|
|
449
|
-
delete merged.stopAt;
|
|
450
|
-
await importCommand(getProjectRoot(), pickDefined(merged));
|
|
443
|
+
await importCommand(getProjectRoot(), pickDefined(options));
|
|
451
444
|
}));
|
|
452
445
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getProjectPaths } from '../core/config.js';
|
|
2
1
|
import type { LintCommandOptions } from '../types/commands/index.js';
|
|
2
|
+
import type { ProjectPaths } from '../types/config.js';
|
|
3
3
|
/**
|
|
4
4
|
* Lints each patch in the queue as its own isolated diff, honouring
|
|
5
5
|
* per-patch `lintIgnore` entries. Cross-patch rules still run once over
|
|
@@ -7,4 +7,4 @@ import type { LintCommandOptions } from '../types/commands/index.js';
|
|
|
7
7
|
* With `options.patches` set, only the named subset is linted (and the
|
|
8
8
|
* queue-level findings are scoped to files those patches touch).
|
|
9
9
|
*/
|
|
10
|
-
export declare function lintPerPatch(projectRoot: string, paths:
|
|
10
|
+
export declare function lintPerPatch(projectRoot: string, paths: ProjectPaths, options?: LintCommandOptions): Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { loadConfig } from '../core/config.js';
|
|
4
4
|
import { getDiffForFilesAgainstHead } from '../core/git-diff.js';
|
|
5
5
|
import { withPrivateGitIndex } from '../core/git-readonly-index.js';
|
|
6
6
|
import { buildPatchQueueContext, countNonBinaryDiffLines, formatPatchLintIssue, lintExportedPatch, lintPatchQueue, resolvePatchSizeTier, } from '../core/patch-lint.js';
|
|
@@ -169,7 +169,15 @@ async function applyPerPatchResults(subset, results, issues, checkJs, cache) {
|
|
|
169
169
|
issues.push(...(await checkJs.getGlobal()));
|
|
170
170
|
}
|
|
171
171
|
if (result.cacheWrite && cache) {
|
|
172
|
-
setCachedPerPatchLintIssues(
|
|
172
|
+
setCachedPerPatchLintIssues({
|
|
173
|
+
cache,
|
|
174
|
+
patchFilename: patch.filename,
|
|
175
|
+
key: result.cacheWrite.key,
|
|
176
|
+
issues: result.rawIssues,
|
|
177
|
+
suppressed: result.suppressedIssues,
|
|
178
|
+
lineCount: result.lineCount,
|
|
179
|
+
lintIgnore: result.cacheWrite.lintIgnore,
|
|
180
|
+
});
|
|
173
181
|
totals.cacheDirty = true;
|
|
174
182
|
}
|
|
175
183
|
for (const issue of result.rawIssues) {
|
|
@@ -267,7 +275,7 @@ function reportPerPatchOutcome(issues, linted, skipped, options) {
|
|
|
267
275
|
/**
|
|
268
276
|
* Resolves the `--patches <name…>` subset filter against the manifest,
|
|
269
277
|
* matching each requested name tolerantly (exact filename, filename ±
|
|
270
|
-
* `.patch`, or the manifest `name` field). Throws listing the available
|
|
278
|
+
* `.patch`, the bare order number, or the manifest `name` field). Throws listing the available
|
|
271
279
|
* patches when a requested name matches none, so a typo fails loud rather
|
|
272
280
|
* than silently linting nothing.
|
|
273
281
|
*/
|
|
@@ -278,7 +286,14 @@ function selectPatchSubset(manifest, requested) {
|
|
|
278
286
|
.filter((entry) => entry.length > 0);
|
|
279
287
|
const patchAliases = (p) => {
|
|
280
288
|
const aliases = new Set([p.filename, p.filename.replace(/\.patch$/, ''), p.name]);
|
|
289
|
+
// The bare order number, both as the manifest records it and as the
|
|
290
|
+
// filename spells it (`2` and `002`). The refusal message offers stems,
|
|
291
|
+
// and an operator reading `102-ui-canvas-tiles.patch` in a lint finding
|
|
292
|
+
// reaches for `102` first.
|
|
293
|
+
aliases.add(String(p.order));
|
|
281
294
|
const match = /^(\d+)-([a-z]+)-(.+)\.patch$/.exec(p.filename);
|
|
295
|
+
if (match?.[1])
|
|
296
|
+
aliases.add(match[1]);
|
|
282
297
|
if (match?.[2] && match[3]) {
|
|
283
298
|
aliases.add(`${match[2]}-${match[3]}`);
|
|
284
299
|
aliases.add(match[3]);
|
|
@@ -296,7 +311,7 @@ function selectPatchSubset(manifest, requested) {
|
|
|
296
311
|
if (found.length === 0) {
|
|
297
312
|
const available = manifest.patches.map((p) => p.filename).join(', ');
|
|
298
313
|
throw new GeneralError(`No patch in the queue matches "${name}". In --per-patch mode, positional arguments ` +
|
|
299
|
-
`and --patches select patches (filename, stem, manifest name, or slug) — not engine ` +
|
|
314
|
+
`and --patches select patches (filename, stem, order number, manifest name, or slug) — not engine ` +
|
|
300
315
|
`files; drop --per-patch to lint engine paths. Available patches: ${available}`);
|
|
301
316
|
}
|
|
302
317
|
for (const p of found) {
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
* less than cold" via `probeCheckJsGlobalIssues` instead of building
|
|
21
21
|
* anything.
|
|
22
22
|
*/
|
|
23
|
-
import type { getProjectPaths, loadConfig } from '../core/config.js';
|
|
24
23
|
import { type GroupedCheckJsResult } from '../core/patch-lint-checkjs.js';
|
|
25
24
|
import type { PatchQueueContext } from '../core/patch-lint-cross.js';
|
|
26
25
|
import type { PatchLintIssue } from '../types/commands/index.js';
|
|
26
|
+
import type { FireForgeConfig, ProjectPaths } from '../types/config.js';
|
|
27
27
|
/**
|
|
28
28
|
* Queue-wide checkJs program built once per run and sliced per patch, so a
|
|
29
29
|
* single type regression surfaces once against its owning patch instead of
|
|
@@ -61,4 +61,4 @@ export interface PerRunCheckJs {
|
|
|
61
61
|
* subset's owned files and the test-file pass runs only the subset's own
|
|
62
62
|
* scripts (head.js discovery still spans the queue).
|
|
63
63
|
*/
|
|
64
|
-
export declare function buildPerRunCheckJs(projectRoot: string, paths:
|
|
64
|
+
export declare function buildPerRunCheckJs(projectRoot: string, paths: ProjectPaths, config: FireForgeConfig, ctx: PatchQueueContext, rootScopePatches?: ReadonlySet<string>): PerRunCheckJs | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
+
import { type PatchQueueContext } from '../core/patch-lint.js';
|
|
2
3
|
import type { CommandContext } from '../types/cli.js';
|
|
3
4
|
import type { LintCommandOptions, PatchLintIssue } from '../types/commands/index.js';
|
|
4
5
|
/**
|
|
@@ -34,7 +35,7 @@ export interface AggregateLintIgnoreResult {
|
|
|
34
35
|
* @param ctx - Patch queue context used to attribute file → patch.
|
|
35
36
|
* @returns Filtered issue list and the count of dropped findings.
|
|
36
37
|
*/
|
|
37
|
-
export declare function applyAggregateLintIgnoreSuppression(issues: PatchLintIssue[], ctx:
|
|
38
|
+
export declare function applyAggregateLintIgnoreSuppression(issues: PatchLintIssue[], ctx: PatchQueueContext): AggregateLintIgnoreResult;
|
|
38
39
|
/**
|
|
39
40
|
* Runs the lint command to check engine changes against patch quality rules.
|
|
40
41
|
* @param projectRoot - Root directory of the project
|
|
@@ -495,7 +495,7 @@ export function registerLint(program, { getProjectRoot, withErrorHandling }) {
|
|
|
495
495
|
.option('--since <git-rev>', 'Tag issues as [introduced] or [cumulative] based on whether the file changed since <git-rev> (e.g. HEAD, a branch, a SHA)')
|
|
496
496
|
.option('--only-introduced', 'Fail only on issues tagged [introduced] (requires --since). Cumulative errors still print but do not set a non-zero exit.')
|
|
497
497
|
.option('--per-patch', "Lint each patch in the queue as its own isolated diff. Rescopes patch-size rules so they fire against individual patches rather than the aggregate. Honours each patch's `lintIgnore` entries.")
|
|
498
|
-
.option('--patches <names...>', 'With --per-patch, lint only the named patches. Accepts repeated flags, comma lists, full filenames/stems, manifest names, category-prefixed slugs, or bare slugs. Positional arguments after --per-patch are treated the same way.')
|
|
498
|
+
.option('--patches <names...>', 'With --per-patch, lint only the named patches. Accepts repeated flags, comma lists, full filenames/stems, bare order numbers, manifest names, category-prefixed slugs, or bare slugs. Positional arguments after --per-patch are treated the same way.')
|
|
499
499
|
.option('--max-warnings <n>', 'Fail when lint reports more than <n> warning(s); use 0 for warning-clean release gates.')
|
|
500
500
|
.option('--no-cache', 'Bypass per-patch lint result cache reads and writes.')
|
|
501
501
|
.option('--report <path>', 'With --per-patch, write a machine-readable JSON report (per-patch size metrics, tier, thresholds, issues, and lintIgnore-suppressed issues) to <path>.')
|
|
@@ -12,7 +12,7 @@ import { registerLint } from './lint.js';
|
|
|
12
12
|
import { registerPackage } from './package.js';
|
|
13
13
|
import { registerPatch } from './patch/index.js';
|
|
14
14
|
import { registerReExport } from './re-export-register.js';
|
|
15
|
-
import { registerRebase } from './rebase.js';
|
|
15
|
+
import { registerRebase } from './rebase/index.js';
|
|
16
16
|
import { registerRegister } from './register.js';
|
|
17
17
|
import { registerReset } from './reset.js';
|
|
18
18
|
import { registerResolve } from './resolve.js';
|
|
@@ -8,6 +8,7 @@ import { hasBuildArtifacts, machPackageCapture } from '../core/mach.js';
|
|
|
8
8
|
import { assertBuildArtifacts } from '../core/mach-build-artifacts.js';
|
|
9
9
|
import { explainMachError } from '../core/mach-error-hints.js';
|
|
10
10
|
import { BuildError } from '../errors/build.js';
|
|
11
|
+
import { elapsedSince } from '../utils/elapsed.js';
|
|
11
12
|
import { error, info, intro, outro, verbose } from '../utils/logger.js';
|
|
12
13
|
import { pickDefined } from '../utils/options.js';
|
|
13
14
|
/**
|
|
@@ -54,10 +55,7 @@ export async function packageCommand(projectRoot, options) {
|
|
|
54
55
|
catch (error) {
|
|
55
56
|
throw new BuildError('Package process failed to start', 'mach package', error instanceof Error ? error : undefined);
|
|
56
57
|
}
|
|
57
|
-
const
|
|
58
|
-
const minutes = Math.floor(duration / 60000);
|
|
59
|
-
const seconds = Math.floor((duration % 60000) / 1000);
|
|
60
|
-
const timeStr = minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;
|
|
58
|
+
const timeStr = elapsedSince(startTime);
|
|
61
59
|
if (result.exitCode !== 0) {
|
|
62
60
|
error(`Packaging failed after ${timeStr}`);
|
|
63
61
|
const combinedOutput = `${result.stdout}\n${result.stderr}`;
|
|
@@ -11,14 +11,16 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { Command } from 'commander';
|
|
13
13
|
import { loadConfig } from '../../core/config.js';
|
|
14
|
-
import {
|
|
14
|
+
import { confirmDestructive } from '../../core/destructive.js';
|
|
15
|
+
import { appendHistoryBestEffort } from '../../core/history-log.js';
|
|
15
16
|
import { withPatchDirectoryLock } from '../../core/patch-lock.js';
|
|
16
17
|
import { loadPatchesManifest, renumberPatchesInManifest, } from '../../core/patch-manifest.js';
|
|
17
18
|
import { applyRenameMapToManifest, enforcePatchPolicy } from '../../core/patch-policy.js';
|
|
18
19
|
import { GeneralError } from '../../errors/base.js';
|
|
19
|
-
import { toError } from '../../utils/errors.js';
|
|
20
20
|
import { info, intro, outro, warn } from '../../utils/logger.js';
|
|
21
21
|
import { addWaitLockOption, pickDefined, resolveWaitLockSeconds } from '../../utils/options.js';
|
|
22
|
+
import { proceedAfterDecision } from '../destructive-decision.js';
|
|
23
|
+
import { renameMapsEqual } from '../patch-rename-map.js';
|
|
22
24
|
import { requirePatchQueue } from './patch-context.js';
|
|
23
25
|
import { rebuildFilenameForOrder } from './reorder.js';
|
|
24
26
|
/** True when `order` falls inside a configured reserved range. */
|
|
@@ -139,14 +141,8 @@ export async function patchCompactCommand(projectRoot, options = {}) {
|
|
|
139
141
|
dryRun: options.dryRun === true,
|
|
140
142
|
unsafeOverride: options.forceUnsafe === true,
|
|
141
143
|
});
|
|
142
|
-
if (decision
|
|
143
|
-
outro('Dry run complete — no changes made');
|
|
144
|
+
if (!proceedAfterDecision(decision, 'Compact cancelled'))
|
|
144
145
|
return;
|
|
145
|
-
}
|
|
146
|
-
if (decision === 'declined') {
|
|
147
|
-
outro('Compact cancelled');
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
146
|
await withPatchDirectoryLock(paths.patches, async () => {
|
|
151
147
|
const currentManifest = await loadPatchesManifest(paths.patches);
|
|
152
148
|
if (!currentManifest) {
|
|
@@ -157,6 +153,14 @@ export async function patchCompactCommand(projectRoot, options = {}) {
|
|
|
157
153
|
info('Patch queue was compacted by another process. Nothing to do.');
|
|
158
154
|
return;
|
|
159
155
|
}
|
|
156
|
+
// The operator confirmed a specific plan. A queue that changed between
|
|
157
|
+
// the prompt and the lock (an export landing a new patch, a delete)
|
|
158
|
+
// yields a different plan whose renames were never shown — refuse
|
|
159
|
+
// rather than commit them under a history entry that says "ok", the
|
|
160
|
+
// same gate `patch reorder` applies.
|
|
161
|
+
if (!renameMapsEqual(renameMap, currentRenameMap)) {
|
|
162
|
+
throw new GeneralError('Patch queue changed while waiting for confirmation. Re-run compact to recompute the rename plan.');
|
|
163
|
+
}
|
|
160
164
|
enforcePatchPolicy({
|
|
161
165
|
config,
|
|
162
166
|
manifest: applyRenameMapToManifest(currentManifest, currentRenameMap),
|
|
@@ -179,12 +183,7 @@ export async function patchCompactCommand(projectRoot, options = {}) {
|
|
|
179
183
|
...(options.forceUnsafe === true ? { unsafeOverride: true } : {}),
|
|
180
184
|
result: 'ok',
|
|
181
185
|
};
|
|
182
|
-
|
|
183
|
-
await appendHistory(paths.patches, historyEntry);
|
|
184
|
-
}
|
|
185
|
-
catch (historyError) {
|
|
186
|
-
warn(`History log append failed after patch compact committed: ${toError(historyError).message}`);
|
|
187
|
-
}
|
|
186
|
+
await appendHistoryBestEffort(paths.patches, historyEntry, `patch compact committed`);
|
|
188
187
|
}, { waitLockSeconds: resolveWaitLockSeconds(options.waitLock), command: 'patch compact' });
|
|
189
188
|
info(`Compacted ${renameMap.size} patch(es).`);
|
|
190
189
|
outro('Compact complete');
|
|
@@ -9,13 +9,14 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { basename } from 'node:path';
|
|
11
11
|
import { Command } from 'commander';
|
|
12
|
-
import {
|
|
12
|
+
import { confirmDestructive } from '../../core/destructive.js';
|
|
13
|
+
import { appendHistoryBestEffort } from '../../core/history-log.js';
|
|
13
14
|
import { buildPatchQueueContext, extractImportSpecifiersWithLines, findForwardImportIgnoreLines, isForwardImportableFile, } from '../../core/patch-lint.js';
|
|
14
15
|
import { withPatchDirectoryLock } from '../../core/patch-lock.js';
|
|
15
16
|
import { removePatchFileAndManifest } from '../../core/patch-manifest.js';
|
|
16
|
-
import { toError } from '../../utils/errors.js';
|
|
17
17
|
import { info, intro, outro, warn } from '../../utils/logger.js';
|
|
18
18
|
import { addWaitLockOption, pickDefined, resolveWaitLockSeconds } from '../../utils/options.js';
|
|
19
|
+
import { proceedAfterDecision } from '../destructive-decision.js';
|
|
19
20
|
import { requirePatchQueue, requirePatchTarget } from './patch-context.js';
|
|
20
21
|
/**
|
|
21
22
|
* Runs the `patch delete` command: removes a patch file and its manifest
|
|
@@ -138,14 +139,8 @@ export async function patchDeleteCommand(projectRoot, identifier, options = {})
|
|
|
138
139
|
unsafeOverride: options.forceUnsafe === true,
|
|
139
140
|
conflicts,
|
|
140
141
|
});
|
|
141
|
-
if (decision
|
|
142
|
-
outro('Dry run complete — no changes made');
|
|
142
|
+
if (!proceedAfterDecision(decision, 'Delete cancelled'))
|
|
143
143
|
return;
|
|
144
|
-
}
|
|
145
|
-
if (decision === 'declined') {
|
|
146
|
-
outro('Delete cancelled');
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
144
|
// Proceed: remove under the patch directory lock so concurrent exports
|
|
150
145
|
// cannot race us into the same manifest row. The history append lives
|
|
151
146
|
// inside the same lock so two concurrent deletes cannot interleave history
|
|
@@ -156,22 +151,17 @@ export async function patchDeleteCommand(projectRoot, identifier, options = {})
|
|
|
156
151
|
// failure to the caller would mislead.
|
|
157
152
|
await withPatchDirectoryLock(paths.patches, async () => {
|
|
158
153
|
await removePatchFileAndManifest(paths.patches, target.filename);
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
catch (historyError) {
|
|
173
|
-
warn(`History log append failed after patch delete committed (${target.filename}): ${toError(historyError).message}`);
|
|
174
|
-
}
|
|
154
|
+
await appendHistoryBestEffort(paths.patches, {
|
|
155
|
+
operation: 'patch-delete',
|
|
156
|
+
args: {
|
|
157
|
+
filename: target.filename,
|
|
158
|
+
order: target.order,
|
|
159
|
+
filesAffected: target.filesAffected,
|
|
160
|
+
},
|
|
161
|
+
...(options.yes === true ? { yes: true } : {}),
|
|
162
|
+
...(options.forceUnsafe === true ? { unsafeOverride: true } : {}),
|
|
163
|
+
result: 'ok',
|
|
164
|
+
}, `patch delete committed (${target.filename})`);
|
|
175
165
|
}, { waitLockSeconds: resolveWaitLockSeconds(options.waitLock), command: 'patch delete' });
|
|
176
166
|
info(`Deleted ${target.filename}.`);
|
|
177
167
|
outro('Delete complete');
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PatchQueueEntry } from '../../core/patch-lint.js';
|
|
2
|
+
/**
|
|
3
|
+
* Projects a rewritten patch body into the three fields cross-patch lint reads
|
|
4
|
+
* off a queue entry.
|
|
5
|
+
*
|
|
6
|
+
* `patch split` and `patch move-files` each had a byte-identical copy of this
|
|
7
|
+
* (`buildEntryProjection` / `projectEntryBody`). Both feed the same linter, so
|
|
8
|
+
* a change to what the projection carries has to reach both or the two
|
|
9
|
+
* commands start refusing different things for the same queue.
|
|
10
|
+
* @param diff - The rewritten patch body.
|
|
11
|
+
* @returns The diff plus its derived new-file and modified-file projections.
|
|
12
|
+
*/
|
|
13
|
+
export declare function projectEntryBody(diff: string): Pick<PatchQueueEntry, 'diff' | 'newFiles' | 'createdFiles' | 'modifiedFileAdditions'>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { buildModifiedFileAdditionsFromDiff } from '../../core/patch-lint.js';
|
|
2
|
+
import { detectNewFilesInDiff } from '../../core/patch-lint-diff.js';
|
|
3
|
+
import { buildNewFileTextProjection } from '../../core/patch-transform.js';
|
|
4
|
+
/**
|
|
5
|
+
* Projects a rewritten patch body into the three fields cross-patch lint reads
|
|
6
|
+
* off a queue entry.
|
|
7
|
+
*
|
|
8
|
+
* `patch split` and `patch move-files` each had a byte-identical copy of this
|
|
9
|
+
* (`buildEntryProjection` / `projectEntryBody`). Both feed the same linter, so
|
|
10
|
+
* a change to what the projection carries has to reach both or the two
|
|
11
|
+
* commands start refusing different things for the same queue.
|
|
12
|
+
* @param diff - The rewritten patch body.
|
|
13
|
+
* @returns The diff plus its derived new-file and modified-file projections.
|
|
14
|
+
*/
|
|
15
|
+
export function projectEntryBody(diff) {
|
|
16
|
+
const newFiles = buildNewFileTextProjection(diff);
|
|
17
|
+
return {
|
|
18
|
+
diff,
|
|
19
|
+
newFiles,
|
|
20
|
+
// Body-kind agnostic: a binary creation is still a creation.
|
|
21
|
+
createdFiles: detectNewFilesInDiff(diff),
|
|
22
|
+
modifiedFileAdditions: buildModifiedFileAdditionsFromDiff(diff),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -21,13 +21,6 @@
|
|
|
21
21
|
import { Command } from 'commander';
|
|
22
22
|
import type { CommandContext } from '../../types/cli.js';
|
|
23
23
|
import type { PatchLintIgnoreOptions } from '../../types/commands/index.js';
|
|
24
|
-
type LintIgnoreMode = 'add' | 'remove' | 'clear';
|
|
25
|
-
/**
|
|
26
|
-
* Renders a one-line summary of the planned change for use in
|
|
27
|
-
* `info()` / dry-run / history args. Exported for unit-testing the
|
|
28
|
-
* message format directly without mocking the logger transport.
|
|
29
|
-
*/
|
|
30
|
-
export declare function describeChange(before: ReadonlyArray<string>, after: ReadonlyArray<string>, mode: LintIgnoreMode, values: ReadonlyArray<string>): string;
|
|
31
24
|
/**
|
|
32
25
|
* Runs the `patch lint-ignore` command: reads the patch's existing
|
|
33
26
|
* `lintIgnore`, applies the requested mode, and writes the manifest.
|
|
@@ -44,4 +37,3 @@ export declare function patchLintIgnoreCommand(projectRoot: string, identifier:
|
|
|
44
37
|
* @param context - Shared CLI registration context
|
|
45
38
|
*/
|
|
46
39
|
export declare function registerPatchLintIgnore(parent: Command, context: CommandContext): void;
|
|
47
|
-
export {};
|