@hominis/fireforge 0.49.2 → 0.51.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 +87 -1
- package/README.md +1 -1
- package/dist/bin/fireforge.js +6 -0
- package/dist/build-info.json +4 -4
- package/dist/src/commands/build-prelock.d.ts +20 -0
- package/dist/src/commands/build-prelock.js +50 -0
- package/dist/src/commands/build.d.ts +3 -1
- package/dist/src/commands/build.js +13 -6
- package/dist/src/commands/check-report.d.ts +41 -0
- package/dist/src/commands/check-report.js +91 -0
- package/dist/src/commands/check-run.d.ts +33 -0
- package/dist/src/commands/check-run.js +112 -0
- package/dist/src/commands/check-steps.d.ts +75 -0
- package/dist/src/commands/check-steps.js +200 -0
- package/dist/src/commands/check.d.ts +32 -0
- package/dist/src/commands/check.js +160 -0
- package/dist/src/commands/config.js +5 -6
- package/dist/src/commands/declarations-report.d.ts +43 -0
- package/dist/src/commands/declarations-report.js +76 -0
- package/dist/src/commands/doctor-engine-eslint.js +6 -1
- package/dist/src/commands/doctor-source-pin.js +4 -1
- package/dist/src/commands/export-adopt-check.d.ts +38 -0
- package/dist/src/commands/export-adopt-check.js +98 -0
- package/dist/src/commands/export-flow.js +29 -14
- package/dist/src/commands/export-placement-gate.d.ts +6 -2
- package/dist/src/commands/export-placement-gate.js +8 -0
- package/dist/src/commands/export-shared.d.ts +2 -1
- package/dist/src/commands/export-staged-registration.d.ts +46 -0
- package/dist/src/commands/export-staged-registration.js +91 -0
- package/dist/src/commands/forward-import-remedy.d.ts +32 -0
- package/dist/src/commands/forward-import-remedy.js +63 -0
- package/dist/src/commands/furnace/apply.js +3 -3
- package/dist/src/commands/furnace/chrome-doc-remove.d.ts +2 -1
- package/dist/src/commands/furnace/chrome-doc-remove.js +2 -2
- package/dist/src/commands/furnace/chrome-doc.d.ts +2 -1
- package/dist/src/commands/furnace/chrome-doc.js +2 -2
- package/dist/src/commands/furnace/create.js +2 -2
- package/dist/src/commands/furnace/deploy-named.d.ts +48 -0
- package/dist/src/commands/furnace/deploy-named.js +107 -0
- package/dist/src/commands/furnace/deploy.d.ts +3 -2
- package/dist/src/commands/furnace/deploy.js +50 -86
- package/dist/src/commands/furnace/diff.js +26 -3
- package/dist/src/commands/furnace/index.js +66 -41
- package/dist/src/commands/furnace/init.js +13 -6
- package/dist/src/commands/furnace/override.js +4 -2
- package/dist/src/commands/furnace/preview.js +4 -3
- package/dist/src/commands/furnace/refresh.js +2 -2
- package/dist/src/commands/furnace/remove.js +4 -3
- package/dist/src/commands/furnace/rename-dry-run.d.ts +29 -0
- package/dist/src/commands/furnace/rename-dry-run.js +127 -0
- package/dist/src/commands/furnace/rename-helpers.d.ts +7 -0
- package/dist/src/commands/furnace/rename-helpers.js +15 -1
- package/dist/src/commands/furnace/rename-registrations.d.ts +41 -0
- package/dist/src/commands/furnace/rename-registrations.js +98 -0
- package/dist/src/commands/furnace/rename.d.ts +2 -1
- package/dist/src/commands/furnace/rename.js +28 -66
- package/dist/src/commands/furnace/scan.d.ts +9 -4
- package/dist/src/commands/furnace/scan.js +11 -9
- package/dist/src/commands/furnace/sync.js +3 -2
- package/dist/src/commands/furnace/validate-report.d.ts +45 -0
- package/dist/src/commands/furnace/validate-report.js +91 -0
- package/dist/src/commands/furnace/validate.d.ts +1 -1
- package/dist/src/commands/furnace/validate.js +151 -113
- package/dist/src/commands/furnace/validation-output.js +14 -3
- package/dist/src/commands/lint-per-patch.js +36 -61
- package/dist/src/commands/lint-per-run-checkjs.js +2 -2
- package/dist/src/commands/lint-report.d.ts +8 -4
- package/dist/src/commands/lint-report.js +20 -5
- package/dist/src/commands/lint.js +15 -34
- package/dist/src/commands/manifest.js +4 -0
- package/dist/src/commands/park.d.ts +22 -0
- package/dist/src/commands/park.js +232 -0
- package/dist/src/commands/patch/delete-gap-notice.js +3 -1
- package/dist/src/commands/patch/delete.d.ts +1 -1
- package/dist/src/commands/patch/delete.js +24 -104
- package/dist/src/commands/patch/index.d.ts +3 -3
- package/dist/src/commands/patch/index.js +10 -4
- package/dist/src/commands/patch/lint-ignore-from.d.ts +44 -0
- package/dist/src/commands/patch/lint-ignore-from.js +142 -0
- package/dist/src/commands/patch/lint-ignore.d.ts +5 -1
- package/dist/src/commands/patch/lint-ignore.js +78 -31
- package/dist/src/commands/patch/move-files-create.js +34 -18
- package/dist/src/commands/patch/move-files-into.js +15 -7
- package/dist/src/commands/patch/move-files.js +6 -2
- package/dist/src/commands/patch/removal-created-files.d.ts +48 -0
- package/dist/src/commands/patch/removal-created-files.js +83 -0
- package/dist/src/commands/patch/removal-dependents.d.ts +63 -0
- package/dist/src/commands/patch/removal-dependents.js +133 -0
- package/dist/src/commands/patch/rename.js +20 -1
- package/dist/src/commands/patch/reserve.d.ts +33 -0
- package/dist/src/commands/patch/reserve.js +152 -0
- package/dist/src/commands/patch/retire.d.ts +34 -0
- package/dist/src/commands/patch/retire.js +133 -0
- package/dist/src/commands/patch/split-plan.d.ts +17 -8
- package/dist/src/commands/patch/split-plan.js +60 -28
- package/dist/src/commands/patch/split-staged.d.ts +108 -0
- package/dist/src/commands/patch/split-staged.js +202 -0
- package/dist/src/commands/patch/split.d.ts +5 -0
- package/dist/src/commands/patch/split.js +62 -17
- package/dist/src/commands/patch/stage.d.ts +34 -0
- package/dist/src/commands/patch/stage.js +153 -0
- package/dist/src/commands/patch/staged-dependency-batch.d.ts +48 -0
- package/dist/src/commands/patch/staged-dependency-batch.js +176 -0
- package/dist/src/commands/patch/staged-dependency-entries.d.ts +36 -0
- package/dist/src/commands/patch/staged-dependency-entries.js +52 -0
- package/dist/src/commands/patch/staged-dependency-from.d.ts +14 -0
- package/dist/src/commands/patch/staged-dependency-from.js +108 -0
- package/dist/src/commands/patch/staged-dependency-remove.d.ts +31 -0
- package/dist/src/commands/patch/staged-dependency-remove.js +80 -0
- package/dist/src/commands/patch/staged-dependency.js +54 -139
- package/dist/src/commands/re-export-adjacent-registrations.d.ts +20 -0
- package/dist/src/commands/re-export-adjacent-registrations.js +75 -0
- package/dist/src/commands/re-export-adjacent.d.ts +50 -2
- package/dist/src/commands/re-export-adjacent.js +160 -40
- package/dist/src/commands/re-export-bulk-scan.d.ts +2 -1
- package/dist/src/commands/re-export-bulk-scan.js +22 -7
- package/dist/src/commands/re-export-drift.d.ts +36 -8
- package/dist/src/commands/re-export-drift.js +73 -49
- package/dist/src/commands/re-export-files.js +11 -8
- package/dist/src/commands/re-export-hunks.d.ts +35 -0
- package/dist/src/commands/re-export-hunks.js +220 -0
- package/dist/src/commands/re-export-lint.d.ts +2 -1
- package/dist/src/commands/re-export-lint.js +23 -10
- package/dist/src/commands/re-export-options.js +74 -6
- package/dist/src/commands/re-export-preflight.d.ts +23 -0
- package/dist/src/commands/re-export-preflight.js +160 -0
- package/dist/src/commands/re-export-purity-scope.d.ts +18 -0
- package/dist/src/commands/re-export-purity-scope.js +131 -0
- package/dist/src/commands/re-export-register.js +56 -17
- package/dist/src/commands/re-export-removed.d.ts +13 -2
- package/dist/src/commands/re-export-removed.js +57 -12
- package/dist/src/commands/re-export-scan-owner.d.ts +44 -0
- package/dist/src/commands/re-export-scan-owner.js +116 -0
- package/dist/src/commands/re-export-scan.d.ts +19 -9
- package/dist/src/commands/re-export-scan.js +60 -24
- package/dist/src/commands/re-export-single.js +122 -46
- package/dist/src/commands/re-export-stale-registrations.d.ts +18 -0
- package/dist/src/commands/re-export-stale-registrations.js +62 -0
- package/dist/src/commands/re-export-summary.d.ts +28 -0
- package/dist/src/commands/re-export-summary.js +36 -0
- package/dist/src/commands/re-export.js +71 -57
- package/dist/src/commands/rebase/index.js +17 -17
- package/dist/src/commands/run.js +16 -2
- package/dist/src/commands/status-check.d.ts +55 -16
- package/dist/src/commands/status-check.js +92 -37
- package/dist/src/commands/status-json.d.ts +22 -9
- package/dist/src/commands/status-json.js +47 -32
- package/dist/src/commands/status-output.js +3 -1
- package/dist/src/commands/status-scope.d.ts +37 -0
- package/dist/src/commands/status-scope.js +54 -0
- package/dist/src/commands/status.js +66 -23
- package/dist/src/commands/test-browser-preflight.js +19 -3
- package/dist/src/commands/test-build-furnace.d.ts +22 -0
- package/dist/src/commands/test-build-furnace.js +54 -0
- package/dist/src/commands/test-build-phase.js +64 -41
- package/dist/src/commands/test-checkjs.js +10 -2
- package/dist/src/commands/test-diagnose.js +7 -0
- package/dist/src/commands/test-dispatch.d.ts +39 -0
- package/dist/src/commands/test-dispatch.js +211 -0
- package/dist/src/commands/test-furnace-reach.d.ts +37 -0
- package/dist/src/commands/test-furnace-reach.js +132 -0
- package/dist/src/commands/test-modes.d.ts +16 -1
- package/dist/src/commands/test-modes.js +24 -1
- package/dist/src/commands/test-multi-verdict.d.ts +61 -0
- package/dist/src/commands/test-multi-verdict.js +111 -0
- package/dist/src/commands/test-orchestrate.d.ts +52 -0
- package/dist/src/commands/test-orchestrate.js +240 -0
- package/dist/src/commands/test-perf-scope.d.ts +50 -0
- package/dist/src/commands/test-perf-scope.js +138 -0
- package/dist/src/commands/test-prelock.d.ts +51 -0
- package/dist/src/commands/test-prelock.js +273 -0
- package/dist/src/commands/test-register.js +69 -10
- package/dist/src/commands/test-results.d.ts +62 -0
- package/dist/src/commands/test-results.js +62 -0
- package/dist/src/commands/test-run.d.ts +13 -55
- package/dist/src/commands/test-run.js +74 -99
- package/dist/src/commands/test-shards.d.ts +110 -0
- package/dist/src/commands/test-shards.js +255 -0
- package/dist/src/commands/test-stale-gate.d.ts +5 -1
- package/dist/src/commands/test-stale-gate.js +60 -28
- package/dist/src/commands/test-verdict.d.ts +11 -1
- package/dist/src/commands/test-verdict.js +28 -1
- package/dist/src/commands/test.d.ts +6 -1
- package/dist/src/commands/test.js +120 -124
- package/dist/src/commands/token-lint.d.ts +14 -0
- package/dist/src/commands/token-lint.js +151 -0
- package/dist/src/commands/token.js +10 -0
- package/dist/src/commands/verify-scope.d.ts +28 -0
- package/dist/src/commands/verify-scope.js +67 -0
- package/dist/src/commands/verify.d.ts +10 -2
- package/dist/src/commands/verify.js +67 -36
- package/dist/src/core/build-baseline-types.d.ts +46 -0
- package/dist/src/core/build-baseline-validate.js +19 -0
- package/dist/src/core/build-baseline.d.ts +5 -1
- package/dist/src/core/build-baseline.js +3 -1
- package/dist/src/core/build-overwrite-guard.d.ts +50 -0
- package/dist/src/core/build-overwrite-guard.js +84 -4
- package/dist/src/core/build-prepare.d.ts +13 -0
- package/dist/src/core/build-prepare.js +42 -10
- package/dist/src/core/build-run-record.d.ts +74 -0
- package/dist/src/core/build-run-record.js +136 -0
- package/dist/src/core/checkjs-support-heads.d.ts +41 -0
- package/dist/src/core/checkjs-support-heads.js +104 -0
- package/dist/src/core/config-paths.d.ts +2 -2
- package/dist/src/core/config-paths.js +10 -0
- package/dist/src/core/config-validate-check.d.ts +8 -0
- package/dist/src/core/config-validate-check.js +219 -0
- package/dist/src/core/config-validate-file-size.d.ts +9 -6
- package/dist/src/core/config-validate-file-size.js +91 -2
- package/dist/src/core/config-validate-history.d.ts +11 -0
- package/dist/src/core/config-validate-history.js +38 -0
- package/dist/src/core/config-validate-patch-policy.js +100 -0
- package/dist/src/core/config-validate-test-toolchains.js +21 -0
- package/dist/src/core/config-validate-token-scales.d.ts +9 -0
- package/dist/src/core/config-validate-token-scales.js +92 -0
- package/dist/src/core/config-validate.js +20 -5
- package/dist/src/core/config.d.ts +5 -0
- package/dist/src/core/config.js +16 -0
- package/dist/src/core/coverage-dispatch.d.ts +24 -0
- package/dist/src/core/coverage-dispatch.js +44 -0
- package/dist/src/core/coverage-extend.d.ts +70 -45
- package/dist/src/core/coverage-extend.js +199 -144
- package/dist/src/core/coverage-records.d.ts +108 -0
- package/dist/src/core/coverage-records.js +384 -0
- package/dist/src/core/destructive.d.ts +7 -4
- package/dist/src/core/destructive.js +10 -10
- package/dist/src/core/engine-session-lock.d.ts +16 -1
- package/dist/src/core/engine-session-lock.js +38 -10
- package/dist/src/core/export-moved-code-shape.d.ts +49 -11
- package/dist/src/core/export-moved-code-shape.js +135 -44
- package/dist/src/core/file-lock-queue.d.ts +67 -0
- package/dist/src/core/file-lock-queue.js +221 -0
- package/dist/src/core/file-lock-shared.d.ts +57 -0
- package/dist/src/core/file-lock-shared.js +117 -0
- package/dist/src/core/file-lock.d.ts +13 -25
- package/dist/src/core/file-lock.js +163 -140
- package/dist/src/core/furnace-apply-output.d.ts +10 -0
- package/dist/src/core/furnace-apply-output.js +31 -1
- package/dist/src/core/furnace-apply.js +22 -12
- package/dist/src/core/furnace-composed-source.d.ts +76 -0
- package/dist/src/core/furnace-composed-source.js +167 -0
- package/dist/src/core/furnace-config-validate-exceptions.d.ts +16 -0
- package/dist/src/core/furnace-config-validate-exceptions.js +102 -0
- package/dist/src/core/furnace-config-validate.js +14 -0
- package/dist/src/core/furnace-css-fragments.d.ts +10 -0
- package/dist/src/core/furnace-css-fragments.js +26 -0
- package/dist/src/core/furnace-operation.d.ts +3 -3
- package/dist/src/core/furnace-registration-jar-inplace.d.ts +12 -0
- package/dist/src/core/furnace-registration-jar-inplace.js +80 -0
- package/dist/src/core/furnace-registration-remove.d.ts +22 -1
- package/dist/src/core/furnace-registration-remove.js +53 -17
- package/dist/src/core/furnace-registration-rename.d.ts +26 -0
- package/dist/src/core/furnace-registration-rename.js +77 -0
- package/dist/src/core/furnace-registration.d.ts +14 -4
- package/dist/src/core/furnace-registration.js +44 -10
- package/dist/src/core/furnace-staleness.d.ts +7 -0
- package/dist/src/core/furnace-staleness.js +34 -24
- package/dist/src/core/furnace-validate-accessibility.d.ts +8 -4
- package/dist/src/core/furnace-validate-accessibility.js +71 -28
- package/dist/src/core/furnace-validate-exceptions.d.ts +48 -0
- package/dist/src/core/furnace-validate-exceptions.js +80 -0
- package/dist/src/core/furnace-validate-icon-button.d.ts +7 -0
- package/dist/src/core/furnace-validate-icon-button.js +78 -0
- package/dist/src/core/furnace-validate.js +1 -1
- package/dist/src/core/harness-port-fallback.d.ts +60 -0
- package/dist/src/core/harness-port-fallback.js +96 -0
- package/dist/src/core/history-log-file.d.ts +61 -0
- package/dist/src/core/history-log-file.js +164 -0
- package/dist/src/core/history-log.d.ts +2 -1
- package/dist/src/core/history-log.js +2 -1
- package/dist/src/core/json-preserving-edit.d.ts +22 -0
- package/dist/src/core/json-preserving-edit.js +199 -0
- package/dist/src/core/line-prefixer.d.ts +18 -0
- package/dist/src/core/line-prefixer.js +34 -0
- package/dist/src/core/mach.d.ts +7 -0
- package/dist/src/core/mach.js +32 -10
- package/dist/src/core/module-resolution-preflight.d.ts +19 -3
- package/dist/src/core/module-resolution-preflight.js +24 -6
- package/dist/src/core/negative-control-compiled.d.ts +27 -0
- package/dist/src/core/negative-control-compiled.js +73 -0
- package/dist/src/core/negative-control-diff.d.ts +51 -0
- package/dist/src/core/negative-control-diff.js +179 -0
- package/dist/src/core/negative-control.d.ts +150 -0
- package/dist/src/core/negative-control.js +399 -0
- package/dist/src/core/objdir-install-manifests.d.ts +73 -0
- package/dist/src/core/objdir-install-manifests.js +226 -0
- package/dist/src/core/park-store.d.ts +63 -0
- package/dist/src/core/park-store.js +216 -0
- package/dist/src/core/patch-export-update.d.ts +6 -0
- package/dist/src/core/patch-export-update.js +13 -3
- package/dist/src/core/patch-export.d.ts +3 -2
- package/dist/src/core/patch-export.js +22 -16
- package/dist/src/core/patch-files.js +26 -8
- package/dist/src/core/patch-lint-checkjs-any-import.d.ts +39 -0
- package/dist/src/core/patch-lint-checkjs-any-import.js +63 -0
- package/dist/src/core/patch-lint-checkjs-diagnostics.d.ts +17 -0
- package/dist/src/core/patch-lint-checkjs-diagnostics.js +32 -0
- package/dist/src/core/patch-lint-checkjs.d.ts +10 -1
- package/dist/src/core/patch-lint-checkjs.js +20 -13
- package/dist/src/core/patch-lint-code-lines.d.ts +59 -0
- package/dist/src/core/patch-lint-code-lines.js +105 -0
- package/dist/src/core/patch-lint-cross.d.ts +3 -1
- package/dist/src/core/patch-lint-cross.js +17 -4
- package/dist/src/core/patch-lint-css.d.ts +8 -2
- package/dist/src/core/patch-lint-css.js +24 -14
- package/dist/src/core/patch-lint-file-size.d.ts +12 -5
- package/dist/src/core/patch-lint-file-size.js +22 -11
- package/dist/src/core/patch-lint-forward-registration-extended.d.ts +23 -0
- package/dist/src/core/patch-lint-forward-registration-extended.js +36 -11
- package/dist/src/core/patch-lint-forward-registration.js +10 -0
- package/dist/src/core/patch-lint-ignore.d.ts +196 -0
- package/dist/src/core/patch-lint-ignore.js +429 -0
- package/dist/src/core/patch-lint-ownership.d.ts +10 -0
- package/dist/src/core/patch-lint-ownership.js +26 -0
- package/dist/src/core/patch-lint-size-thresholds.d.ts +52 -0
- package/dist/src/core/patch-lint-size-thresholds.js +110 -0
- package/dist/src/core/patch-lint-size.d.ts +117 -0
- package/dist/src/core/patch-lint-size.js +331 -0
- package/dist/src/core/patch-lint-staged-registration.d.ts +18 -1
- package/dist/src/core/patch-lint-staged-registration.js +20 -0
- package/dist/src/core/patch-lint-token-scale.d.ts +57 -0
- package/dist/src/core/patch-lint-token-scale.js +286 -0
- package/dist/src/core/patch-lint.d.ts +11 -83
- package/dist/src/core/patch-lint.js +66 -288
- package/dist/src/core/patch-lock.js +7 -6
- package/dist/src/core/patch-manifest-consistency.js +7 -6
- package/dist/src/core/patch-manifest-io.d.ts +6 -3
- package/dist/src/core/patch-manifest-io.js +27 -9
- package/dist/src/core/patch-manifest-key-order.d.ts +24 -0
- package/dist/src/core/patch-manifest-key-order.js +61 -0
- package/dist/src/core/patch-manifest-stage.d.ts +46 -0
- package/dist/src/core/patch-manifest-stage.js +96 -0
- package/dist/src/core/patch-manifest-validate.js +61 -3
- package/dist/src/core/patch-order-legal.d.ts +26 -0
- package/dist/src/core/patch-order-legal.js +88 -0
- package/dist/src/core/patch-policy-content.d.ts +40 -0
- package/dist/src/core/patch-policy-content.js +216 -0
- package/dist/src/core/patch-policy.d.ts +22 -5
- package/dist/src/core/patch-policy.js +26 -12
- package/dist/src/core/patch-retired.d.ts +57 -0
- package/dist/src/core/patch-retired.js +92 -0
- package/dist/src/core/patch-subset.d.ts +16 -0
- package/dist/src/core/patch-subset.js +66 -0
- package/dist/src/core/preflight-wait.d.ts +20 -0
- package/dist/src/core/preflight-wait.js +38 -0
- package/dist/src/core/rebase-from-version.d.ts +46 -0
- package/dist/src/core/rebase-from-version.js +71 -0
- package/dist/src/core/run-log.d.ts +26 -0
- package/dist/src/core/run-log.js +106 -4
- package/dist/src/core/run-profile.d.ts +7 -0
- package/dist/src/core/run-profile.js +7 -1
- package/dist/src/core/smoke-patterns.d.ts +5 -0
- package/dist/src/core/smoke-patterns.js +13 -0
- package/dist/src/core/test-harness-crash.d.ts +19 -1
- package/dist/src/core/test-harness-crash.js +8 -9
- package/dist/src/core/test-harness-signature.d.ts +33 -0
- package/dist/src/core/test-harness-signature.js +23 -1
- package/dist/src/core/test-raw-log.d.ts +66 -0
- package/dist/src/core/test-raw-log.js +122 -0
- package/dist/src/core/test-run-completeness.d.ts +90 -0
- package/dist/src/core/test-run-completeness.js +184 -0
- package/dist/src/core/test-stale-check.d.ts +27 -1
- package/dist/src/core/test-stale-check.js +39 -49
- package/dist/src/core/test-stale-exempt.d.ts +40 -0
- package/dist/src/core/test-stale-exempt.js +70 -0
- package/dist/src/core/test-xpcshell-retry.d.ts +2 -0
- package/dist/src/core/test-xpcshell-retry.js +2 -1
- package/dist/src/core/token-lint.d.ts +53 -0
- package/dist/src/core/token-lint.js +131 -0
- package/dist/src/core/token-sibling-sheets.d.ts +46 -0
- package/dist/src/core/token-sibling-sheets.js +119 -0
- package/dist/src/core/tree-guard.js +5 -0
- package/dist/src/core/typecheck-shim.d.ts +6 -2
- package/dist/src/core/typecheck-shim.js +205 -4
- package/dist/src/core/typecheck.js +3 -1
- package/dist/src/index.d.ts +14 -3
- package/dist/src/index.js +6 -1
- package/dist/src/types/commands/index.d.ts +2 -2
- package/dist/src/types/commands/options.d.ts +212 -24
- package/dist/src/types/commands/patches.d.ts +118 -1
- package/dist/src/types/config.d.ts +264 -0
- package/dist/src/types/config.js +9 -0
- package/dist/src/types/furnace.d.ts +63 -1
- package/dist/src/types/furnace.js +7 -0
- package/dist/src/types/index.d.ts +1 -1
- package/dist/src/utils/options.d.ts +36 -7
- package/dist/src/utils/options.js +94 -8
- package/dist/src/utils/path-glob.d.ts +15 -0
- package/dist/src/utils/path-glob.js +47 -0
- package/dist/src/utils/regex.d.ts +15 -3
- package/dist/src/utils/regex.js +37 -16
- package/docs/configuration.md +369 -11
- package/docs/exit-codes.md +18 -1
- package/docs/furnace.md +139 -3
- package/docs/lifecycle-invariants.md +65 -30
- package/docs/machine-output.md +120 -12
- package/docs/patch-workflow.md +458 -22
- package/docs/run-logs.md +20 -1
- package/docs/testing.md +346 -21
- package/package.json +3 -3
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The advice an export placement refusal appends for new files: "register
|
|
3
|
+
* first" when a new system module only lacks its moz.build line, and
|
|
4
|
+
* adopt-then-split for a real moved-code block, but only after checking
|
|
5
|
+
* that the adopt itself would pass.
|
|
6
|
+
*
|
|
7
|
+
* The advice used to be offered on the moved-code heuristic alone. On one
|
|
8
|
+
* queue it told the operator to adopt six new modules into an existing
|
|
9
|
+
* patch when the only error was the missing registration; the adopt then
|
|
10
|
+
* refused one module for importing later patches, and without it breached
|
|
11
|
+
* the source patch's hard size limit. Split out of export-flow.ts for the
|
|
12
|
+
* line budget.
|
|
13
|
+
*/
|
|
14
|
+
import { type PatchQueueContext } from '../core/patch-lint.js';
|
|
15
|
+
import type { PatchLintIssue } from '../types/commands/index.js';
|
|
16
|
+
/**
|
|
17
|
+
* Why adopting `diff` into `sourceFilename` would itself be refused: the
|
|
18
|
+
* forward imports the adopted files would give the source patch, and the
|
|
19
|
+
* source patch's hard size limit. Empty when the adopt is clean.
|
|
20
|
+
*
|
|
21
|
+
* @param baseCtx - The current queue
|
|
22
|
+
* @param sourceFilename - The patch the adopt would grow
|
|
23
|
+
* @param diff - The pending export's diff
|
|
24
|
+
*/
|
|
25
|
+
export declare function findAdoptBlockers(baseCtx: PatchQueueContext, sourceFilename: string, diff: string): string[];
|
|
26
|
+
/**
|
|
27
|
+
* Detail lines for a placement refusal: register-first and moved-code
|
|
28
|
+
* advice, each only when the projection supports it.
|
|
29
|
+
*
|
|
30
|
+
* @param baseCtx - The current queue
|
|
31
|
+
* @param diff - The pending export's diff
|
|
32
|
+
* @param projectedIssues - Error findings of the placement projection
|
|
33
|
+
* @param plan - The placement's new filename and order
|
|
34
|
+
*/
|
|
35
|
+
export declare function describePlacementAdvice(baseCtx: PatchQueueContext, diff: string, projectedIssues: readonly PatchLintIssue[], plan: {
|
|
36
|
+
newFilename: string;
|
|
37
|
+
insertionOrder: number;
|
|
38
|
+
}): string[];
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* The advice an export placement refusal appends for new files: "register
|
|
4
|
+
* first" when a new system module only lacks its moz.build line, and
|
|
5
|
+
* adopt-then-split for a real moved-code block, but only after checking
|
|
6
|
+
* that the adopt itself would pass.
|
|
7
|
+
*
|
|
8
|
+
* The advice used to be offered on the moved-code heuristic alone. On one
|
|
9
|
+
* queue it told the operator to adopt six new modules into an existing
|
|
10
|
+
* patch when the only error was the missing registration; the adopt then
|
|
11
|
+
* refused one module for importing later patches, and without it breached
|
|
12
|
+
* the source patch's hard size limit. Split out of export-flow.ts for the
|
|
13
|
+
* line budget.
|
|
14
|
+
*/
|
|
15
|
+
import { detectMovedCodeOverlaps, formatMovedCodeAdvice } from '../core/export-moved-code-shape.js';
|
|
16
|
+
import { countNonBinaryDiffLines, getPatchSizeThresholds, lintPatchQueue, resolvePatchSizeTier, } from '../core/patch-lint.js';
|
|
17
|
+
import { computeProjectedLintRegressions } from '../core/patch-lint-projection.js';
|
|
18
|
+
import { projectEntryBody } from './patch/entry-projection.js';
|
|
19
|
+
/**
|
|
20
|
+
* Why adopting `diff` into `sourceFilename` would itself be refused: the
|
|
21
|
+
* forward imports the adopted files would give the source patch, and the
|
|
22
|
+
* source patch's hard size limit. Empty when the adopt is clean.
|
|
23
|
+
*
|
|
24
|
+
* @param baseCtx - The current queue
|
|
25
|
+
* @param sourceFilename - The patch the adopt would grow
|
|
26
|
+
* @param diff - The pending export's diff
|
|
27
|
+
*/
|
|
28
|
+
export function findAdoptBlockers(baseCtx, sourceFilename, diff) {
|
|
29
|
+
const source = baseCtx.entries.find((entry) => entry.filename === sourceFilename);
|
|
30
|
+
if (source === undefined)
|
|
31
|
+
return [];
|
|
32
|
+
const blockers = [];
|
|
33
|
+
const pending = projectEntryBody(diff);
|
|
34
|
+
const adopted = {
|
|
35
|
+
...source,
|
|
36
|
+
diff: `${source.diff}\n${diff}`,
|
|
37
|
+
newFiles: new Map([...source.newFiles, ...pending.newFiles]),
|
|
38
|
+
createdFiles: new Set([...source.createdFiles, ...pending.createdFiles]),
|
|
39
|
+
modifiedFileAdditions: new Map([
|
|
40
|
+
...source.modifiedFileAdditions,
|
|
41
|
+
...pending.modifiedFileAdditions,
|
|
42
|
+
]),
|
|
43
|
+
};
|
|
44
|
+
const isError = (issue) => issue.severity === 'error';
|
|
45
|
+
const baseline = lintPatchQueue(baseCtx).filter(isError);
|
|
46
|
+
const projected = lintPatchQueue({
|
|
47
|
+
...baseCtx,
|
|
48
|
+
entries: baseCtx.entries.map((entry) => (entry.filename === sourceFilename ? adopted : entry)),
|
|
49
|
+
}).filter(isError);
|
|
50
|
+
for (const issue of computeProjectedLintRegressions(baseline, projected)) {
|
|
51
|
+
if (issue.check !== 'forward-import' || !issue.patches?.includes(sourceFilename))
|
|
52
|
+
continue;
|
|
53
|
+
for (const declaration of issue.stagedDeclarations ?? []) {
|
|
54
|
+
blockers.push(`${declaration.file} imports "${declaration.specifier ?? ''}", created by ` +
|
|
55
|
+
`${declaration.owner}, which applies after ${sourceFilename} (forward-import)`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (!(source.metadata?.lintIgnore ?? []).includes('large-patch-lines')) {
|
|
59
|
+
const tier = resolvePatchSizeTier([...(source.metadata?.filesAffected ?? []), ...pending.newFiles.keys()], source.metadata?.tier);
|
|
60
|
+
const limit = getPatchSizeThresholds(tier.tier).lines.error;
|
|
61
|
+
const lines = countNonBinaryDiffLines(source.diff).textLines + countNonBinaryDiffLines(diff).textLines;
|
|
62
|
+
if (lines > limit) {
|
|
63
|
+
blockers.push(`${sourceFilename} would grow to about ${lines} lines, over its ${tier.tier} hard limit ` +
|
|
64
|
+
`of ${limit} (large-patch-lines)`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return blockers;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Detail lines for a placement refusal: register-first and moved-code
|
|
71
|
+
* advice, each only when the projection supports it.
|
|
72
|
+
*
|
|
73
|
+
* @param baseCtx - The current queue
|
|
74
|
+
* @param diff - The pending export's diff
|
|
75
|
+
* @param projectedIssues - Error findings of the placement projection
|
|
76
|
+
* @param plan - The placement's new filename and order
|
|
77
|
+
*/
|
|
78
|
+
export function describePlacementAdvice(baseCtx, diff, projectedIssues, plan) {
|
|
79
|
+
const newFiles = projectEntryBody(diff).newFiles;
|
|
80
|
+
const exported = projectedIssues.filter((issue) => issue.patches?.includes(plan.newFilename) ?? issue.message.includes(plan.newFilename));
|
|
81
|
+
const unregisteredModules = [
|
|
82
|
+
...new Set(exported
|
|
83
|
+
.filter((issue) => issue.check === 'unregistered-system-module' && newFiles.has(issue.file))
|
|
84
|
+
.map((issue) => issue.file)),
|
|
85
|
+
];
|
|
86
|
+
const registrationResolvesAll = unregisteredModules.length > 0 &&
|
|
87
|
+
exported.every((issue) => issue.check === 'unregistered-system-module');
|
|
88
|
+
const overlaps = registrationResolvesAll ? [] : detectMovedCodeOverlaps(diff, baseCtx.entries);
|
|
89
|
+
const strongest = overlaps[0];
|
|
90
|
+
return formatMovedCodeAdvice({
|
|
91
|
+
overlaps,
|
|
92
|
+
newPatchName: plan.newFilename,
|
|
93
|
+
insertionOrder: plan.insertionOrder,
|
|
94
|
+
unregisteredModules,
|
|
95
|
+
registrationResolvesAll,
|
|
96
|
+
adoptBlockers: strongest !== undefined ? findAdoptBlockers(baseCtx, strongest.sourcePatch, diff) : [],
|
|
97
|
+
});
|
|
98
|
+
}
|
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
* per-file / per-function line budgets and makes each step individually
|
|
8
8
|
* testable without dragging the whole command harness along for the ride.
|
|
9
9
|
*/
|
|
10
|
-
import { join } from 'node:path';
|
|
10
|
+
import { dirname, join } from 'node:path';
|
|
11
11
|
import {} from '../core/destructive.js';
|
|
12
|
-
import { detectMovedCodeOverlaps, formatAdoptThenSplitRemedy, } from '../core/export-moved-code-shape.js';
|
|
13
12
|
import { buildPlanExportInput, findAllPatchesForFilesWithDetails, patchNameSlug, planExport, } from '../core/patch-export.js';
|
|
14
13
|
import { buildPatchQueueContext, lintPatchQueue } from '../core/patch-lint.js';
|
|
14
|
+
import { formatLintIgnoreList } from '../core/patch-lint-ignore.js';
|
|
15
15
|
import { withPatchDirectoryLock } from '../core/patch-lock.js';
|
|
16
16
|
import { addPatchToManifest, loadPatchesManifest, loadPatchesManifestForWrite, renumberPatchesInManifest, resolvePatchIdentifier, savePatchesManifest, } from '../core/patch-manifest.js';
|
|
17
17
|
import { formatPatchOrder, requirePatchOrder } from '../core/patch-parse.js';
|
|
@@ -20,9 +20,11 @@ import { GeneralError, InvalidArgumentError } from '../errors/base.js';
|
|
|
20
20
|
import { toError } from '../utils/errors.js';
|
|
21
21
|
import { pathExists, readText, removeFile, writeText } from '../utils/fs.js';
|
|
22
22
|
import { info, warn } from '../utils/logger.js';
|
|
23
|
+
import { describePlacementAdvice } from './export-adopt-check.js';
|
|
23
24
|
import { groupProjectedPlacementErrors } from './export-placement-conflicts.js';
|
|
24
25
|
import { assertPlacementAvoidsReservedRanges } from './export-placement-policy.js';
|
|
25
26
|
import { findPartialOwnershipOverlap } from './export-shared.js';
|
|
27
|
+
import { acceptTreeRegisteredModules } from './export-staged-registration.js';
|
|
26
28
|
import { projectEntryBody } from './patch/entry-projection.js';
|
|
27
29
|
import { getSortedRenameEntries, renameMapsEqual } from './patch-rename-map.js';
|
|
28
30
|
function buildFilenameForPlacement(category, name, order, width) {
|
|
@@ -170,18 +172,31 @@ export async function projectPlacementForLint(patchesDir, plan, diff, config) {
|
|
|
170
172
|
// whether they live in a brand-new file or are added to an existing one.
|
|
171
173
|
// Leaving either map empty lets a patch land before one of its own
|
|
172
174
|
// dependencies and still pass the gate.
|
|
175
|
+
const pendingBody = projectEntryBody(diff);
|
|
173
176
|
projectedEntries.push({
|
|
174
177
|
filename: plan.newFilename,
|
|
175
178
|
order: plan.insertionOrder,
|
|
176
179
|
metadata: null,
|
|
177
|
-
...
|
|
180
|
+
...pendingBody,
|
|
178
181
|
});
|
|
179
182
|
projectedEntries.sort((a, b) => a.order - b.order || a.filename.localeCompare(b.filename));
|
|
180
183
|
const policyRest = baseCtx.patchPolicy ? { patchPolicy: baseCtx.patchPolicy } : {};
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
184
|
+
// A new module whose moz.build line is declared (staged registration)
|
|
185
|
+
// and present in the working tree, but not yet exported by its owner, is
|
|
186
|
+
// accepted with a "re-export the owner next" note instead of refused.
|
|
187
|
+
const registration = await acceptTreeRegisteredModules({
|
|
188
|
+
engineDir: join(dirname(patchesDir), 'engine'),
|
|
189
|
+
baseCtx,
|
|
190
|
+
newFilename: plan.newFilename,
|
|
191
|
+
pendingNewFiles: new Set(pendingBody.newFiles.keys()),
|
|
192
|
+
projectedIssues: lintPatchQueue({
|
|
193
|
+
entries: projectedEntries,
|
|
194
|
+
...policyRest,
|
|
195
|
+
}).filter((i) => i.severity === 'error'),
|
|
196
|
+
});
|
|
197
|
+
for (const note of registration.accepted)
|
|
198
|
+
warn(note);
|
|
199
|
+
const projectedIssues = registration.remaining;
|
|
185
200
|
if (projectedIssues.length === 0)
|
|
186
201
|
return null;
|
|
187
202
|
// Baseline lint over the un-renumbered queue: an error present here is
|
|
@@ -192,16 +207,16 @@ export async function projectPlacementForLint(patchesDir, plan, diff, config) {
|
|
|
192
207
|
entries: baseCtx.entries,
|
|
193
208
|
...policyRest,
|
|
194
209
|
}).filter((i) => i.severity === 'error');
|
|
195
|
-
//
|
|
196
|
-
//
|
|
197
|
-
//
|
|
198
|
-
//
|
|
199
|
-
const movedCode = detectMovedCodeOverlaps(diff, baseCtx.entries);
|
|
210
|
+
// Register-first and new-file + moved-code advice: name the working
|
|
211
|
+
// sequence instead of leaving the operator to derive it from two
|
|
212
|
+
// individually-correct guards that together dead-end, but only offer
|
|
213
|
+
// adopt-then-split for a real moved block whose adopt would itself pass.
|
|
200
214
|
return {
|
|
201
215
|
reason: `placement would introduce ${projectedIssues.length} cross-patch lint error(s)`,
|
|
202
216
|
details: [
|
|
203
217
|
...groupProjectedPlacementErrors(projectedIssues, baselineIssues, plan),
|
|
204
|
-
...
|
|
218
|
+
...registration.advice,
|
|
219
|
+
...describePlacementAdvice(baseCtx, diff, projectedIssues, plan),
|
|
205
220
|
],
|
|
206
221
|
};
|
|
207
222
|
}
|
|
@@ -380,7 +395,7 @@ export async function renderDryRunPreview(input) {
|
|
|
380
395
|
info(` tier: ${plan.metadata.tier}`);
|
|
381
396
|
}
|
|
382
397
|
if (plan.metadata.lintIgnore !== undefined && plan.metadata.lintIgnore.length > 0) {
|
|
383
|
-
info(` lintIgnore: ${plan.metadata.lintIgnore
|
|
398
|
+
info(` lintIgnore: ${formatLintIgnoreList(plan.metadata.lintIgnore)}`);
|
|
384
399
|
}
|
|
385
400
|
if (supersedeDetails.length > 0) {
|
|
386
401
|
info(`\n[dry-run] Would supersede ${supersedeDetails.length} existing patch(es):`);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* budgets. `gatePlacementPlan` owns every policy/confirmation decision a
|
|
5
5
|
* placement export makes before the locked commit in `export.ts` runs.
|
|
6
6
|
*/
|
|
7
|
-
import type { ExportOptions
|
|
7
|
+
import type { ExportOptions } from '../types/commands/index.js';
|
|
8
8
|
import type { FireForgeConfig } from '../types/config.js';
|
|
9
9
|
import type { SpinnerHandle } from '../utils/logger.js';
|
|
10
10
|
import { type PlacementPlan } from './export-flow.js';
|
|
@@ -14,7 +14,11 @@ import { type PlacementPlan } from './export-flow.js';
|
|
|
14
14
|
* shares this shape. With exactOptionalPropertyTypes the keys must be
|
|
15
15
|
* omitted entirely (not set to undefined) when the flags are absent.
|
|
16
16
|
*/
|
|
17
|
-
export declare function patchMetadataExtras(options: ExportOptions):
|
|
17
|
+
export declare function patchMetadataExtras(options: ExportOptions): {
|
|
18
|
+
tier?: 'branding';
|
|
19
|
+
/** CLI flags only ever carry bare check IDs. */
|
|
20
|
+
lintIgnore?: string[];
|
|
21
|
+
};
|
|
18
22
|
/**
|
|
19
23
|
* Resolves and gates the placement plan when any placement flag
|
|
20
24
|
* (`--order`/`--before`/`--after`) was given: rejects the `--supersede`
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { confirmDestructive } from '../core/destructive.js';
|
|
9
9
|
import { loadPatchesManifest } from '../core/patch-manifest.js';
|
|
10
10
|
import { applyRenameMapToManifest, buildProjectedManifest, enforcePatchPolicy, } from '../core/patch-policy.js';
|
|
11
|
+
import { reservationAt } from '../core/patch-retired.js';
|
|
11
12
|
import { buildPatchSourceMetadata } from '../core/patch-source-metadata.js';
|
|
12
13
|
import { InvalidArgumentError } from '../errors/base.js';
|
|
13
14
|
import { proceedAfterDecision } from './destructive-decision.js';
|
|
@@ -68,6 +69,13 @@ export async function gatePlacementPlan(args) {
|
|
|
68
69
|
forceUnsafe: options.forceUnsafe === true,
|
|
69
70
|
});
|
|
70
71
|
const summary = placementSummary(placementPlan);
|
|
72
|
+
const reservation = reservationAt(currentManifest, placementPlan.insertionOrder);
|
|
73
|
+
if (reservation !== undefined) {
|
|
74
|
+
const notice = `order ${placementPlan.insertionOrder} is reserved by ${reservation.owner}; ` +
|
|
75
|
+
'this export fills the reservation';
|
|
76
|
+
summary.push(notice);
|
|
77
|
+
s.message(notice);
|
|
78
|
+
}
|
|
71
79
|
const renameCount = placementPlan.renameMap.size;
|
|
72
80
|
// Route through confirmDestructive when the operation is destructive
|
|
73
81
|
// enough to warrant a prompt (more than one rename) or when the user asked
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { LintIgnoreChecks } from '../core/patch-lint-ignore.js';
|
|
1
2
|
import type { PatchesManifest, PatchLintIssue } from '../types/commands/index.js';
|
|
2
3
|
import type { ExportOptions, PatchCategory } from '../types/commands/index.js';
|
|
3
4
|
import type { FireForgeConfig } from '../types/config.js';
|
|
@@ -22,7 +23,7 @@ export interface RunPatchLintOptions {
|
|
|
22
23
|
* `large-patch-lines` on a cohesive branding bundle that genuinely cannot
|
|
23
24
|
* be split.
|
|
24
25
|
*/
|
|
25
|
-
ignoreChecks?:
|
|
26
|
+
ignoreChecks?: LintIgnoreChecks | undefined;
|
|
26
27
|
/**
|
|
27
28
|
* Optional explicit tier override (threaded from `PatchMetadata.tier`).
|
|
28
29
|
* Forces the branding-tier thresholds when set, independent of the
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lets `export --order` land a new system module whose moz.build line is
|
|
3
|
+
* still unexported working-tree drift in the patch that registers it.
|
|
4
|
+
*
|
|
5
|
+
* The two refusals used to deadlock: the module's export failed
|
|
6
|
+
* `unregistered-system-module` because no patch body carried its moz.build
|
|
7
|
+
* line yet, and the registering patch could not be re-exported first
|
|
8
|
+
* because its line named a file no patch created. The way through is
|
|
9
|
+
* declared intent plus evidence: when the registering patch carries a
|
|
10
|
+
* staged registration for the module and the working tree's moz.build has
|
|
11
|
+
* exactly that line, the export is accepted and the operator is told to
|
|
12
|
+
* re-export the registering patch next. Without the declaration the
|
|
13
|
+
* refusal names the steps, with the exact `patch staged-dependency`
|
|
14
|
+
* command, instead of stopping at "register it".
|
|
15
|
+
*
|
|
16
|
+
* Consumed by export-flow.ts.
|
|
17
|
+
*/
|
|
18
|
+
import type { PatchQueueContext } from '../core/patch-lint.js';
|
|
19
|
+
import type { PatchLintIssue } from '../types/commands/index.js';
|
|
20
|
+
/** Result of {@link acceptTreeRegisteredModules}. */
|
|
21
|
+
export interface TreeRegistrationOutcome {
|
|
22
|
+
/** The projected errors left after accepted modules are removed. */
|
|
23
|
+
remaining: PatchLintIssue[];
|
|
24
|
+
/** One note per accepted module, naming the re-export to run next. */
|
|
25
|
+
accepted: string[];
|
|
26
|
+
/** Detail lines for modules whose registration is in the tree but undeclared. */
|
|
27
|
+
advice: string[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Removes `unregistered-system-module` findings for modules the pending
|
|
31
|
+
* export creates when a queue patch declares their registration as a
|
|
32
|
+
* staged dependency and the working tree's moz.build carries that line.
|
|
33
|
+
* For a module whose line is in the tree but undeclared, returns the steps
|
|
34
|
+
* that make it acceptable.
|
|
35
|
+
*
|
|
36
|
+
* @param args - The engine directory (the working tree), the current queue,
|
|
37
|
+
* the filename the pending export would take, the files it creates, and
|
|
38
|
+
* the placement projection's error findings
|
|
39
|
+
*/
|
|
40
|
+
export declare function acceptTreeRegisteredModules(args: {
|
|
41
|
+
engineDir: string;
|
|
42
|
+
baseCtx: PatchQueueContext;
|
|
43
|
+
newFilename: string;
|
|
44
|
+
pendingNewFiles: ReadonlySet<string>;
|
|
45
|
+
projectedIssues: readonly PatchLintIssue[];
|
|
46
|
+
}): Promise<TreeRegistrationOutcome>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* Lets `export --order` land a new system module whose moz.build line is
|
|
4
|
+
* still unexported working-tree drift in the patch that registers it.
|
|
5
|
+
*
|
|
6
|
+
* The two refusals used to deadlock: the module's export failed
|
|
7
|
+
* `unregistered-system-module` because no patch body carried its moz.build
|
|
8
|
+
* line yet, and the registering patch could not be re-exported first
|
|
9
|
+
* because its line named a file no patch created. The way through is
|
|
10
|
+
* declared intent plus evidence: when the registering patch carries a
|
|
11
|
+
* staged registration for the module and the working tree's moz.build has
|
|
12
|
+
* exactly that line, the export is accepted and the operator is told to
|
|
13
|
+
* re-export the registering patch next. Without the declaration the
|
|
14
|
+
* refusal names the steps, with the exact `patch staged-dependency`
|
|
15
|
+
* command, instead of stopping at "register it".
|
|
16
|
+
*
|
|
17
|
+
* Consumed by export-flow.ts.
|
|
18
|
+
*/
|
|
19
|
+
import { basename, dirname, join } from 'node:path';
|
|
20
|
+
import { STAGED_DEPENDENCY_REASON_PLACEHOLDER } from '../core/patch-lint-staged-registration.js';
|
|
21
|
+
import { pathExists, readText } from '../utils/fs.js';
|
|
22
|
+
async function readLines(path) {
|
|
23
|
+
if (!(await pathExists(path)))
|
|
24
|
+
return undefined;
|
|
25
|
+
return (await readText(path)).split('\n').map((line) => line.trim());
|
|
26
|
+
}
|
|
27
|
+
/** The nearest moz.build at or above `modulePath` whose lines name `leaf` quoted. */
|
|
28
|
+
async function findTreeRegistration(engineDir, modulePath) {
|
|
29
|
+
const leaf = basename(modulePath);
|
|
30
|
+
let dir = dirname(modulePath);
|
|
31
|
+
for (;;) {
|
|
32
|
+
const file = dir === '.' ? 'moz.build' : `${dir}/moz.build`;
|
|
33
|
+
const line = (await readLines(join(engineDir, file)))?.find((candidate) => candidate.includes(`"${leaf}"`) || candidate.includes(`'${leaf}'`));
|
|
34
|
+
if (line !== undefined)
|
|
35
|
+
return { file, line };
|
|
36
|
+
if (dir === '.' || dir === '')
|
|
37
|
+
return undefined;
|
|
38
|
+
const parent = dirname(dir);
|
|
39
|
+
dir = parent === dir ? '.' : parent;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Removes `unregistered-system-module` findings for modules the pending
|
|
44
|
+
* export creates when a queue patch declares their registration as a
|
|
45
|
+
* staged dependency and the working tree's moz.build carries that line.
|
|
46
|
+
* For a module whose line is in the tree but undeclared, returns the steps
|
|
47
|
+
* that make it acceptable.
|
|
48
|
+
*
|
|
49
|
+
* @param args - The engine directory (the working tree), the current queue,
|
|
50
|
+
* the filename the pending export would take, the files it creates, and
|
|
51
|
+
* the placement projection's error findings
|
|
52
|
+
*/
|
|
53
|
+
export async function acceptTreeRegisteredModules(args) {
|
|
54
|
+
const outcome = { remaining: [], accepted: [], advice: [] };
|
|
55
|
+
for (const issue of args.projectedIssues) {
|
|
56
|
+
if (issue.check !== 'unregistered-system-module' || !args.pendingNewFiles.has(issue.file)) {
|
|
57
|
+
outcome.remaining.push(issue);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const declared = args.baseCtx.entries.flatMap((entry) => (entry.metadata?.stagedDependencies?.registrations ?? [])
|
|
61
|
+
.filter((registration) => registration.creates === issue.file &&
|
|
62
|
+
(registration.owner === undefined || registration.owner === args.newFilename))
|
|
63
|
+
.map((registration) => ({ holder: entry.filename, registration })));
|
|
64
|
+
let accepted = false;
|
|
65
|
+
for (const { holder, registration } of declared) {
|
|
66
|
+
const lines = await readLines(join(args.engineDir, registration.file));
|
|
67
|
+
if (lines?.includes(registration.line.trim()) !== true)
|
|
68
|
+
continue;
|
|
69
|
+
outcome.accepted.push(`${issue.file} is registered by the working tree's ${registration.file} ` +
|
|
70
|
+
`("${registration.line.trim()}"), which ${holder} declares as a staged registration ` +
|
|
71
|
+
`but has not exported yet. Re-export ${holder} right after this export to land the ` +
|
|
72
|
+
`line: fireforge re-export ${holder}`);
|
|
73
|
+
accepted = true;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
if (accepted)
|
|
77
|
+
continue;
|
|
78
|
+
outcome.remaining.push(issue);
|
|
79
|
+
const tree = await findTreeRegistration(args.engineDir, issue.file);
|
|
80
|
+
if (tree === undefined)
|
|
81
|
+
continue;
|
|
82
|
+
const owner = args.baseCtx.entries.find((entry) => entry.metadata?.filesAffected.includes(tree.file))?.filename;
|
|
83
|
+
if (owner === undefined)
|
|
84
|
+
continue;
|
|
85
|
+
outcome.advice.push('', `${issue.file} is registered in the working tree's ${tree.file}, but ${owner} has not ` +
|
|
86
|
+
'exported that line. Land both without untangling the tree:', ` 1. fireforge patch staged-dependency ${owner} --add --kind registration --file ${tree.file} ` +
|
|
87
|
+
`--line "${tree.line.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}" --creates ${issue.file} ` +
|
|
88
|
+
`--owner ${args.newFilename} ${STAGED_DEPENDENCY_REASON_PLACEHOLDER}`, ' 2. re-run this export (a declared registration present in the working tree is accepted)', ` 3. fireforge re-export ${owner}`);
|
|
89
|
+
}
|
|
90
|
+
return outcome;
|
|
91
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The remedy printed under a forward-import refusal from `re-export`
|
|
3
|
+
* (plain refresh and `--scan` adoption alike): the earliest order the files
|
|
4
|
+
* can take as their own later patch, and the exact `patch staged-dependency
|
|
5
|
+
* --add` commands that declare the edges instead.
|
|
6
|
+
*
|
|
7
|
+
* The refusal used to end with "export them with --order <n> or run
|
|
8
|
+
* patch staged-dependency --add", which left the operator to work out both
|
|
9
|
+
* the number and every flag of the declaration from the finding text.
|
|
10
|
+
*/
|
|
11
|
+
import type { PatchesManifest, PatchLintIssue } from '../types/commands/index.js';
|
|
12
|
+
import type { FireForgeConfig } from '../types/config.js';
|
|
13
|
+
/** Inputs to {@link formatForwardImportRemedy}. */
|
|
14
|
+
export interface ForwardImportRemedyInput {
|
|
15
|
+
/** What to do after the fix, e.g. "re-running the scan". */
|
|
16
|
+
reRunHint: string;
|
|
17
|
+
/** The refusal's findings; only `forward-import` and `forward-registration` ones are read. */
|
|
18
|
+
issues: readonly PatchLintIssue[];
|
|
19
|
+
/** Current manifest (null when unavailable: the order is then not named). */
|
|
20
|
+
manifest: PatchesManifest | null;
|
|
21
|
+
/** Project config; only `patchPolicy` is read. */
|
|
22
|
+
config?: Pick<FireForgeConfig, 'patchPolicy'>;
|
|
23
|
+
/** Category the files would be exported under (the refused patch's). */
|
|
24
|
+
category?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Renders the remedy lines. Falls back to the generic sentence when the
|
|
28
|
+
* findings carry no structured declarations.
|
|
29
|
+
*
|
|
30
|
+
* @param input - See {@link ForwardImportRemedyInput}
|
|
31
|
+
*/
|
|
32
|
+
export declare function formatForwardImportRemedy(input: ForwardImportRemedyInput): string;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* The remedy printed under a forward-import refusal from `re-export`
|
|
4
|
+
* (plain refresh and `--scan` adoption alike): the earliest order the files
|
|
5
|
+
* can take as their own later patch, and the exact `patch staged-dependency
|
|
6
|
+
* --add` commands that declare the edges instead.
|
|
7
|
+
*
|
|
8
|
+
* The refusal used to end with "export them with --order <n> or run
|
|
9
|
+
* patch staged-dependency --add", which left the operator to work out both
|
|
10
|
+
* the number and every flag of the declaration from the finding text.
|
|
11
|
+
*/
|
|
12
|
+
import { STAGED_DEPENDENCY_REASON_PLACEHOLDER } from '../core/patch-lint-staged-registration.js';
|
|
13
|
+
import { earliestLegalOrderAfter } from '../core/patch-order-legal.js';
|
|
14
|
+
import { formatPatchOrder } from '../core/patch-parse.js';
|
|
15
|
+
function quoteArg(value) {
|
|
16
|
+
return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
|
|
17
|
+
}
|
|
18
|
+
function declarationCommand(declaration) {
|
|
19
|
+
const anchor = declaration.kind === 'import'
|
|
20
|
+
? `--specifier ${quoteArg(declaration.specifier ?? '')}`
|
|
21
|
+
: `--kind registration --line ${quoteArg(declaration.line ?? '')}`;
|
|
22
|
+
return (`fireforge patch staged-dependency ${declaration.patch} --add --file ${declaration.file} ` +
|
|
23
|
+
`${anchor} --creates ${declaration.creates} --owner ${declaration.owner} ` +
|
|
24
|
+
STAGED_DEPENDENCY_REASON_PLACEHOLDER);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Renders the remedy lines. Falls back to the generic sentence when the
|
|
28
|
+
* findings carry no structured declarations.
|
|
29
|
+
*
|
|
30
|
+
* @param input - See {@link ForwardImportRemedyInput}
|
|
31
|
+
*/
|
|
32
|
+
export function formatForwardImportRemedy(input) {
|
|
33
|
+
const declarations = input.issues
|
|
34
|
+
.filter((issue) => issue.check === 'forward-import' || issue.check === 'forward-registration')
|
|
35
|
+
.flatMap((issue) => issue.stagedDeclarations ?? []);
|
|
36
|
+
const ownerOrders = declarations
|
|
37
|
+
.map((declaration) => input.manifest?.patches.find((patch) => patch.filename === declaration.owner)?.order)
|
|
38
|
+
.filter((order) => order !== undefined);
|
|
39
|
+
const latestOwner = ownerOrders.length > 0 ? Math.max(...ownerOrders) : undefined;
|
|
40
|
+
const legalOrder = latestOwner !== undefined && input.manifest !== null && input.category !== undefined
|
|
41
|
+
? earliestLegalOrderAfter(input.config ?? {}, input.manifest, input.category, latestOwner)
|
|
42
|
+
: null;
|
|
43
|
+
const orderText = legalOrder !== null
|
|
44
|
+
? `"fireforge export <files> --order ${formatPatchOrder(legalOrder)}"; ` +
|
|
45
|
+
`${formatPatchOrder(legalOrder)} is the earliest legal order after the latest creator ` +
|
|
46
|
+
`(${formatPatchOrder(latestOwner ?? legalOrder)})`
|
|
47
|
+
: '"fireforge export --order <n>"';
|
|
48
|
+
const lines = [
|
|
49
|
+
`Export those files as their own later patch (${orderText}; or ` +
|
|
50
|
+
'"fireforge patch split --order <n>"), or declare the intentional dependency with ' +
|
|
51
|
+
`"fireforge patch staged-dependency --add" before ${input.reRunHint}` +
|
|
52
|
+
(declarations.length > 0 ? ':' : '.'),
|
|
53
|
+
];
|
|
54
|
+
const seen = new Set();
|
|
55
|
+
for (const declaration of declarations) {
|
|
56
|
+
const command = declarationCommand(declaration);
|
|
57
|
+
if (seen.has(command))
|
|
58
|
+
continue;
|
|
59
|
+
seen.add(command);
|
|
60
|
+
lines.push(` ${command}`);
|
|
61
|
+
}
|
|
62
|
+
return lines.join('\n');
|
|
63
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { watch as fsWatch } from 'node:fs';
|
|
3
3
|
import { loadConfig } from '../../core/config.js';
|
|
4
4
|
import { applyAllComponents, computeComponentChecksums } from '../../core/furnace-apply.js';
|
|
5
|
-
import { logApplyResult } from '../../core/furnace-apply-output.js';
|
|
5
|
+
import { formatSkipBreakdown, logApplyResult } from '../../core/furnace-apply-output.js';
|
|
6
6
|
import { getFurnacePaths } from '../../core/furnace-config.js';
|
|
7
7
|
import { isComponentSourceFile } from '../../core/furnace-constants.js';
|
|
8
8
|
import { runFurnaceMutation, waitLockMutationOptions } from '../../core/furnace-operation.js';
|
|
@@ -108,7 +108,7 @@ async function runWatchLoop(projectRoot) {
|
|
|
108
108
|
}
|
|
109
109
|
const applied = result.applied.length;
|
|
110
110
|
const skipped = result.skipped.length;
|
|
111
|
-
info(`Re-applied: ${applied} applied, ${skipped} skipped`);
|
|
111
|
+
info(`Re-applied: ${applied} applied, ${skipped} skipped${formatSkipBreakdown(result.skipped)}`);
|
|
112
112
|
retryNeeded = false;
|
|
113
113
|
lastChecksums = await snapshotWatchedChecksums(watchDirs);
|
|
114
114
|
}
|
|
@@ -318,7 +318,7 @@ export async function furnaceApplyCommand(projectRoot, name, options = {}) {
|
|
|
318
318
|
outro(`Dry run complete — would apply ${appliedCount}, skip ${skippedCount}`);
|
|
319
319
|
}
|
|
320
320
|
else {
|
|
321
|
-
outro(`Applied ${appliedCount}, skipped ${skippedCount}`);
|
|
321
|
+
outro(`Applied ${appliedCount}, skipped ${skippedCount}${formatSkipBreakdown(result.skipped)}`);
|
|
322
322
|
}
|
|
323
323
|
// Watch mode: re-apply on file changes in component directories
|
|
324
324
|
if (options.watch && !dryRun) {
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* `fireforge furnace chrome-doc remove <name>` removes the files and
|
|
3
3
|
* registrations created by `furnace chrome-doc create`.
|
|
4
4
|
*/
|
|
5
|
+
import type { FurnaceLockWaitable } from '../../types/commands/index.js';
|
|
5
6
|
/** Options for `furnace chrome-doc remove`. */
|
|
6
|
-
export interface FurnaceChromeDocRemoveOptions {
|
|
7
|
+
export interface FurnaceChromeDocRemoveOptions extends FurnaceLockWaitable {
|
|
7
8
|
/** Skip confirmation. Required for real non-interactive removal. */
|
|
8
9
|
yes?: boolean;
|
|
9
10
|
/** Print the removal plan without writing files. */
|
|
@@ -8,7 +8,7 @@ import { join } from 'node:path';
|
|
|
8
8
|
import { confirm } from '@clack/prompts';
|
|
9
9
|
import { loadConfig } from '../../core/config.js';
|
|
10
10
|
import { stdioIsInteractive } from '../../core/destructive.js';
|
|
11
|
-
import { completeJournalRollback, runFurnaceMutation, } from '../../core/furnace-operation.js';
|
|
11
|
+
import { completeJournalRollback, runFurnaceMutation, waitLockMutationOptions, } from '../../core/furnace-operation.js';
|
|
12
12
|
import { assertFurnaceEngineReady } from '../../core/furnace-precondition.js';
|
|
13
13
|
import { createRollbackJournal, snapshotDir, snapshotFile, } from '../../core/furnace-rollback.js';
|
|
14
14
|
import { FurnaceError } from '../../errors/furnace.js';
|
|
@@ -138,7 +138,7 @@ export async function furnaceChromeDocRemoveCommand(projectRoot, name, options =
|
|
|
138
138
|
plan,
|
|
139
139
|
binaryName: forgeConfig.binaryName,
|
|
140
140
|
operationContext: ctx,
|
|
141
|
-
}));
|
|
141
|
+
}), waitLockMutationOptions(options.waitLockSeconds));
|
|
142
142
|
info(`Removed ${result.removedFiles} source file${result.removedFiles === 1 ? '' : 's'} and ` +
|
|
143
143
|
`${result.removedJarEntries} jar registration${result.removedJarEntries === 1 ? '' : 's'} for "${name}".`);
|
|
144
144
|
if (result.removedTestDir) {
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
* mid-scaffold restores every touched file. A successful run leaves the tree
|
|
16
16
|
* ready for `fireforge build`.
|
|
17
17
|
*/
|
|
18
|
+
import type { FurnaceLockWaitable } from '../../types/commands/index.js';
|
|
18
19
|
/** Options for `furnace chrome-doc create`. */
|
|
19
|
-
export interface FurnaceChromeDocCreateOptions {
|
|
20
|
+
export interface FurnaceChromeDocCreateOptions extends FurnaceLockWaitable {
|
|
20
21
|
/**
|
|
21
22
|
* Emit the titlebar-buttonbox markup and leave platform window controls
|
|
22
23
|
* visible. Defaults to `true` because the common case is a full chrome
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
import { join } from 'node:path';
|
|
20
20
|
import { loadConfig } from '../../core/config.js';
|
|
21
21
|
import { furnaceConfigExists, loadFurnaceConfig } from '../../core/furnace-config.js';
|
|
22
|
-
import { completeJournalRollback, runFurnaceMutation, } from '../../core/furnace-operation.js';
|
|
22
|
+
import { completeJournalRollback, runFurnaceMutation, waitLockMutationOptions, } from '../../core/furnace-operation.js';
|
|
23
23
|
import { assertFurnaceEngineReady } from '../../core/furnace-precondition.js';
|
|
24
24
|
import { createRollbackJournal, recordCreatedDir, snapshotFile, } from '../../core/furnace-rollback.js';
|
|
25
25
|
import { DEFAULT_LICENSE, getLicenseHeader } from '../../core/license-headers.js';
|
|
@@ -343,7 +343,7 @@ export async function furnaceChromeDocCreateCommand(projectRoot, name, options =
|
|
|
343
343
|
browserWindow,
|
|
344
344
|
binaryName: forgeConfig.binaryName,
|
|
345
345
|
operationContext: ctx,
|
|
346
|
-
}));
|
|
346
|
+
}), waitLockMutationOptions(options.waitLockSeconds));
|
|
347
347
|
const nextSteps = [
|
|
348
348
|
` 1. Edit engine/browser/base/content/${name}.xhtml and fill in the body.`,
|
|
349
349
|
` 2. Localize strings in engine/browser/locales/en-US/browser/${name}.ftl.`,
|
|
@@ -5,7 +5,7 @@ import { getProjectPaths, loadConfig } from '../../core/config.js';
|
|
|
5
5
|
import { stdioIsInteractive } from '../../core/destructive.js';
|
|
6
6
|
import { getFurnacePaths, writeFurnaceConfig } from '../../core/furnace-config.js';
|
|
7
7
|
import { resolveFtlChromeSubPath, tagNameToClassName, WIDGETS_DIR, } from '../../core/furnace-constants.js';
|
|
8
|
-
import { completeJournalRollback, runFurnaceMutation, } from '../../core/furnace-operation.js';
|
|
8
|
+
import { completeJournalRollback, runFurnaceMutation, waitLockMutationOptions, } from '../../core/furnace-operation.js';
|
|
9
9
|
import { CUSTOM_ELEMENT_TAG_PATTERN, CUSTOM_ELEMENT_TAG_RULES, describeTagNameProblem, } from '../../core/furnace-registration-validate.js';
|
|
10
10
|
import { createRollbackJournal, recordCreatedDir, snapshotFile, } from '../../core/furnace-rollback.js';
|
|
11
11
|
import { isComponentInEngine, scanWidgetsDirectory } from '../../core/furnace-scanner.js';
|
|
@@ -394,7 +394,7 @@ export async function furnaceCreateCommand(projectRoot, name, options = {}) {
|
|
|
394
394
|
testStyle,
|
|
395
395
|
testDir,
|
|
396
396
|
operationContext: ctx,
|
|
397
|
-
}));
|
|
397
|
+
}), waitLockMutationOptions(options.waitLockSeconds));
|
|
398
398
|
note(formatSuccessNote({
|
|
399
399
|
componentName,
|
|
400
400
|
files,
|