@hominis/fireforge 0.45.0 → 0.46.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +409 -446
- package/dist/bin/fireforge.d.ts +1 -1
- package/dist/bin/fireforge.js +21 -15
- package/dist/build-info.json +4 -4
- package/dist/src/cli-usage-error.d.ts +46 -0
- package/dist/src/cli-usage-error.js +81 -0
- package/dist/src/cli.d.ts +7 -2
- package/dist/src/cli.js +47 -47
- package/dist/src/commands/bootstrap-checks.js +2 -1
- package/dist/src/commands/bootstrap.js +3 -4
- package/dist/src/commands/build.js +27 -17
- package/dist/src/commands/config.js +9 -9
- package/dist/src/commands/destructive-decision.d.ts +19 -0
- package/dist/src/commands/destructive-decision.js +31 -0
- package/dist/src/commands/discard.js +5 -5
- package/dist/src/commands/doctor-check-core.d.ts +4 -10
- package/dist/src/commands/doctor-check-core.js +0 -8
- package/dist/src/commands/doctor-external-toolchains.js +2 -2
- package/dist/src/commands/doctor-furnace-config-sync.d.ts +2 -2
- package/dist/src/commands/doctor-furnace-config-sync.js +20 -20
- package/dist/src/commands/doctor-furnace-jar.d.ts +1 -1
- package/dist/src/commands/doctor-furnace-jar.js +1 -1
- package/dist/src/commands/doctor-furnace.js +22 -22
- package/dist/src/commands/doctor-orphaned-harness.d.ts +10 -17
- package/dist/src/commands/doctor-orphaned-harness.js +14 -23
- package/dist/src/commands/doctor-patch-manifest.d.ts +2 -1
- package/dist/src/commands/doctor-patch-manifest.js +7 -6
- package/dist/src/commands/doctor-post-rebase-audit.js +3 -3
- package/dist/src/commands/doctor-source-pin.d.ts +12 -12
- package/dist/src/commands/doctor-source-pin.js +14 -14
- package/dist/src/commands/doctor-working-tree.d.ts +3 -3
- package/dist/src/commands/doctor-working-tree.js +3 -3
- package/dist/src/commands/doctor.d.ts +3 -1
- package/dist/src/commands/doctor.js +15 -16
- package/dist/src/commands/download.js +50 -37
- package/dist/src/commands/export-all.js +29 -12
- package/dist/src/commands/export-flow.d.ts +5 -5
- package/dist/src/commands/export-flow.js +29 -59
- package/dist/src/commands/export-placement-conflicts.d.ts +3 -3
- package/dist/src/commands/export-placement-conflicts.js +12 -12
- package/dist/src/commands/export-placement-gate.d.ts +2 -2
- package/dist/src/commands/export-placement-gate.js +7 -13
- package/dist/src/commands/export-placement-policy.d.ts +1 -1
- package/dist/src/commands/export-placement-policy.js +4 -6
- package/dist/src/commands/export-shared.d.ts +51 -32
- package/dist/src/commands/export-shared.js +17 -32
- package/dist/src/commands/export.js +14 -5
- package/dist/src/commands/furnace/apply.js +16 -16
- package/dist/src/commands/furnace/authoring-config.d.ts +13 -0
- package/dist/src/commands/furnace/authoring-config.js +19 -0
- package/dist/src/commands/furnace/chrome-doc-remove.d.ts +1 -1
- package/dist/src/commands/furnace/chrome-doc-remove.js +2 -2
- package/dist/src/commands/furnace/chrome-doc-templates.d.ts +14 -14
- package/dist/src/commands/furnace/chrome-doc-templates.js +17 -17
- package/dist/src/commands/furnace/chrome-doc-tests.d.ts +2 -2
- package/dist/src/commands/furnace/chrome-doc-tests.js +4 -4
- package/dist/src/commands/furnace/chrome-doc.d.ts +8 -8
- package/dist/src/commands/furnace/chrome-doc.js +18 -18
- package/dist/src/commands/furnace/create-browser-test.d.ts +1 -1
- package/dist/src/commands/furnace/create-browser-test.js +7 -12
- package/dist/src/commands/furnace/create-dry-run.d.ts +4 -4
- package/dist/src/commands/furnace/create-dry-run.js +6 -9
- package/dist/src/commands/furnace/create-features.d.ts +2 -2
- package/dist/src/commands/furnace/create-features.js +2 -2
- package/dist/src/commands/furnace/create-mochikit.d.ts +4 -4
- package/dist/src/commands/furnace/create-mochikit.js +7 -7
- package/dist/src/commands/furnace/create-templates.d.ts +31 -15
- package/dist/src/commands/furnace/create-templates.js +20 -19
- package/dist/src/commands/furnace/create-xpcshell.d.ts +5 -5
- package/dist/src/commands/furnace/create-xpcshell.js +8 -8
- package/dist/src/commands/furnace/create.d.ts +1 -1
- package/dist/src/commands/furnace/create.js +35 -29
- package/dist/src/commands/furnace/deploy.js +15 -6
- package/dist/src/commands/furnace/diff.js +7 -7
- package/dist/src/commands/furnace/index.js +1 -1
- package/dist/src/commands/furnace/init.js +17 -16
- package/dist/src/commands/furnace/list.js +2 -2
- package/dist/src/commands/furnace/override.d.ts +1 -1
- package/dist/src/commands/furnace/override.js +43 -34
- package/dist/src/commands/furnace/preview.js +17 -17
- package/dist/src/commands/furnace/refresh.js +15 -7
- package/dist/src/commands/furnace/remove-mutations.d.ts +9 -10
- package/dist/src/commands/furnace/remove-mutations.js +19 -19
- package/dist/src/commands/furnace/remove-state.d.ts +1 -1
- package/dist/src/commands/furnace/remove-state.js +1 -1
- package/dist/src/commands/furnace/remove.js +4 -8
- package/dist/src/commands/furnace/rename-browser-test.js +10 -15
- package/dist/src/commands/furnace/rename-xpcshell.d.ts +2 -2
- package/dist/src/commands/furnace/rename-xpcshell.js +3 -3
- package/dist/src/commands/furnace/rename.js +36 -36
- package/dist/src/commands/furnace/scan.js +3 -3
- package/dist/src/commands/furnace/status.js +19 -16
- package/dist/src/commands/furnace/sync.js +6 -6
- package/dist/src/commands/furnace/test-file-name.d.ts +28 -0
- package/dist/src/commands/furnace/test-file-name.js +39 -0
- package/dist/src/commands/furnace/validate.js +11 -12
- package/dist/src/commands/furnace/validation-output.d.ts +21 -9
- package/dist/src/commands/furnace/validation-output.js +3 -8
- package/dist/src/commands/import.js +22 -29
- package/dist/src/commands/lint-per-patch.d.ts +2 -2
- package/dist/src/commands/lint-per-patch.js +27 -12
- package/dist/src/commands/lint-per-run-checkjs.d.ts +14 -15
- package/dist/src/commands/lint-per-run-checkjs.js +14 -15
- package/dist/src/commands/lint-report.d.ts +3 -3
- package/dist/src/commands/lint-report.js +4 -4
- package/dist/src/commands/lint.d.ts +5 -4
- package/dist/src/commands/lint.js +36 -36
- package/dist/src/commands/manifest.d.ts +4 -4
- package/dist/src/commands/manifest.js +1 -1
- package/dist/src/commands/package.js +4 -6
- package/dist/src/commands/patch/compact.d.ts +2 -2
- package/dist/src/commands/patch/compact.js +19 -20
- package/dist/src/commands/patch/delete.d.ts +1 -1
- package/dist/src/commands/patch/delete.js +23 -33
- package/dist/src/commands/patch/entry-projection.d.ts +13 -0
- package/dist/src/commands/patch/entry-projection.js +24 -0
- package/dist/src/commands/patch/lint-ignore.d.ts +3 -12
- package/dist/src/commands/patch/lint-ignore.js +33 -44
- package/dist/src/commands/patch/move-files-create.d.ts +2 -2
- package/dist/src/commands/patch/move-files-create.js +29 -15
- package/dist/src/commands/patch/move-files-into.d.ts +2 -2
- package/dist/src/commands/patch/move-files-into.js +41 -37
- package/dist/src/commands/patch/move-files.js +5 -14
- package/dist/src/commands/patch/patch-context.d.ts +1 -1
- package/dist/src/commands/patch/rename.d.ts +4 -4
- package/dist/src/commands/patch/rename.js +35 -49
- package/dist/src/commands/patch/reorder.js +35 -48
- package/dist/src/commands/patch/split-plan.d.ts +7 -8
- package/dist/src/commands/patch/split-plan.js +10 -13
- package/dist/src/commands/patch/split.d.ts +2 -2
- package/dist/src/commands/patch/split.js +50 -48
- package/dist/src/commands/patch/staged-dependency-validate.d.ts +1 -1
- package/dist/src/commands/patch/staged-dependency-validate.js +3 -3
- package/dist/src/commands/patch/staged-dependency.d.ts +1 -1
- package/dist/src/commands/patch/staged-dependency.js +22 -28
- package/dist/src/commands/patch/tier.d.ts +2 -2
- package/dist/src/commands/patch/tier.js +20 -30
- package/dist/src/commands/patch-rename-map.d.ts +19 -0
- package/dist/src/commands/patch-rename-map.js +36 -0
- package/dist/src/commands/pending-resolution.d.ts +15 -0
- package/dist/src/commands/pending-resolution.js +25 -0
- package/dist/src/commands/re-export-adjacent.d.ts +25 -3
- package/dist/src/commands/re-export-adjacent.js +40 -24
- package/dist/src/commands/re-export-bulk-scan.d.ts +3 -3
- package/dist/src/commands/re-export-bulk-scan.js +23 -27
- package/dist/src/commands/re-export-drift.d.ts +10 -10
- package/dist/src/commands/re-export-drift.js +33 -33
- package/dist/src/commands/re-export-files.d.ts +2 -3
- package/dist/src/commands/re-export-files.js +52 -44
- package/dist/src/commands/re-export-lint.d.ts +29 -30
- package/dist/src/commands/re-export-lint.js +36 -29
- package/dist/src/commands/re-export-options.d.ts +1 -1
- package/dist/src/commands/re-export-options.js +1 -1
- package/dist/src/commands/re-export-register.d.ts +1 -1
- package/dist/src/commands/re-export-register.js +1 -1
- package/dist/src/commands/re-export-scan.d.ts +1 -1
- package/dist/src/commands/re-export-scan.js +12 -9
- package/dist/src/commands/re-export-single.d.ts +23 -4
- package/dist/src/commands/re-export-single.js +39 -31
- package/dist/src/commands/re-export.js +35 -17
- package/dist/src/commands/rebase/abort.js +9 -14
- package/dist/src/commands/rebase/continue.js +20 -19
- package/dist/src/commands/rebase/index.d.ts +1 -1
- package/dist/src/commands/rebase/index.js +5 -5
- package/dist/src/commands/rebase/patch-loop.d.ts +2 -2
- package/dist/src/commands/rebase/patch-loop.js +20 -24
- package/dist/src/commands/register.js +5 -5
- package/dist/src/commands/reset.js +1 -1
- package/dist/src/commands/resolve.d.ts +2 -2
- package/dist/src/commands/resolve.js +21 -13
- package/dist/src/commands/run.d.ts +0 -13
- package/dist/src/commands/run.js +38 -51
- package/dist/src/commands/setup-support.d.ts +16 -4
- package/dist/src/commands/setup-support.js +20 -20
- package/dist/src/commands/setup.js +4 -10
- package/dist/src/commands/source.js +9 -2
- package/dist/src/commands/status-check.d.ts +3 -3
- package/dist/src/commands/status-check.js +6 -6
- package/dist/src/commands/status-json.d.ts +14 -13
- package/dist/src/commands/status-json.js +9 -8
- package/dist/src/commands/status-output.d.ts +3 -3
- package/dist/src/commands/status-output.js +5 -5
- package/dist/src/commands/status-ownership.d.ts +3 -3
- package/dist/src/commands/status-ownership.js +3 -3
- package/dist/src/commands/status.js +25 -26
- package/dist/src/commands/test-build-phase.d.ts +3 -3
- package/dist/src/commands/test-build-phase.js +48 -24
- package/dist/src/commands/test-diagnose.d.ts +1 -1
- package/dist/src/commands/test-diagnose.js +20 -20
- package/dist/src/commands/test-modes.d.ts +4 -4
- package/dist/src/commands/test-modes.js +4 -5
- package/dist/src/commands/test-register.js +5 -3
- package/dist/src/commands/test-run.d.ts +11 -11
- package/dist/src/commands/test-run.js +40 -33
- package/dist/src/commands/test-stale-gate.d.ts +12 -12
- package/dist/src/commands/test-stale-gate.js +17 -17
- package/dist/src/commands/test-verdict.d.ts +19 -5
- package/dist/src/commands/test-verdict.js +26 -11
- package/dist/src/commands/test.d.ts +3 -3
- package/dist/src/commands/test.js +73 -36
- package/dist/src/commands/token-coverage.js +3 -3
- package/dist/src/commands/token-list.d.ts +26 -0
- package/dist/src/commands/token-list.js +153 -0
- package/dist/src/commands/token.js +26 -10
- package/dist/src/commands/tree.js +26 -21
- package/dist/src/commands/typecheck.d.ts +6 -6
- package/dist/src/commands/typecheck.js +16 -16
- package/dist/src/commands/verify.d.ts +3 -3
- package/dist/src/commands/verify.js +10 -10
- package/dist/src/commands/watch.js +11 -11
- package/dist/src/commands/wire.js +17 -16
- package/dist/src/core/ast-utils.d.ts +7 -7
- package/dist/src/core/ast-utils.js +8 -8
- package/dist/src/core/branding.d.ts +5 -12
- package/dist/src/core/branding.js +6 -5
- package/dist/src/core/browser-wire.d.ts +1 -1
- package/dist/src/core/browser-wire.js +10 -7
- package/dist/src/core/build-audit-platform.d.ts +32 -3
- package/dist/src/core/build-audit-platform.js +153 -13
- package/dist/src/core/build-audit-registration.d.ts +5 -5
- package/dist/src/core/build-audit-registration.js +10 -9
- package/dist/src/core/build-audit-resolve.d.ts +5 -5
- package/dist/src/core/build-audit-resolve.js +6 -6
- package/dist/src/core/build-audit-skip.d.ts +57 -0
- package/dist/src/core/build-audit-skip.js +112 -0
- package/dist/src/core/build-audit-transforms.d.ts +2 -2
- package/dist/src/core/build-audit-transforms.js +3 -3
- package/dist/src/core/build-audit.d.ts +21 -8
- package/dist/src/core/build-audit.js +142 -40
- package/dist/src/core/build-baseline-types.d.ts +19 -18
- package/dist/src/core/build-baseline-types.js +1 -1
- package/dist/src/core/build-baseline.d.ts +48 -31
- package/dist/src/core/build-baseline.js +20 -43
- package/dist/src/core/build-jar-escalation.d.ts +8 -8
- package/dist/src/core/build-jar-escalation.js +18 -17
- package/dist/src/core/build-overwrite-guard.d.ts +4 -4
- package/dist/src/core/build-overwrite-guard.js +14 -14
- package/dist/src/core/build-prepare.d.ts +4 -12
- package/dist/src/core/build-prepare.js +22 -26
- package/dist/src/core/config-mutate.js +4 -4
- package/dist/src/core/config-paths.d.ts +2 -6
- package/dist/src/core/config-paths.js +4 -2
- package/dist/src/core/config-state.d.ts +0 -6
- package/dist/src/core/config-state.js +3 -21
- package/dist/src/core/config-validate-build-audit.d.ts +8 -0
- package/dist/src/core/config-validate-build-audit.js +80 -0
- package/dist/src/core/config-validate-file-size.d.ts +1 -1
- package/dist/src/core/config-validate-file-size.js +3 -3
- package/dist/src/core/config-validate-patch-policy.d.ts +2 -2
- package/dist/src/core/config-validate-patch-policy.js +3 -3
- package/dist/src/core/config-validate-test-toolchains.d.ts +2 -2
- package/dist/src/core/config-validate-test-toolchains.js +4 -5
- package/dist/src/core/config-validate.js +22 -12
- package/dist/src/core/config.d.ts +12 -12
- package/dist/src/core/config.js +21 -25
- package/dist/src/core/coverage-extend.d.ts +16 -16
- package/dist/src/core/coverage-extend.js +20 -20
- package/dist/src/core/destructive.d.ts +14 -14
- package/dist/src/core/destructive.js +9 -9
- package/dist/src/core/diff-hunks.d.ts +2 -2
- package/dist/src/core/diff-hunks.js +7 -7
- package/dist/src/core/discard-baseline.d.ts +10 -10
- package/dist/src/core/discard-baseline.js +22 -23
- package/dist/src/core/display-state.d.ts +11 -11
- package/dist/src/core/display-state.js +12 -12
- package/dist/src/core/engine-changes.d.ts +2 -2
- package/dist/src/core/engine-changes.js +2 -2
- package/dist/src/core/engine-precondition.d.ts +5 -13
- package/dist/src/core/engine-precondition.js +5 -10
- package/dist/src/core/engine-session-lock.d.ts +18 -18
- package/dist/src/core/engine-session-lock.js +50 -54
- package/dist/src/core/export-moved-code-shape.d.ts +7 -7
- package/dist/src/core/export-moved-code-shape.js +10 -10
- package/dist/src/core/file-lock-owner.d.ts +103 -0
- package/dist/src/core/file-lock-owner.js +259 -0
- package/dist/src/core/file-lock.d.ts +14 -19
- package/dist/src/core/file-lock.js +90 -128
- package/dist/src/core/firefox-cache.d.ts +13 -1
- package/dist/src/core/firefox-cache.js +61 -36
- package/dist/src/core/firefox-download.d.ts +15 -0
- package/dist/src/core/firefox-download.js +38 -22
- package/dist/src/core/firefox-extract.d.ts +8 -7
- package/dist/src/core/firefox-extract.js +45 -27
- package/dist/src/core/firefox.d.ts +34 -36
- package/dist/src/core/firefox.js +13 -44
- package/dist/src/core/furnace-apply-dry-run.d.ts +1 -6
- package/dist/src/core/furnace-apply-dry-run.js +2 -8
- package/dist/src/core/furnace-apply-ftl.d.ts +5 -5
- package/dist/src/core/furnace-apply-ftl.js +8 -8
- package/dist/src/core/furnace-apply-helpers.d.ts +9 -20
- package/dist/src/core/furnace-apply-helpers.js +28 -39
- package/dist/src/core/furnace-apply-output.js +1 -1
- package/dist/src/core/furnace-apply-overwrite-warn.d.ts +9 -9
- package/dist/src/core/furnace-apply-overwrite-warn.js +13 -11
- package/dist/src/core/furnace-apply-undeploy-actions.d.ts +1 -1
- package/dist/src/core/furnace-apply-undeploy-actions.js +1 -1
- package/dist/src/core/furnace-apply.d.ts +4 -4
- package/dist/src/core/furnace-apply.js +50 -29
- package/dist/src/core/furnace-checksum-utils.d.ts +5 -5
- package/dist/src/core/furnace-checksum-utils.js +5 -5
- package/dist/src/core/furnace-config-custom.d.ts +1 -1
- package/dist/src/core/furnace-config-custom.js +2 -2
- package/dist/src/core/furnace-config-order.js +1 -1
- package/dist/src/core/furnace-config-tokens.d.ts +3 -3
- package/dist/src/core/furnace-config-tokens.js +3 -3
- package/dist/src/core/furnace-config-validate.js +2 -2
- package/dist/src/core/furnace-config.d.ts +5 -5
- package/dist/src/core/furnace-config.js +40 -53
- package/dist/src/core/furnace-constants.d.ts +6 -6
- package/dist/src/core/furnace-constants.js +9 -8
- package/dist/src/core/furnace-css-fragments.d.ts +6 -6
- package/dist/src/core/furnace-css-fragments.js +11 -11
- package/dist/src/core/furnace-dir-entry.d.ts +20 -0
- package/dist/src/core/furnace-dir-entry.js +21 -0
- package/dist/src/core/furnace-jsconfig.d.ts +7 -7
- package/dist/src/core/furnace-jsconfig.js +22 -20
- package/dist/src/core/furnace-operation.d.ts +22 -19
- package/dist/src/core/furnace-operation.js +38 -34
- package/dist/src/core/furnace-precondition.d.ts +10 -10
- package/dist/src/core/furnace-precondition.js +8 -8
- package/dist/src/core/furnace-refresh.d.ts +18 -6
- package/dist/src/core/furnace-refresh.js +5 -8
- package/dist/src/core/furnace-registration-ast.d.ts +2 -3
- package/dist/src/core/furnace-registration-ast.js +9 -12
- package/dist/src/core/furnace-registration-remove.d.ts +4 -4
- package/dist/src/core/furnace-registration-remove.js +6 -6
- package/dist/src/core/furnace-registration-validate.d.ts +2 -2
- package/dist/src/core/furnace-registration-validate.js +2 -2
- package/dist/src/core/furnace-registration.d.ts +7 -6
- package/dist/src/core/furnace-registration.js +29 -36
- package/dist/src/core/furnace-rollback.d.ts +1 -1
- package/dist/src/core/furnace-rollback.js +5 -5
- package/dist/src/core/furnace-scanner.js +3 -6
- package/dist/src/core/furnace-stale-export.d.ts +17 -16
- package/dist/src/core/furnace-stale-export.js +16 -15
- package/dist/src/core/furnace-staleness.d.ts +2 -2
- package/dist/src/core/furnace-staleness.js +2 -2
- package/dist/src/core/furnace-state-persist.d.ts +12 -12
- package/dist/src/core/furnace-state-persist.js +10 -10
- package/dist/src/core/furnace-step-errors.d.ts +6 -6
- package/dist/src/core/furnace-step-errors.js +6 -6
- package/dist/src/core/furnace-validate-accessibility.js +14 -14
- package/dist/src/core/furnace-validate-compatibility.js +9 -9
- package/dist/src/core/furnace-validate-registration.d.ts +2 -2
- package/dist/src/core/furnace-validate-registration.js +18 -20
- package/dist/src/core/furnace-validate-structure.d.ts +1 -1
- package/dist/src/core/furnace-validate-structure.js +4 -4
- package/dist/src/core/furnace-validate.js +9 -9
- package/dist/src/core/furnace-version-drift.d.ts +5 -5
- package/dist/src/core/furnace-version-drift.js +5 -5
- package/dist/src/core/git-base.d.ts +6 -4
- package/dist/src/core/git-base.js +29 -7
- package/dist/src/core/git-diff-new-file.d.ts +40 -0
- package/dist/src/core/git-diff-new-file.js +119 -0
- package/dist/src/core/git-diff.d.ts +13 -13
- package/dist/src/core/git-diff.js +121 -189
- package/dist/src/core/git-file-ops.d.ts +6 -13
- package/dist/src/core/git-file-ops.js +11 -35
- package/dist/src/core/git-readonly-index.d.ts +12 -14
- package/dist/src/core/git-readonly-index.js +12 -16
- package/dist/src/core/git-status.d.ts +9 -2
- package/dist/src/core/git-status.js +23 -11
- package/dist/src/core/git.d.ts +3 -9
- package/dist/src/core/git.js +28 -57
- package/dist/src/core/harness-orphans.d.ts +17 -17
- package/dist/src/core/harness-orphans.js +28 -27
- package/dist/src/core/history-log.d.ts +19 -0
- package/dist/src/core/history-log.js +29 -0
- package/dist/src/core/license-headers.d.ts +19 -18
- package/dist/src/core/license-headers.js +29 -28
- package/dist/src/core/mach-build-artifacts.d.ts +21 -21
- package/dist/src/core/mach-build-artifacts.js +23 -23
- package/dist/src/core/mach-error-hints.d.ts +5 -10
- package/dist/src/core/mach-error-hints.js +14 -14
- package/dist/src/core/mach-known-noise-filter.d.ts +42 -38
- package/dist/src/core/mach-known-noise-filter.js +57 -56
- package/dist/src/core/mach-mozconfig.d.ts +6 -6
- package/dist/src/core/mach-mozconfig.js +17 -16
- package/dist/src/core/mach-python.d.ts +3 -0
- package/dist/src/core/mach-python.js +13 -7
- package/dist/src/core/mach-resource-shim.d.ts +24 -12
- package/dist/src/core/mach-resource-shim.js +124 -21
- package/dist/src/core/mach.d.ts +59 -73
- package/dist/src/core/mach.js +47 -115
- package/dist/src/core/marionette-port.d.ts +15 -30
- package/dist/src/core/marionette-port.js +46 -89
- package/dist/src/core/marionette-preflight.d.ts +6 -6
- package/dist/src/core/marionette-preflight.js +32 -50
- package/dist/src/core/markdown-table.d.ts +9 -9
- package/dist/src/core/markdown-table.js +14 -14
- package/dist/src/core/mochitest-server-port.d.ts +8 -8
- package/dist/src/core/mochitest-server-port.js +17 -17
- package/dist/src/core/module-resolution-preflight.d.ts +8 -8
- package/dist/src/core/module-resolution-preflight.js +11 -11
- package/dist/src/core/moz-manifest-helpers.d.ts +7 -7
- package/dist/src/core/moz-manifest-helpers.js +7 -7
- package/dist/src/core/moz-manifest-register.d.ts +1 -1
- package/dist/src/core/moz-manifest-register.js +2 -2
- package/dist/src/core/moz-manifest-rules.js +46 -42
- package/dist/src/core/moz-manifest-tokenizers.js +1 -1
- package/dist/src/core/ownership-table.d.ts +5 -5
- package/dist/src/core/ownership-table.js +7 -7
- package/dist/src/core/parser-fallback.d.ts +3 -3
- package/dist/src/core/parser-fallback.js +3 -3
- package/dist/src/core/patch-apply-fuzz.d.ts +5 -5
- package/dist/src/core/patch-apply-fuzz.js +13 -13
- package/dist/src/core/patch-apply.d.ts +13 -14
- package/dist/src/core/patch-apply.js +36 -42
- package/dist/src/core/patch-export-coverage.d.ts +0 -9
- package/dist/src/core/patch-export-coverage.js +1 -30
- package/dist/src/core/patch-export-update.d.ts +21 -4
- package/dist/src/core/patch-export-update.js +7 -6
- package/dist/src/core/patch-export.d.ts +20 -30
- package/dist/src/core/patch-export.js +55 -77
- package/dist/src/core/patch-files.d.ts +0 -4
- package/dist/src/core/patch-files.js +0 -11
- package/dist/src/core/patch-identifier-suggest.d.ts +1 -1
- package/dist/src/core/patch-identifier-suggest.js +4 -4
- package/dist/src/core/patch-lint-binary.d.ts +12 -18
- package/dist/src/core/patch-lint-cache.d.ts +18 -2
- package/dist/src/core/patch-lint-cache.js +16 -19
- package/dist/src/core/patch-lint-checkjs.d.ts +55 -38
- package/dist/src/core/patch-lint-checkjs.js +78 -64
- package/dist/src/core/patch-lint-chrome-jsdoc.d.ts +8 -9
- package/dist/src/core/patch-lint-chrome-jsdoc.js +10 -11
- package/dist/src/core/patch-lint-creators.d.ts +5 -9
- package/dist/src/core/patch-lint-creators.js +3 -3
- package/dist/src/core/patch-lint-cross.d.ts +27 -19
- package/dist/src/core/patch-lint-cross.js +67 -110
- package/dist/src/core/patch-lint-css.d.ts +1 -1
- package/dist/src/core/patch-lint-css.js +15 -11
- package/dist/src/core/patch-lint-diff-tag.d.ts +5 -5
- package/dist/src/core/patch-lint-diff-tag.js +5 -5
- package/dist/src/core/patch-lint-diff.d.ts +4 -4
- package/dist/src/core/patch-lint-diff.js +4 -4
- package/dist/src/core/patch-lint-file-size.d.ts +3 -3
- package/dist/src/core/patch-lint-file-size.js +6 -6
- package/dist/src/core/patch-lint-forward-registration.d.ts +58 -0
- package/dist/src/core/patch-lint-forward-registration.js +210 -0
- package/dist/src/core/patch-lint-jsdoc.d.ts +2 -2
- package/dist/src/core/patch-lint-jsdoc.js +46 -46
- package/dist/src/core/patch-lint-module-registration.d.ts +3 -9
- package/dist/src/core/patch-lint-module-registration.js +1 -1
- package/dist/src/core/patch-lint-mozbuild.d.ts +1 -1
- package/dist/src/core/patch-lint-mozbuild.js +10 -10
- package/dist/src/core/patch-lint-observer.d.ts +3 -3
- package/dist/src/core/patch-lint-observer.js +7 -7
- package/dist/src/core/patch-lint-ownership.d.ts +6 -6
- package/dist/src/core/patch-lint-ownership.js +6 -6
- package/dist/src/core/patch-lint-prettier.d.ts +6 -6
- package/dist/src/core/patch-lint-prettier.js +7 -7
- package/dist/src/core/patch-lint-queue-types.d.ts +60 -0
- package/dist/src/core/patch-lint-queue-types.js +12 -0
- package/dist/src/core/patch-lint-staged-registration.d.ts +61 -0
- package/dist/src/core/patch-lint-staged-registration.js +90 -0
- package/dist/src/core/patch-lint-unmanaged-companion.d.ts +23 -23
- package/dist/src/core/patch-lint-unmanaged-companion.js +26 -26
- package/dist/src/core/patch-lint.d.ts +41 -35
- package/dist/src/core/patch-lint.js +52 -49
- package/dist/src/core/patch-lock.d.ts +1 -1
- package/dist/src/core/patch-lock.js +11 -11
- package/dist/src/core/patch-manifest-consistency.d.ts +7 -7
- package/dist/src/core/patch-manifest-consistency.js +16 -17
- package/dist/src/core/patch-manifest-files-affected.d.ts +1 -1
- package/dist/src/core/patch-manifest-files-affected.js +3 -3
- package/dist/src/core/patch-manifest-io.d.ts +14 -14
- package/dist/src/core/patch-manifest-io.js +35 -34
- package/dist/src/core/patch-manifest-query.d.ts +1 -1
- package/dist/src/core/patch-manifest-query.js +4 -4
- package/dist/src/core/patch-manifest-resolve.d.ts +5 -5
- package/dist/src/core/patch-manifest-resolve.js +7 -7
- package/dist/src/core/patch-manifest-validate.js +3 -3
- package/dist/src/core/patch-manifest.d.ts +2 -2
- package/dist/src/core/patch-manifest.js +2 -2
- package/dist/src/core/patch-parse.d.ts +32 -21
- package/dist/src/core/patch-parse.js +40 -15
- package/dist/src/core/patch-policy.js +15 -27
- package/dist/src/core/patch-registration-refs.d.ts +4 -4
- package/dist/src/core/patch-registration-refs.js +7 -7
- package/dist/src/core/patch-source-metadata.d.ts +1 -3
- package/dist/src/core/patch-source-metadata.js +0 -4
- package/dist/src/core/patch-transform.d.ts +8 -16
- package/dist/src/core/patch-transform.js +13 -23
- package/dist/src/core/process-cpu-time.d.ts +1 -1
- package/dist/src/core/process-cpu-time.js +6 -6
- package/dist/src/core/rebase-session.d.ts +9 -15
- package/dist/src/core/rebase-session.js +13 -25
- package/dist/src/core/register-browser-content.js +3 -2
- package/dist/src/core/register-browser-test.js +2 -1
- package/dist/src/core/register-module.js +2 -1
- package/dist/src/core/register-result.d.ts +1 -1
- package/dist/src/core/register-result.js +1 -1
- package/dist/src/core/register-scaffold.d.ts +2 -2
- package/dist/src/core/register-scaffold.js +8 -7
- package/dist/src/core/register-shared-css.d.ts +3 -3
- package/dist/src/core/register-shared-css.js +6 -5
- package/dist/src/core/register-xpcshell-test.d.ts +2 -2
- package/dist/src/core/register-xpcshell-test.js +2 -2
- package/dist/src/core/run-log-redact.d.ts +38 -0
- package/dist/src/core/run-log-redact.js +69 -0
- package/dist/src/core/run-log.d.ts +21 -10
- package/dist/src/core/run-log.js +76 -27
- package/dist/src/core/shared-ftl.d.ts +2 -2
- package/dist/src/core/shared-ftl.js +6 -6
- package/dist/src/core/signal-critical.d.ts +2 -2
- package/dist/src/core/signal-critical.js +4 -6
- package/dist/src/core/smoke-patterns.d.ts +5 -6
- package/dist/src/core/smoke-patterns.js +15 -20
- package/dist/src/core/state-file.d.ts +15 -4
- package/dist/src/core/state-file.js +14 -1
- package/dist/src/core/status-binary.d.ts +8 -8
- package/dist/src/core/status-binary.js +12 -12
- package/dist/src/core/status-classify.d.ts +17 -17
- package/dist/src/core/status-classify.js +13 -12
- package/dist/src/core/test-changed-prefs.d.ts +12 -12
- package/dist/src/core/test-changed-prefs.js +40 -25
- package/dist/src/core/test-harness-crash.d.ts +39 -39
- package/dist/src/core/test-harness-crash.js +69 -69
- package/dist/src/core/test-harness-output.d.ts +7 -7
- package/dist/src/core/test-harness-output.js +7 -7
- package/dist/src/core/test-harness-verdict-notes.d.ts +13 -14
- package/dist/src/core/test-harness-verdict-notes.js +4 -4
- package/dist/src/core/test-path-scope.d.ts +8 -8
- package/dist/src/core/test-path-scope.js +11 -11
- package/dist/src/core/test-stale-check.d.ts +22 -23
- package/dist/src/core/test-stale-check.js +31 -30
- package/dist/src/core/test-stale-symlink.d.ts +1 -1
- package/dist/src/core/test-stale-symlink.js +1 -1
- package/dist/src/core/test-stall-triage.d.ts +9 -9
- package/dist/src/core/test-stall-triage.js +22 -22
- package/dist/src/core/test-xpcshell-retry.d.ts +26 -7
- package/dist/src/core/test-xpcshell-retry.js +14 -11
- package/dist/src/core/token-category.d.ts +35 -2
- package/dist/src/core/token-category.js +67 -58
- package/dist/src/core/token-coverage.js +4 -5
- package/dist/src/core/token-dark-mode.d.ts +9 -9
- package/dist/src/core/token-dark-mode.js +13 -25
- package/dist/src/core/token-docs.d.ts +1 -1
- package/dist/src/core/token-inventory.d.ts +56 -0
- package/dist/src/core/token-inventory.js +109 -0
- package/dist/src/core/token-manager.d.ts +4 -4
- package/dist/src/core/token-manager.js +22 -22
- package/dist/src/core/token-scaffold.d.ts +4 -4
- package/dist/src/core/token-scaffold.js +4 -4
- package/dist/src/core/token-variant.d.ts +14 -14
- package/dist/src/core/token-variant.js +52 -53
- package/dist/src/core/toolchain-preflight.d.ts +15 -15
- package/dist/src/core/toolchain-preflight.js +23 -23
- package/dist/src/core/tree-cow.d.ts +3 -5
- package/dist/src/core/tree-cow.js +8 -8
- package/dist/src/core/tree-guard.d.ts +3 -3
- package/dist/src/core/tree-guard.js +23 -23
- package/dist/src/core/tree-store.d.ts +15 -15
- package/dist/src/core/tree-store.js +39 -38
- package/dist/src/core/typecheck-shim.d.ts +16 -15
- package/dist/src/core/typecheck-shim.js +26 -25
- package/dist/src/core/typecheck.d.ts +12 -12
- package/dist/src/core/typecheck.js +33 -33
- package/dist/src/core/wire-destroy.d.ts +2 -2
- package/dist/src/core/wire-destroy.js +5 -5
- package/dist/src/core/wire-dom-fragment.d.ts +3 -3
- package/dist/src/core/wire-dom-fragment.js +12 -23
- package/dist/src/core/wire-init.d.ts +2 -2
- package/dist/src/core/wire-init.js +7 -7
- package/dist/src/core/wire-subscript.d.ts +1 -1
- package/dist/src/core/wire-subscript.js +3 -3
- package/dist/src/core/wire-utils.d.ts +9 -9
- package/dist/src/core/wire-utils.js +16 -28
- package/dist/src/core/xpcshell-appdir.d.ts +20 -20
- package/dist/src/core/xpcshell-appdir.js +28 -30
- package/dist/src/core/xpcshell-profile-dir.d.ts +3 -3
- package/dist/src/core/xpcshell-profile-dir.js +7 -7
- package/dist/src/errors/base.d.ts +69 -16
- package/dist/src/errors/base.js +95 -26
- package/dist/src/errors/build.d.ts +6 -6
- package/dist/src/errors/build.js +26 -34
- package/dist/src/errors/codes.d.ts +10 -10
- package/dist/src/errors/codes.js +10 -10
- package/dist/src/errors/config.d.ts +0 -14
- package/dist/src/errors/config.js +13 -34
- package/dist/src/errors/download.d.ts +13 -0
- package/dist/src/errors/download.js +53 -24
- package/dist/src/errors/furnace.d.ts +2 -2
- package/dist/src/errors/furnace.js +8 -9
- package/dist/src/errors/git.d.ts +9 -9
- package/dist/src/errors/git.js +21 -31
- package/dist/src/errors/patch.d.ts +3 -3
- package/dist/src/errors/patch.js +11 -13
- package/dist/src/errors/rebase.d.ts +1 -1
- package/dist/src/errors/rebase.js +8 -8
- package/dist/src/errors/run.d.ts +1 -1
- package/dist/src/errors/run.js +1 -1
- package/dist/src/index.d.ts +4 -4
- package/dist/src/index.js +4 -4
- package/dist/src/types/commands/options.d.ts +155 -200
- package/dist/src/types/commands/patches.d.ts +19 -19
- package/dist/src/types/commands/project.d.ts +3 -3
- package/dist/src/types/config.d.ts +52 -19
- package/dist/src/types/furnace.d.ts +17 -17
- package/dist/src/types/index.d.ts +0 -1
- package/dist/src/types/json.d.ts +3 -3
- package/dist/src/types/json.js +2 -2
- package/dist/src/types/typecheck.d.ts +3 -3
- package/dist/src/utils/assert.d.ts +4 -16
- package/dist/src/utils/assert.js +7 -24
- package/dist/src/utils/build-info.d.ts +6 -6
- package/dist/src/utils/build-info.js +6 -6
- package/dist/src/utils/child-env.d.ts +7 -6
- package/dist/src/utils/child-env.js +5 -5
- package/dist/src/utils/concurrency.d.ts +2 -2
- package/dist/src/utils/concurrency.js +2 -2
- package/dist/src/utils/elapsed.js +10 -1
- package/dist/src/utils/errors.d.ts +8 -8
- package/dist/src/utils/errors.js +8 -8
- package/dist/src/utils/fs.d.ts +1 -1
- package/dist/src/utils/fs.js +15 -20
- package/dist/src/utils/hash.d.ts +12 -0
- package/dist/src/utils/hash.js +16 -0
- package/dist/src/utils/line-dispatch.d.ts +15 -0
- package/dist/src/utils/line-dispatch.js +48 -0
- package/dist/src/utils/logger.d.ts +4 -4
- package/dist/src/utils/logger.js +11 -11
- package/dist/src/utils/machine-output.js +2 -2
- package/dist/src/utils/options.d.ts +14 -20
- package/dist/src/utils/options.js +26 -27
- package/dist/src/utils/package-root.js +5 -14
- package/dist/src/utils/paths.d.ts +4 -4
- package/dist/src/utils/paths.js +4 -4
- package/dist/src/utils/platform.d.ts +0 -4
- package/dist/src/utils/process-group.d.ts +10 -9
- package/dist/src/utils/process-group.js +37 -36
- package/dist/src/utils/process.d.ts +70 -55
- package/dist/src/utils/process.js +129 -179
- package/dist/src/utils/ps-duration.d.ts +4 -4
- package/dist/src/utils/ps-duration.js +9 -9
- package/dist/src/utils/regex.d.ts +4 -4
- package/dist/src/utils/regex.js +7 -7
- package/dist/src/utils/sleep.d.ts +26 -0
- package/dist/src/utils/sleep.js +31 -0
- package/dist/src/utils/stdio-drain.d.ts +7 -7
- package/dist/src/utils/stdio-drain.js +8 -8
- package/dist/src/utils/validation.d.ts +12 -49
- package/dist/src/utils/validation.js +26 -36
- package/docs/README.md +2 -2
- package/docs/configuration.md +163 -69
- package/docs/exit-codes.md +66 -49
- package/docs/furnace.md +20 -19
- package/docs/lifecycle-invariants.md +414 -247
- package/docs/machine-output.md +58 -34
- package/docs/patch-workflow.md +48 -44
- package/docs/run-logs.md +72 -28
- package/docs/testing.md +105 -98
- package/docs/verification-trees.md +23 -22
- package/package.json +7 -6
- package/dist/src/commands/rebase.d.ts +0 -4
- package/dist/src/commands/rebase.js +0 -5
- package/dist/src/core/patch-artifact-normalize.d.ts +0 -21
- package/dist/src/core/patch-artifact-normalize.js +0 -24
- package/dist/src/core/patch-lint-reexports.d.ts +0 -7
- package/dist/src/core/patch-lint-reexports.js +0 -8
- package/dist/src/core/wire-targets.d.ts +0 -7
- package/dist/src/core/wire-targets.js +0 -8
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
-
import { loadConfig } from '../core/config.js';
|
|
3
2
|
import { findNearestXpcshellManifest } from '../core/xpcshell-appdir.js';
|
|
4
3
|
import { GeneralError } from '../errors/base.js';
|
|
5
4
|
import { info, success } from '../utils/logger.js';
|
|
@@ -46,7 +45,7 @@ export function canaryTimeoutSeconds(projectConfig) {
|
|
|
46
45
|
/** Emits or throws the one-word canary verdict. */
|
|
47
46
|
export function reportCanaryOutcome(outcome) {
|
|
48
47
|
// Written raw as the run's last stdout line on green and throw paths
|
|
49
|
-
// alike
|
|
48
|
+
// alike. See the FIREFORGE-VERDICT contract in test-harness-crash.ts.
|
|
50
49
|
try {
|
|
51
50
|
if (outcome.verdict.kind === 'tests-ran-ok') {
|
|
52
51
|
success('Canary: green');
|
|
@@ -98,16 +97,16 @@ function buildMixedHarnessMessage(classification) {
|
|
|
98
97
|
* dispatch, so refusing it before spending minutes in a pre-test build
|
|
99
98
|
* is strictly better. A nonexistent path classifies as
|
|
100
99
|
* nonXpcshell (findNearestXpcshellManifest returns null), so classifying
|
|
101
|
-
* before assertTestPathsExist is harmless
|
|
100
|
+
* before assertTestPathsExist is harmless: existence is still asserted
|
|
102
101
|
* after the stale/coverage gates, preserving their precedence over
|
|
103
102
|
* missing-path errors. `xpcshellOnly` (non-empty request, zero
|
|
104
103
|
* nonXpcshell paths) gates the Marionette preflight and the mochitest
|
|
105
|
-
* client flags
|
|
104
|
+
* client flags. Pathless runs keep the full-suite behavior.
|
|
106
105
|
*/
|
|
107
106
|
export async function classifyBeforeDispatch(engineDir, normalizedPaths, options) {
|
|
108
107
|
const classification = await classifyTestHarnesses(engineDir, normalizedPaths);
|
|
109
108
|
if (classification.xpcshell.length > 0 && classification.nonXpcshell.length > 0) {
|
|
110
|
-
// `--build-only` never dispatches, so a mixed request is legal there
|
|
109
|
+
// `--build-only` never dispatches, so a mixed request is legal there:
|
|
111
110
|
// packaging the union is the whole point.
|
|
112
111
|
if (options?.allowMixed !== true) {
|
|
113
112
|
throw new GeneralError(buildMixedHarnessMessage(classification));
|
|
@@ -28,7 +28,7 @@ const TEST_HELP_TEXT = [
|
|
|
28
28
|
'Machine-readable verdict: every run (single, sharded, --canary,',
|
|
29
29
|
'--doctor) ends with exactly one raw stdout line',
|
|
30
30
|
' FIREFORGE-VERDICT: PASS|FAIL [reason=crash|test-failures|',
|
|
31
|
-
' no-tests|preflight|inconclusive|lock-timeout] [checks=<n>]',
|
|
31
|
+
' no-tests|preflight|inconclusive|lock-timeout|killed] [checks=<n>]',
|
|
32
32
|
' [unexpected=<n>] [shards=<p>/<t>] [(<note>)] [log=<path>]',
|
|
33
33
|
"log=<path> names this run's complete output, written to",
|
|
34
34
|
'.fireforge/logs/ as the run streams, so a piped or truncated run',
|
|
@@ -41,7 +41,9 @@ const TEST_HELP_TEXT = [
|
|
|
41
41
|
'errors); reason=inconclusive means engine/ changed while the',
|
|
42
42
|
'tests ran, so the harness result cannot be trusted;',
|
|
43
43
|
'reason=lock-timeout means the run never started because another',
|
|
44
|
-
'engine-mutating command held the lock past the wait budget
|
|
44
|
+
'engine-mutating command held the lock past the wait budget;',
|
|
45
|
+
'reason=killed means a signal terminated the run before it reached',
|
|
46
|
+
'any other outcome (written from the signal handler). A sharded',
|
|
45
47
|
'aggregate reason is the most structural failing shard (crash,',
|
|
46
48
|
'then no-tests, then test-failures). Count keys are omitted when',
|
|
47
49
|
'the embedded summary did not print them. A trailing parenthetical',
|
|
@@ -71,7 +73,7 @@ export function registerTest(program, { getProjectRoot, withErrorHandling }) {
|
|
|
71
73
|
.option('--canary [path]', 'Run one short browser-chrome harness canary. Uses test.canaryPath from fireforge.json when no path is supplied.')
|
|
72
74
|
.option('--doctor', 'Run a marionette handshake preflight before tests (exit 1 on FAIL). With no paths, runs the preflight only.')
|
|
73
75
|
.option('--mach-arg <arg>', 'Forward this argument verbatim to `mach test` (repeatable). Escape valve for upstream xpcshell/mochitest flags FireForge does not model.', ...stringListOption())
|
|
74
|
-
.option('--harness-retries <n>', `Retry budget for recognized harness crashes (resource-monitor tracebacks, pre-test hangs, post-green shutdown re-entry). 0 disables retries. Default: ${
|
|
76
|
+
.option('--harness-retries <n>', `Retry budget for recognized harness crashes (resource-monitor tracebacks, pre-test hangs, post-green shutdown re-entry). 0 disables retries. Default: ${DEFAULT_HARNESS_RETRIES}.`, commanderArgParser((raw) => {
|
|
75
77
|
const n = Number.parseInt(raw, 10);
|
|
76
78
|
if (!Number.isFinite(n) || n < 0 || n > 10) {
|
|
77
79
|
throw new GeneralError(`--harness-retries must be an integer in 0..10 (got "${raw}")`);
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* sequential per-file sharding of multi-path invocations.
|
|
4
4
|
*
|
|
5
5
|
* Sharding exists because passing several browser-chrome files to one mach
|
|
6
|
-
* invocation destabilizes later files
|
|
6
|
+
* invocation destabilizes later files: cross-file profile/pref bleed in the
|
|
7
7
|
* shared mochitest profile makes the second file time out at window-open
|
|
8
8
|
* while each file passes in isolation. Sequential single-file harness runs
|
|
9
|
-
* cost startup time but make results reproducible
|
|
9
|
+
* cost startup time but make results reproducible. The combined invocation
|
|
10
10
|
* stays available via `--no-shard`.
|
|
11
11
|
*/
|
|
12
12
|
import { type DisplaySleepState } from '../core/display-state.js';
|
|
@@ -54,8 +54,8 @@ export interface TestRunOutcome {
|
|
|
54
54
|
/** Whether xpcshell appdir injection was attempted for this invocation. */
|
|
55
55
|
appdirInjectionAttempted: boolean;
|
|
56
56
|
/**
|
|
57
|
-
* Display power state measured for a HEADED no-output stall
|
|
58
|
-
*
|
|
57
|
+
* Display power state measured for a HEADED no-output stall. Undefined
|
|
58
|
+
* when the shape did not apply and no probe ran.
|
|
59
59
|
*/
|
|
60
60
|
displayState?: DisplaySleepState | undefined;
|
|
61
61
|
}
|
|
@@ -68,7 +68,7 @@ export declare function runTestsWithRetries(ctx: TestRunContext, paths: string[]
|
|
|
68
68
|
/**
|
|
69
69
|
* One sequential harness invocation of a sharded run: a requested path
|
|
70
70
|
* argument and the mach paths dispatched for it. A file argument is a group
|
|
71
|
-
* of one
|
|
71
|
+
* of one. A directory argument groups its enumerated test files so the whole
|
|
72
72
|
* directory still runs in ONE browser instance, keeping cross-file state
|
|
73
73
|
* behaviour within a directory run.
|
|
74
74
|
*/
|
|
@@ -88,25 +88,25 @@ export interface ShardedRunSummary {
|
|
|
88
88
|
shards: ShardOutcome[];
|
|
89
89
|
passed: number;
|
|
90
90
|
total: number;
|
|
91
|
-
/** Aggregate classifier verdict
|
|
91
|
+
/** Aggregate classifier verdict. See {@link deriveAggregateShardVerdict}. */
|
|
92
92
|
aggregate: HarnessRunVerdict;
|
|
93
93
|
}
|
|
94
94
|
/**
|
|
95
95
|
* Derives the aggregate classification for a sharded run: all-green is
|
|
96
|
-
* `tests-ran-ok
|
|
96
|
+
* `tests-ran-ok`. Otherwise the most structural failure wins. A crashed
|
|
97
97
|
* shard makes the whole run `harness-crash`, then `no-tests`, then plain
|
|
98
|
-
* `test-failures
|
|
98
|
+
* `test-failures`, so the aggregate `reason=` keeps the classifier-driven
|
|
99
99
|
* contract instead of collapsing every failure to `test-failures`.
|
|
100
100
|
*/
|
|
101
101
|
export declare function deriveAggregateShardVerdict(shards: ShardOutcome[]): HarnessRunVerdict;
|
|
102
102
|
/**
|
|
103
103
|
* Runs each requested path argument as its own sequential harness
|
|
104
104
|
* invocation (a directory argument's enumerated files stay together in
|
|
105
|
-
* one invocation
|
|
105
|
+
* one invocation, see {@link ShardGroup}) and prints an aggregate
|
|
106
106
|
* report. Per-shard failures are diagnosed via `diagnoseShardFailure`
|
|
107
107
|
* (which receives the throwing diagnosis chain from the command layer)
|
|
108
108
|
* but downgraded to warnings so every shard runs. The aggregate verdict
|
|
109
|
-
* line and the aggregate error are
|
|
109
|
+
* line and the aggregate error are not produced here: the caller runs
|
|
110
110
|
* the engine-generation integrity check first and then calls
|
|
111
111
|
* {@link finalizeShardedOutcome}, so a run invalidated by a concurrent
|
|
112
112
|
* `engine/` mutation can never print `PASS` before the check fails.
|
|
@@ -114,7 +114,7 @@ export declare function deriveAggregateShardVerdict(shards: ShardOutcome[]): Har
|
|
|
114
114
|
export declare function runShardedTests(ctx: TestRunContext, groups: ShardGroup[], diagnoseShardFailure: (outcome: TestRunOutcome, label: string) => string | undefined): Promise<ShardedRunSummary>;
|
|
115
115
|
/**
|
|
116
116
|
* Emits the aggregate FIREFORGE-VERDICT line for a sharded run, then
|
|
117
|
-
* throws the aggregate error when any shard did not pass
|
|
117
|
+
* throws the aggregate error when any shard did not pass, the same
|
|
118
118
|
* emit-then-throw shape as `finalizeSingleRunOutcome`. Called only after
|
|
119
119
|
* the engine-generation check succeeded.
|
|
120
120
|
*/
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
* sequential per-file sharding of multi-path invocations.
|
|
5
5
|
*
|
|
6
6
|
* Sharding exists because passing several browser-chrome files to one mach
|
|
7
|
-
* invocation destabilizes later files
|
|
7
|
+
* invocation destabilizes later files: cross-file profile/pref bleed in the
|
|
8
8
|
* shared mochitest profile makes the second file time out at window-open
|
|
9
9
|
* while each file passes in isolation. Sequential single-file harness runs
|
|
10
|
-
* cost startup time but make results reproducible
|
|
10
|
+
* cost startup time but make results reproducible. The combined invocation
|
|
11
11
|
* stays available via `--no-shard`.
|
|
12
12
|
*/
|
|
13
13
|
import { probeDisplaySleepState } from '../core/display-state.js';
|
|
14
|
-
import {
|
|
14
|
+
import { runMachTestSuite } from '../core/mach.js';
|
|
15
15
|
import { getActiveRunLogPath } from '../core/run-log.js';
|
|
16
16
|
import { changedPrefNoiseVerdictNote } from '../core/test-changed-prefs.js';
|
|
17
17
|
import { buildHarnessCrashMessage, classifyHarnessRun, headedDisplayAsleepVerdictNote, headedNoOutputTimeoutHint, } from '../core/test-harness-crash.js';
|
|
@@ -24,13 +24,13 @@ import { maybeInjectAppdirArg } from './test-appdir.js';
|
|
|
24
24
|
import { emitHarnessVerdict } from './test-verdict.js';
|
|
25
25
|
/** Default bounded retry budget for recognized harness crashes. */
|
|
26
26
|
export const DEFAULT_HARNESS_RETRIES = 2;
|
|
27
|
-
/** Resolves the
|
|
28
|
-
function
|
|
27
|
+
/** Resolves the mach test command a suite dispatches to. */
|
|
28
|
+
function machKindForSuite(suite) {
|
|
29
29
|
if (suite === 'xpcshell')
|
|
30
|
-
return
|
|
30
|
+
return 'xpcshell-test';
|
|
31
31
|
if (suite === 'mochitest')
|
|
32
|
-
return
|
|
33
|
-
return
|
|
32
|
+
return 'mochitest';
|
|
33
|
+
return 'test';
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
36
|
* Runs one mach test invocation for `paths`, retrying recognized harness
|
|
@@ -38,40 +38,47 @@ function dispatchForSuite(suite) {
|
|
|
38
38
|
* stale-xpcshell-symlink repair path the single-run flow already used.
|
|
39
39
|
*/
|
|
40
40
|
export async function runTestsWithRetries(ctx, paths) {
|
|
41
|
-
// Pure mochitest dispatches keep their env byte-identical
|
|
41
|
+
// Pure mochitest dispatches keep their env byte-identical, since the profile
|
|
42
42
|
// variable is xpcshell-harness-specific. Generic `mach
|
|
43
43
|
// test` runs may include xpcshell paths, so they get the isolation too.
|
|
44
44
|
if (ctx.suite === 'mochitest') {
|
|
45
45
|
return runTestsWithRetriesInner(ctx, paths, ctx.env);
|
|
46
46
|
}
|
|
47
47
|
// Fresh profile dir per harness invocation: shards isolate from each
|
|
48
|
-
// other and from concurrent `fireforge test` processes
|
|
49
|
-
// symlink-repair retries inside one invocation
|
|
50
|
-
//
|
|
48
|
+
// other and from concurrent `fireforge test` processes. The crash /
|
|
49
|
+
// symlink-repair retries inside one invocation reuse the same directory
|
|
50
|
+
// on purpose (they are the same logical run and the harness
|
|
51
51
|
// re-initialises the profile contents itself).
|
|
52
52
|
return withXpcshellProfileDir(ctx.env, (env) => runTestsWithRetriesInner(ctx, paths, env));
|
|
53
53
|
}
|
|
54
54
|
async function runTestsWithRetriesInner(ctx, paths, env) {
|
|
55
55
|
const extraArgs = [...ctx.baseExtraArgs];
|
|
56
56
|
const appdirInjectionAttempted = await maybeInjectAppdirArg(ctx.engineDir, paths, ctx.objDir, extraArgs);
|
|
57
|
-
const
|
|
57
|
+
const kind = machKindForSuite(ctx.suite);
|
|
58
58
|
const maxAttempts = Math.max(1, ctx.harnessRetries + 1);
|
|
59
59
|
let attempts = 0;
|
|
60
60
|
let result;
|
|
61
61
|
let verdict;
|
|
62
62
|
for (;;) {
|
|
63
63
|
attempts += 1;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
ctx.fullOutput
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
64
|
+
result = await runMachTestSuite(kind, {
|
|
65
|
+
engineDir: ctx.engineDir,
|
|
66
|
+
testPaths: paths,
|
|
67
|
+
args: extraArgs,
|
|
68
|
+
env,
|
|
69
|
+
fullOutput: ctx.fullOutput,
|
|
70
|
+
});
|
|
71
|
+
result = await retryAfterXpcshellSymlinkRepair({
|
|
72
|
+
engineDir: ctx.engineDir,
|
|
73
|
+
objDir: ctx.objDir,
|
|
74
|
+
result,
|
|
75
|
+
classification: ctx.classification,
|
|
76
|
+
normalizedPaths: paths,
|
|
77
|
+
extraArgs,
|
|
78
|
+
env,
|
|
79
|
+
kind,
|
|
80
|
+
fullOutput: ctx.fullOutput,
|
|
81
|
+
});
|
|
75
82
|
const combined = `${result.stdout}\n${result.stderr}`;
|
|
76
83
|
verdict = classifyHarnessRun(result.exitCode, combined, paths);
|
|
77
84
|
if (verdict.kind !== 'harness-crash' || attempts >= maxAttempts)
|
|
@@ -81,7 +88,7 @@ async function runTestsWithRetriesInner(ctx, paths, env) {
|
|
|
81
88
|
`Retrying (attempt ${attempts + 1} of ${maxAttempts})...`);
|
|
82
89
|
}
|
|
83
90
|
// A verdict whose every unexpected result is time-driven pref noise is
|
|
84
|
-
// still a FAIL
|
|
91
|
+
// still a FAIL. Only the note changes, so a `unexpected=2` line is not
|
|
85
92
|
// read as two real assertion failures.
|
|
86
93
|
if (verdict.kind === 'test-failures' && verdict.note === undefined) {
|
|
87
94
|
const prefNote = changedPrefNoiseVerdictNote(`${result.stdout}\n${result.stderr}`);
|
|
@@ -101,9 +108,9 @@ async function runTestsWithRetriesInner(ctx, paths, env) {
|
|
|
101
108
|
return { result, verdict, attempts, appdirInjectionAttempted, displayState };
|
|
102
109
|
}
|
|
103
110
|
/**
|
|
104
|
-
* Probes the display's power state for a
|
|
105
|
-
* that shape. Every other outcome
|
|
106
|
-
* headless run, any other crash shape
|
|
111
|
+
* Probes the display's power state for a headed no-output stall, and only for
|
|
112
|
+
* that shape. Every other outcome (a passing run, a real test failure, a
|
|
113
|
+
* headless run, any other crash shape) skips the probe entirely, so the
|
|
107
114
|
* common paths spawn nothing.
|
|
108
115
|
*
|
|
109
116
|
* @returns The measured state, or undefined when the shape does not apply
|
|
@@ -125,9 +132,9 @@ const SHARD_STATUS_LABEL = {
|
|
|
125
132
|
};
|
|
126
133
|
/**
|
|
127
134
|
* Derives the aggregate classification for a sharded run: all-green is
|
|
128
|
-
* `tests-ran-ok
|
|
135
|
+
* `tests-ran-ok`. Otherwise the most structural failure wins. A crashed
|
|
129
136
|
* shard makes the whole run `harness-crash`, then `no-tests`, then plain
|
|
130
|
-
* `test-failures
|
|
137
|
+
* `test-failures`, so the aggregate `reason=` keeps the classifier-driven
|
|
131
138
|
* contract instead of collapsing every failure to `test-failures`.
|
|
132
139
|
*/
|
|
133
140
|
export function deriveAggregateShardVerdict(shards) {
|
|
@@ -143,11 +150,11 @@ export function deriveAggregateShardVerdict(shards) {
|
|
|
143
150
|
/**
|
|
144
151
|
* Runs each requested path argument as its own sequential harness
|
|
145
152
|
* invocation (a directory argument's enumerated files stay together in
|
|
146
|
-
* one invocation
|
|
153
|
+
* one invocation, see {@link ShardGroup}) and prints an aggregate
|
|
147
154
|
* report. Per-shard failures are diagnosed via `diagnoseShardFailure`
|
|
148
155
|
* (which receives the throwing diagnosis chain from the command layer)
|
|
149
156
|
* but downgraded to warnings so every shard runs. The aggregate verdict
|
|
150
|
-
* line and the aggregate error are
|
|
157
|
+
* line and the aggregate error are not produced here: the caller runs
|
|
151
158
|
* the engine-generation integrity check first and then calls
|
|
152
159
|
* {@link finalizeShardedOutcome}, so a run invalidated by a concurrent
|
|
153
160
|
* `engine/` mutation can never print `PASS` before the check fails.
|
|
@@ -186,7 +193,7 @@ export async function runShardedTests(ctx, groups, diagnoseShardFailure) {
|
|
|
186
193
|
}
|
|
187
194
|
/**
|
|
188
195
|
* Emits the aggregate FIREFORGE-VERDICT line for a sharded run, then
|
|
189
|
-
* throws the aggregate error when any shard did not pass
|
|
196
|
+
* throws the aggregate error when any shard did not pass, the same
|
|
190
197
|
* emit-then-throw shape as `finalizeSingleRunOutcome`. Called only after
|
|
191
198
|
* the engine-generation check succeeded.
|
|
192
199
|
*/
|
|
@@ -3,40 +3,40 @@
|
|
|
3
3
|
* and a run against a stale or under-packaged runtime: the packaging
|
|
4
4
|
* coverage refusal, the stale-content refusal, and the compiled
|
|
5
5
|
* StaticComponents refusal. Split out of `test.ts` so the command module
|
|
6
|
-
* stays wiring
|
|
6
|
+
* stays wiring. The probes and refusal copy live in
|
|
7
7
|
* `src/core/test-stale-check.ts`.
|
|
8
8
|
*/
|
|
9
9
|
import type { BuildBaseline } from '../core/build-baseline-types.js';
|
|
10
10
|
import type { TestOptions } from '../types/commands/index.js';
|
|
11
11
|
/**
|
|
12
|
-
* Stale-build preflight
|
|
13
|
-
* engine edits since the last successful build and fail
|
|
12
|
+
* Stale-build preflight: when `--build` was not requested, detect packageable
|
|
13
|
+
* engine edits since the last successful build and fail up front unless the
|
|
14
14
|
* operator explicitly accepts the stale package risk.
|
|
15
15
|
*
|
|
16
|
-
* Packaging
|
|
16
|
+
* Packaging coverage is checked first, on every non-`--build` run and
|
|
17
17
|
* regardless of staleness or `--allow-stale-build`: a runtime packaged by a
|
|
18
|
-
* file-scoped `test --build` can lack support fixtures for
|
|
19
|
-
* even when nothing changed since
|
|
18
|
+
* file-scoped `test --build` can lack support fixtures for other manifests
|
|
19
|
+
* even when nothing changed since, and dispatching such a run hangs on missing
|
|
20
20
|
* fixtures rather than failing, so the flag (which only accepts stale
|
|
21
|
-
*
|
|
21
|
+
* content) must not be the trigger. A three-file scoped rebuild leaving one
|
|
22
22
|
* fixture unpackaged makes a later run over different files time out waiting
|
|
23
23
|
* on an event that never fires.
|
|
24
24
|
*
|
|
25
25
|
* Exception: a path-less `test --doctor` stops at the Marionette health check
|
|
26
26
|
* (`runDoctorPreflight` returns 'stop' when no test paths were given) and
|
|
27
|
-
* never dispatches a test, so it needs no packaging coverage
|
|
27
|
+
* never dispatches a test, so it needs no packaging coverage. Treating it as
|
|
28
28
|
* a full-suite request would refuse a probe that touches no fixtures. The
|
|
29
29
|
* stale-content refusal still applies to it unchanged.
|
|
30
30
|
*/
|
|
31
31
|
export declare function enforceStaleBuildGate(projectRoot: string, engineDir: string, options: TestOptions, normalizedPaths: readonly string[]): Promise<void>;
|
|
32
32
|
/**
|
|
33
|
-
* Compiled-StaticComponents gate
|
|
33
|
+
* Compiled-StaticComponents gate: refuses runs whose child process would
|
|
34
34
|
* resolve a stale compiled component table. `components.conf` entries bake
|
|
35
|
-
* into compiled code that only a
|
|
35
|
+
* into compiled code that only a full build regenerates. A scoped
|
|
36
36
|
* `test --build` repackages the file but the failure surfaces as
|
|
37
37
|
* `NS_ERROR_MALFORMED_URI` inside the test. Applies to build-less runs
|
|
38
|
-
* (after the coverage refusal)
|
|
39
|
-
* the pre-test build
|
|
38
|
+
* (after the coverage refusal) and to scoped `test --build` runs (before
|
|
39
|
+
* the pre-test build, which cannot fix the table). A path-less
|
|
40
40
|
* `test --build` is exempt: its full build refreshes the anchor itself.
|
|
41
41
|
* `--allow-stale-components` downgrades the refusal to a warning.
|
|
42
42
|
*/
|
|
@@ -4,29 +4,29 @@
|
|
|
4
4
|
* and a run against a stale or under-packaged runtime: the packaging
|
|
5
5
|
* coverage refusal, the stale-content refusal, and the compiled
|
|
6
6
|
* StaticComponents refusal. Split out of `test.ts` so the command module
|
|
7
|
-
* stays wiring
|
|
7
|
+
* stays wiring. The probes and refusal copy live in
|
|
8
8
|
* `src/core/test-stale-check.ts`.
|
|
9
9
|
*/
|
|
10
10
|
import { checkStaleBuildForTest, checkStaticComponentsStale, findChangedTestManifestsForPaths, findUncoveredRequestPaths, formatStaleBuildWarning, formatStaticComponentsRefusal, formatTestCoverageRefusal, } from '../core/test-stale-check.js';
|
|
11
|
-
import {
|
|
11
|
+
import { PreflightRefusalError } from '../errors/base.js';
|
|
12
12
|
import { warn } from '../utils/logger.js';
|
|
13
13
|
/**
|
|
14
|
-
* Stale-build preflight
|
|
15
|
-
* engine edits since the last successful build and fail
|
|
14
|
+
* Stale-build preflight: when `--build` was not requested, detect packageable
|
|
15
|
+
* engine edits since the last successful build and fail up front unless the
|
|
16
16
|
* operator explicitly accepts the stale package risk.
|
|
17
17
|
*
|
|
18
|
-
* Packaging
|
|
18
|
+
* Packaging coverage is checked first, on every non-`--build` run and
|
|
19
19
|
* regardless of staleness or `--allow-stale-build`: a runtime packaged by a
|
|
20
|
-
* file-scoped `test --build` can lack support fixtures for
|
|
21
|
-
* even when nothing changed since
|
|
20
|
+
* file-scoped `test --build` can lack support fixtures for other manifests
|
|
21
|
+
* even when nothing changed since, and dispatching such a run hangs on missing
|
|
22
22
|
* fixtures rather than failing, so the flag (which only accepts stale
|
|
23
|
-
*
|
|
23
|
+
* content) must not be the trigger. A three-file scoped rebuild leaving one
|
|
24
24
|
* fixture unpackaged makes a later run over different files time out waiting
|
|
25
25
|
* on an event that never fires.
|
|
26
26
|
*
|
|
27
27
|
* Exception: a path-less `test --doctor` stops at the Marionette health check
|
|
28
28
|
* (`runDoctorPreflight` returns 'stop' when no test paths were given) and
|
|
29
|
-
* never dispatches a test, so it needs no packaging coverage
|
|
29
|
+
* never dispatches a test, so it needs no packaging coverage. Treating it as
|
|
30
30
|
* a full-suite request would refuse a probe that touches no fixtures. The
|
|
31
31
|
* stale-content refusal still applies to it unchanged.
|
|
32
32
|
*/
|
|
@@ -37,10 +37,10 @@ export async function enforceStaleBuildGate(projectRoot, engineDir, options, nor
|
|
|
37
37
|
const recordedCoverage = stale.baseline?.testPackagingCoverage;
|
|
38
38
|
const uncovered = findUncoveredRequestPaths(recordedCoverage, normalizedPaths);
|
|
39
39
|
if (uncovered.length > 0) {
|
|
40
|
-
// The refusal is correct on its own
|
|
40
|
+
// The refusal is correct on its own. Naming the manifest that gained
|
|
41
41
|
// an entry is the triage step it otherwise leaves to the reader.
|
|
42
42
|
const changedManifests = await findChangedTestManifestsForPaths(engineDir, stale.baseline, uncovered);
|
|
43
|
-
throw new
|
|
43
|
+
throw new PreflightRefusalError(formatTestCoverageRefusal(uncovered, Array.isArray(recordedCoverage) ? recordedCoverage : [], changedManifests), 'coverage-replaced');
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
await enforceStaticComponentsGate(engineDir, stale.baseline, options);
|
|
@@ -59,18 +59,18 @@ export async function enforceStaleBuildGate(projectRoot, engineDir, options, nor
|
|
|
59
59
|
warn(staleMessage);
|
|
60
60
|
}
|
|
61
61
|
else {
|
|
62
|
-
throw new
|
|
62
|
+
throw new PreflightRefusalError(staleMessage, 'stale-build');
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
/**
|
|
67
|
-
* Compiled-StaticComponents gate
|
|
67
|
+
* Compiled-StaticComponents gate: refuses runs whose child process would
|
|
68
68
|
* resolve a stale compiled component table. `components.conf` entries bake
|
|
69
|
-
* into compiled code that only a
|
|
69
|
+
* into compiled code that only a full build regenerates. A scoped
|
|
70
70
|
* `test --build` repackages the file but the failure surfaces as
|
|
71
71
|
* `NS_ERROR_MALFORMED_URI` inside the test. Applies to build-less runs
|
|
72
|
-
* (after the coverage refusal)
|
|
73
|
-
* the pre-test build
|
|
72
|
+
* (after the coverage refusal) and to scoped `test --build` runs (before
|
|
73
|
+
* the pre-test build, which cannot fix the table). A path-less
|
|
74
74
|
* `test --build` is exempt: its full build refreshes the anchor itself.
|
|
75
75
|
* `--allow-stale-components` downgrades the refusal to a warning.
|
|
76
76
|
*/
|
|
@@ -84,5 +84,5 @@ export async function enforceStaticComponentsGate(engineDir, baseline, options)
|
|
|
84
84
|
warn(message);
|
|
85
85
|
return;
|
|
86
86
|
}
|
|
87
|
-
throw new
|
|
87
|
+
throw new PreflightRefusalError(message, 'stale-components');
|
|
88
88
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { HarnessRunVerdict } from '../core/test-harness-crash.js';
|
|
2
2
|
/**
|
|
3
3
|
* Reason codes the emission layer can put on a `FIREFORGE-VERDICT: FAIL`
|
|
4
|
-
* line. The first three mirror the harness classifier
|
|
4
|
+
* line. The first three mirror the harness classifier. `preflight` covers
|
|
5
5
|
* every failure before harness classification (missing/stale builds,
|
|
6
6
|
* invalid paths, port conflicts, config errors, spawn failures),
|
|
7
7
|
* `inconclusive` marks a run whose harness result exists but cannot be
|
|
@@ -30,13 +30,27 @@ export declare function emitHarnessVerdict(verdict: HarnessRunVerdict, shards?:
|
|
|
30
30
|
}): void;
|
|
31
31
|
/** Emits the pathless `--doctor` PASS verdict. */
|
|
32
32
|
export declare function emitPassVerdict(): void;
|
|
33
|
-
/**
|
|
34
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Emits a FAIL verdict carrying an emission-layer reason code, and
|
|
35
|
+
* optionally the refusal class that produced it.
|
|
36
|
+
*
|
|
37
|
+
* `note=` is additive, like the `log=`, `signal=` and `shards=` keys already
|
|
38
|
+
* on this line: `reason=` is unchanged and still comes from the closed set
|
|
39
|
+
* in `docs/machine-output.md`, so a consumer that tokenises `key=value`
|
|
40
|
+
* pairs is unaffected. It exists because `reason=preflight` covers every
|
|
41
|
+
* gate before the harness (a missing build, a peer's packaging record, a
|
|
42
|
+
* developer browser holding the objdir), and an unattended reader whose
|
|
43
|
+
* pipe kept only the verdict line could not tell those apart.
|
|
44
|
+
*
|
|
45
|
+
* @param reason - Closed-set verdict reason
|
|
46
|
+
* @param note - Stable refusal class, when the thrower named one
|
|
47
|
+
*/
|
|
48
|
+
export declare function emitFailVerdict(reason: FireforgeVerdictReason, note?: string): void;
|
|
35
49
|
/**
|
|
36
50
|
* Emits the terminal verdict for a run killed by a signal.
|
|
37
51
|
*
|
|
38
|
-
* Without it a killed run wrote
|
|
39
|
-
* distinguish "killed" from "still running" from "never started"
|
|
52
|
+
* Without it a killed run wrote no terminal line, so a log tail could not
|
|
53
|
+
* distinguish "killed" from "still running" from "never started". Recovery
|
|
40
54
|
* meant checking `ps` and the lock file by hand, at the exact moment (a
|
|
41
55
|
* mass kill under a usage limit, mid-drain) when the tree's state most
|
|
42
56
|
* needs to be readable. A no-op unless a run was actually in flight: the
|
|
@@ -27,21 +27,21 @@ export function verdictEmitted() {
|
|
|
27
27
|
return emitted;
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
|
-
* Writes the run's single verdict line
|
|
31
|
-
* drop output under non-TTY capture)
|
|
30
|
+
* Writes the run's single verdict line to raw stdout (clack's renderer can
|
|
31
|
+
* drop output under non-TTY capture). First write wins. Every later call
|
|
32
32
|
* is a no-op: the writer closest to the harness result runs first, so the
|
|
33
33
|
* fallback layers (the engine-generation guard, the preflight wrapper)
|
|
34
34
|
* can emit unconditionally without risking a second line. Writing also
|
|
35
|
-
* seals stdout: the verdict must stay the run's
|
|
36
|
-
* subsequent logger output
|
|
37
|
-
* rendering after an emit-then-throw path
|
|
35
|
+
* seals stdout: the verdict must stay the run's last stdout write, so all
|
|
36
|
+
* subsequent logger output, including the CLI-boundary error/cancel
|
|
37
|
+
* rendering after an emit-then-throw path, routes to stderr.
|
|
38
38
|
*/
|
|
39
39
|
function writeVerdictLine(line) {
|
|
40
40
|
if (emitted)
|
|
41
41
|
return;
|
|
42
42
|
emitted = true;
|
|
43
43
|
// The run log's path rides the verdict line because the verdict must stay
|
|
44
|
-
// the run's
|
|
44
|
+
// the run's last stdout write: a separate announcement after it would
|
|
45
45
|
// break that contract, and one before it is the first thing a `tail` cuts.
|
|
46
46
|
// Appended as an additive `key=value`, so consumers that tokenize the line
|
|
47
47
|
// are unaffected and a truncated tail still says where the full output is.
|
|
@@ -61,15 +61,30 @@ export function emitHarnessVerdict(verdict, shards) {
|
|
|
61
61
|
export function emitPassVerdict() {
|
|
62
62
|
writeVerdictLine('FIREFORGE-VERDICT: PASS');
|
|
63
63
|
}
|
|
64
|
-
/**
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Emits a FAIL verdict carrying an emission-layer reason code, and
|
|
66
|
+
* optionally the refusal class that produced it.
|
|
67
|
+
*
|
|
68
|
+
* `note=` is additive, like the `log=`, `signal=` and `shards=` keys already
|
|
69
|
+
* on this line: `reason=` is unchanged and still comes from the closed set
|
|
70
|
+
* in `docs/machine-output.md`, so a consumer that tokenises `key=value`
|
|
71
|
+
* pairs is unaffected. It exists because `reason=preflight` covers every
|
|
72
|
+
* gate before the harness (a missing build, a peer's packaging record, a
|
|
73
|
+
* developer browser holding the objdir), and an unattended reader whose
|
|
74
|
+
* pipe kept only the verdict line could not tell those apart.
|
|
75
|
+
*
|
|
76
|
+
* @param reason - Closed-set verdict reason
|
|
77
|
+
* @param note - Stable refusal class, when the thrower named one
|
|
78
|
+
*/
|
|
79
|
+
export function emitFailVerdict(reason, note) {
|
|
80
|
+
const suffix = note === undefined ? '' : ` note=${note}`;
|
|
81
|
+
writeVerdictLine(`FIREFORGE-VERDICT: FAIL reason=${reason}${suffix}`);
|
|
67
82
|
}
|
|
68
83
|
/**
|
|
69
84
|
* Emits the terminal verdict for a run killed by a signal.
|
|
70
85
|
*
|
|
71
|
-
* Without it a killed run wrote
|
|
72
|
-
* distinguish "killed" from "still running" from "never started"
|
|
86
|
+
* Without it a killed run wrote no terminal line, so a log tail could not
|
|
87
|
+
* distinguish "killed" from "still running" from "never started". Recovery
|
|
73
88
|
* meant checking `ps` and the lock file by hand, at the exact moment (a
|
|
74
89
|
* mass kill under a usage limit, mid-drain) when the tree's state most
|
|
75
90
|
* needs to be readable. A no-op unless a run was actually in flight: the
|
|
@@ -4,9 +4,9 @@ import type { TestOptions } from '../types/commands/index.js';
|
|
|
4
4
|
*
|
|
5
5
|
* Owns the run's exactly-one-`FIREFORGE-VERDICT:`-line guarantee: the sink
|
|
6
6
|
* is re-armed at entry, and any failure that reaches this boundary without
|
|
7
|
-
* an inner writer having emitted
|
|
8
|
-
* build, config errors, stale-build and port gates, missing paths
|
|
9
|
-
* harness process that failed to start
|
|
7
|
+
* an inner writer having emitted (the preflight ladder: missing engine or
|
|
8
|
+
* build, config errors, stale-build and port gates, missing paths, and a
|
|
9
|
+
* harness process that failed to start) emits `FAIL reason=preflight`,
|
|
10
10
|
* since no harness classification exists for such a run. Writers closer to
|
|
11
11
|
* the harness (doctor, canary, single, sharded, the engine-generation
|
|
12
12
|
* guard) emit first and win.
|