@hominis/fireforge 0.46.0 → 0.46.2
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 +381 -498
- package/dist/bin/fireforge.d.ts +1 -1
- package/dist/bin/fireforge.js +17 -17
- package/dist/build-info.json +4 -4
- package/dist/src/cli-usage-error.d.ts +9 -9
- package/dist/src/cli-usage-error.js +12 -12
- package/dist/src/cli.d.ts +3 -2
- package/dist/src/cli.js +29 -28
- package/dist/src/commands/bootstrap-checks.js +2 -1
- package/dist/src/commands/bootstrap.js +2 -2
- package/dist/src/commands/build.js +12 -11
- package/dist/src/commands/config.js +9 -9
- package/dist/src/commands/destructive-decision.d.ts +4 -4
- package/dist/src/commands/destructive-decision.js +4 -4
- package/dist/src/commands/discard.js +5 -5
- package/dist/src/commands/doctor-check-core.d.ts +4 -4
- package/dist/src/commands/doctor-external-toolchains.js +2 -2
- package/dist/src/commands/doctor-furnace-config-sync.d.ts +2 -2
- package/dist/src/commands/doctor-furnace-config-sync.js +20 -20
- package/dist/src/commands/doctor-furnace-jar.d.ts +1 -1
- package/dist/src/commands/doctor-furnace-jar.js +1 -1
- package/dist/src/commands/doctor-furnace.js +22 -22
- package/dist/src/commands/doctor-orphaned-harness.d.ts +10 -11
- package/dist/src/commands/doctor-orphaned-harness.js +10 -11
- package/dist/src/commands/doctor-patch-manifest.d.ts +2 -1
- package/dist/src/commands/doctor-patch-manifest.js +7 -6
- package/dist/src/commands/doctor-post-rebase-audit.js +2 -2
- package/dist/src/commands/doctor-source-pin.d.ts +12 -12
- package/dist/src/commands/doctor-source-pin.js +14 -14
- package/dist/src/commands/doctor-working-tree.d.ts +3 -3
- package/dist/src/commands/doctor-working-tree.js +3 -3
- package/dist/src/commands/doctor.d.ts +2 -2
- package/dist/src/commands/doctor.js +9 -9
- package/dist/src/commands/download.js +15 -13
- package/dist/src/commands/export-all.js +8 -8
- package/dist/src/commands/export-flow.d.ts +5 -5
- package/dist/src/commands/export-flow.js +14 -14
- package/dist/src/commands/export-placement-conflicts.d.ts +3 -3
- package/dist/src/commands/export-placement-conflicts.js +9 -9
- package/dist/src/commands/export-placement-gate.d.ts +2 -2
- package/dist/src/commands/export-placement-gate.js +5 -5
- package/dist/src/commands/export-placement-policy.d.ts +1 -1
- package/dist/src/commands/export-placement-policy.js +1 -1
- package/dist/src/commands/export-shared.d.ts +10 -10
- package/dist/src/commands/export-shared.js +13 -13
- package/dist/src/commands/export.js +4 -4
- package/dist/src/commands/furnace/apply.js +16 -16
- package/dist/src/commands/furnace/chrome-doc-remove.d.ts +1 -1
- package/dist/src/commands/furnace/chrome-doc-remove.js +1 -1
- package/dist/src/commands/furnace/chrome-doc-templates.d.ts +14 -14
- package/dist/src/commands/furnace/chrome-doc-templates.js +17 -17
- package/dist/src/commands/furnace/chrome-doc-tests.d.ts +2 -2
- package/dist/src/commands/furnace/chrome-doc-tests.js +4 -4
- package/dist/src/commands/furnace/chrome-doc.d.ts +8 -8
- package/dist/src/commands/furnace/chrome-doc.js +18 -18
- package/dist/src/commands/furnace/create-browser-test.d.ts +1 -1
- package/dist/src/commands/furnace/create-browser-test.js +4 -4
- package/dist/src/commands/furnace/create-dry-run.d.ts +4 -4
- package/dist/src/commands/furnace/create-dry-run.js +4 -4
- package/dist/src/commands/furnace/create-features.d.ts +2 -2
- package/dist/src/commands/furnace/create-features.js +2 -2
- package/dist/src/commands/furnace/create-mochikit.d.ts +4 -4
- package/dist/src/commands/furnace/create-mochikit.js +7 -7
- package/dist/src/commands/furnace/create-templates.d.ts +14 -14
- package/dist/src/commands/furnace/create-templates.js +18 -18
- package/dist/src/commands/furnace/create-xpcshell.d.ts +5 -5
- package/dist/src/commands/furnace/create-xpcshell.js +8 -8
- package/dist/src/commands/furnace/create.d.ts +1 -1
- package/dist/src/commands/furnace/create.js +10 -10
- package/dist/src/commands/furnace/deploy.js +4 -4
- package/dist/src/commands/furnace/diff.js +7 -7
- package/dist/src/commands/furnace/index.js +1 -1
- package/dist/src/commands/furnace/init.js +15 -15
- package/dist/src/commands/furnace/list.js +2 -2
- package/dist/src/commands/furnace/override.d.ts +1 -1
- package/dist/src/commands/furnace/override.js +15 -15
- package/dist/src/commands/furnace/preview.js +17 -17
- package/dist/src/commands/furnace/refresh.js +6 -6
- package/dist/src/commands/furnace/remove-mutations.d.ts +3 -3
- package/dist/src/commands/furnace/remove-mutations.js +19 -18
- package/dist/src/commands/furnace/remove-state.d.ts +1 -1
- package/dist/src/commands/furnace/remove-state.js +1 -1
- package/dist/src/commands/furnace/remove.js +2 -2
- package/dist/src/commands/furnace/rename-browser-test.js +9 -8
- package/dist/src/commands/furnace/rename-xpcshell.d.ts +2 -2
- package/dist/src/commands/furnace/rename-xpcshell.js +3 -3
- package/dist/src/commands/furnace/rename.js +9 -9
- package/dist/src/commands/furnace/scan.js +3 -3
- package/dist/src/commands/furnace/status.js +7 -7
- package/dist/src/commands/furnace/sync.js +6 -6
- package/dist/src/commands/furnace/test-file-name.d.ts +2 -2
- package/dist/src/commands/furnace/test-file-name.js +2 -2
- package/dist/src/commands/furnace/validate.js +11 -12
- package/dist/src/commands/import.js +20 -20
- package/dist/src/commands/lint-per-patch.js +8 -8
- package/dist/src/commands/lint-per-run-checkjs.d.ts +12 -13
- package/dist/src/commands/lint-per-run-checkjs.js +14 -15
- package/dist/src/commands/lint-report.d.ts +3 -3
- package/dist/src/commands/lint-report.js +4 -4
- package/dist/src/commands/lint.d.ts +3 -3
- package/dist/src/commands/lint.js +35 -35
- package/dist/src/commands/manifest.d.ts +4 -4
- package/dist/src/commands/package.js +2 -2
- package/dist/src/commands/patch/compact.d.ts +2 -2
- package/dist/src/commands/patch/compact.js +8 -8
- package/dist/src/commands/patch/delete.d.ts +1 -1
- package/dist/src/commands/patch/delete.js +8 -8
- package/dist/src/commands/patch/lint-ignore.d.ts +3 -4
- package/dist/src/commands/patch/lint-ignore.js +14 -15
- package/dist/src/commands/patch/move-files-create.d.ts +2 -2
- package/dist/src/commands/patch/move-files-create.js +5 -5
- package/dist/src/commands/patch/move-files-into.d.ts +2 -2
- package/dist/src/commands/patch/move-files-into.js +3 -3
- package/dist/src/commands/patch/move-files.js +1 -1
- package/dist/src/commands/patch/patch-context.d.ts +1 -1
- package/dist/src/commands/patch/rename.d.ts +4 -4
- package/dist/src/commands/patch/rename.js +8 -8
- package/dist/src/commands/patch/reorder.js +10 -10
- package/dist/src/commands/patch/split-plan.d.ts +3 -3
- package/dist/src/commands/patch/split-plan.js +6 -5
- package/dist/src/commands/patch/split.d.ts +2 -2
- package/dist/src/commands/patch/split.js +5 -5
- package/dist/src/commands/patch/staged-dependency-validate.d.ts +1 -1
- package/dist/src/commands/patch/staged-dependency-validate.js +3 -3
- package/dist/src/commands/patch/staged-dependency.d.ts +1 -1
- package/dist/src/commands/patch/staged-dependency.js +6 -6
- package/dist/src/commands/patch/tier.d.ts +2 -2
- package/dist/src/commands/patch/tier.js +5 -5
- package/dist/src/commands/patch-rename-map.d.ts +1 -1
- package/dist/src/commands/patch-rename-map.js +1 -1
- package/dist/src/commands/pending-resolution.d.ts +5 -5
- package/dist/src/commands/pending-resolution.js +5 -5
- package/dist/src/commands/re-export-adjacent.d.ts +3 -3
- package/dist/src/commands/re-export-adjacent.js +8 -8
- package/dist/src/commands/re-export-bulk-scan.d.ts +3 -3
- package/dist/src/commands/re-export-bulk-scan.js +17 -17
- package/dist/src/commands/re-export-drift.d.ts +10 -10
- package/dist/src/commands/re-export-drift.js +29 -29
- package/dist/src/commands/re-export-files.js +14 -15
- package/dist/src/commands/re-export-lint.d.ts +26 -26
- package/dist/src/commands/re-export-lint.js +27 -27
- package/dist/src/commands/re-export-options.d.ts +1 -1
- package/dist/src/commands/re-export-options.js +1 -1
- package/dist/src/commands/re-export-register.d.ts +1 -1
- package/dist/src/commands/re-export-register.js +1 -1
- package/dist/src/commands/re-export-scan.d.ts +1 -1
- package/dist/src/commands/re-export-scan.js +7 -7
- package/dist/src/commands/re-export-single.d.ts +1 -1
- package/dist/src/commands/re-export-single.js +20 -20
- package/dist/src/commands/re-export.js +7 -6
- package/dist/src/commands/rebase/abort.js +6 -6
- package/dist/src/commands/rebase/continue.js +8 -7
- package/dist/src/commands/rebase/index.d.ts +1 -1
- package/dist/src/commands/rebase/index.js +3 -3
- package/dist/src/commands/rebase/patch-loop.js +18 -17
- package/dist/src/commands/register.js +5 -5
- package/dist/src/commands/reset.js +1 -1
- package/dist/src/commands/resolve.d.ts +2 -2
- package/dist/src/commands/resolve.js +3 -3
- package/dist/src/commands/run.js +26 -26
- package/dist/src/commands/setup-support.js +4 -4
- package/dist/src/commands/setup.js +1 -1
- package/dist/src/commands/source.js +1 -1
- package/dist/src/commands/status-check.d.ts +3 -3
- package/dist/src/commands/status-check.js +4 -4
- package/dist/src/commands/status-json.d.ts +14 -13
- package/dist/src/commands/status-json.js +9 -8
- package/dist/src/commands/status-output.d.ts +3 -3
- package/dist/src/commands/status-output.js +3 -3
- package/dist/src/commands/status-ownership.d.ts +3 -3
- package/dist/src/commands/status-ownership.js +3 -3
- package/dist/src/commands/status.js +22 -22
- package/dist/src/commands/test-build-phase.d.ts +1 -1
- package/dist/src/commands/test-build-phase.js +17 -17
- package/dist/src/commands/test-diagnose.d.ts +1 -1
- package/dist/src/commands/test-diagnose.js +20 -20
- package/dist/src/commands/test-modes.d.ts +2 -2
- package/dist/src/commands/test-modes.js +4 -4
- package/dist/src/commands/test-run.d.ts +11 -11
- package/dist/src/commands/test-run.js +15 -15
- package/dist/src/commands/test-stale-gate.d.ts +12 -12
- package/dist/src/commands/test-stale-gate.js +13 -13
- package/dist/src/commands/test-verdict.d.ts +6 -6
- package/dist/src/commands/test-verdict.js +11 -11
- package/dist/src/commands/test.d.ts +3 -3
- package/dist/src/commands/test.js +36 -36
- package/dist/src/commands/token-coverage.js +3 -3
- package/dist/src/commands/token-list.js +5 -5
- package/dist/src/commands/token.js +9 -9
- package/dist/src/commands/tree.js +19 -19
- package/dist/src/commands/typecheck.d.ts +6 -6
- package/dist/src/commands/typecheck.js +7 -7
- package/dist/src/commands/verify.d.ts +3 -3
- package/dist/src/commands/verify.js +10 -10
- package/dist/src/commands/watch.js +11 -11
- package/dist/src/commands/wire.js +13 -13
- package/dist/src/core/ast-utils.d.ts +7 -7
- package/dist/src/core/ast-utils.js +8 -8
- package/dist/src/core/branding.d.ts +5 -5
- package/dist/src/core/branding.js +3 -3
- package/dist/src/core/browser-wire.d.ts +1 -1
- package/dist/src/core/browser-wire.js +4 -4
- package/dist/src/core/build-audit-platform.d.ts +6 -6
- package/dist/src/core/build-audit-platform.js +26 -26
- package/dist/src/core/build-audit-registration.d.ts +5 -5
- package/dist/src/core/build-audit-registration.js +7 -7
- package/dist/src/core/build-audit-resolve.d.ts +5 -5
- package/dist/src/core/build-audit-resolve.js +6 -6
- package/dist/src/core/build-audit-skip.d.ts +8 -8
- package/dist/src/core/build-audit-skip.js +12 -12
- package/dist/src/core/build-audit-transforms.d.ts +2 -2
- package/dist/src/core/build-audit-transforms.js +3 -3
- package/dist/src/core/build-audit.d.ts +8 -8
- package/dist/src/core/build-audit.js +39 -37
- package/dist/src/core/build-baseline-types.d.ts +19 -18
- package/dist/src/core/build-baseline-types.js +1 -1
- package/dist/src/core/build-baseline.d.ts +8 -8
- package/dist/src/core/build-baseline.js +14 -14
- package/dist/src/core/build-jar-escalation.d.ts +8 -8
- package/dist/src/core/build-jar-escalation.js +15 -15
- package/dist/src/core/build-overwrite-guard.d.ts +4 -4
- package/dist/src/core/build-overwrite-guard.js +13 -13
- package/dist/src/core/build-prepare.d.ts +4 -4
- package/dist/src/core/build-prepare.js +16 -15
- package/dist/src/core/config-mutate.js +4 -4
- package/dist/src/core/config-state.js +2 -2
- package/dist/src/core/config-validate-build-audit.js +3 -3
- package/dist/src/core/config-validate-file-size.d.ts +1 -1
- package/dist/src/core/config-validate-file-size.js +2 -2
- package/dist/src/core/config-validate.js +8 -9
- package/dist/src/core/config.d.ts +10 -10
- package/dist/src/core/config.js +10 -10
- package/dist/src/core/coverage-extend.d.ts +16 -16
- package/dist/src/core/coverage-extend.js +16 -16
- package/dist/src/core/destructive.d.ts +14 -14
- package/dist/src/core/destructive.js +9 -9
- package/dist/src/core/diff-hunks.d.ts +2 -2
- package/dist/src/core/diff-hunks.js +7 -7
- package/dist/src/core/discard-baseline.d.ts +10 -10
- package/dist/src/core/discard-baseline.js +15 -16
- package/dist/src/core/display-state.d.ts +11 -11
- package/dist/src/core/display-state.js +12 -12
- package/dist/src/core/engine-changes.d.ts +2 -2
- package/dist/src/core/engine-changes.js +2 -2
- package/dist/src/core/engine-precondition.d.ts +4 -4
- package/dist/src/core/engine-precondition.js +2 -2
- package/dist/src/core/engine-session-lock.d.ts +18 -18
- package/dist/src/core/engine-session-lock.js +37 -37
- package/dist/src/core/export-moved-code-shape.d.ts +7 -7
- package/dist/src/core/export-moved-code-shape.js +8 -8
- package/dist/src/core/file-lock-owner.d.ts +11 -11
- package/dist/src/core/file-lock-owner.js +18 -18
- package/dist/src/core/file-lock.d.ts +12 -12
- package/dist/src/core/file-lock.js +52 -39
- package/dist/src/core/firefox-cache.d.ts +1 -1
- package/dist/src/core/firefox-cache.js +10 -10
- package/dist/src/core/firefox-download.d.ts +3 -3
- package/dist/src/core/firefox-download.js +6 -6
- package/dist/src/core/firefox-extract.d.ts +2 -2
- package/dist/src/core/firefox-extract.js +13 -13
- package/dist/src/core/firefox.d.ts +5 -5
- package/dist/src/core/firefox.js +8 -8
- package/dist/src/core/furnace-apply-dry-run.js +1 -1
- package/dist/src/core/furnace-apply-ftl.d.ts +5 -5
- package/dist/src/core/furnace-apply-ftl.js +8 -8
- package/dist/src/core/furnace-apply-helpers.d.ts +9 -9
- package/dist/src/core/furnace-apply-helpers.js +21 -21
- package/dist/src/core/furnace-apply-output.js +1 -1
- package/dist/src/core/furnace-apply-overwrite-warn.d.ts +9 -9
- package/dist/src/core/furnace-apply-overwrite-warn.js +9 -9
- package/dist/src/core/furnace-apply-undeploy-actions.d.ts +1 -1
- package/dist/src/core/furnace-apply-undeploy-actions.js +1 -1
- package/dist/src/core/furnace-apply.d.ts +3 -3
- package/dist/src/core/furnace-apply.js +22 -21
- package/dist/src/core/furnace-checksum-utils.d.ts +5 -5
- package/dist/src/core/furnace-checksum-utils.js +5 -5
- package/dist/src/core/furnace-config-custom.d.ts +1 -1
- package/dist/src/core/furnace-config-custom.js +2 -2
- package/dist/src/core/furnace-config-order.js +1 -1
- package/dist/src/core/furnace-config-tokens.d.ts +3 -3
- package/dist/src/core/furnace-config-tokens.js +3 -3
- package/dist/src/core/furnace-config-validate.js +2 -2
- package/dist/src/core/furnace-config.d.ts +4 -4
- package/dist/src/core/furnace-config.js +18 -18
- package/dist/src/core/furnace-constants.d.ts +6 -6
- package/dist/src/core/furnace-constants.js +6 -6
- package/dist/src/core/furnace-css-fragments.d.ts +6 -6
- package/dist/src/core/furnace-css-fragments.js +11 -11
- package/dist/src/core/furnace-dir-entry.d.ts +1 -1
- package/dist/src/core/furnace-dir-entry.js +1 -1
- package/dist/src/core/furnace-jsconfig.d.ts +7 -7
- package/dist/src/core/furnace-jsconfig.js +22 -20
- package/dist/src/core/furnace-operation.d.ts +21 -20
- package/dist/src/core/furnace-operation.js +36 -34
- package/dist/src/core/furnace-precondition.d.ts +10 -10
- package/dist/src/core/furnace-precondition.js +8 -8
- package/dist/src/core/furnace-refresh.js +2 -2
- package/dist/src/core/furnace-registration-ast.d.ts +2 -2
- package/dist/src/core/furnace-registration-ast.js +9 -9
- package/dist/src/core/furnace-registration-remove.d.ts +4 -4
- package/dist/src/core/furnace-registration-remove.js +6 -6
- package/dist/src/core/furnace-registration-validate.d.ts +2 -2
- package/dist/src/core/furnace-registration-validate.js +2 -2
- package/dist/src/core/furnace-registration.d.ts +5 -5
- package/dist/src/core/furnace-registration.js +7 -7
- package/dist/src/core/furnace-rollback.d.ts +1 -1
- package/dist/src/core/furnace-rollback.js +5 -5
- package/dist/src/core/furnace-stale-export.d.ts +17 -16
- package/dist/src/core/furnace-stale-export.js +16 -15
- package/dist/src/core/furnace-staleness.d.ts +2 -2
- package/dist/src/core/furnace-staleness.js +2 -2
- package/dist/src/core/furnace-state-persist.d.ts +10 -10
- package/dist/src/core/furnace-state-persist.js +10 -10
- package/dist/src/core/furnace-step-errors.d.ts +6 -6
- package/dist/src/core/furnace-step-errors.js +6 -6
- package/dist/src/core/furnace-validate-accessibility.js +14 -14
- package/dist/src/core/furnace-validate-compatibility.js +9 -9
- package/dist/src/core/furnace-validate-registration.d.ts +2 -2
- package/dist/src/core/furnace-validate-registration.js +13 -13
- package/dist/src/core/furnace-validate-structure.d.ts +1 -1
- package/dist/src/core/furnace-validate-structure.js +4 -4
- package/dist/src/core/furnace-validate.js +9 -9
- package/dist/src/core/furnace-version-drift.d.ts +5 -5
- package/dist/src/core/furnace-version-drift.js +5 -5
- package/dist/src/core/git-base.d.ts +4 -4
- package/dist/src/core/git-base.js +9 -9
- package/dist/src/core/git-diff-new-file.d.ts +4 -4
- package/dist/src/core/git-diff-new-file.js +8 -8
- package/dist/src/core/git-diff.d.ts +4 -4
- package/dist/src/core/git-diff.js +35 -34
- package/dist/src/core/git-file-ops.d.ts +6 -6
- package/dist/src/core/git-file-ops.js +7 -7
- package/dist/src/core/git-readonly-index.d.ts +12 -12
- package/dist/src/core/git-readonly-index.js +12 -12
- package/dist/src/core/git-status.d.ts +4 -4
- package/dist/src/core/git-status.js +4 -4
- package/dist/src/core/git.d.ts +3 -3
- package/dist/src/core/git.js +14 -14
- package/dist/src/core/harness-orphans.d.ts +17 -17
- package/dist/src/core/harness-orphans.js +20 -20
- package/dist/src/core/history-log.d.ts +3 -3
- package/dist/src/core/history-log.js +3 -3
- package/dist/src/core/license-headers.d.ts +19 -18
- package/dist/src/core/license-headers.js +29 -28
- package/dist/src/core/mach-build-artifacts.d.ts +21 -21
- package/dist/src/core/mach-build-artifacts.js +23 -23
- package/dist/src/core/mach-error-hints.d.ts +5 -5
- package/dist/src/core/mach-error-hints.js +13 -13
- package/dist/src/core/mach-known-noise-filter.d.ts +41 -38
- package/dist/src/core/mach-known-noise-filter.js +53 -50
- package/dist/src/core/mach-mozconfig.d.ts +6 -6
- package/dist/src/core/mach-mozconfig.js +15 -15
- package/dist/src/core/mach-python.d.ts +2 -1
- package/dist/src/core/mach-python.js +4 -3
- package/dist/src/core/mach-resource-shim.d.ts +12 -12
- package/dist/src/core/mach-resource-shim.js +20 -20
- package/dist/src/core/mach.d.ts +23 -23
- package/dist/src/core/mach.js +36 -36
- package/dist/src/core/marionette-port.d.ts +15 -13
- package/dist/src/core/marionette-port.js +34 -31
- package/dist/src/core/marionette-preflight.d.ts +6 -6
- package/dist/src/core/marionette-preflight.js +23 -23
- package/dist/src/core/markdown-table.d.ts +9 -9
- package/dist/src/core/markdown-table.js +14 -14
- package/dist/src/core/mochitest-server-port.d.ts +8 -8
- package/dist/src/core/mochitest-server-port.js +14 -14
- package/dist/src/core/module-resolution-preflight.d.ts +8 -8
- package/dist/src/core/module-resolution-preflight.js +11 -11
- package/dist/src/core/moz-manifest-helpers.d.ts +7 -7
- package/dist/src/core/moz-manifest-helpers.js +7 -7
- package/dist/src/core/moz-manifest-register.d.ts +1 -1
- package/dist/src/core/moz-manifest-register.js +2 -2
- package/dist/src/core/moz-manifest-rules.js +11 -11
- package/dist/src/core/moz-manifest-tokenizers.js +1 -1
- package/dist/src/core/ownership-table.d.ts +5 -5
- package/dist/src/core/ownership-table.js +7 -7
- package/dist/src/core/parser-fallback.d.ts +3 -3
- package/dist/src/core/parser-fallback.js +3 -3
- package/dist/src/core/patch-apply-fuzz.d.ts +5 -5
- package/dist/src/core/patch-apply-fuzz.js +9 -9
- package/dist/src/core/patch-apply.d.ts +9 -9
- package/dist/src/core/patch-apply.js +30 -30
- package/dist/src/core/patch-export-update.d.ts +4 -4
- package/dist/src/core/patch-export-update.js +3 -3
- package/dist/src/core/patch-export.d.ts +10 -10
- package/dist/src/core/patch-export.js +13 -13
- package/dist/src/core/patch-identifier-suggest.d.ts +1 -1
- package/dist/src/core/patch-identifier-suggest.js +4 -4
- package/dist/src/core/patch-lint-binary.d.ts +7 -7
- package/dist/src/core/patch-lint-cache.d.ts +2 -2
- package/dist/src/core/patch-lint-cache.js +13 -13
- package/dist/src/core/patch-lint-checkjs.d.ts +26 -26
- package/dist/src/core/patch-lint-checkjs.js +42 -41
- package/dist/src/core/patch-lint-chrome-jsdoc.d.ts +8 -9
- package/dist/src/core/patch-lint-chrome-jsdoc.js +10 -11
- package/dist/src/core/patch-lint-creators.d.ts +3 -3
- package/dist/src/core/patch-lint-creators.js +3 -3
- package/dist/src/core/patch-lint-cross.d.ts +13 -13
- package/dist/src/core/patch-lint-cross.js +21 -21
- package/dist/src/core/patch-lint-css.d.ts +1 -1
- package/dist/src/core/patch-lint-css.js +5 -5
- package/dist/src/core/patch-lint-diff-tag.d.ts +5 -5
- package/dist/src/core/patch-lint-diff-tag.js +5 -5
- package/dist/src/core/patch-lint-diff.d.ts +4 -4
- package/dist/src/core/patch-lint-diff.js +4 -4
- package/dist/src/core/patch-lint-file-size.d.ts +3 -3
- package/dist/src/core/patch-lint-file-size.js +3 -3
- package/dist/src/core/patch-lint-forward-registration.d.ts +4 -4
- package/dist/src/core/patch-lint-forward-registration.js +12 -12
- package/dist/src/core/patch-lint-jsdoc.d.ts +2 -2
- package/dist/src/core/patch-lint-jsdoc.js +11 -11
- package/dist/src/core/patch-lint-module-registration.d.ts +1 -1
- package/dist/src/core/patch-lint-module-registration.js +1 -1
- package/dist/src/core/patch-lint-mozbuild.d.ts +1 -1
- package/dist/src/core/patch-lint-mozbuild.js +10 -10
- package/dist/src/core/patch-lint-observer.d.ts +3 -3
- package/dist/src/core/patch-lint-observer.js +7 -7
- package/dist/src/core/patch-lint-ownership.d.ts +6 -6
- package/dist/src/core/patch-lint-ownership.js +6 -6
- package/dist/src/core/patch-lint-prettier.d.ts +6 -6
- package/dist/src/core/patch-lint-prettier.js +6 -6
- package/dist/src/core/patch-lint-queue-types.d.ts +1 -1
- package/dist/src/core/patch-lint-queue-types.js +1 -1
- package/dist/src/core/patch-lint-staged-registration.d.ts +2 -2
- package/dist/src/core/patch-lint-staged-registration.js +6 -6
- package/dist/src/core/patch-lint-unmanaged-companion.d.ts +23 -23
- package/dist/src/core/patch-lint-unmanaged-companion.js +26 -26
- package/dist/src/core/patch-lint.d.ts +27 -26
- package/dist/src/core/patch-lint.js +48 -46
- package/dist/src/core/patch-lock.d.ts +1 -1
- package/dist/src/core/patch-lock.js +8 -8
- package/dist/src/core/patch-manifest-consistency.d.ts +7 -7
- package/dist/src/core/patch-manifest-consistency.js +16 -17
- package/dist/src/core/patch-manifest-files-affected.d.ts +1 -1
- package/dist/src/core/patch-manifest-files-affected.js +3 -3
- package/dist/src/core/patch-manifest-io.d.ts +14 -14
- package/dist/src/core/patch-manifest-io.js +27 -27
- package/dist/src/core/patch-manifest-query.d.ts +1 -1
- package/dist/src/core/patch-manifest-query.js +4 -4
- package/dist/src/core/patch-manifest-resolve.d.ts +5 -5
- package/dist/src/core/patch-manifest-resolve.js +7 -7
- package/dist/src/core/patch-manifest-validate.js +3 -3
- package/dist/src/core/patch-manifest.d.ts +2 -2
- package/dist/src/core/patch-manifest.js +2 -2
- package/dist/src/core/patch-parse.d.ts +14 -14
- package/dist/src/core/patch-parse.js +16 -16
- package/dist/src/core/patch-registration-refs.d.ts +4 -4
- package/dist/src/core/patch-registration-refs.js +7 -7
- package/dist/src/core/patch-transform.d.ts +8 -8
- package/dist/src/core/patch-transform.js +13 -13
- package/dist/src/core/process-cpu-time.d.ts +1 -1
- package/dist/src/core/process-cpu-time.js +5 -5
- package/dist/src/core/rebase-session.d.ts +7 -7
- package/dist/src/core/rebase-session.js +8 -8
- package/dist/src/core/register-result.d.ts +1 -1
- package/dist/src/core/register-result.js +1 -1
- package/dist/src/core/register-scaffold.d.ts +2 -2
- package/dist/src/core/register-scaffold.js +3 -3
- package/dist/src/core/register-shared-css.d.ts +3 -3
- package/dist/src/core/register-shared-css.js +4 -4
- package/dist/src/core/register-xpcshell-test.d.ts +2 -2
- package/dist/src/core/register-xpcshell-test.js +2 -2
- package/dist/src/core/run-log-redact.d.ts +12 -12
- package/dist/src/core/run-log-redact.js +16 -16
- package/dist/src/core/run-log.d.ts +9 -9
- package/dist/src/core/run-log.js +14 -14
- package/dist/src/core/shared-ftl.d.ts +2 -2
- package/dist/src/core/shared-ftl.js +6 -6
- package/dist/src/core/signal-critical.d.ts +2 -2
- package/dist/src/core/signal-critical.js +2 -2
- package/dist/src/core/smoke-patterns.d.ts +5 -5
- package/dist/src/core/smoke-patterns.js +9 -9
- package/dist/src/core/state-file.d.ts +3 -3
- package/dist/src/core/status-binary.d.ts +8 -8
- package/dist/src/core/status-binary.js +12 -12
- package/dist/src/core/status-classify.d.ts +17 -17
- package/dist/src/core/status-classify.js +11 -11
- package/dist/src/core/test-changed-prefs.d.ts +12 -12
- package/dist/src/core/test-changed-prefs.js +15 -15
- package/dist/src/core/test-harness-crash.d.ts +39 -39
- package/dist/src/core/test-harness-crash.js +67 -67
- package/dist/src/core/test-harness-output.d.ts +7 -7
- package/dist/src/core/test-harness-output.js +7 -7
- package/dist/src/core/test-harness-verdict-notes.d.ts +13 -14
- package/dist/src/core/test-harness-verdict-notes.js +4 -4
- package/dist/src/core/test-path-scope.d.ts +8 -8
- package/dist/src/core/test-path-scope.js +11 -11
- package/dist/src/core/test-stale-check.d.ts +22 -21
- package/dist/src/core/test-stale-check.js +29 -28
- package/dist/src/core/test-stale-symlink.d.ts +1 -1
- package/dist/src/core/test-stale-symlink.js +1 -1
- package/dist/src/core/test-stall-triage.d.ts +9 -9
- package/dist/src/core/test-stall-triage.js +22 -22
- package/dist/src/core/token-category.d.ts +4 -4
- package/dist/src/core/token-category.js +13 -12
- package/dist/src/core/token-coverage.js +4 -5
- package/dist/src/core/token-dark-mode.d.ts +17 -9
- package/dist/src/core/token-dark-mode.js +41 -28
- package/dist/src/core/token-docs.d.ts +1 -1
- package/dist/src/core/token-inventory.d.ts +6 -6
- package/dist/src/core/token-inventory.js +7 -7
- package/dist/src/core/token-manager.d.ts +3 -3
- package/dist/src/core/token-manager.js +21 -21
- package/dist/src/core/token-scaffold.d.ts +4 -4
- package/dist/src/core/token-scaffold.js +4 -4
- package/dist/src/core/token-variant.d.ts +14 -14
- package/dist/src/core/token-variant.js +32 -32
- package/dist/src/core/toolchain-preflight.d.ts +15 -15
- package/dist/src/core/toolchain-preflight.js +22 -22
- package/dist/src/core/tree-cow.d.ts +3 -3
- package/dist/src/core/tree-cow.js +6 -6
- package/dist/src/core/tree-guard.d.ts +3 -3
- package/dist/src/core/tree-guard.js +23 -23
- package/dist/src/core/tree-store.d.ts +15 -15
- package/dist/src/core/tree-store.js +35 -33
- package/dist/src/core/typecheck-shim.d.ts +16 -15
- package/dist/src/core/typecheck-shim.js +26 -25
- package/dist/src/core/typecheck.d.ts +12 -12
- package/dist/src/core/typecheck.js +31 -31
- package/dist/src/core/wire-destroy.d.ts +2 -2
- package/dist/src/core/wire-destroy.js +5 -5
- package/dist/src/core/wire-dom-fragment.d.ts +3 -3
- package/dist/src/core/wire-dom-fragment.js +6 -6
- package/dist/src/core/wire-init.d.ts +2 -2
- package/dist/src/core/wire-init.js +7 -7
- package/dist/src/core/wire-subscript.d.ts +1 -1
- package/dist/src/core/wire-subscript.js +3 -3
- package/dist/src/core/wire-utils.d.ts +9 -9
- package/dist/src/core/wire-utils.js +11 -11
- package/dist/src/core/xpcshell-appdir.d.ts +20 -20
- package/dist/src/core/xpcshell-appdir.js +26 -26
- package/dist/src/core/xpcshell-profile-dir.d.ts +3 -3
- package/dist/src/core/xpcshell-profile-dir.js +7 -7
- package/dist/src/errors/base.d.ts +22 -21
- package/dist/src/errors/base.js +22 -21
- package/dist/src/errors/build.d.ts +6 -6
- package/dist/src/errors/build.js +6 -6
- package/dist/src/errors/codes.d.ts +10 -10
- package/dist/src/errors/codes.js +10 -10
- package/dist/src/errors/furnace.d.ts +2 -2
- package/dist/src/errors/git.d.ts +1 -1
- package/dist/src/errors/git.js +1 -1
- package/dist/src/errors/patch.d.ts +3 -3
- package/dist/src/errors/patch.js +3 -3
- package/dist/src/errors/rebase.d.ts +1 -1
- package/dist/src/errors/rebase.js +1 -1
- package/dist/src/errors/run.d.ts +1 -1
- package/dist/src/errors/run.js +1 -1
- package/dist/src/index.d.ts +4 -4
- package/dist/src/index.js +4 -4
- package/dist/src/types/commands/options.d.ts +86 -85
- package/dist/src/types/commands/patches.d.ts +19 -19
- package/dist/src/types/commands/project.d.ts +3 -3
- package/dist/src/types/config.d.ts +24 -23
- package/dist/src/types/furnace.d.ts +17 -17
- package/dist/src/types/json.d.ts +3 -3
- package/dist/src/types/json.js +2 -2
- package/dist/src/types/typecheck.d.ts +3 -3
- package/dist/src/utils/assert.d.ts +1 -1
- package/dist/src/utils/assert.js +6 -6
- package/dist/src/utils/build-info.d.ts +5 -5
- package/dist/src/utils/build-info.js +6 -6
- package/dist/src/utils/child-env.d.ts +5 -5
- package/dist/src/utils/child-env.js +5 -5
- package/dist/src/utils/concurrency.d.ts +2 -2
- package/dist/src/utils/concurrency.js +2 -2
- package/dist/src/utils/elapsed.js +1 -1
- package/dist/src/utils/errors.d.ts +8 -8
- package/dist/src/utils/errors.js +8 -8
- package/dist/src/utils/fs.d.ts +1 -1
- package/dist/src/utils/fs.js +8 -8
- package/dist/src/utils/line-dispatch.d.ts +3 -3
- package/dist/src/utils/line-dispatch.js +5 -5
- package/dist/src/utils/logger.d.ts +4 -4
- package/dist/src/utils/logger.js +11 -11
- package/dist/src/utils/machine-output.js +2 -2
- package/dist/src/utils/options.d.ts +13 -13
- package/dist/src/utils/options.js +20 -20
- package/dist/src/utils/package-root.js +2 -2
- package/dist/src/utils/paths.d.ts +4 -4
- package/dist/src/utils/paths.js +4 -4
- package/dist/src/utils/process-group.d.ts +8 -8
- package/dist/src/utils/process-group.js +19 -19
- package/dist/src/utils/process.d.ts +34 -33
- package/dist/src/utils/process.js +20 -19
- package/dist/src/utils/ps-duration.d.ts +4 -4
- package/dist/src/utils/ps-duration.js +6 -6
- package/dist/src/utils/regex.d.ts +4 -4
- package/dist/src/utils/regex.js +7 -7
- package/dist/src/utils/sleep.d.ts +7 -7
- package/dist/src/utils/sleep.js +7 -7
- package/dist/src/utils/stdio-drain.d.ts +7 -7
- package/dist/src/utils/stdio-drain.js +8 -8
- package/dist/src/utils/validation.d.ts +11 -12
- package/dist/src/utils/validation.js +20 -21
- package/docs/README.md +2 -2
- package/docs/configuration.md +120 -114
- package/docs/exit-codes.md +63 -58
- package/docs/furnace.md +20 -19
- package/docs/lifecycle-invariants.md +412 -251
- package/docs/machine-output.md +33 -32
- package/docs/patch-workflow.md +48 -45
- package/docs/run-logs.md +62 -58
- package/docs/testing.md +101 -101
- package/docs/verification-trees.md +23 -22
- package/package.json +2 -2
|
@@ -16,7 +16,7 @@ import { getUntrackedFiles, getUntrackedFilesInDir } from './git-status.js';
|
|
|
16
16
|
* `--binary` is load-bearing: without it git degrades a binary file's section
|
|
17
17
|
* to the informational `Binary files a/x and b/x differ`, which carries none
|
|
18
18
|
* of the bytes and cannot be replayed by `git apply`. It only expands the
|
|
19
|
-
*
|
|
19
|
+
* binary section's index line to full hashes (text sections keep their
|
|
20
20
|
* abbreviated form), so text output stays byte-identical.
|
|
21
21
|
* @param repoDir - Repository directory
|
|
22
22
|
* @param filePath - Path to the file (relative to repo)
|
|
@@ -42,7 +42,7 @@ function abbreviateBlobHash(fullHash) {
|
|
|
42
42
|
/**
|
|
43
43
|
* Pure formatter for a new (untracked) file's unified diff. Shared by the
|
|
44
44
|
* batched cold-run path in {@link getDiffForFilesAgainstHead} and the
|
|
45
|
-
* standalone {@link generateNewFileDiff}
|
|
45
|
+
* standalone {@link generateNewFileDiff}. The only thing that differs is
|
|
46
46
|
* where `blobHash` comes from (a single batched `git hash-object` vs a
|
|
47
47
|
* per-file one), never the formatting. Preserves the empty-file form, the
|
|
48
48
|
* trailing-newline handling, and the "No newline at end of file" marker
|
|
@@ -151,9 +151,9 @@ export async function generateFullFilePatch(repoDir, filePath) {
|
|
|
151
151
|
/**
|
|
152
152
|
* Gets the diff for all modified files, including untracked (new) files.
|
|
153
153
|
*
|
|
154
|
-
* Tracked binary files round-trip through `git diff --binary
|
|
154
|
+
* Tracked binary files round-trip through `git diff --binary`. Untracked ones
|
|
155
155
|
* go through {@link generateBinaryFilePatch} below. Both arms must stay
|
|
156
|
-
* binary-aware
|
|
156
|
+
* binary-aware. See {@link getFileDiff} for why.
|
|
157
157
|
* @param repoDir - Repository directory
|
|
158
158
|
* @returns Diff content
|
|
159
159
|
*/
|
|
@@ -164,8 +164,8 @@ export async function getAllDiff(repoDir) {
|
|
|
164
164
|
const untrackedFiles = await getUntrackedFiles(repoDir);
|
|
165
165
|
// Classify first. `readNewFileContent` reads the file directly and spawns
|
|
166
166
|
// nothing, so the only per-file process in this loop would be the
|
|
167
|
-
// `git hash-object` inside `generateNewFileDiff
|
|
168
|
-
//
|
|
167
|
+
// `git hash-object` inside `generateNewFileDiff`: one spawn per untracked
|
|
168
|
+
// text file, uncapped, against a Firefox tree where "untracked" can mean a
|
|
169
169
|
// very large number. Hence classify → one batched hash → render. The
|
|
170
170
|
// classification carries each text file's content so it is read once.
|
|
171
171
|
//
|
|
@@ -183,7 +183,7 @@ export async function getAllDiff(repoDir) {
|
|
|
183
183
|
const textHashes = await hashObjectBatch(repoDir, untrackedFiles
|
|
184
184
|
.filter((file) => classified.get(file)?.binary === false)
|
|
185
185
|
.map((file) => join(repoDir, file)));
|
|
186
|
-
// Binary patches stage into the index and must stay serial
|
|
186
|
+
// Binary patches stage into the index and must stay serial. Text patches
|
|
187
187
|
// are pure formatting over the already-batched hashes.
|
|
188
188
|
const binaryDiffs = new Map();
|
|
189
189
|
for (const file of untrackedFiles) {
|
|
@@ -203,7 +203,7 @@ export async function getAllDiff(repoDir) {
|
|
|
203
203
|
const fullPath = join(repoDir, file);
|
|
204
204
|
untrackedDiffs.push(buildNewFileDiffBody(file, entry.content, abbreviateBlobHash(textHashes.get(fullPath))));
|
|
205
205
|
}
|
|
206
|
-
// Combine all diffs
|
|
206
|
+
// Combine all diffs. Each already ends with \n, so concatenate directly
|
|
207
207
|
// to avoid inserting blank lines between diff sections.
|
|
208
208
|
const allDiffs = [trackedDiff, ...untrackedDiffs].filter((d) => d.trim().length > 0);
|
|
209
209
|
const combined = allDiffs.join('');
|
|
@@ -215,8 +215,8 @@ export async function getAllDiff(repoDir) {
|
|
|
215
215
|
* to (but not including) the next such line. Boundary detection is anchored to
|
|
216
216
|
* column 0 because every diff *body* line is prefixed by a space, `+`, `-`,
|
|
217
217
|
* `\`, or `@`, so a context or added line that merely contains the text
|
|
218
|
-
* `diff --git` can never be mistaken for a header. Paths are
|
|
219
|
-
*
|
|
218
|
+
* `diff --git` can never be mistaken for a header. Paths are not parsed out
|
|
219
|
+
* of the header here on purpose. See {@link buildTrackedSections}.
|
|
220
220
|
* @param combined - Combined `git diff` stdout
|
|
221
221
|
* @returns File sections in git's emission order
|
|
222
222
|
*/
|
|
@@ -243,18 +243,18 @@ function splitDiffSections(combined) {
|
|
|
243
243
|
*
|
|
244
244
|
* `--binary` is load-bearing: a tracked binary file would otherwise degrade to
|
|
245
245
|
* the un-appliable `Binary files a/x and b/x differ` stub. It expands only the
|
|
246
|
-
* binary section's index line to full hashes, so text sections are
|
|
247
|
-
*
|
|
246
|
+
* binary section's index line to full hashes, so text sections are
|
|
247
|
+
* unaffected. See {@link getFileDiff}.
|
|
248
248
|
*
|
|
249
249
|
* `--no-renames` is load-bearing: a multi-path diff under a user's
|
|
250
250
|
* `diff.renames=true`/`=copies` could otherwise emit a single 2-path rename
|
|
251
251
|
* section (`a/<old> b/<new>`) that a single-path `git diff HEAD -- <file>` can
|
|
252
|
-
* never produce
|
|
252
|
+
* never produce. `--no-renames` re-splits it into the same delete + add bytes
|
|
253
253
|
* the per-file loop emitted.
|
|
254
254
|
*
|
|
255
|
-
* Sections are attributed to paths by
|
|
255
|
+
* Sections are attributed to paths by position against a companion
|
|
256
256
|
* `git diff --no-renames HEAD -z --name-only` (raw, unquoted, NUL-delimited
|
|
257
|
-
* paths, emitted in the same order as the sections)
|
|
257
|
+
* paths, emitted in the same order as the sections), never by parsing the
|
|
258
258
|
* `diff --git` header, which is ambiguous or unparseable under `core.quotePath`
|
|
259
259
|
* (non-ASCII paths are C-quoted), paths containing spaces, or
|
|
260
260
|
* `diff.noprefix`/`diff.mnemonicPrefix`. If the section and name counts ever
|
|
@@ -273,14 +273,14 @@ async function buildTrackedSections(repoDir, trackedFiles) {
|
|
|
273
273
|
const sections = splitDiffSections(combined);
|
|
274
274
|
if (sections.length === names.length) {
|
|
275
275
|
for (let i = 0; i < names.length; i++) {
|
|
276
|
-
// Exact-path keys (raw git bytes, same encoding as the inputs)
|
|
276
|
+
// Exact-path keys (raw git bytes, same encoding as the inputs), never
|
|
277
277
|
// a substring/startsWith match, so `foo.txt` cannot capture
|
|
278
278
|
// `foo.txt.bak`'s section.
|
|
279
279
|
sectionsByPath.set(names[i], sections[i]);
|
|
280
280
|
}
|
|
281
281
|
continue;
|
|
282
282
|
}
|
|
283
|
-
// Counts disagree
|
|
283
|
+
// Counts disagree, so recover the exact pre-batch per-file bytes for this
|
|
284
284
|
// chunk rather than risk dropping or mis-keying a section.
|
|
285
285
|
for (const file of chunk) {
|
|
286
286
|
const diff = await getFileDiff(repoDir, file);
|
|
@@ -293,7 +293,7 @@ async function buildTrackedSections(repoDir, trackedFiles) {
|
|
|
293
293
|
/**
|
|
294
294
|
* Builds a combined diff against HEAD for the provided files without touching
|
|
295
295
|
* the real git index. Tracked files use `git diff --binary HEAD` (binary
|
|
296
|
-
* sections included)
|
|
296
|
+
* sections included). Untracked files use synthesized new-file diffs, or
|
|
297
297
|
* {@link generateBinaryFilePatch} when the file is binary.
|
|
298
298
|
*
|
|
299
299
|
* Performance: the work is batched into a handful of `git` invocations (one
|
|
@@ -314,7 +314,7 @@ export async function getDiffForFilesAgainstHead(repoDir, files) {
|
|
|
314
314
|
// that feeds the aggregate working-tree state into this function must not
|
|
315
315
|
// trigger an EISDIR when the diff pass reads `dir/` as if it were a file.
|
|
316
316
|
// The caller-side expansion in `lint.ts` and `export-all.ts` covers the
|
|
317
|
-
// common path
|
|
317
|
+
// common path. Guarding here makes a single bad call site harmless.
|
|
318
318
|
const expandedFiles = [];
|
|
319
319
|
for (const file of files) {
|
|
320
320
|
if (file.endsWith('/')) {
|
|
@@ -336,7 +336,7 @@ export async function getDiffForFilesAgainstHead(repoDir, files) {
|
|
|
336
336
|
const trackedSections = await buildTrackedSections(repoDir, uniqueFiles.filter((file) => tracked.has(file)));
|
|
337
337
|
// Classify the non-tracked files. Directory and binary entries keep their
|
|
338
338
|
// per-file handling (rare, and binary patches mutate the index so they must
|
|
339
|
-
// stay serial)
|
|
339
|
+
// stay serial). Plain new text files are collected for a single batched
|
|
340
340
|
// `git hash-object`. Results land in `sectionByFile`, keyed by path, to be
|
|
341
341
|
// emitted in sorted order below.
|
|
342
342
|
const sectionByFile = new Map();
|
|
@@ -353,7 +353,7 @@ export async function getDiffForFilesAgainstHead(repoDir, files) {
|
|
|
353
353
|
// the trailing slash `expandUntrackedDirectoryEntries` would have
|
|
354
354
|
// produced (caller stripped it, submodule entry, tracked-file-replaced-
|
|
355
355
|
// by-dir). Expand it via the same helper used by the slash branch and
|
|
356
|
-
// recurse so each contained file is diffed individually
|
|
356
|
+
// recurse so each contained file is diffed individually. Fail loud when
|
|
357
357
|
// the directory has no readable content rather than silently skipping it.
|
|
358
358
|
const fileStat = await stat(fullPath);
|
|
359
359
|
if (fileStat.isDirectory()) {
|
|
@@ -366,8 +366,8 @@ export async function getDiffForFilesAgainstHead(repoDir, files) {
|
|
|
366
366
|
sectionByFile.set(file, innerDiff);
|
|
367
367
|
continue;
|
|
368
368
|
}
|
|
369
|
-
// Binary
|
|
370
|
-
// UTF-8
|
|
369
|
+
// Binary (by git's NUL heuristic or because the bytes are not valid
|
|
370
|
+
// UTF-8) takes the byte-faithful binary-patch arm.
|
|
371
371
|
const newFile = await readNewFileContent(repoDir, file);
|
|
372
372
|
if (newFile.binary) {
|
|
373
373
|
const diff = await generateBinaryFilePatch(repoDir, file);
|
|
@@ -390,7 +390,7 @@ export async function getDiffForFilesAgainstHead(repoDir, files) {
|
|
|
390
390
|
if (body.trim())
|
|
391
391
|
sectionByFile.set(file, body);
|
|
392
392
|
}
|
|
393
|
-
// Reassemble in the sorted `uniqueFiles` order
|
|
393
|
+
// Reassemble in the sorted `uniqueFiles` order, not git's section order,
|
|
394
394
|
// which uses git's own collation and diverges from JS `.sort()` for
|
|
395
395
|
// non-ASCII paths. Driving emission off `uniqueFiles` (as the previous
|
|
396
396
|
// per-file loop did) keeps the combined output byte-identical. Do not change
|
|
@@ -422,7 +422,7 @@ export async function getStagedDiffForFiles(repoDir, files) {
|
|
|
422
422
|
/**
|
|
423
423
|
* Serializes the index-mutating untracked-binary path. The bounded per-patch
|
|
424
424
|
* lint pool can call {@link getDiffForFilesAgainstHead} (and thus this) for
|
|
425
|
-
* several patches at once
|
|
425
|
+
* several patches at once. Two concurrent `git add --intent-to-add` / `git
|
|
426
426
|
* reset` sequences would collide on `.git/index.lock` (a hard failure) or
|
|
427
427
|
* interleave one file's stage with another's unstage. This process-level
|
|
428
428
|
* promise chain runs the staging sequences one at a time. Read-only callers
|
|
@@ -460,16 +460,16 @@ export async function generateBinaryFilePatch(repoDir, filePath) {
|
|
|
460
460
|
* @returns The binary diff string, or empty string if no diff
|
|
461
461
|
*/
|
|
462
462
|
async function generateBinaryFilePatchWithConfig(repoDir, filePath, gitConfigArgs) {
|
|
463
|
-
// Try tracked file diff first (read-only
|
|
463
|
+
// Try tracked file diff first (read-only, so no index lock needed)
|
|
464
464
|
const tracked = await git([...gitConfigArgs, 'diff', '--binary', 'HEAD', '--', filePath], repoDir);
|
|
465
465
|
if (tracked.trim())
|
|
466
466
|
return tracked;
|
|
467
467
|
// The diff for an untracked file has to come from an index entry, so one
|
|
468
|
-
// has to be written. Writing it to a
|
|
468
|
+
// has to be written. Writing it to a private index is what keeps that
|
|
469
469
|
// write invisible: the primary `.git/index` never moves, so a concurrent
|
|
470
470
|
// `fireforge test` fingerprinting `engine/` with `git status` cannot
|
|
471
471
|
// observe the transient `--intent-to-add` entry and void its own verdict
|
|
472
|
-
// on our bookkeeping. That was a real failure mode
|
|
472
|
+
// on our bookkeeping. That was a real failure mode: parallel gate lanes
|
|
473
473
|
// killed three runs with `FAIL reason=inconclusive` on branding PNGs
|
|
474
474
|
// flapping between `A` and `??`.
|
|
475
475
|
//
|
|
@@ -498,8 +498,8 @@ async function generateBinaryFilePatchWithConfig(repoDir, filePath, gitConfigArg
|
|
|
498
498
|
verbose(`Binary patch for ${filePath} is staging on the shared index (no private index).`);
|
|
499
499
|
return runWithBinaryStagingLock(async () => {
|
|
500
500
|
// Snapshot the path's exact index entry before touching it. A blanket
|
|
501
|
-
// `git reset HEAD -- <file>` cleanup restores the path to its HEAD state
|
|
502
|
-
//
|
|
501
|
+
// `git reset HEAD -- <file>` cleanup restores the path to its HEAD state.
|
|
502
|
+
// For a path absent from HEAD that means *removing* whatever entry the
|
|
503
503
|
// index carried, silently discarding any staged state that arrived
|
|
504
504
|
// between the read-only diff above and this staging block (a concurrent
|
|
505
505
|
// writer, or a staged-add whose worktree file was deleted). Restoring
|
|
@@ -517,11 +517,12 @@ async function generateBinaryFilePatchWithConfig(repoDir, filePath, gitConfigArg
|
|
|
517
517
|
/**
|
|
518
518
|
* Restores a path's index entry to a previously captured `ls-files --stage`
|
|
519
519
|
* snapshot after a temporary `--intent-to-add` staging. No prior entry means
|
|
520
|
-
* the temporary entry is dropped via `reset HEAD` (the path's HEAD state
|
|
521
|
-
* "absent"
|
|
520
|
+
* the temporary entry is dropped via `reset HEAD` (the path's HEAD state is
|
|
521
|
+
* "absent", and this branch only runs for files untracked in HEAD). A prior
|
|
522
522
|
* stage-0 entry is re-pointed at its recorded mode and blob. Unmerged entries
|
|
523
|
-
* (stages 1
|
|
524
|
-
* keeps the legacy reset-to-HEAD behavior rather than corrupting the
|
|
523
|
+
* (stages 1 to 3) cannot be rebuilt through `--cacheinfo`. That degenerate
|
|
524
|
+
* state keeps the legacy reset-to-HEAD behavior rather than corrupting the
|
|
525
|
+
* conflict.
|
|
525
526
|
* @param repoDir - Repository directory
|
|
526
527
|
* @param filePath - File path (relative to repo root)
|
|
527
528
|
* @param priorEntry - Raw `git ls-files --stage -- <file>` output from before staging
|
|
@@ -33,10 +33,10 @@ export declare function fileExistsInHead(repoDir: string, filePath: string): Pro
|
|
|
33
33
|
/**
|
|
34
34
|
* Batched equivalent of {@link fileExistsInHead}: returns the subset of
|
|
35
35
|
* `files` that are tracked in HEAD, using a single `git ls-tree` per ARG_MAX
|
|
36
|
-
* chunk instead of one spawn per file. This is the cold-run hot path
|
|
37
|
-
* Firefox-sized checkout has hundreds of affected files.
|
|
36
|
+
* chunk instead of one spawn per file. This is the cold-run hot path, and
|
|
37
|
+
* a Firefox-sized checkout has hundreds of affected files.
|
|
38
38
|
*
|
|
39
|
-
* `-r` lists nested blobs by full repo-relative path
|
|
39
|
+
* `-r` lists nested blobs by full repo-relative path. `--name-only -z` makes
|
|
40
40
|
* the output a trivial NUL-split with no quoting to undo. Membership in the
|
|
41
41
|
* returned Set is exactly `await fileExistsInHead(repoDir, file)` for any
|
|
42
42
|
* non-directory `file`. Throws (via {@link git}) when HEAD itself is
|
|
@@ -56,10 +56,10 @@ export declare function listTrackedInHead(repoDir: string, files: string[]): Pro
|
|
|
56
56
|
* Uses {@link import('../utils/process.js').exec} rather than {@link git}
|
|
57
57
|
* (which throws on a non-zero exit) because `git hash-object f1 f2 …` is
|
|
58
58
|
* all-or-nothing: it aborts at the first unreadable path and emits nothing
|
|
59
|
-
* for the rest. To keep the per-file contract
|
|
60
|
-
* only its own index line
|
|
59
|
+
* for the rest. To keep the per-file contract, where one bad path zeroes
|
|
60
|
+
* only its own index line, a chunk that does not return exactly one hash
|
|
61
61
|
* per input falls back to hashing that chunk's paths individually. A path
|
|
62
|
-
* that is still unhashable is left out of the map
|
|
62
|
+
* that is still unhashable is left out of the map. The caller applies the
|
|
63
63
|
* `0000000000` zero-hash fallback for any miss. Hashing stays in git rather
|
|
64
64
|
* than in-process so filters and `.gitattributes` are applied per path and
|
|
65
65
|
* the result cannot diverge under `core.autocrlf`/`text` attributes.
|
|
@@ -76,10 +76,10 @@ export async function fileExistsInHead(repoDir, filePath) {
|
|
|
76
76
|
/**
|
|
77
77
|
* Batched equivalent of {@link fileExistsInHead}: returns the subset of
|
|
78
78
|
* `files` that are tracked in HEAD, using a single `git ls-tree` per ARG_MAX
|
|
79
|
-
* chunk instead of one spawn per file. This is the cold-run hot path
|
|
80
|
-
* Firefox-sized checkout has hundreds of affected files.
|
|
79
|
+
* chunk instead of one spawn per file. This is the cold-run hot path, and
|
|
80
|
+
* a Firefox-sized checkout has hundreds of affected files.
|
|
81
81
|
*
|
|
82
|
-
* `-r` lists nested blobs by full repo-relative path
|
|
82
|
+
* `-r` lists nested blobs by full repo-relative path. `--name-only -z` makes
|
|
83
83
|
* the output a trivial NUL-split with no quoting to undo. Membership in the
|
|
84
84
|
* returned Set is exactly `await fileExistsInHead(repoDir, file)` for any
|
|
85
85
|
* non-directory `file`. Throws (via {@link git}) when HEAD itself is
|
|
@@ -98,7 +98,7 @@ export async function listTrackedInHead(repoDir, files) {
|
|
|
98
98
|
const output = await git(['ls-tree', '-r', 'HEAD', '--name-only', '-z', '--', ...chunk], repoDir);
|
|
99
99
|
for (const name of output.split('\0')) {
|
|
100
100
|
// `ls-tree -r` can surface entries beyond the literal inputs only when an
|
|
101
|
-
// input is itself a directory in HEAD
|
|
101
|
+
// input is itself a directory in HEAD. Intersect with `wanted` so the
|
|
102
102
|
// result is always a subset of the requested files, never a superset.
|
|
103
103
|
if (name.length > 0 && wanted.has(name))
|
|
104
104
|
tracked.add(name);
|
|
@@ -115,10 +115,10 @@ export async function listTrackedInHead(repoDir, files) {
|
|
|
115
115
|
* Uses {@link import('../utils/process.js').exec} rather than {@link git}
|
|
116
116
|
* (which throws on a non-zero exit) because `git hash-object f1 f2 …` is
|
|
117
117
|
* all-or-nothing: it aborts at the first unreadable path and emits nothing
|
|
118
|
-
* for the rest. To keep the per-file contract
|
|
119
|
-
* only its own index line
|
|
118
|
+
* for the rest. To keep the per-file contract, where one bad path zeroes
|
|
119
|
+
* only its own index line, a chunk that does not return exactly one hash
|
|
120
120
|
* per input falls back to hashing that chunk's paths individually. A path
|
|
121
|
-
* that is still unhashable is left out of the map
|
|
121
|
+
* that is still unhashable is left out of the map. The caller applies the
|
|
122
122
|
* `0000000000` zero-hash fallback for any miss. Hashing stays in git rather
|
|
123
123
|
* than in-process so filters and `.gitattributes` are applied per path and
|
|
124
124
|
* the result cannot diverge under `core.autocrlf`/`text` attributes.
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Private-index scope for FireForge's
|
|
2
|
+
* Private-index scope for FireForge's read-only git plumbing.
|
|
3
3
|
*
|
|
4
4
|
* `git status` and `git diff HEAD` are read-only in the sense operators care
|
|
5
|
-
* about
|
|
5
|
+
* about (they never change tracked content), but they are not read-only to
|
|
6
6
|
* git: both refresh the index's stat cache and write `.git/index` (through
|
|
7
7
|
* `.git/index.lock`) when a file's stat data has moved. That makes
|
|
8
|
-
* `fireforge verify` / `lint --per-patch` / `typecheck` a second
|
|
8
|
+
* `fireforge verify` / `lint --per-patch` / `typecheck` a second writer of
|
|
9
9
|
* the primary `engine/` checkout, even when the command was pointed at a CoW
|
|
10
10
|
* tree clone.
|
|
11
11
|
*
|
|
12
12
|
* The consequence is not cosmetic. A concurrent `fireforge test`
|
|
13
13
|
* fingerprints `engine/` before and after the harness run and refuses a
|
|
14
14
|
* verdict taken across a change (`FAIL reason=inconclusive`). That refusal is
|
|
15
|
-
*
|
|
15
|
+
* correct and stays. The defect is FireForge's own read-only commands
|
|
16
16
|
* tripping it.
|
|
17
17
|
*
|
|
18
|
-
* The fix is the standard git one: point the plumbing at a
|
|
18
|
+
* The fix is the standard git one: point the plumbing at a private index
|
|
19
19
|
* (`GIT_INDEX_FILE`) seeded from the repository's own, in a temp directory.
|
|
20
|
-
* Refreshes land there and are thrown away
|
|
21
|
-
* `.git/index.lock`, which is what makes a
|
|
22
|
-
* outright rather than merely churn
|
|
20
|
+
* Refreshes land there and are thrown away. The primary `.git/index` is
|
|
21
|
+
* never touched, and neither is `.git/index.lock`, which is what makes a
|
|
22
|
+
* concurrent `git status` fail outright rather than merely churn.
|
|
23
23
|
*
|
|
24
24
|
* Fail-open by design: if the git dir or the index cannot be resolved or
|
|
25
25
|
* copied, the scope does not activate and the commands behave exactly as
|
|
@@ -56,7 +56,7 @@ export declare function withPrivateGitIndex<T>(repoDir: string, operation: () =>
|
|
|
56
56
|
/**
|
|
57
57
|
* A private index file plus the cleanup that removes it.
|
|
58
58
|
*
|
|
59
|
-
* `env` is meant to be handed to a
|
|
59
|
+
* `env` is meant to be handed to a single git invocation (or a small
|
|
60
60
|
* sequence of them), rather than installed process-wide the way
|
|
61
61
|
* {@link withPrivateGitIndex} installs a scope.
|
|
62
62
|
*/
|
|
@@ -68,20 +68,20 @@ export interface DisposableGitIndex {
|
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
70
70
|
* Mints a private index seeded from `repoDir`'s own, for a caller that
|
|
71
|
-
* needs to
|
|
71
|
+
* needs to write the index without the write being visible to anyone else.
|
|
72
72
|
*
|
|
73
73
|
* The distinction from {@link withPrivateGitIndex} matters. That one exists
|
|
74
74
|
* so a read-only command's incidental index refreshes do not touch the
|
|
75
75
|
* primary checkout, and it is process-global, non-reentrant, and fail-open,
|
|
76
76
|
* all of which are right for that job. This one serves a caller whose index
|
|
77
|
-
* write is
|
|
77
|
+
* write is intentional and whose visibility is the defect: it is per-call, so
|
|
78
78
|
* two concurrent callers cannot collide, and it never depends on an ambient
|
|
79
79
|
* scope having been installed by whichever command happens to be running.
|
|
80
80
|
*
|
|
81
81
|
* The seed is a plain copy, which is safe against a concurrent writer: git
|
|
82
82
|
* writes the index through `index.lock` and an atomic rename, so a reader
|
|
83
83
|
* sees either the old file or the new one, never a torn one. Seeding is
|
|
84
|
-
*
|
|
84
|
+
* required rather than merely tidy: an empty index makes a tracked,
|
|
85
85
|
* unmodified file look like a fresh add.
|
|
86
86
|
*
|
|
87
87
|
* @param repoDir - Repository whose index should be shadowed
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
/**
|
|
3
|
-
* Private-index scope for FireForge's
|
|
3
|
+
* Private-index scope for FireForge's read-only git plumbing.
|
|
4
4
|
*
|
|
5
5
|
* `git status` and `git diff HEAD` are read-only in the sense operators care
|
|
6
|
-
* about
|
|
6
|
+
* about (they never change tracked content), but they are not read-only to
|
|
7
7
|
* git: both refresh the index's stat cache and write `.git/index` (through
|
|
8
8
|
* `.git/index.lock`) when a file's stat data has moved. That makes
|
|
9
|
-
* `fireforge verify` / `lint --per-patch` / `typecheck` a second
|
|
9
|
+
* `fireforge verify` / `lint --per-patch` / `typecheck` a second writer of
|
|
10
10
|
* the primary `engine/` checkout, even when the command was pointed at a CoW
|
|
11
11
|
* tree clone.
|
|
12
12
|
*
|
|
13
13
|
* The consequence is not cosmetic. A concurrent `fireforge test`
|
|
14
14
|
* fingerprints `engine/` before and after the harness run and refuses a
|
|
15
15
|
* verdict taken across a change (`FAIL reason=inconclusive`). That refusal is
|
|
16
|
-
*
|
|
16
|
+
* correct and stays. The defect is FireForge's own read-only commands
|
|
17
17
|
* tripping it.
|
|
18
18
|
*
|
|
19
|
-
* The fix is the standard git one: point the plumbing at a
|
|
19
|
+
* The fix is the standard git one: point the plumbing at a private index
|
|
20
20
|
* (`GIT_INDEX_FILE`) seeded from the repository's own, in a temp directory.
|
|
21
|
-
* Refreshes land there and are thrown away
|
|
22
|
-
* `.git/index.lock`, which is what makes a
|
|
23
|
-
* outright rather than merely churn
|
|
21
|
+
* Refreshes land there and are thrown away. The primary `.git/index` is
|
|
22
|
+
* never touched, and neither is `.git/index.lock`, which is what makes a
|
|
23
|
+
* concurrent `git status` fail outright rather than merely churn.
|
|
24
24
|
*
|
|
25
25
|
* Fail-open by design: if the git dir or the index cannot be resolved or
|
|
26
26
|
* copied, the scope does not activate and the commands behave exactly as
|
|
@@ -66,7 +66,7 @@ export function readOnlyGitIndexEnv(cwd) {
|
|
|
66
66
|
}
|
|
67
67
|
/**
|
|
68
68
|
* Resolves a repository's git directory. Returns undefined for anything
|
|
69
|
-
* that is not a readable git checkout
|
|
69
|
+
* that is not a readable git checkout. `engine/` is not always one
|
|
70
70
|
* (`fireforge download` extracts a source tarball).
|
|
71
71
|
*/
|
|
72
72
|
async function resolveGitDir(repoDir) {
|
|
@@ -115,20 +115,20 @@ export async function withPrivateGitIndex(repoDir, operation) {
|
|
|
115
115
|
}
|
|
116
116
|
/**
|
|
117
117
|
* Mints a private index seeded from `repoDir`'s own, for a caller that
|
|
118
|
-
* needs to
|
|
118
|
+
* needs to write the index without the write being visible to anyone else.
|
|
119
119
|
*
|
|
120
120
|
* The distinction from {@link withPrivateGitIndex} matters. That one exists
|
|
121
121
|
* so a read-only command's incidental index refreshes do not touch the
|
|
122
122
|
* primary checkout, and it is process-global, non-reentrant, and fail-open,
|
|
123
123
|
* all of which are right for that job. This one serves a caller whose index
|
|
124
|
-
* write is
|
|
124
|
+
* write is intentional and whose visibility is the defect: it is per-call, so
|
|
125
125
|
* two concurrent callers cannot collide, and it never depends on an ambient
|
|
126
126
|
* scope having been installed by whichever command happens to be running.
|
|
127
127
|
*
|
|
128
128
|
* The seed is a plain copy, which is safe against a concurrent writer: git
|
|
129
129
|
* writes the index through `index.lock` and an atomic rename, so a reader
|
|
130
130
|
* sees either the old file or the new one, never a torn one. Seeding is
|
|
131
|
-
*
|
|
131
|
+
* required rather than merely tidy: an empty index makes a tracked,
|
|
132
132
|
* unmodified file look like a fresh add.
|
|
133
133
|
*
|
|
134
134
|
* @param repoDir - Repository whose index should be shadowed
|
|
@@ -2,8 +2,8 @@ import type { GitStatusEntry } from './git-base.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Parses NUL-delimited porcelain status output.
|
|
4
4
|
*
|
|
5
|
-
* A rename or copy occupies
|
|
6
|
-
* may sit in
|
|
5
|
+
* A rename or copy occupies two NUL records (`XY new\0old\0`), and the `R`/`C`
|
|
6
|
+
* may sit in either column: git >= 2.18 detects renames in the worktree too
|
|
7
7
|
* (`status.renames`), emitting ` R new\0old\0` for an unstaged rename and
|
|
8
8
|
* `RM`/`R ` for a staged one. Only consuming the second record for an index
|
|
9
9
|
* `R`/`C` turned the worktree form's `old` field into a bogus extra entry
|
|
@@ -30,8 +30,8 @@ export declare function resolveMaxUntrackedFilesPerDir(): number;
|
|
|
30
30
|
*
|
|
31
31
|
* Expansion is capped per directory (FIREFORGE_MAX_UNTRACKED_FILES, default
|
|
32
32
|
* 5000) with a warning on overflow. Without the cap, `reset --dry-run` after
|
|
33
|
-
* an interrupted download
|
|
34
|
-
* untracked
|
|
33
|
+
* an interrupted download (unborn HEAD, the entire ~300k file tree
|
|
34
|
+
* untracked) enumerates and prints every file.
|
|
35
35
|
*
|
|
36
36
|
* @param repoDir - Repository directory
|
|
37
37
|
* @param entries - Parsed status entries
|
|
@@ -14,8 +14,8 @@ function isRenameOrCopyColumn(column) {
|
|
|
14
14
|
/**
|
|
15
15
|
* Parses NUL-delimited porcelain status output.
|
|
16
16
|
*
|
|
17
|
-
* A rename or copy occupies
|
|
18
|
-
* may sit in
|
|
17
|
+
* A rename or copy occupies two NUL records (`XY new\0old\0`), and the `R`/`C`
|
|
18
|
+
* may sit in either column: git >= 2.18 detects renames in the worktree too
|
|
19
19
|
* (`status.renames`), emitting ` R new\0old\0` for an unstaged rename and
|
|
20
20
|
* `RM`/`R ` for a staged one. Only consuming the second record for an index
|
|
21
21
|
* `R`/`C` turned the worktree form's `old` field into a bogus extra entry
|
|
@@ -84,8 +84,8 @@ export function resolveMaxUntrackedFilesPerDir() {
|
|
|
84
84
|
*
|
|
85
85
|
* Expansion is capped per directory (FIREFORGE_MAX_UNTRACKED_FILES, default
|
|
86
86
|
* 5000) with a warning on overflow. Without the cap, `reset --dry-run` after
|
|
87
|
-
* an interrupted download
|
|
88
|
-
* untracked
|
|
87
|
+
* an interrupted download (unborn HEAD, the entire ~300k file tree
|
|
88
|
+
* untracked) enumerates and prints every file.
|
|
89
89
|
*
|
|
90
90
|
* @param repoDir - Repository directory
|
|
91
91
|
* @param entries - Parsed status entries
|
package/dist/src/core/git.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare function isGitRepository(dir: string): Promise<boolean>;
|
|
|
17
17
|
export declare function ensureOriginRemote(dir: string): Promise<void>;
|
|
18
18
|
/**
|
|
19
19
|
* Stages all files in the repository.
|
|
20
|
-
* Tries a monolithic `git add -A` first
|
|
20
|
+
* Tries a monolithic `git add -A` first. If that times out, falls back to
|
|
21
21
|
* directory-by-directory staged adds.
|
|
22
22
|
*/
|
|
23
23
|
export declare function stageAllFiles(dir: string, options?: {
|
|
@@ -56,8 +56,8 @@ export declare function applyPatch(patchPath: string, repoDir: string, options?:
|
|
|
56
56
|
* @param patchPath - Path to the patch file
|
|
57
57
|
* @param repoDir - Repository directory
|
|
58
58
|
* @param options.reject - Fall back to `git apply --reject`
|
|
59
|
-
* @param options.protectedFiles - Files that must
|
|
60
|
-
* recovery step. Callers applying a patch
|
|
59
|
+
* @param options.protectedFiles - Files that must not be reset to HEAD by the
|
|
60
|
+
* recovery step. Callers applying a patch queue pass the files already
|
|
61
61
|
* touched by previously applied patches in the same run: two overlapping
|
|
62
62
|
* patches (an `--allow-overlap` queue) share files, and a blanket
|
|
63
63
|
* `checkout HEAD` would wipe the earlier patch's changes from the shared
|
package/dist/src/core/git.js
CHANGED
|
@@ -41,8 +41,8 @@ export async function ensureOriginRemote(dir) {
|
|
|
41
41
|
const GIT_ADD_ENV = { GIT_INDEX_THREADS: '0' };
|
|
42
42
|
/**
|
|
43
43
|
* Returns true when the error looks like a process killed by the spawn
|
|
44
|
-
* timeout (SIGTERM → exit code 143)
|
|
45
|
-
* `AbortSignal.timeout
|
|
44
|
+
* timeout (SIGTERM → exit code 143) or an AbortError raised by
|
|
45
|
+
* `AbortSignal.timeout`. Node's `child_process` layer rejects with an
|
|
46
46
|
* AbortError when the signal fires, so both shapes have to be recognised.
|
|
47
47
|
*/
|
|
48
48
|
function isTimeoutError(error) {
|
|
@@ -76,7 +76,7 @@ async function cleanupIndexLock(dir) {
|
|
|
76
76
|
* other exclusion mechanism git considers, e.g. `.git/info/exclude`,
|
|
77
77
|
* core.excludesFile). Used by the chunked staging fallback to skip entries
|
|
78
78
|
* that would otherwise fail `git add -- <path>` with the fatal "The
|
|
79
|
-
* following paths are ignored by one of your .gitignore files" error
|
|
79
|
+
* following paths are ignored by one of your .gitignore files" error, a
|
|
80
80
|
* state the monolithic `git add -A` path silently handles. A Firefox
|
|
81
81
|
* checkout's top-level `.vscode/` is the common case: without this, the
|
|
82
82
|
* chunked invocation aborts the whole fallback and turns a recoverable
|
|
@@ -93,7 +93,7 @@ async function isPathIgnored(dir, relativePath) {
|
|
|
93
93
|
return true;
|
|
94
94
|
if (result.exitCode === 1)
|
|
95
95
|
return false;
|
|
96
|
-
// Any other shape is "we don't know"
|
|
96
|
+
// Any other shape is "we don't know", so let the caller proceed and
|
|
97
97
|
// surface the real error if `git add` rejects the path.
|
|
98
98
|
return false;
|
|
99
99
|
}
|
|
@@ -104,7 +104,7 @@ async function isPathIgnored(dir, relativePath) {
|
|
|
104
104
|
*
|
|
105
105
|
* A chunked pass that hits its own timeout raises a typed
|
|
106
106
|
* {@link GitIndexingTimeoutError} rather than an opaque `AbortError: The
|
|
107
|
-
* operation was aborted
|
|
107
|
+
* operation was aborted`. The typed error carries the environment-variable
|
|
108
108
|
* override so the operator can extend the budget and re-run.
|
|
109
109
|
*/
|
|
110
110
|
async function stageAllFilesChunked(dir, scan, options = {}) {
|
|
@@ -134,7 +134,7 @@ async function stageAllFilesChunked(dir, scan, options = {}) {
|
|
|
134
134
|
options.onProgress?.(`Staging directory ${stagedDirectories}/${directories.length}: ${dirName}/...`);
|
|
135
135
|
await runChunk(['add', '--', dirName], dirName);
|
|
136
136
|
}
|
|
137
|
-
// Stage any top-level files (excluding gitignored ones
|
|
137
|
+
// Stage any top-level files (excluding gitignored ones, because `git add`
|
|
138
138
|
// on an explicit ignored path errors out, which would otherwise
|
|
139
139
|
// abort the chunked fallback after the monolithic path has already
|
|
140
140
|
// timed out).
|
|
@@ -154,7 +154,7 @@ async function stageAllFilesChunked(dir, scan, options = {}) {
|
|
|
154
154
|
/**
|
|
155
155
|
* Interval between heartbeat progress messages during the monolithic
|
|
156
156
|
* `git add -A`. On a fresh ~600 MB Firefox tree the monolithic add runs
|
|
157
|
-
* 60
|
|
157
|
+
* 60 to 120 seconds, during which git emits nothing to stdout/stderr. Without a
|
|
158
158
|
* heartbeat the CLI spinner stays pinned on "Indexing Firefox source …" for
|
|
159
159
|
* the full window and looks hung, which invites a SIGINT mid-way.
|
|
160
160
|
*/
|
|
@@ -175,7 +175,7 @@ async function scanTopLevelSource(dir) {
|
|
|
175
175
|
}
|
|
176
176
|
/**
|
|
177
177
|
* Stages all files in the repository.
|
|
178
|
-
* Tries a monolithic `git add -A` first
|
|
178
|
+
* Tries a monolithic `git add -A` first. If that times out, falls back to
|
|
179
179
|
* directory-by-directory staged adds.
|
|
180
180
|
*/
|
|
181
181
|
export async function stageAllFiles(dir, options = {}) {
|
|
@@ -184,7 +184,7 @@ export async function stageAllFiles(dir, options = {}) {
|
|
|
184
184
|
reportProgress?.('Scanning Firefox source tree before indexing...');
|
|
185
185
|
const scan = await scanTopLevelSource(dir);
|
|
186
186
|
reportProgress?.(`Source scan complete: ${scan.directories.length} top-level director${scan.directories.length === 1 ? 'y' : 'ies'}, ${scan.topLevelFiles.length} top-level file${scan.topLevelFiles.length === 1 ? '' : 's'}`);
|
|
187
|
-
// The heartbeat tracks a
|
|
187
|
+
// The heartbeat tracks a per-phase start timestamp and labels each tick
|
|
188
188
|
// with the phase. A single start time set at function entry reports
|
|
189
189
|
// cumulative elapsed for the whole `stageAllFiles` invocation, so after a
|
|
190
190
|
// monolithic timeout the chunked-phase ticks name numbers that already
|
|
@@ -392,8 +392,8 @@ export async function applyPatch(patchPath, repoDir, options = {}) {
|
|
|
392
392
|
* @param patchPath - Path to the patch file
|
|
393
393
|
* @param repoDir - Repository directory
|
|
394
394
|
* @param options.reject - Fall back to `git apply --reject`
|
|
395
|
-
* @param options.protectedFiles - Files that must
|
|
396
|
-
* recovery step. Callers applying a patch
|
|
395
|
+
* @param options.protectedFiles - Files that must not be reset to HEAD by the
|
|
396
|
+
* recovery step. Callers applying a patch queue pass the files already
|
|
397
397
|
* touched by previously applied patches in the same run: two overlapping
|
|
398
398
|
* patches (an `--allow-overlap` queue) share files, and a blanket
|
|
399
399
|
* `checkout HEAD` would wipe the earlier patch's changes from the shared
|
|
@@ -424,14 +424,14 @@ export async function applyPatchIdempotent(patchPath, repoDir, options = {}) {
|
|
|
424
424
|
await applyPatch(patchPath, repoDir, options);
|
|
425
425
|
}
|
|
426
426
|
/**
|
|
427
|
-
* Restores `files` to their HEAD state, deleting files the patch would
|
|
428
|
-
* (present on disk from a partial apply but absent in HEAD
|
|
427
|
+
* Restores `files` to their HEAD state, deleting files the patch would create
|
|
428
|
+
* (present on disk from a partial apply but absent in HEAD, where
|
|
429
429
|
* `git checkout HEAD --` fails, and ignoring that failure leaves stray files
|
|
430
430
|
* that make the subsequent forward apply die with "already exists" and no
|
|
431
431
|
* hint why).
|
|
432
432
|
*
|
|
433
433
|
* Every git invocation is chunked via {@link chunkPathspecs} so a very large
|
|
434
|
-
* patch cannot hit `E2BIG`, and every exit code is checked
|
|
434
|
+
* patch cannot hit `E2BIG`, and every exit code is checked. A silent failed
|
|
435
435
|
* restore is the confusing state this recovery step exists to prevent.
|
|
436
436
|
*/
|
|
437
437
|
async function restoreFilesToHead(repoDir, patchPath, files) {
|