@hominis/fireforge 0.45.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +80 -0
- package/dist/bin/fireforge.js +6 -0
- package/dist/build-info.json +4 -4
- package/dist/src/cli-usage-error.d.ts +46 -0
- package/dist/src/cli-usage-error.js +81 -0
- package/dist/src/cli.d.ts +5 -1
- package/dist/src/cli.js +20 -21
- package/dist/src/commands/bootstrap.js +1 -2
- package/dist/src/commands/build.js +15 -6
- package/dist/src/commands/destructive-decision.d.ts +19 -0
- package/dist/src/commands/destructive-decision.js +31 -0
- package/dist/src/commands/doctor-check-core.d.ts +0 -6
- package/dist/src/commands/doctor-check-core.js +0 -8
- package/dist/src/commands/doctor-orphaned-harness.d.ts +0 -6
- package/dist/src/commands/doctor-orphaned-harness.js +4 -12
- package/dist/src/commands/doctor-post-rebase-audit.js +1 -1
- package/dist/src/commands/doctor.d.ts +2 -0
- package/dist/src/commands/doctor.js +7 -8
- package/dist/src/commands/download.js +35 -24
- package/dist/src/commands/export-all.js +21 -4
- package/dist/src/commands/export-flow.js +15 -45
- package/dist/src/commands/export-placement-conflicts.js +3 -3
- package/dist/src/commands/export-placement-gate.js +2 -8
- package/dist/src/commands/export-placement-policy.js +3 -5
- package/dist/src/commands/export-shared.d.ts +42 -23
- package/dist/src/commands/export-shared.js +4 -19
- package/dist/src/commands/export.js +10 -1
- package/dist/src/commands/furnace/authoring-config.d.ts +13 -0
- package/dist/src/commands/furnace/authoring-config.js +19 -0
- package/dist/src/commands/furnace/chrome-doc-remove.js +1 -1
- package/dist/src/commands/furnace/create-browser-test.js +3 -8
- package/dist/src/commands/furnace/create-dry-run.js +2 -5
- package/dist/src/commands/furnace/create-templates.d.ts +17 -1
- package/dist/src/commands/furnace/create-templates.js +2 -1
- package/dist/src/commands/furnace/create.js +25 -19
- package/dist/src/commands/furnace/deploy.js +11 -2
- package/dist/src/commands/furnace/init.js +2 -1
- package/dist/src/commands/furnace/override.js +28 -19
- package/dist/src/commands/furnace/refresh.js +9 -1
- package/dist/src/commands/furnace/remove-mutations.d.ts +6 -7
- package/dist/src/commands/furnace/remove-mutations.js +0 -1
- package/dist/src/commands/furnace/remove.js +2 -6
- package/dist/src/commands/furnace/rename-browser-test.js +1 -7
- package/dist/src/commands/furnace/rename.js +29 -29
- package/dist/src/commands/furnace/status.js +12 -9
- package/dist/src/commands/furnace/test-file-name.d.ts +28 -0
- package/dist/src/commands/furnace/test-file-name.js +39 -0
- package/dist/src/commands/furnace/validation-output.d.ts +21 -9
- package/dist/src/commands/furnace/validation-output.js +3 -8
- package/dist/src/commands/import.js +2 -9
- package/dist/src/commands/lint-per-patch.d.ts +2 -2
- package/dist/src/commands/lint-per-patch.js +19 -4
- package/dist/src/commands/lint-per-run-checkjs.d.ts +2 -2
- package/dist/src/commands/lint.d.ts +2 -1
- package/dist/src/commands/lint.js +1 -1
- package/dist/src/commands/manifest.js +1 -1
- package/dist/src/commands/package.js +2 -4
- package/dist/src/commands/patch/compact.js +14 -15
- package/dist/src/commands/patch/delete.js +15 -25
- package/dist/src/commands/patch/entry-projection.d.ts +13 -0
- package/dist/src/commands/patch/entry-projection.js +24 -0
- package/dist/src/commands/patch/lint-ignore.d.ts +0 -8
- package/dist/src/commands/patch/lint-ignore.js +19 -29
- package/dist/src/commands/patch/move-files-create.js +24 -10
- package/dist/src/commands/patch/move-files-into.js +38 -34
- package/dist/src/commands/patch/move-files.js +4 -13
- package/dist/src/commands/patch/rename.js +27 -41
- package/dist/src/commands/patch/reorder.js +25 -38
- package/dist/src/commands/patch/split-plan.d.ts +4 -5
- package/dist/src/commands/patch/split-plan.js +4 -8
- package/dist/src/commands/patch/split.js +45 -43
- package/dist/src/commands/patch/staged-dependency.js +16 -22
- package/dist/src/commands/patch/tier.js +15 -25
- package/dist/src/commands/patch-rename-map.d.ts +19 -0
- package/dist/src/commands/patch-rename-map.js +36 -0
- package/dist/src/commands/pending-resolution.d.ts +15 -0
- package/dist/src/commands/pending-resolution.js +25 -0
- package/dist/src/commands/re-export-adjacent.d.ts +24 -2
- package/dist/src/commands/re-export-adjacent.js +32 -16
- package/dist/src/commands/re-export-bulk-scan.js +6 -10
- package/dist/src/commands/re-export-drift.js +4 -4
- package/dist/src/commands/re-export-files.d.ts +2 -3
- package/dist/src/commands/re-export-files.js +38 -29
- package/dist/src/commands/re-export-lint.d.ts +3 -4
- package/dist/src/commands/re-export-lint.js +9 -2
- package/dist/src/commands/re-export-scan.js +5 -2
- package/dist/src/commands/re-export-single.d.ts +22 -3
- package/dist/src/commands/re-export-single.js +19 -11
- package/dist/src/commands/re-export.js +28 -11
- package/dist/src/commands/rebase/abort.js +3 -8
- package/dist/src/commands/rebase/continue.js +12 -12
- package/dist/src/commands/rebase/index.js +2 -2
- package/dist/src/commands/rebase/patch-loop.d.ts +2 -2
- package/dist/src/commands/rebase/patch-loop.js +2 -7
- package/dist/src/commands/resolve.js +18 -10
- package/dist/src/commands/run.d.ts +0 -13
- package/dist/src/commands/run.js +12 -25
- package/dist/src/commands/setup-support.d.ts +16 -4
- package/dist/src/commands/setup-support.js +16 -16
- package/dist/src/commands/setup.js +3 -9
- package/dist/src/commands/source.js +8 -1
- package/dist/src/commands/status-check.js +2 -2
- package/dist/src/commands/status-output.js +2 -2
- package/dist/src/commands/status.js +3 -4
- package/dist/src/commands/test-build-phase.d.ts +2 -2
- package/dist/src/commands/test-build-phase.js +31 -7
- package/dist/src/commands/test-modes.d.ts +2 -2
- package/dist/src/commands/test-modes.js +0 -1
- package/dist/src/commands/test-register.js +5 -3
- package/dist/src/commands/test-run.js +25 -18
- package/dist/src/commands/test-stale-gate.js +4 -4
- package/dist/src/commands/test-verdict.d.ts +16 -2
- package/dist/src/commands/test-verdict.js +18 -3
- package/dist/src/commands/test.js +42 -5
- package/dist/src/commands/token-list.d.ts +26 -0
- package/dist/src/commands/token-list.js +153 -0
- package/dist/src/commands/token.js +17 -1
- package/dist/src/commands/tree.js +7 -2
- package/dist/src/commands/typecheck.js +9 -9
- package/dist/src/commands/wire.js +4 -3
- package/dist/src/core/branding.d.ts +0 -7
- package/dist/src/core/branding.js +3 -2
- package/dist/src/core/browser-wire.js +6 -3
- package/dist/src/core/build-audit-platform.d.ts +29 -0
- package/dist/src/core/build-audit-platform.js +140 -0
- package/dist/src/core/build-audit-registration.js +3 -2
- package/dist/src/core/build-audit-skip.d.ts +57 -0
- package/dist/src/core/build-audit-skip.js +112 -0
- package/dist/src/core/build-audit.d.ts +15 -2
- package/dist/src/core/build-audit.js +110 -10
- package/dist/src/core/build-baseline.d.ts +45 -28
- package/dist/src/core/build-baseline.js +6 -29
- package/dist/src/core/build-jar-escalation.js +3 -2
- package/dist/src/core/build-overwrite-guard.js +1 -1
- package/dist/src/core/build-prepare.d.ts +0 -8
- package/dist/src/core/build-prepare.js +7 -12
- package/dist/src/core/config-paths.d.ts +2 -6
- package/dist/src/core/config-paths.js +4 -2
- package/dist/src/core/config-state.d.ts +0 -6
- package/dist/src/core/config-state.js +1 -19
- package/dist/src/core/config-validate-build-audit.d.ts +8 -0
- package/dist/src/core/config-validate-build-audit.js +80 -0
- package/dist/src/core/config-validate-file-size.js +1 -1
- 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 +14 -3
- package/dist/src/core/config.d.ts +2 -2
- package/dist/src/core/config.js +11 -15
- package/dist/src/core/coverage-extend.js +4 -4
- package/dist/src/core/discard-baseline.js +7 -7
- package/dist/src/core/engine-precondition.d.ts +1 -9
- package/dist/src/core/engine-precondition.js +3 -8
- package/dist/src/core/engine-session-lock.js +13 -17
- package/dist/src/core/export-moved-code-shape.js +2 -2
- package/dist/src/core/file-lock-owner.d.ts +103 -0
- package/dist/src/core/file-lock-owner.js +259 -0
- package/dist/src/core/file-lock.d.ts +2 -7
- package/dist/src/core/file-lock.js +40 -91
- package/dist/src/core/firefox-cache.d.ts +13 -1
- package/dist/src/core/firefox-cache.js +59 -34
- package/dist/src/core/firefox-download.d.ts +15 -0
- package/dist/src/core/firefox-download.js +37 -21
- package/dist/src/core/firefox-extract.d.ts +6 -5
- package/dist/src/core/firefox-extract.js +36 -18
- package/dist/src/core/firefox.d.ts +30 -32
- package/dist/src/core/firefox.js +5 -36
- package/dist/src/core/furnace-apply-dry-run.d.ts +1 -6
- package/dist/src/core/furnace-apply-dry-run.js +1 -7
- package/dist/src/core/furnace-apply-helpers.d.ts +0 -11
- package/dist/src/core/furnace-apply-helpers.js +8 -19
- package/dist/src/core/furnace-apply-overwrite-warn.js +4 -2
- package/dist/src/core/furnace-apply.d.ts +1 -1
- package/dist/src/core/furnace-apply.js +30 -10
- package/dist/src/core/furnace-config.d.ts +1 -1
- package/dist/src/core/furnace-config.js +23 -36
- package/dist/src/core/furnace-constants.js +3 -2
- package/dist/src/core/furnace-dir-entry.d.ts +20 -0
- package/dist/src/core/furnace-dir-entry.js +21 -0
- package/dist/src/core/furnace-operation.d.ts +2 -0
- package/dist/src/core/furnace-operation.js +3 -1
- package/dist/src/core/furnace-refresh.d.ts +18 -6
- package/dist/src/core/furnace-refresh.js +3 -6
- package/dist/src/core/furnace-registration-ast.d.ts +0 -1
- package/dist/src/core/furnace-registration-ast.js +0 -3
- package/dist/src/core/furnace-registration.d.ts +2 -1
- package/dist/src/core/furnace-registration.js +22 -29
- package/dist/src/core/furnace-scanner.js +3 -6
- package/dist/src/core/furnace-state-persist.d.ts +2 -2
- package/dist/src/core/furnace-validate-registration.js +5 -7
- package/dist/src/core/git-base.d.ts +3 -1
- package/dist/src/core/git-base.js +25 -3
- package/dist/src/core/git-diff-new-file.d.ts +40 -0
- package/dist/src/core/git-diff-new-file.js +119 -0
- package/dist/src/core/git-diff.d.ts +9 -9
- package/dist/src/core/git-diff.js +88 -157
- package/dist/src/core/git-file-ops.d.ts +0 -7
- package/dist/src/core/git-file-ops.js +4 -28
- package/dist/src/core/git-readonly-index.d.ts +0 -2
- package/dist/src/core/git-readonly-index.js +0 -4
- package/dist/src/core/git-status.d.ts +7 -0
- package/dist/src/core/git-status.js +21 -9
- package/dist/src/core/git.d.ts +0 -6
- package/dist/src/core/git.js +14 -43
- package/dist/src/core/harness-orphans.js +8 -7
- package/dist/src/core/history-log.d.ts +19 -0
- package/dist/src/core/history-log.js +29 -0
- package/dist/src/core/mach-error-hints.d.ts +0 -5
- package/dist/src/core/mach-error-hints.js +1 -1
- package/dist/src/core/mach-known-noise-filter.d.ts +4 -3
- package/dist/src/core/mach-known-noise-filter.js +7 -9
- package/dist/src/core/mach-mozconfig.js +2 -1
- package/dist/src/core/mach-python.d.ts +2 -0
- package/dist/src/core/mach-python.js +12 -7
- package/dist/src/core/mach-resource-shim.d.ts +13 -1
- package/dist/src/core/mach-resource-shim.js +112 -9
- package/dist/src/core/mach.d.ts +39 -53
- package/dist/src/core/mach.js +13 -81
- package/dist/src/core/marionette-port.d.ts +0 -17
- package/dist/src/core/marionette-port.js +12 -58
- package/dist/src/core/marionette-preflight.js +9 -27
- package/dist/src/core/mochitest-server-port.js +3 -3
- package/dist/src/core/moz-manifest-rules.js +37 -33
- package/dist/src/core/patch-apply-fuzz.js +4 -4
- package/dist/src/core/patch-apply.d.ts +4 -5
- package/dist/src/core/patch-apply.js +6 -12
- package/dist/src/core/patch-export-coverage.d.ts +0 -9
- package/dist/src/core/patch-export-coverage.js +1 -30
- package/dist/src/core/patch-export-update.d.ts +18 -1
- package/dist/src/core/patch-export-update.js +4 -3
- package/dist/src/core/patch-export.d.ts +11 -21
- package/dist/src/core/patch-export.js +44 -66
- package/dist/src/core/patch-files.d.ts +0 -4
- package/dist/src/core/patch-files.js +0 -11
- package/dist/src/core/patch-lint-binary.d.ts +6 -12
- package/dist/src/core/patch-lint-cache.d.ts +17 -1
- package/dist/src/core/patch-lint-cache.js +3 -6
- package/dist/src/core/patch-lint-checkjs.d.ts +33 -16
- package/dist/src/core/patch-lint-checkjs.js +37 -24
- package/dist/src/core/patch-lint-creators.d.ts +2 -6
- package/dist/src/core/patch-lint-cross.d.ts +16 -8
- package/dist/src/core/patch-lint-cross.js +49 -92
- package/dist/src/core/patch-lint-css.js +10 -6
- package/dist/src/core/patch-lint-file-size.js +3 -3
- package/dist/src/core/patch-lint-forward-registration.d.ts +58 -0
- package/dist/src/core/patch-lint-forward-registration.js +210 -0
- package/dist/src/core/patch-lint-jsdoc.js +36 -36
- package/dist/src/core/patch-lint-module-registration.d.ts +2 -8
- package/dist/src/core/patch-lint-prettier.js +1 -1
- 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.d.ts +14 -9
- package/dist/src/core/patch-lint.js +4 -3
- package/dist/src/core/patch-lock.js +3 -3
- package/dist/src/core/patch-manifest-io.js +8 -7
- package/dist/src/core/patch-parse.d.ts +19 -8
- package/dist/src/core/patch-parse.js +25 -0
- package/dist/src/core/patch-policy.js +15 -27
- package/dist/src/core/patch-source-metadata.d.ts +1 -3
- package/dist/src/core/patch-source-metadata.js +0 -4
- package/dist/src/core/patch-transform.d.ts +0 -8
- package/dist/src/core/patch-transform.js +0 -10
- package/dist/src/core/process-cpu-time.js +1 -1
- package/dist/src/core/rebase-session.d.ts +2 -8
- package/dist/src/core/rebase-session.js +5 -17
- package/dist/src/core/register-browser-content.js +3 -2
- package/dist/src/core/register-browser-test.js +2 -1
- package/dist/src/core/register-module.js +2 -1
- package/dist/src/core/register-scaffold.js +5 -4
- package/dist/src/core/register-shared-css.js +2 -1
- package/dist/src/core/run-log-redact.d.ts +38 -0
- package/dist/src/core/run-log-redact.js +69 -0
- package/dist/src/core/run-log.d.ts +13 -2
- package/dist/src/core/run-log.js +67 -18
- package/dist/src/core/signal-critical.js +2 -4
- package/dist/src/core/smoke-patterns.d.ts +0 -1
- package/dist/src/core/smoke-patterns.js +6 -11
- package/dist/src/core/state-file.d.ts +12 -1
- package/dist/src/core/state-file.js +14 -1
- package/dist/src/core/status-classify.js +2 -1
- package/dist/src/core/test-changed-prefs.js +26 -11
- package/dist/src/core/test-harness-crash.js +2 -2
- package/dist/src/core/test-stale-check.d.ts +0 -2
- package/dist/src/core/test-stale-check.js +2 -2
- package/dist/src/core/test-xpcshell-retry.d.ts +26 -7
- package/dist/src/core/test-xpcshell-retry.js +14 -11
- package/dist/src/core/token-category.d.ts +33 -0
- package/dist/src/core/token-category.js +56 -48
- package/dist/src/core/token-dark-mode.js +2 -14
- package/dist/src/core/token-inventory.d.ts +56 -0
- package/dist/src/core/token-inventory.js +109 -0
- package/dist/src/core/token-manager.d.ts +1 -1
- package/dist/src/core/token-manager.js +1 -1
- package/dist/src/core/token-variant.js +21 -22
- package/dist/src/core/toolchain-preflight.js +1 -1
- package/dist/src/core/tree-cow.d.ts +0 -2
- package/dist/src/core/tree-cow.js +2 -2
- package/dist/src/core/tree-store.js +4 -5
- package/dist/src/core/typecheck.js +2 -2
- package/dist/src/core/wire-dom-fragment.js +6 -17
- package/dist/src/core/wire-utils.js +5 -17
- package/dist/src/core/xpcshell-appdir.js +2 -4
- package/dist/src/errors/base.d.ts +53 -1
- package/dist/src/errors/base.js +79 -11
- package/dist/src/errors/build.js +20 -28
- package/dist/src/errors/config.d.ts +0 -14
- package/dist/src/errors/config.js +13 -34
- package/dist/src/errors/download.d.ts +13 -0
- package/dist/src/errors/download.js +53 -24
- package/dist/src/errors/furnace.js +8 -9
- package/dist/src/errors/git.d.ts +8 -8
- package/dist/src/errors/git.js +20 -30
- package/dist/src/errors/patch.js +8 -10
- package/dist/src/errors/rebase.js +7 -7
- package/dist/src/types/commands/options.d.ts +77 -123
- package/dist/src/types/config.d.ts +34 -2
- package/dist/src/types/index.d.ts +0 -1
- package/dist/src/utils/assert.d.ts +3 -15
- package/dist/src/utils/assert.js +1 -18
- package/dist/src/utils/build-info.d.ts +1 -1
- package/dist/src/utils/child-env.d.ts +2 -1
- package/dist/src/utils/elapsed.js +10 -1
- package/dist/src/utils/fs.js +8 -13
- package/dist/src/utils/hash.d.ts +12 -0
- package/dist/src/utils/hash.js +16 -0
- package/dist/src/utils/line-dispatch.d.ts +15 -0
- package/dist/src/utils/line-dispatch.js +48 -0
- package/dist/src/utils/options.d.ts +1 -7
- package/dist/src/utils/options.js +6 -7
- package/dist/src/utils/package-root.js +3 -12
- package/dist/src/utils/platform.d.ts +0 -4
- package/dist/src/utils/process-group.d.ts +2 -1
- package/dist/src/utils/process-group.js +20 -19
- package/dist/src/utils/process.d.ts +40 -26
- package/dist/src/utils/process.js +115 -166
- package/dist/src/utils/ps-duration.js +3 -3
- package/dist/src/utils/sleep.d.ts +26 -0
- package/dist/src/utils/sleep.js +31 -0
- package/dist/src/utils/validation.d.ts +2 -38
- package/dist/src/utils/validation.js +7 -16
- package/docs/configuration.md +89 -1
- package/docs/exit-codes.md +31 -19
- package/docs/lifecycle-invariants.md +18 -12
- package/docs/machine-output.md +31 -8
- package/docs/patch-workflow.md +2 -1
- package/docs/run-logs.md +44 -4
- package/docs/testing.md +8 -1
- package/package.json +8 -7
- package/dist/src/commands/rebase.d.ts +0 -4
- package/dist/src/commands/rebase.js +0 -5
- package/dist/src/core/patch-artifact-normalize.d.ts +0 -21
- package/dist/src/core/patch-artifact-normalize.js +0 -24
- package/dist/src/core/patch-lint-reexports.d.ts +0 -7
- package/dist/src/core/patch-lint-reexports.js +0 -8
- package/dist/src/core/wire-targets.d.ts +0 -7
- package/dist/src/core/wire-targets.js +0 -8
package/dist/src/core/mach.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type SmokeLineCallback, type SmokeRunResult } from '../utils/process.js
|
|
|
2
2
|
import { type HarnessCrashSignature } from './test-harness-crash.js';
|
|
3
3
|
export { attemptMozinfoRewrite, buildArtifactMismatchMessage, hasBuildArtifacts, hasRunnableBundle, } from './mach-build-artifacts.js';
|
|
4
4
|
export { generateMozconfig } from './mach-mozconfig.js';
|
|
5
|
-
export { ensurePython
|
|
5
|
+
export { ensurePython } from './mach-python.js';
|
|
6
6
|
/**
|
|
7
7
|
* Ensures mach is available in the engine directory.
|
|
8
8
|
* @param engineDir - Path to the engine directory
|
|
@@ -66,12 +66,6 @@ export declare function runMachCapture(args: string[], engineDir: string, option
|
|
|
66
66
|
* capturing stdout/stderr for post-run diagnostics.
|
|
67
67
|
*/
|
|
68
68
|
export declare function runMachInheritCapture(args: string[], engineDir: string, options?: Omit<MachOptions, 'inherit'>): Promise<MachCommandResult>;
|
|
69
|
-
/**
|
|
70
|
-
* Runs mach bootstrap to install build dependencies.
|
|
71
|
-
* @param engineDir - Path to the engine directory
|
|
72
|
-
* @returns Exit code
|
|
73
|
-
*/
|
|
74
|
-
export declare function bootstrap(engineDir: string): Promise<number>;
|
|
75
69
|
/**
|
|
76
70
|
* Runs mach bootstrap while preserving stdin and capturing the emitted output.
|
|
77
71
|
* @param engineDir - Path to the engine directory
|
|
@@ -197,29 +191,15 @@ export interface RunMachSmokeOptions {
|
|
|
197
191
|
* the runner to chrome-specific pattern logic.
|
|
198
192
|
*/
|
|
199
193
|
export declare function runMachSmoke(args: string[], engineDir: string, options: RunMachSmokeOptions): Promise<SmokeRunResult>;
|
|
200
|
-
/**
|
|
201
|
-
* Creates a distribution package.
|
|
202
|
-
* @param engineDir - Path to the engine directory
|
|
203
|
-
* @returns Exit code
|
|
204
|
-
*/
|
|
205
|
-
export declare function machPackage(engineDir: string): Promise<number>;
|
|
206
194
|
/**
|
|
207
195
|
* Creates a distribution package while streaming output to the terminal
|
|
208
|
-
* and capturing the stderr tail for post-run diagnostics
|
|
209
|
-
*
|
|
210
|
-
* variant; the inherit-only `machPackage` above remains for callers that
|
|
211
|
-
* just need an exit code.
|
|
196
|
+
* and capturing the stderr tail for post-run diagnostics, so callers can
|
|
197
|
+
* consult {@link explainMachError} on failure.
|
|
212
198
|
*
|
|
213
199
|
* @param engineDir - Path to the engine directory
|
|
214
200
|
* @returns Captured mach result (stdout tail, stderr tail, exit code)
|
|
215
201
|
*/
|
|
216
202
|
export declare function machPackageCapture(engineDir: string): Promise<MachCommandResult>;
|
|
217
|
-
/**
|
|
218
|
-
* Runs mach watch for auto-rebuilding.
|
|
219
|
-
* @param engineDir - Path to the engine directory
|
|
220
|
-
* @returns Exit code
|
|
221
|
-
*/
|
|
222
|
-
export declare function watch(engineDir: string): Promise<number>;
|
|
223
203
|
/**
|
|
224
204
|
* Runs mach watch while preserving stdin and capturing emitted output.
|
|
225
205
|
*
|
|
@@ -238,38 +218,44 @@ export declare function watchWithOutput(engineDir: string, options?: {
|
|
|
238
218
|
env?: Record<string, string>;
|
|
239
219
|
}): Promise<MachCommandResult>;
|
|
240
220
|
/**
|
|
241
|
-
*
|
|
242
|
-
* @param engineDir - Path to the engine directory
|
|
243
|
-
* @param testPaths - Test file or directory paths (relative to engine)
|
|
244
|
-
* @param args - Additional arguments to pass to mach test
|
|
245
|
-
* @returns Exit code
|
|
246
|
-
*/
|
|
247
|
-
export declare function test(engineDir: string, testPaths?: string[], args?: string[]): Promise<number>;
|
|
248
|
-
/**
|
|
249
|
-
* Runs mach test while capturing streamed output for better diagnostics.
|
|
221
|
+
* Which mach test command a capturing test dispatch runs.
|
|
250
222
|
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
223
|
+
* - `test`: the generic `mach test` (mixed/all-tests runs, or the
|
|
224
|
+
* `--generic-mach-test` opt-out).
|
|
225
|
+
* - `xpcshell-test` / `mochitest`: the suite-specific commands. Unlike the
|
|
226
|
+
* generic `mach test`, these degrade a broken mozlog resource monitor to a
|
|
227
|
+
* warning instead of crashing at startup, so `fireforge test` dispatches
|
|
228
|
+
* single-suite runs to them to stay resilient to the host psutil failure.
|
|
257
229
|
*/
|
|
258
|
-
export
|
|
230
|
+
export type MachTestSuiteKind = 'test' | 'xpcshell-test' | 'mochitest';
|
|
231
|
+
/** Options for {@link runMachTestSuite}. */
|
|
232
|
+
export interface MachTestSuiteOptions {
|
|
233
|
+
/** Absolute path to the engine checkout. */
|
|
234
|
+
engineDir: string;
|
|
235
|
+
/** Test paths to pass to the mach command; empty runs the default set. */
|
|
236
|
+
testPaths?: string[];
|
|
237
|
+
/** Extra mach arguments appended after the paths. */
|
|
238
|
+
args?: string[];
|
|
239
|
+
/**
|
|
240
|
+
* Extra environment variables for the mach process (merged over
|
|
241
|
+
* `process.env` by the exec layer). Used by `fireforge test
|
|
242
|
+
* --perf-samples` to publish the artifact-path contract.
|
|
243
|
+
*/
|
|
244
|
+
env?: Record<string, string> | undefined;
|
|
245
|
+
/**
|
|
246
|
+
* Pass full mozbuild verbosity through by unsetting the coding-agent
|
|
247
|
+
* markers that quiet it. See {@link CODING_AGENT_ENV_MARKERS}.
|
|
248
|
+
*/
|
|
249
|
+
fullOutput?: boolean | undefined;
|
|
250
|
+
}
|
|
259
251
|
/**
|
|
260
|
-
* Runs `mach
|
|
261
|
-
*
|
|
262
|
-
* commands
|
|
263
|
-
*
|
|
264
|
-
*
|
|
252
|
+
* Runs one mach test command (`mach test` / `mach xpcshell-test` / `mach
|
|
253
|
+
* mochitest`) while capturing streamed output for better diagnostics. The
|
|
254
|
+
* three commands share every other detail of the dispatch — resource guard,
|
|
255
|
+
* verbosity env, teardown-noise annotation — so they share one entry point
|
|
256
|
+
* keyed by `kind` rather than three copies that drift.
|
|
265
257
|
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
*/
|
|
269
|
-
export declare function xpcshellTestWithOutput(engineDir: string, testPaths?: string[], args?: string[], env?: Record<string, string>, fullOutput?: boolean): Promise<MachCommandResult>;
|
|
270
|
-
/**
|
|
271
|
-
* Runs `mach mochitest` (covers browser-chrome / mochitest flavors) while
|
|
272
|
-
* capturing output. The suite-specific counterpart to {@link testWithOutput}
|
|
273
|
-
* for non-xpcshell single-suite runs — see {@link xpcshellTestWithOutput}.
|
|
258
|
+
* @param kind - Which mach command to run
|
|
259
|
+
* @param options - Engine checkout, test paths, extra args, env, verbosity
|
|
274
260
|
*/
|
|
275
|
-
export declare function
|
|
261
|
+
export declare function runMachTestSuite(kind: MachTestSuiteKind, options: MachTestSuiteOptions): Promise<MachCommandResult>;
|
package/dist/src/core/mach.js
CHANGED
|
@@ -20,7 +20,7 @@ import { detectHarnessCrashSignature } from './test-harness-crash.js';
|
|
|
20
20
|
// that mocks `mach.js`.
|
|
21
21
|
export { attemptMozinfoRewrite, buildArtifactMismatchMessage, hasBuildArtifacts, hasRunnableBundle, } from './mach-build-artifacts.js';
|
|
22
22
|
export { generateMozconfig } from './mach-mozconfig.js';
|
|
23
|
-
export { ensurePython
|
|
23
|
+
export { ensurePython } from './mach-python.js';
|
|
24
24
|
/**
|
|
25
25
|
* Ensures mach is available in the engine directory.
|
|
26
26
|
* @param engineDir - Path to the engine directory
|
|
@@ -149,14 +149,6 @@ export async function runMachInheritCapture(args, engineDir, options = {}) {
|
|
|
149
149
|
processGroup: true,
|
|
150
150
|
});
|
|
151
151
|
}
|
|
152
|
-
/**
|
|
153
|
-
* Runs mach bootstrap to install build dependencies.
|
|
154
|
-
* @param engineDir - Path to the engine directory
|
|
155
|
-
* @returns Exit code
|
|
156
|
-
*/
|
|
157
|
-
export async function bootstrap(engineDir) {
|
|
158
|
-
return runMach(['bootstrap', '--application-choice', 'browser'], engineDir, { inherit: true });
|
|
159
|
-
}
|
|
160
152
|
/**
|
|
161
153
|
* Runs mach bootstrap while preserving stdin and capturing the emitted output.
|
|
162
154
|
* @param engineDir - Path to the engine directory
|
|
@@ -351,20 +343,10 @@ export async function runMachSmoke(args, engineDir, options) {
|
|
|
351
343
|
...(options.mirror ? { mirror: options.mirror } : {}),
|
|
352
344
|
});
|
|
353
345
|
}
|
|
354
|
-
/**
|
|
355
|
-
* Creates a distribution package.
|
|
356
|
-
* @param engineDir - Path to the engine directory
|
|
357
|
-
* @returns Exit code
|
|
358
|
-
*/
|
|
359
|
-
export async function machPackage(engineDir) {
|
|
360
|
-
return runMach(['package'], engineDir, { inherit: true });
|
|
361
|
-
}
|
|
362
346
|
/**
|
|
363
347
|
* Creates a distribution package while streaming output to the terminal
|
|
364
|
-
* and capturing the stderr tail for post-run diagnostics
|
|
365
|
-
*
|
|
366
|
-
* variant; the inherit-only `machPackage` above remains for callers that
|
|
367
|
-
* just need an exit code.
|
|
348
|
+
* and capturing the stderr tail for post-run diagnostics, so callers can
|
|
349
|
+
* consult {@link explainMachError} on failure.
|
|
368
350
|
*
|
|
369
351
|
* @param engineDir - Path to the engine directory
|
|
370
352
|
* @returns Captured mach result (stdout tail, stderr tail, exit code)
|
|
@@ -372,14 +354,6 @@ export async function machPackage(engineDir) {
|
|
|
372
354
|
export async function machPackageCapture(engineDir) {
|
|
373
355
|
return runMachCapture(['package'], engineDir);
|
|
374
356
|
}
|
|
375
|
-
/**
|
|
376
|
-
* Runs mach watch for auto-rebuilding.
|
|
377
|
-
* @param engineDir - Path to the engine directory
|
|
378
|
-
* @returns Exit code
|
|
379
|
-
*/
|
|
380
|
-
export async function watch(engineDir) {
|
|
381
|
-
return runMach(['watch'], engineDir, { inherit: true });
|
|
382
|
-
}
|
|
383
357
|
/**
|
|
384
358
|
* Runs mach watch while preserving stdin and capturing emitted output.
|
|
385
359
|
*
|
|
@@ -397,16 +371,6 @@ export async function watch(engineDir) {
|
|
|
397
371
|
export async function watchWithOutput(engineDir, options = {}) {
|
|
398
372
|
return runMachInheritCapture(['watch'], engineDir, options.env ? { env: options.env } : {});
|
|
399
373
|
}
|
|
400
|
-
/**
|
|
401
|
-
* Runs mach test with the given test paths.
|
|
402
|
-
* @param engineDir - Path to the engine directory
|
|
403
|
-
* @param testPaths - Test file or directory paths (relative to engine)
|
|
404
|
-
* @param args - Additional arguments to pass to mach test
|
|
405
|
-
* @returns Exit code
|
|
406
|
-
*/
|
|
407
|
-
export async function test(engineDir, testPaths = [], args = []) {
|
|
408
|
-
return runMach(['test', ...testPaths, ...args], engineDir, { inherit: true });
|
|
409
|
-
}
|
|
410
374
|
/**
|
|
411
375
|
* Environment markers mozbuild reads to decide it is running under a coding
|
|
412
376
|
* agent (`mozbuild.util.is_running_under_coding_agent`), which quiets
|
|
@@ -433,52 +397,20 @@ function testVerbosityEnvUnset(fullOutput) {
|
|
|
433
397
|
return fullOutput === true ? CODING_AGENT_ENV_MARKERS : undefined;
|
|
434
398
|
}
|
|
435
399
|
/**
|
|
436
|
-
* Runs mach test
|
|
400
|
+
* Runs one mach test command (`mach test` / `mach xpcshell-test` / `mach
|
|
401
|
+
* mochitest`) while capturing streamed output for better diagnostics. The
|
|
402
|
+
* three commands share every other detail of the dispatch — resource guard,
|
|
403
|
+
* verbosity env, teardown-noise annotation — so they share one entry point
|
|
404
|
+
* keyed by `kind` rather than three copies that drift.
|
|
437
405
|
*
|
|
438
|
-
* @param
|
|
439
|
-
* @param
|
|
440
|
-
* @param args - Extra `mach test` arguments appended after the paths
|
|
441
|
-
* @param env - Optional extra environment variables for the mach process
|
|
442
|
-
* (merged over `process.env` by the exec layer). Used by
|
|
443
|
-
* `fireforge test --perf-samples` to publish the artifact-path contract.
|
|
444
|
-
*/
|
|
445
|
-
export async function testWithOutput(engineDir, testPaths = [], args = [], env, fullOutput) {
|
|
446
|
-
const guard = await installMachResourceGuard(engineDir);
|
|
447
|
-
const envUnset = testVerbosityEnvUnset(fullOutput);
|
|
448
|
-
return runMachCapture(['test', ...testPaths, ...args], engineDir, {
|
|
449
|
-
env: { ...guard.env, ...env },
|
|
450
|
-
...(envUnset ? { envUnset } : {}),
|
|
451
|
-
annotateKnownTeardownNoise: true,
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
/**
|
|
455
|
-
* Runs `mach xpcshell-test` (the suite-specific xpcshell command) while
|
|
456
|
-
* capturing output. Unlike the generic `mach test`, the suite-specific
|
|
457
|
-
* commands degrade a broken mozlog resource monitor to a warning instead of
|
|
458
|
-
* crashing at startup, so `fireforge test` dispatches single-suite runs here
|
|
459
|
-
* to stay resilient to the host psutil failure.
|
|
460
|
-
*
|
|
461
|
-
* Signature mirrors {@link testWithOutput} so the two are interchangeable in
|
|
462
|
-
* the dispatch path.
|
|
463
|
-
*/
|
|
464
|
-
export async function xpcshellTestWithOutput(engineDir, testPaths = [], args = [], env, fullOutput) {
|
|
465
|
-
const guard = await installMachResourceGuard(engineDir);
|
|
466
|
-
const envUnset = testVerbosityEnvUnset(fullOutput);
|
|
467
|
-
return runMachCapture(['xpcshell-test', ...testPaths, ...args], engineDir, {
|
|
468
|
-
env: { ...guard.env, ...env },
|
|
469
|
-
...(envUnset ? { envUnset } : {}),
|
|
470
|
-
annotateKnownTeardownNoise: true,
|
|
471
|
-
});
|
|
472
|
-
}
|
|
473
|
-
/**
|
|
474
|
-
* Runs `mach mochitest` (covers browser-chrome / mochitest flavors) while
|
|
475
|
-
* capturing output. The suite-specific counterpart to {@link testWithOutput}
|
|
476
|
-
* for non-xpcshell single-suite runs — see {@link xpcshellTestWithOutput}.
|
|
406
|
+
* @param kind - Which mach command to run
|
|
407
|
+
* @param options - Engine checkout, test paths, extra args, env, verbosity
|
|
477
408
|
*/
|
|
478
|
-
export async function
|
|
409
|
+
export async function runMachTestSuite(kind, options) {
|
|
410
|
+
const { engineDir, testPaths = [], args = [], env, fullOutput } = options;
|
|
479
411
|
const guard = await installMachResourceGuard(engineDir);
|
|
480
412
|
const envUnset = testVerbosityEnvUnset(fullOutput);
|
|
481
|
-
return runMachCapture([
|
|
413
|
+
return runMachCapture([kind, ...testPaths, ...args], engineDir, {
|
|
482
414
|
env: { ...guard.env, ...env },
|
|
483
415
|
...(envUnset ? { envUnset } : {}),
|
|
484
416
|
annotateKnownTeardownNoise: true,
|
|
@@ -147,20 +147,3 @@ export declare function hasExplicitXpcshellFlavor(machArgs: string[]): boolean;
|
|
|
147
147
|
* Marionette-driven browser).
|
|
148
148
|
*/
|
|
149
149
|
export declare function shouldAutoForwardMarionettePortToMach(machArgs: string[]): boolean;
|
|
150
|
-
/**
|
|
151
|
-
* Heuristic: do the test paths or forwarded mach args indicate a flavour
|
|
152
|
-
* that actually launches a Marionette-driven browser? Browser-chrome and
|
|
153
|
-
* mochitest do; xpcshell does not. A no-paths invocation (the default "run
|
|
154
|
-
* all tests" shape) is treated as marionette-relevant since it includes
|
|
155
|
-
* browser-chrome.
|
|
156
|
-
*
|
|
157
|
-
* Note: `fireforge test` auto-forward of `--marionette-port` to mach uses
|
|
158
|
-
* {@link shouldAutoForwardMarionettePortToMach} (mach-arg flavor gate) rather
|
|
159
|
-
* than this function alone, so toolkit paths without `/mochitest/` still get
|
|
160
|
-
* the listener pref and harness `--marionette=127.0.0.1:<n>` when appropriate.
|
|
161
|
-
*
|
|
162
|
-
* @param testPaths - Engine-relative paths after `stripEnginePrefix`.
|
|
163
|
-
* @param machArgs - Forwarded mach args (post-`--mach-arg`).
|
|
164
|
-
* @returns `true` when the run is likely to bind a Marionette listener.
|
|
165
|
-
*/
|
|
166
|
-
export declare function isMarionetteFlavor(testPaths: string[], machArgs: string[]): boolean;
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* installed the probe returns `{ inUse: false }` rather than failing the
|
|
25
25
|
* test run — it is a best-effort friendliness check, not a prerequisite.
|
|
26
26
|
*/
|
|
27
|
-
import {
|
|
27
|
+
import { PreflightRefusalError } from '../errors/base.js';
|
|
28
28
|
import { toError } from '../utils/errors.js';
|
|
29
29
|
import { getPlatform } from '../utils/platform.js';
|
|
30
30
|
import { exec } from '../utils/process.js';
|
|
@@ -133,10 +133,10 @@ export async function ensureLaunchableBrowserNotRunning(launchableBinary, option
|
|
|
133
133
|
return;
|
|
134
134
|
}
|
|
135
135
|
catch (error) {
|
|
136
|
-
throw new
|
|
136
|
+
throw new PreflightRefusalError(`A browser from this objdir is still running (PID ${holder.pid}), but FireForge could not terminate it: ${toError(error).message}`, 'stale-browser-kill-failed');
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
|
-
throw new
|
|
139
|
+
throw new PreflightRefusalError(describeRunningBundleRefusal(holder), 'stale-browser');
|
|
140
140
|
}
|
|
141
141
|
/**
|
|
142
142
|
* True when the process was launched BY a test harness — its command line
|
|
@@ -349,18 +349,18 @@ export async function assertMarionettePortAvailable(port = DEFAULT_MARIONETTE_PO
|
|
|
349
349
|
const killHint = process.platform === 'win32'
|
|
350
350
|
? `Stop-Process -Id ${holder.pid} -Force`
|
|
351
351
|
: `kill ${holder.pid} # or "kill -9 ${holder.pid}" if it doesn't exit`;
|
|
352
|
-
throw new
|
|
352
|
+
throw new PreflightRefusalError(`Marionette port ${port} is already in use by ${holder.command} (PID ${holder.pid}). ` +
|
|
353
353
|
`This is usually a browser left running by a previously interrupted "fireforge test" run. ` +
|
|
354
354
|
`Kill it with "${killHint}", then retry. ` +
|
|
355
355
|
`(If you expected ${holder.command} to be running on ${port}, stop it manually or pass ` +
|
|
356
|
-
`"--marionette-port <port>" to launch mach test on a different port.)
|
|
356
|
+
`"--marionette-port <port>" to launch mach test on a different port.)`, 'marionette-port-busy');
|
|
357
357
|
}
|
|
358
358
|
// Non-browser holder: mach test will still fail to bind, but the
|
|
359
359
|
// cause is not a stale FireForge-launched browser. Flag it
|
|
360
360
|
// explicitly so the operator can decide what to do instead of
|
|
361
361
|
// getting mach's bind error with no FireForge context.
|
|
362
|
-
throw new
|
|
363
|
-
`This is not a FireForge-launched browser; stop the holder process or free the port before rerunning
|
|
362
|
+
throw new PreflightRefusalError(`Marionette port ${port} is already in use by ${holder.command} (PID ${holder.pid}). ` +
|
|
363
|
+
`This is not a FireForge-launched browser; stop the holder process or free the port before rerunning.`, 'marionette-port-busy');
|
|
364
364
|
}
|
|
365
365
|
/**
|
|
366
366
|
* Ensures the Marionette port is usable, optionally terminating a stale
|
|
@@ -390,8 +390,8 @@ export async function ensureMarionettePortAvailable(port = DEFAULT_MARIONETTE_PO
|
|
|
390
390
|
}
|
|
391
391
|
}
|
|
392
392
|
catch (error) {
|
|
393
|
-
throw new
|
|
394
|
-
`but FireForge could not terminate it: ${toError(error).message}
|
|
393
|
+
throw new PreflightRefusalError(`Marionette port ${port} is held by stale browser ${holder.command} (PID ${holder.pid}), ` +
|
|
394
|
+
`but FireForge could not terminate it: ${toError(error).message}`, 'stale-browser-kill-failed');
|
|
395
395
|
}
|
|
396
396
|
}
|
|
397
397
|
/**
|
|
@@ -410,10 +410,7 @@ export async function ensureMarionettePortAvailable(port = DEFAULT_MARIONETTE_PO
|
|
|
410
410
|
* `undefined`.
|
|
411
411
|
*/
|
|
412
412
|
export function extractForwardedMarionettePort(machArgs) {
|
|
413
|
-
for (
|
|
414
|
-
const arg = machArgs[i];
|
|
415
|
-
if (arg === undefined)
|
|
416
|
-
continue;
|
|
413
|
+
for (const [i, arg] of machArgs.entries()) {
|
|
417
414
|
// `--marionette-port=NNNN`
|
|
418
415
|
let match = /^--marionette-port=(\d+)$/.exec(arg);
|
|
419
416
|
if (match?.[1]) {
|
|
@@ -452,10 +449,7 @@ export function extractForwardedMarionettePort(machArgs) {
|
|
|
452
449
|
*/
|
|
453
450
|
export function forwardedMachArgsIncludeMarionetteClient(machArgs) {
|
|
454
451
|
const valueLooksLikeHostPort = (token) => /:[0-9]+$/.test(token) || /^\[[^]]+\]:[0-9]+$/.test(token);
|
|
455
|
-
for (
|
|
456
|
-
const arg = machArgs[i];
|
|
457
|
-
if (arg === undefined)
|
|
458
|
-
continue;
|
|
452
|
+
for (const [i, arg] of machArgs.entries()) {
|
|
459
453
|
if (arg.startsWith('--marionette=') && !arg.startsWith('--marionette-port=')) {
|
|
460
454
|
return true;
|
|
461
455
|
}
|
|
@@ -473,8 +467,7 @@ export function forwardedMachArgsIncludeMarionetteClient(machArgs) {
|
|
|
473
467
|
* for runs where the pref is ignored anyway.
|
|
474
468
|
*/
|
|
475
469
|
export function hasExplicitXpcshellFlavor(machArgs) {
|
|
476
|
-
for (
|
|
477
|
-
const arg = machArgs[i] ?? '';
|
|
470
|
+
for (const [i, arg] of machArgs.entries()) {
|
|
478
471
|
if (/^--flavor=xpcshell\b/.test(arg) || arg === '--flavor=xpcshell-tests')
|
|
479
472
|
return true;
|
|
480
473
|
if (arg === '--flavor' && /^xpcshell(?:-tests)?$/.test(machArgs[i + 1] ?? ''))
|
|
@@ -493,42 +486,3 @@ export function hasExplicitXpcshellFlavor(machArgs) {
|
|
|
493
486
|
export function shouldAutoForwardMarionettePortToMach(machArgs) {
|
|
494
487
|
return !hasExplicitXpcshellFlavor(machArgs);
|
|
495
488
|
}
|
|
496
|
-
/**
|
|
497
|
-
* Heuristic: do the test paths or forwarded mach args indicate a flavour
|
|
498
|
-
* that actually launches a Marionette-driven browser? Browser-chrome and
|
|
499
|
-
* mochitest do; xpcshell does not. A no-paths invocation (the default "run
|
|
500
|
-
* all tests" shape) is treated as marionette-relevant since it includes
|
|
501
|
-
* browser-chrome.
|
|
502
|
-
*
|
|
503
|
-
* Note: `fireforge test` auto-forward of `--marionette-port` to mach uses
|
|
504
|
-
* {@link shouldAutoForwardMarionettePortToMach} (mach-arg flavor gate) rather
|
|
505
|
-
* than this function alone, so toolkit paths without `/mochitest/` still get
|
|
506
|
-
* the listener pref and harness `--marionette=127.0.0.1:<n>` when appropriate.
|
|
507
|
-
*
|
|
508
|
-
* @param testPaths - Engine-relative paths after `stripEnginePrefix`.
|
|
509
|
-
* @param machArgs - Forwarded mach args (post-`--mach-arg`).
|
|
510
|
-
* @returns `true` when the run is likely to bind a Marionette listener.
|
|
511
|
-
*/
|
|
512
|
-
export function isMarionetteFlavor(testPaths, machArgs) {
|
|
513
|
-
if (hasExplicitXpcshellFlavor(machArgs))
|
|
514
|
-
return false;
|
|
515
|
-
for (const arg of machArgs) {
|
|
516
|
-
if (/^--flavor=(browser-chrome|mochitest|chrome|a11y)\b/.test(arg))
|
|
517
|
-
return true;
|
|
518
|
-
}
|
|
519
|
-
if (testPaths.length === 0)
|
|
520
|
-
return true;
|
|
521
|
-
for (const path of testPaths) {
|
|
522
|
-
const base = path.split('/').pop() ?? path;
|
|
523
|
-
if (/^browser_.+\.(js|ini|toml)$/.test(base))
|
|
524
|
-
return true;
|
|
525
|
-
if (path.includes('/mochitest/') || path.startsWith('mochitest/'))
|
|
526
|
-
return true;
|
|
527
|
-
if (path.includes('/browser-chrome/') || path.startsWith('browser-chrome/'))
|
|
528
|
-
return true;
|
|
529
|
-
if (path.includes('toolkit/content/tests/') && !path.includes('/tests/xpcshell/')) {
|
|
530
|
-
return true;
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
return false;
|
|
534
|
-
}
|
|
@@ -22,6 +22,7 @@ import { pathExists } from '../utils/fs.js';
|
|
|
22
22
|
import { info, verbose, warn } from '../utils/logger.js';
|
|
23
23
|
import { installGracefulShutdownForwarder, trackChildClosure } from '../utils/process.js';
|
|
24
24
|
import { killProcessTree, sweepProcessGroup } from '../utils/process-group.js';
|
|
25
|
+
import { sleep } from '../utils/sleep.js';
|
|
25
26
|
import { ensureMach } from './mach.js';
|
|
26
27
|
import { getPython } from './mach-python.js';
|
|
27
28
|
/** Marionette's default TCP port when the browser is launched with `--marionette`. */
|
|
@@ -143,7 +144,7 @@ export async function runMarionettePreflight(engineDir, options = {}) {
|
|
|
143
144
|
const spawnedChild = child;
|
|
144
145
|
closure = trackChildClosure();
|
|
145
146
|
forwarder = installGracefulShutdownForwarder(spawnedChild, 500, (signal) => {
|
|
146
|
-
|
|
147
|
+
killProcessTree(spawnedChild, signal, process.platform !== 'win32');
|
|
147
148
|
});
|
|
148
149
|
child.stderr?.on('data', (data) => {
|
|
149
150
|
const chunk = data.toString();
|
|
@@ -155,10 +156,10 @@ export async function runMarionettePreflight(engineDir, options = {}) {
|
|
|
155
156
|
// never come.
|
|
156
157
|
const settleDeadline = Math.min(spawnSettleMs, Math.max(0, timeoutMs - elapsed()));
|
|
157
158
|
if (settleDeadline > 0) {
|
|
158
|
-
await
|
|
159
|
+
await sleep(settleDeadline, { unref: true });
|
|
159
160
|
}
|
|
160
161
|
if (hasChildExited(spawnedChild)) {
|
|
161
|
-
return fail('browser-spawns', `Browser process exited during spawn (exit code ${
|
|
162
|
+
return fail('browser-spawns', `Browser process exited during spawn (exit code ${spawnedChild.exitCode}, signal ${spawnedChild.signalCode ?? 'none'}). ` +
|
|
162
163
|
`stderr tail: ${stderrTail.trim().slice(-2_000) || '(empty)'}`, elapsed());
|
|
163
164
|
}
|
|
164
165
|
// Layer 6: marionette handshake within the remaining budget.
|
|
@@ -175,7 +176,7 @@ export async function runMarionettePreflight(engineDir, options = {}) {
|
|
|
175
176
|
// Child may have exited before the socket was ever ready — surface that
|
|
176
177
|
// distinctly from "socket never answered" so the operator has a lead.
|
|
177
178
|
if (hasChildExited(spawnedChild)) {
|
|
178
|
-
return fail('marionette-handshake', `Browser process exited before marionette handshake (exit code ${
|
|
179
|
+
return fail('marionette-handshake', `Browser process exited before marionette handshake (exit code ${spawnedChild.exitCode}, signal ${spawnedChild.signalCode ?? 'none'}). ` +
|
|
179
180
|
`stderr tail: ${stderrTail.trim().slice(-2_000) || '(empty)'}`, elapsed());
|
|
180
181
|
}
|
|
181
182
|
return fail('marionette-handshake', `Marionette socket on 127.0.0.1:${port} did not respond within ${timeoutMs}ms. ` +
|
|
@@ -203,12 +204,12 @@ async function teardownPreflightChild(child, forwarder, closure, profileDir) {
|
|
|
203
204
|
forwarder?.dispose();
|
|
204
205
|
const groupPid = child?.pid;
|
|
205
206
|
if (child && !hasChildExited(child)) {
|
|
206
|
-
|
|
207
|
+
killProcessTree(child, 'SIGTERM', process.platform !== 'win32');
|
|
207
208
|
// Small escalation: if the child doesn't honour SIGTERM quickly, SIGKILL
|
|
208
209
|
// so we don't leave a ghost mach process around after a failed probe.
|
|
209
|
-
await
|
|
210
|
+
await sleep(500, { unref: true });
|
|
210
211
|
if (!hasChildExited(child)) {
|
|
211
|
-
|
|
212
|
+
killProcessTree(child, 'SIGKILL', process.platform !== 'win32');
|
|
212
213
|
}
|
|
213
214
|
}
|
|
214
215
|
// Reap anything that outlived the group signal. The file's own comments
|
|
@@ -237,19 +238,6 @@ async function teardownPreflightChild(child, forwarder, closure, profileDir) {
|
|
|
237
238
|
warn(`Could not clean up marionette preflight profile: ${toError(error).message}`);
|
|
238
239
|
}
|
|
239
240
|
}
|
|
240
|
-
/**
|
|
241
|
-
* Sends `signal` to the child's whole process group when possible, falling
|
|
242
|
-
* back to a direct `child.kill` for environments that don't support
|
|
243
|
-
* `detached: true` (Windows in particular: Node still returns a pid, but
|
|
244
|
-
* `kill(-pid, …)` is not a supported kernel primitive).
|
|
245
|
-
*/
|
|
246
|
-
function killProcessGroup(child, signal) {
|
|
247
|
-
// Delegates to the shared implementation, which is a strict superset of
|
|
248
|
-
// the hand-rolled one this replaced: same POSIX `kill(-pid)` with the same
|
|
249
|
-
// fall-through to a direct `child.kill`, plus a Windows `taskkill /T /F`
|
|
250
|
-
// branch and an already-exited early return.
|
|
251
|
-
killProcessTree(child, signal, process.platform !== 'win32');
|
|
252
|
-
}
|
|
253
241
|
function fail(layer, message, durationMs) {
|
|
254
242
|
return {
|
|
255
243
|
ok: false,
|
|
@@ -267,7 +255,7 @@ async function waitForMarionetteSocket(port, connectFn, keepTrying) {
|
|
|
267
255
|
if (result.ok) {
|
|
268
256
|
return { ok: true };
|
|
269
257
|
}
|
|
270
|
-
await
|
|
258
|
+
await sleep(400, { unref: true });
|
|
271
259
|
}
|
|
272
260
|
return { ok: false };
|
|
273
261
|
}
|
|
@@ -312,12 +300,6 @@ function attemptMarionetteConnect(port, connectFn) {
|
|
|
312
300
|
});
|
|
313
301
|
});
|
|
314
302
|
}
|
|
315
|
-
function delay(ms) {
|
|
316
|
-
return new Promise((resolve) => {
|
|
317
|
-
const timer = setTimeout(resolve, ms);
|
|
318
|
-
timer.unref();
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
303
|
/** Renders a PASS/FAIL banner to the CLI using the shared logger helpers. */
|
|
322
304
|
export function reportMarionettePreflight(result) {
|
|
323
305
|
if (result.ok) {
|
|
@@ -100,8 +100,8 @@ export function describeMochitestServerRefusal(port, holder, recognized) {
|
|
|
100
100
|
const killHint = process.platform === 'win32'
|
|
101
101
|
? `Stop-Process -Id ${holder.pid} -Force`
|
|
102
102
|
: `kill -9 ${holder.pid}`;
|
|
103
|
-
const evidence = `The mochitest server port ${
|
|
104
|
-
`(PID ${
|
|
103
|
+
const evidence = `The mochitest server port ${port} is already held by ${holder.command} ` +
|
|
104
|
+
`(PID ${holder.pid}).\n` +
|
|
105
105
|
` command: ${holder.commandLine}\n` +
|
|
106
106
|
" A browser launched now would connect to THAT server, which cannot serve this run's " +
|
|
107
107
|
'manifest — the run would stall before TEST_START and die on the no-output timeout with ' +
|
|
@@ -115,5 +115,5 @@ export function describeMochitestServerRefusal(port, holder, recognized) {
|
|
|
115
115
|
return (evidence +
|
|
116
116
|
" This is NOT the mochitest harness's server.js, so FireForge will not offer to kill it. " +
|
|
117
117
|
`Stop the holder yourself with "${killHint}" if it is yours, or free the port, then retry. ` +
|
|
118
|
-
`Diagnose with "lsof -nP -iTCP:${
|
|
118
|
+
`Diagnose with "lsof -nP -iTCP:${port}".`);
|
|
119
119
|
}
|