@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
|
@@ -25,17 +25,7 @@ import { explainMachError } from './mach-error-hints.js';
|
|
|
25
25
|
/** Path fragments of files whose edits invalidate the recursive-make backend. */
|
|
26
26
|
const BACKEND_INVALIDATING_SUFFIXES = ['moz.build', 'moz.configure', 'Makefile.in'];
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
29
|
-
* build. Path-shape only: {@link evaluateJarManifestEscalation} decides
|
|
30
|
-
* whether a given changed manifest actually forces one (a new manifest, or
|
|
31
|
-
* one that redirects its install base directory), so an entry added to an
|
|
32
|
-
* existing `dist/bin` manifest no longer costs a ~10-minute build.
|
|
33
|
-
*/
|
|
34
|
-
export function requiresFullBuildForIncrementalTest(path) {
|
|
35
|
-
return isJarManifestPath(path);
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Build-input manifests changed since the last SUCCESSFUL build — not
|
|
28
|
+
* Build-input manifests changed since the last successful build, not
|
|
39
29
|
* merely dirty against HEAD. `collectChangedEnginePaths` unions the
|
|
40
30
|
* baseline-to-HEAD diff with every worktree modification, and a fork's
|
|
41
31
|
* worktree is permanently dirty (imported patches, Furnace-applied
|
|
@@ -43,8 +33,8 @@ export function requiresFullBuildForIncrementalTest(path) {
|
|
|
43
33
|
* `moz.build` as changed on every run: `mach configure` re-ran and the
|
|
44
34
|
* pre-test build escalated to a full `mach build` after each full build
|
|
45
35
|
* that had already consumed exactly this content. The baseline's
|
|
46
|
-
* `buildInputFingerprints` say what the last successful build saw
|
|
47
|
-
*
|
|
36
|
+
* `buildInputFingerprints` say what the last successful build saw.
|
|
37
|
+
* Anything byte-identical to that is dropped here. A baseline without the
|
|
48
38
|
* field (written before it existed) keeps every dirty input, which is the
|
|
49
39
|
* old behaviour.
|
|
50
40
|
*
|
|
@@ -66,8 +56,9 @@ async function collectChangedBuildInputs(engineDir, baseline) {
|
|
|
66
56
|
* Extracts the tail of captured `mach configure` output so the underlying
|
|
67
57
|
* mozbuild failure (e.g. `mozbuild.util.UnsortedError: ... is not in sorted
|
|
68
58
|
* order`) is carried into the thrown `BuildError` instead of being reduced to
|
|
69
|
-
* a bare exit code. mozbuild writes the error and its traceback to stderr
|
|
70
|
-
* stdout is included as a fallback for shells that interleave the
|
|
59
|
+
* a bare exit code. mozbuild writes the error and its traceback to stderr,
|
|
60
|
+
* and stdout is included as a fallback for shells that interleave the
|
|
61
|
+
* streams.
|
|
71
62
|
* Returns an empty string when nothing useful was captured.
|
|
72
63
|
*/
|
|
73
64
|
function extractMachConfigureError(result) {
|
|
@@ -79,7 +70,7 @@ function extractMachConfigureError(result) {
|
|
|
79
70
|
/**
|
|
80
71
|
* Describes an exit code in the shell's 128+N signal convention. Truncated
|
|
81
72
|
* configure/build logs with a signal-shaped exit (e.g. 144 = 128+16, SIGURG
|
|
82
|
-
* on macOS) are environmental interruptions, not compiler failures
|
|
73
|
+
* on macOS) are environmental interruptions, not compiler failures. Naming
|
|
83
74
|
* that in the failure text saves the operator a fruitless log hunt.
|
|
84
75
|
* Returns undefined for codes <= 128 (regular failures) and
|
|
85
76
|
* for codes past the conventional signal range, so callers append nothing.
|
|
@@ -101,7 +92,7 @@ export function describeSignalShapedExit(exitCode) {
|
|
|
101
92
|
* Builds the `BuildError` for a non-zero auto-configure exit: the output
|
|
102
93
|
* tail (so the underlying mozbuild failure survives), any matched
|
|
103
94
|
* mach-error hints (so e.g. a toolchain minimum that moved with a source
|
|
104
|
-
* hop names `fireforge bootstrap` on this path too,
|
|
95
|
+
* hop names `fireforge bootstrap` on this path too, just like the
|
|
105
96
|
* protected build dispatch), and the stop rationale.
|
|
106
97
|
*/
|
|
107
98
|
function buildConfigureFailureError(captured) {
|
|
@@ -126,9 +117,14 @@ function buildConfigureFailureError(captured) {
|
|
|
126
117
|
* @param baseline - Last successful build's baseline
|
|
127
118
|
*/
|
|
128
119
|
async function decideJarEscalation(engineDir, changed, baseline) {
|
|
129
|
-
|
|
120
|
+
// Packaging manifests whose graph/destination directories may need a full
|
|
121
|
+
// build. Path-shape only: `evaluateJarManifestEscalation` decides whether a
|
|
122
|
+
// given changed manifest actually forces one (a new manifest, or one that
|
|
123
|
+
// redirects its install base directory), so an entry added to an existing
|
|
124
|
+
// `dist/bin` manifest no longer costs a ~10-minute build.
|
|
125
|
+
const decision = await evaluateJarManifestEscalation(engineDir, changed.filter(isJarManifestPath), baseline);
|
|
130
126
|
if (decision.cleared.length > 0) {
|
|
131
|
-
verbose(`jar escalation: ${
|
|
127
|
+
verbose(`jar escalation: ${decision.cleared.length} changed jar.mn add entries to an existing dist/bin manifest; not escalating for ${decision.cleared.join(', ')}.`);
|
|
132
128
|
}
|
|
133
129
|
return decision.escalate ? formatJarEscalationNotice(decision) : undefined;
|
|
134
130
|
}
|
|
@@ -144,10 +140,10 @@ export function isBackendInvalidatingFile(path) {
|
|
|
144
140
|
return false;
|
|
145
141
|
}
|
|
146
142
|
/**
|
|
147
|
-
*
|
|
143
|
+
* Warns before the overwrite rather than after it.
|
|
148
144
|
*
|
|
149
|
-
* Every write `prepareBuildEnvironment` performs
|
|
150
|
-
* components, `mozconfig`
|
|
145
|
+
* Every write `prepareBuildEnvironment` performs (branding, Furnace
|
|
146
|
+
* components, `mozconfig`) rewrites engine files from a FireForge-owned
|
|
151
147
|
* source. Content recorded in neither a patch body nor the pristine baseline
|
|
152
148
|
* is destroyed by that, and on a multi-session checkout the destruction is
|
|
153
149
|
* what lets a later re-export capture a half-reverted hybrid that every gate
|
|
@@ -220,9 +216,9 @@ export async function prepareBuildEnvironment(projectRoot, paths, config, option
|
|
|
220
216
|
const exitCode = captured.exitCode;
|
|
221
217
|
if (exitCode !== 0) {
|
|
222
218
|
configureSpinner.error(`mach configure failed with exit code ${exitCode}`);
|
|
223
|
-
// Surface the underlying mozbuild error (e.g. UnsortedError)
|
|
224
|
-
// of a bare exit code
|
|
225
|
-
// plus any matched mach-error hints (see the helper).
|
|
219
|
+
// Surface the underlying mozbuild error (e.g. UnsortedError)
|
|
220
|
+
// instead of a bare exit code, since the generic message hid the
|
|
221
|
+
// actual cause, plus any matched mach-error hints (see the helper).
|
|
226
222
|
throw buildConfigureFailureError(captured);
|
|
227
223
|
}
|
|
228
224
|
else {
|
|
@@ -246,7 +242,7 @@ export async function prepareBuildEnvironment(projectRoot, paths, config, option
|
|
|
246
242
|
// Set up custom branding directory and patch moz.configure. Thread the
|
|
247
243
|
// project license through so `buildConfigureScriptContent` /
|
|
248
244
|
// `buildBrandPropertiesContent` / `buildBrandFtlContent` stamp the
|
|
249
|
-
// generated files with a matching SPDX header
|
|
245
|
+
// generated files with a matching SPDX header. Otherwise `patch-lint`
|
|
250
246
|
// flags them with `missing-license-header` on every subsequent export when
|
|
251
247
|
// the project is not MPL-2.0.
|
|
252
248
|
const brandingConfig = {
|
|
@@ -18,10 +18,10 @@ function cloneConfigDocument(config) {
|
|
|
18
18
|
return cloned;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
-
* The error every sentinel-segment refusal raises. Only the
|
|
21
|
+
* The error every sentinel-segment refusal raises. Only the message lives
|
|
22
22
|
* here: the comparison itself is spelled inline at each write site, because
|
|
23
23
|
* that is what both a reader and CodeQL's `js/prototype-pollution-utility`
|
|
24
|
-
* barrier detection need
|
|
24
|
+
* barrier detection need. That detection is not interprocedural, so a check
|
|
25
25
|
* hidden behind a helper leaves the descent below looking unguarded.
|
|
26
26
|
*/
|
|
27
27
|
function sentinelSegmentError(key, part) {
|
|
@@ -41,8 +41,8 @@ function getOrCreateChildRecord(parent, key) {
|
|
|
41
41
|
export function mutateConfig(config, key, value, skipValidation = false) {
|
|
42
42
|
const parts = key.split('.');
|
|
43
43
|
const raw = cloneConfigDocument(config);
|
|
44
|
-
// Every segment is checked at the point it is
|
|
45
|
-
// the descent below and the leaf assignment
|
|
44
|
+
// Every segment is checked at the point it is used as a property name
|
|
45
|
+
// (the descent below and the leaf assignment) rather than once up front,
|
|
46
46
|
// so `--force` cannot be used to mutate Object.prototype and neither write
|
|
47
47
|
// can drift out from behind the guard. `raw` is a private clone, so a
|
|
48
48
|
// refusal here has mutated nothing the caller can observe.
|
|
@@ -2,16 +2,12 @@
|
|
|
2
2
|
* Project path derivation from a root directory.
|
|
3
3
|
*/
|
|
4
4
|
import type { ProjectPaths } from '../types/config.js';
|
|
5
|
-
/** Name of the configuration file */
|
|
6
|
-
export declare const CONFIG_FILENAME = "fireforge.json";
|
|
7
5
|
/** Name of the fireforge data directory */
|
|
8
6
|
export declare const FIREFORGE_DIR = ".fireforge";
|
|
9
|
-
/** Name of the state file */
|
|
10
|
-
export declare const STATE_FILENAME = "state.json";
|
|
11
7
|
/** Supported top-level fireforge.json keys backed by the current schema. */
|
|
12
|
-
export declare const SUPPORTED_CONFIG_ROOT_KEYS: readonly ["name", "vendor", "appId", "binaryName", "firefox", "build", "test", "externalToolchains", "license", "wire", "patchLint", "patchPolicy", "typecheck", "markerComment"];
|
|
8
|
+
export declare const SUPPORTED_CONFIG_ROOT_KEYS: readonly ["name", "vendor", "appId", "binaryName", "firefox", "build", "buildAudit", "test", "externalToolchains", "license", "wire", "patchLint", "patchPolicy", "typecheck", "markerComment"];
|
|
13
9
|
/** Supported config paths that can be read or set without --force. */
|
|
14
|
-
export declare const SUPPORTED_CONFIG_PATHS: readonly ["name", "vendor", "appId", "binaryName", "license", "firefox", "firefox.version", "firefox.product", "firefox.sha256", "firefox.candidate", "build", "build.jobs", "test", "test.canaryPath", "test.canaryTimeoutSeconds", "externalToolchains", "wire", "wire.subscriptDir", "patchLint", "patchLint.checkJs", "patchLint.checkJsStrict", "patchLint.checkJsCompilerOptions", "patchLint.checkJsExtraShim", "patchLint.checkJsTestFiles", "patchLint.checkJsTestShim", "patchLint.rawColorAllowlist", "patchLint.jsdocClassMethods", "patchLint.testAssertionFloor", "patchLint.chromeScriptJsDoc", "patchPolicy", "typecheck", "typecheck.projects", "typecheck.extraShim", "markerComment"];
|
|
10
|
+
export declare const SUPPORTED_CONFIG_PATHS: readonly ["name", "vendor", "appId", "binaryName", "license", "firefox", "firefox.version", "firefox.product", "firefox.sha256", "firefox.candidate", "firefox.allowUnverifiedDownload", "build", "build.jobs", "test", "test.canaryPath", "test.canaryTimeoutSeconds", "externalToolchains", "wire", "wire.subscriptDir", "patchLint", "patchLint.checkJs", "patchLint.checkJsStrict", "patchLint.checkJsCompilerOptions", "patchLint.checkJsExtraShim", "patchLint.checkJsTestFiles", "patchLint.checkJsTestShim", "patchLint.rawColorAllowlist", "patchLint.jsdocClassMethods", "patchLint.testAssertionFloor", "patchLint.chromeScriptJsDoc", "patchPolicy", "typecheck", "typecheck.projects", "typecheck.extraShim", "markerComment"];
|
|
15
11
|
/**
|
|
16
12
|
* Gets all project paths based on a root directory.
|
|
17
13
|
* @param root - Root directory of the project
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
/** Name of the configuration file */
|
|
7
|
-
|
|
7
|
+
const CONFIG_FILENAME = 'fireforge.json';
|
|
8
8
|
/** Name of the fireforge data directory */
|
|
9
9
|
export const FIREFORGE_DIR = '.fireforge';
|
|
10
10
|
/** Name of the state file */
|
|
11
|
-
|
|
11
|
+
const STATE_FILENAME = 'state.json';
|
|
12
12
|
/** Name of the engine directory */
|
|
13
13
|
const ENGINE_DIR = 'engine';
|
|
14
14
|
/** Name of the patches directory */
|
|
@@ -25,6 +25,7 @@ export const SUPPORTED_CONFIG_ROOT_KEYS = [
|
|
|
25
25
|
'binaryName',
|
|
26
26
|
'firefox',
|
|
27
27
|
'build',
|
|
28
|
+
'buildAudit',
|
|
28
29
|
'test',
|
|
29
30
|
'externalToolchains',
|
|
30
31
|
'license',
|
|
@@ -46,6 +47,7 @@ export const SUPPORTED_CONFIG_PATHS = [
|
|
|
46
47
|
'firefox.product',
|
|
47
48
|
'firefox.sha256',
|
|
48
49
|
'firefox.candidate',
|
|
50
|
+
'firefox.allowUnverifiedDownload',
|
|
49
51
|
'build',
|
|
50
52
|
'build.jobs',
|
|
51
53
|
'test',
|
|
@@ -8,12 +8,6 @@ import type { FireForgeState } from '../types/config.js';
|
|
|
8
8
|
* @returns FireForge state
|
|
9
9
|
*/
|
|
10
10
|
export declare function loadState(root: string): Promise<FireForgeState>;
|
|
11
|
-
/**
|
|
12
|
-
* Saves the fireforge state.
|
|
13
|
-
* @param root - Root directory of the project
|
|
14
|
-
* @param state - State to save
|
|
15
|
-
*/
|
|
16
|
-
export declare function saveState(root: string, state: FireForgeState): Promise<void>;
|
|
17
11
|
/**
|
|
18
12
|
* Updates specific fields in the fireforge state.
|
|
19
13
|
* @param root - Root directory of the project
|
|
@@ -24,13 +24,7 @@ function sanitizeProjectState(data) {
|
|
|
24
24
|
const state = {};
|
|
25
25
|
const issues = [];
|
|
26
26
|
const recoveredFields = [];
|
|
27
|
-
const stringFields = [
|
|
28
|
-
'brand',
|
|
29
|
-
'buildMode',
|
|
30
|
-
'lastBuild',
|
|
31
|
-
'downloadedVersion',
|
|
32
|
-
'baseCommit',
|
|
33
|
-
];
|
|
27
|
+
const stringFields = ['brand', 'buildMode', 'downloadedVersion', 'baseCommit'];
|
|
34
28
|
for (const key of stringFields) {
|
|
35
29
|
const value = data[key];
|
|
36
30
|
if (value === undefined) {
|
|
@@ -41,9 +35,9 @@ function sanitizeProjectState(data) {
|
|
|
41
35
|
continue;
|
|
42
36
|
}
|
|
43
37
|
if (key === 'buildMode') {
|
|
44
|
-
// Validate and assign in
|
|
38
|
+
// Validate and assign in one block so the predicate's narrowing reaches
|
|
45
39
|
// the assignment. Split across two `key === 'buildMode'` guards,
|
|
46
|
-
// TypeScript cannot correlate them and the assignment needed a cast
|
|
40
|
+
// TypeScript cannot correlate them and the assignment needed a cast,
|
|
47
41
|
// which is what let the untyped allowlist drift from the union.
|
|
48
42
|
if (!isBuildMode(value)) {
|
|
49
43
|
issues.push(`field "buildMode" must be one of: ${BUILD_MODES.join(', ')}`);
|
|
@@ -132,18 +126,6 @@ export async function loadState(root) {
|
|
|
132
126
|
const paths = getProjectPaths(root);
|
|
133
127
|
return loadStateFromPath(paths.state);
|
|
134
128
|
}
|
|
135
|
-
/**
|
|
136
|
-
* Saves the fireforge state.
|
|
137
|
-
* @param root - Root directory of the project
|
|
138
|
-
* @param state - State to save
|
|
139
|
-
*/
|
|
140
|
-
export async function saveState(root, state) {
|
|
141
|
-
const paths = getProjectPaths(root);
|
|
142
|
-
const validatedState = validateFireForgeState(state);
|
|
143
|
-
await withStateFileLock(paths.state, async () => {
|
|
144
|
-
await writeJson(paths.state, validatedState);
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
129
|
/**
|
|
148
130
|
* Updates specific fields in the fireforge state.
|
|
149
131
|
* @param root - Root directory of the project
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BuildAuditConfig } from '../types/config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parses the `buildAudit` block.
|
|
4
|
+
*
|
|
5
|
+
* @param raw - The raw `buildAudit` value from fireforge.json
|
|
6
|
+
* @returns The validated block
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseBuildAuditConfig(raw: unknown): BuildAuditConfig;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* Validation for the `buildAudit` block.
|
|
4
|
+
*
|
|
5
|
+
* Split out of `config-validate.ts`, which is at its per-file line budget,
|
|
6
|
+
* following the `config-validate-file-size.ts` precedent.
|
|
7
|
+
*
|
|
8
|
+
* The rules here are stricter than the schema strictly needs, on purpose:
|
|
9
|
+
* every entry is a standing suppression of a warning the
|
|
10
|
+
* audit would otherwise raise. A malformed one must fail loudly at config
|
|
11
|
+
* load rather than quietly admit nothing (leaving the operator believing a
|
|
12
|
+
* path is carved out) or quietly admit everything.
|
|
13
|
+
*/
|
|
14
|
+
import { ConfigError } from '../errors/config.js';
|
|
15
|
+
import { isContainedRelativePath } from '../utils/paths.js';
|
|
16
|
+
import { isObject } from '../utils/validation.js';
|
|
17
|
+
/** Parses one `buildAudit.unpackaged[]` entry. */
|
|
18
|
+
function parseUnpackagedEntry(raw, field) {
|
|
19
|
+
if (!isObject(raw)) {
|
|
20
|
+
throw new ConfigError(`Config field "${field}" must be a plain object with "path" and "reason"`);
|
|
21
|
+
}
|
|
22
|
+
for (const key of Object.keys(raw)) {
|
|
23
|
+
if (key !== 'path' && key !== 'reason') {
|
|
24
|
+
throw new ConfigError(`Config field "${field}" has unknown key "${key}"`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const path = raw['path'];
|
|
28
|
+
if (typeof path !== 'string' || path.trim().length === 0) {
|
|
29
|
+
throw new ConfigError(`Config field "${field}.path" must be a non-empty string`);
|
|
30
|
+
}
|
|
31
|
+
if (!isContainedRelativePath(path)) {
|
|
32
|
+
throw new ConfigError(`Config field "${field}.path" must be an engine-relative path`);
|
|
33
|
+
}
|
|
34
|
+
if (path.includes('**')) {
|
|
35
|
+
// A `**` carve-out admits an entire subtree, which is how a reviewed
|
|
36
|
+
// exception quietly becomes a blanket one. `*` inside a single segment
|
|
37
|
+
// is enough for the shapes this exists for.
|
|
38
|
+
throw new ConfigError(`Config field "${field}.path" must not use "**" — a carve-out may glob within one path segment only`);
|
|
39
|
+
}
|
|
40
|
+
const reason = raw['reason'];
|
|
41
|
+
if (typeof reason !== 'string' || reason.trim().length === 0) {
|
|
42
|
+
// Required on purpose: this is the one audit class FireForge cannot
|
|
43
|
+
// derive from the tree, so the declaration is the evidence.
|
|
44
|
+
throw new ConfigError(`Config field "${field}.reason" must be a non-empty string explaining why the file is never packaged`);
|
|
45
|
+
}
|
|
46
|
+
return { path, reason };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Parses the `buildAudit` block.
|
|
50
|
+
*
|
|
51
|
+
* @param raw - The raw `buildAudit` value from fireforge.json
|
|
52
|
+
* @returns The validated block
|
|
53
|
+
*/
|
|
54
|
+
export function parseBuildAuditConfig(raw) {
|
|
55
|
+
if (!isObject(raw)) {
|
|
56
|
+
throw new ConfigError('Config field "buildAudit" must be a plain object');
|
|
57
|
+
}
|
|
58
|
+
for (const key of Object.keys(raw)) {
|
|
59
|
+
if (key !== 'unpackaged') {
|
|
60
|
+
throw new ConfigError(`Config field "buildAudit" has unknown key "${key}"`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const unpackaged = raw['unpackaged'];
|
|
64
|
+
if (unpackaged === undefined)
|
|
65
|
+
return {};
|
|
66
|
+
if (!Array.isArray(unpackaged)) {
|
|
67
|
+
throw new ConfigError('Config field "buildAudit.unpackaged" must be an array');
|
|
68
|
+
}
|
|
69
|
+
const entries = unpackaged.map((entry, index) => parseUnpackagedEntry(entry, `buildAudit.unpackaged[${String(index)}]`));
|
|
70
|
+
const seen = new Set();
|
|
71
|
+
for (const entry of entries) {
|
|
72
|
+
if (seen.has(entry.path)) {
|
|
73
|
+
// Two rows for one path means one of the two reasons is not the
|
|
74
|
+
// operative one, and nothing says which.
|
|
75
|
+
throw new ConfigError(`Config field "buildAudit.unpackaged" declares "${entry.path}" more than once`);
|
|
76
|
+
}
|
|
77
|
+
seen.add(entry.path);
|
|
78
|
+
}
|
|
79
|
+
return { unpackaged: entries };
|
|
80
|
+
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import type { PatchLintFileSizeThresholds } from '../types/config.js';
|
|
7
7
|
/**
|
|
8
8
|
* Parses the `patchLint.fileSizeThresholds` block. Ordering is validated
|
|
9
|
-
* against the
|
|
9
|
+
* against the merged triple (overrides on top of the defaults), so setting
|
|
10
10
|
* only `warning` cannot land below the default `notice`.
|
|
11
11
|
*/
|
|
12
12
|
export declare function parsePatchLintFileSizeThresholds(raw: unknown): PatchLintFileSizeThresholds;
|
|
@@ -9,7 +9,7 @@ import { isObject } from '../utils/validation.js';
|
|
|
9
9
|
import { DEFAULT_FILE_SIZE_THRESHOLDS } from './patch-lint-file-size.js';
|
|
10
10
|
/**
|
|
11
11
|
* Parses one `patchLint.fileSizeThresholds.<tier>` triple. Every field is
|
|
12
|
-
* optional and merges over the built-in default
|
|
12
|
+
* optional and merges over the built-in default. Values must be positive
|
|
13
13
|
* integers and stay ordered `notice <= warning <= error`, because an
|
|
14
14
|
* out-of-order triple would silently disable a band instead of failing.
|
|
15
15
|
*/
|
|
@@ -36,7 +36,7 @@ function parseFileSizeTier(raw, field) {
|
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
38
|
* Parses the `patchLint.fileSizeThresholds` block. Ordering is validated
|
|
39
|
-
* against the
|
|
39
|
+
* against the merged triple (overrides on top of the defaults), so setting
|
|
40
40
|
* only `warning` cannot land below the default `notice`.
|
|
41
41
|
*/
|
|
42
42
|
export function parsePatchLintFileSizeThresholds(raw) {
|
|
@@ -52,7 +52,7 @@ export function parsePatchLintFileSizeThresholds(raw) {
|
|
|
52
52
|
const merged = { ...DEFAULT_FILE_SIZE_THRESHOLDS[tier], ...parsed };
|
|
53
53
|
if (merged.notice > merged.warning || merged.warning > merged.error) {
|
|
54
54
|
throw new ConfigError(`Config field "patchLint.fileSizeThresholds.${tier}" must satisfy notice <= warning <= error ` +
|
|
55
|
-
`(resolved: ${
|
|
55
|
+
`(resolved: ${merged.notice}/${merged.warning}/${merged.error})`);
|
|
56
56
|
}
|
|
57
57
|
out[tier] = parsed;
|
|
58
58
|
}
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* Validation helpers for `fireforge.json#patchPolicy`.
|
|
3
3
|
*/
|
|
4
4
|
import type { PatchPolicyConfig } from '../types/config.js';
|
|
5
|
-
import {
|
|
5
|
+
import { type ParsedRecord } from '../utils/parse.js';
|
|
6
6
|
/** Parses and validates the optional patch policy config block. */
|
|
7
|
-
export declare function parsePatchPolicyBlock(rec:
|
|
7
|
+
export declare function parsePatchPolicyBlock(rec: ParsedRecord): PatchPolicyConfig;
|
|
@@ -108,7 +108,7 @@ function parsePatchPolicyReservedRange(raw, label) {
|
|
|
108
108
|
return {
|
|
109
109
|
from,
|
|
110
110
|
to,
|
|
111
|
-
allowed: allowedRaw.map((entry, index) => parseReservedAllowedPatch(entry, `${label}.allowed[${
|
|
111
|
+
allowed: allowedRaw.map((entry, index) => parseReservedAllowedPatch(entry, `${label}.allowed[${index}]`)),
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
114
|
function assertPolicyRangesDoNotOverlap(ranges, label) {
|
|
@@ -160,14 +160,14 @@ export function parsePatchPolicyBlock(rec) {
|
|
|
160
160
|
if (!Array.isArray(rangesRaw) || rangesRaw.length === 0) {
|
|
161
161
|
throw new ConfigError('Config field "patchPolicy.ranges" must be a non-empty array');
|
|
162
162
|
}
|
|
163
|
-
out.ranges = rangesRaw.map((entry, index) => parsePatchPolicyRange(entry, `patchPolicy.ranges[${
|
|
163
|
+
out.ranges = rangesRaw.map((entry, index) => parsePatchPolicyRange(entry, `patchPolicy.ranges[${index}]`));
|
|
164
164
|
assertPolicyRangesDoNotOverlap(out.ranges, 'patchPolicy.ranges');
|
|
165
165
|
const reservedRangesRaw = rec.raw('reservedRanges');
|
|
166
166
|
if (reservedRangesRaw !== undefined) {
|
|
167
167
|
if (!Array.isArray(reservedRangesRaw)) {
|
|
168
168
|
throw new ConfigError('Config field "patchPolicy.reservedRanges" must be an array');
|
|
169
169
|
}
|
|
170
|
-
out.reservedRanges = reservedRangesRaw.map((entry, index) => parsePatchPolicyReservedRange(entry, `patchPolicy.reservedRanges[${
|
|
170
|
+
out.reservedRanges = reservedRangesRaw.map((entry, index) => parsePatchPolicyReservedRange(entry, `patchPolicy.reservedRanges[${index}]`));
|
|
171
171
|
assertPolicyRangesDoNotOverlap(out.reservedRanges, 'patchPolicy.reservedRanges');
|
|
172
172
|
}
|
|
173
173
|
return out;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FireForgeConfig } from '../types/config.js';
|
|
2
|
-
import {
|
|
3
|
-
type ConfigRecord =
|
|
2
|
+
import type { ParsedRecord } from '../utils/parse.js';
|
|
3
|
+
type ConfigRecord = ParsedRecord;
|
|
4
4
|
/** Parses the optional `test` block. */
|
|
5
5
|
export declare function parseTestBlock(rec: ConfigRecord, config: FireForgeConfig): void;
|
|
6
6
|
/** Parses optional project-specific external toolchain doctor probes. */
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
import { ConfigError } from '../errors/config.js';
|
|
3
|
-
import { parseObject } from '../utils/parse.js';
|
|
4
3
|
import { isContainedRelativePath } from '../utils/paths.js';
|
|
5
4
|
import { isObject } from '../utils/validation.js';
|
|
6
5
|
function optionalConfigString(rec, key, label) {
|
|
@@ -58,16 +57,16 @@ export function parseExternalToolchainsBlock(rec, config) {
|
|
|
58
57
|
}
|
|
59
58
|
config.externalToolchains = raw.map((entry, index) => {
|
|
60
59
|
if (!isObject(entry)) {
|
|
61
|
-
throw new ConfigError(`Config field "externalToolchains[${
|
|
60
|
+
throw new ConfigError(`Config field "externalToolchains[${index}]" must be an object`);
|
|
62
61
|
}
|
|
63
62
|
const item = entry;
|
|
64
63
|
const name = item['name'];
|
|
65
64
|
if (typeof name !== 'string' || name.trim() === '') {
|
|
66
|
-
throw new ConfigError(`Config field "externalToolchains[${
|
|
65
|
+
throw new ConfigError(`Config field "externalToolchains[${index}].name" must be a non-empty string`);
|
|
67
66
|
}
|
|
68
67
|
const tools = item['tools'];
|
|
69
68
|
if (!Array.isArray(tools) || tools.length === 0) {
|
|
70
|
-
throw new ConfigError(`Config field "externalToolchains[${
|
|
69
|
+
throw new ConfigError(`Config field "externalToolchains[${index}].tools" must be a non-empty array`);
|
|
71
70
|
}
|
|
72
71
|
return {
|
|
73
72
|
name,
|
|
@@ -76,7 +75,7 @@ export function parseExternalToolchainsBlock(rec, config) {
|
|
|
76
75
|
});
|
|
77
76
|
}
|
|
78
77
|
function parseExternalToolRequirement(tool, index, toolIndex) {
|
|
79
|
-
const label = `externalToolchains[${
|
|
78
|
+
const label = `externalToolchains[${index}].tools[${toolIndex}]`;
|
|
80
79
|
if (!isObject(tool)) {
|
|
81
80
|
throw new ConfigError(`Config field "${label}" must be an object`);
|
|
82
81
|
}
|
|
@@ -8,6 +8,7 @@ import { parseObject } from '../utils/parse.js';
|
|
|
8
8
|
import { isContainedRelativePath, isExplicitAbsolutePath } from '../utils/paths.js';
|
|
9
9
|
import { describeProductVersionIncompatibility, FIREFOX_PRODUCTS, isObject, isValidAppId, isValidFirefoxCandidate, isValidFirefoxProduct, isValidFirefoxVersion, isValidProjectLicense, PROJECT_LICENSES, } from '../utils/validation.js';
|
|
10
10
|
import { SUPPORTED_CONFIG_ROOT_KEYS } from './config-paths.js';
|
|
11
|
+
import { parseBuildAuditConfig } from './config-validate-build-audit.js';
|
|
11
12
|
import { parsePatchLintFileSizeThresholds } from './config-validate-file-size.js';
|
|
12
13
|
import { parsePatchPolicyBlock } from './config-validate-patch-policy.js';
|
|
13
14
|
import { parseExternalToolchainsBlock, parseTestBlock } from './config-validate-test-toolchains.js';
|
|
@@ -20,7 +21,7 @@ import { parseExternalToolchainsBlock, parseTestBlock } from './config-validate-
|
|
|
20
21
|
function parseIdentityFields(rec) {
|
|
21
22
|
// Empty strings would technically pass the
|
|
22
23
|
// typeof-check below but are never valid for any of these identifier
|
|
23
|
-
// fields
|
|
24
|
+
// fields. Rejecting them here prevents downstream code (Firefox build,
|
|
24
25
|
// launcher binary lookup, AppID assertions) from failing with confusing
|
|
25
26
|
// errors much later.
|
|
26
27
|
const name = requireConfigString(rec, 'name');
|
|
@@ -54,7 +55,8 @@ function parseIdentityFields(rec) {
|
|
|
54
55
|
/**
|
|
55
56
|
* Parses and validates the required `firefox` block: version shape,
|
|
56
57
|
* product allowlist, product/version cross-compatibility, and the
|
|
57
|
-
* optional sha256 digest (normalized to lowercase)
|
|
58
|
+
* optional sha256 digest (normalized to lowercase), optional
|
|
59
|
+
* `allowUnverifiedDownload` opt-out, optional candidate directory.
|
|
58
60
|
*/
|
|
59
61
|
function parseFirefoxBlock(rec) {
|
|
60
62
|
let firefoxRec;
|
|
@@ -70,7 +72,7 @@ function parseFirefoxBlock(rec) {
|
|
|
70
72
|
}
|
|
71
73
|
const firefoxProduct = requireConfigString(firefoxRec, 'product', 'firefox.product');
|
|
72
74
|
// Uses the shared guard rather than a fourth copy of the member list. This
|
|
73
|
-
// is the fireforge.json
|
|
75
|
+
// is the fireforge.json read path: a product added to the union but not to
|
|
74
76
|
// the copy that used to live here would have been silently rejected from
|
|
75
77
|
// every project config.
|
|
76
78
|
if (!isValidFirefoxProduct(firefoxProduct)) {
|
|
@@ -85,6 +87,10 @@ function parseFirefoxBlock(rec) {
|
|
|
85
87
|
if (firefoxSha256 !== undefined && !/^[a-f0-9]{64}$/i.test(firefoxSha256)) {
|
|
86
88
|
throw new ConfigError('Config field "firefox.sha256" must be a 64-character SHA-256 hex digest');
|
|
87
89
|
}
|
|
90
|
+
const allowUnverifiedDownload = firefoxRec.raw('allowUnverifiedDownload');
|
|
91
|
+
if (allowUnverifiedDownload !== undefined && typeof allowUnverifiedDownload !== 'boolean') {
|
|
92
|
+
throw new ConfigError('Config field "firefox.allowUnverifiedDownload" must be a boolean');
|
|
93
|
+
}
|
|
88
94
|
const firefoxCandidate = optionalConfigString(firefoxRec, 'candidate', 'firefox.candidate');
|
|
89
95
|
if (firefoxCandidate !== undefined && !isValidFirefoxCandidate(firefoxCandidate)) {
|
|
90
96
|
throw new ConfigError('Config field "firefox.candidate" must look like "buildN" (e.g. "build2")');
|
|
@@ -93,6 +99,7 @@ function parseFirefoxBlock(rec) {
|
|
|
93
99
|
version: firefoxVersion,
|
|
94
100
|
product: firefoxProduct,
|
|
95
101
|
...(firefoxSha256 !== undefined ? { sha256: firefoxSha256.toLowerCase() } : {}),
|
|
102
|
+
...(allowUnverifiedDownload !== undefined ? { allowUnverifiedDownload } : {}),
|
|
96
103
|
...(firefoxCandidate !== undefined ? { candidate: firefoxCandidate } : {}),
|
|
97
104
|
};
|
|
98
105
|
}
|
|
@@ -155,11 +162,15 @@ export function validateConfig(data) {
|
|
|
155
162
|
const firefox = parseFirefoxBlock(rec);
|
|
156
163
|
const config = { ...identity, firefox };
|
|
157
164
|
parseBuildBlock(rec, config);
|
|
165
|
+
const buildAuditRaw = rec.raw('buildAudit');
|
|
166
|
+
if (buildAuditRaw !== undefined) {
|
|
167
|
+
config.buildAudit = parseBuildAuditConfig(buildAuditRaw);
|
|
168
|
+
}
|
|
158
169
|
parseTestBlock(rec, config);
|
|
159
170
|
parseExternalToolchainsBlock(rec, config);
|
|
160
171
|
parseWireBlock(rec, config);
|
|
161
172
|
parseLicenseField(rec, config);
|
|
162
|
-
// Marker comment
|
|
173
|
+
// Marker comment, appended to lines FireForge writes into upstream files.
|
|
163
174
|
const markerComment = parseMarkerComment(rec.raw('markerComment'));
|
|
164
175
|
if (markerComment !== undefined) {
|
|
165
176
|
config.markerComment = markerComment;
|
|
@@ -174,7 +185,7 @@ export function validateConfig(data) {
|
|
|
174
185
|
if (patchPolicyRec) {
|
|
175
186
|
config.patchPolicy = parsePatchPolicyBlock(patchPolicyRec);
|
|
176
187
|
}
|
|
177
|
-
// Typecheck (top-level, distinct from patchLint
|
|
188
|
+
// Typecheck (top-level, distinct from patchLint). See TypecheckConfig docs.
|
|
178
189
|
const typecheckRec = optionalConfigObject(rec, 'typecheck');
|
|
179
190
|
if (typecheckRec) {
|
|
180
191
|
config.typecheck = parseTypecheckBlock(typecheckRec);
|
|
@@ -389,10 +400,9 @@ function parsePatchLintBlock(rec) {
|
|
|
389
400
|
* file. Shared between `patchLint.checkJsExtraShim` and
|
|
390
401
|
* `typecheck.extraShim` so both fields reject the same absolute-path /
|
|
391
402
|
* traversal / empty-string inputs with consistent error messages. The
|
|
392
|
-
* file's existence is
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
* for unrelated commands.
|
|
403
|
+
* file's existence is not checked here. That lives at the engine layer,
|
|
404
|
+
* where a missing file produces a typed runtime error pointing at the
|
|
405
|
+
* actual command, rather than blocking config reads for unrelated commands.
|
|
396
406
|
*/
|
|
397
407
|
function parseShimPath(raw, label) {
|
|
398
408
|
if (typeof raw !== 'string' || raw.trim() === '') {
|
|
@@ -406,7 +416,7 @@ function parseShimPath(raw, label) {
|
|
|
406
416
|
/**
|
|
407
417
|
* Validates the optional top-level `typecheck` block. Empty `projects`
|
|
408
418
|
* is rejected because a silent no-op for `fireforge typecheck` is a
|
|
409
|
-
* footgun
|
|
419
|
+
* footgun, since operators set the block expecting it to do something. Each
|
|
410
420
|
* project path must be a contained relative path so `--project` / CLI
|
|
411
421
|
* scripts can't escape the project root.
|
|
412
422
|
*/
|
|
@@ -425,10 +435,10 @@ function parseTypecheckBlock(rec) {
|
|
|
425
435
|
for (let i = 0; i < projectsRaw.length; i++) {
|
|
426
436
|
const entry = projectsRaw[i];
|
|
427
437
|
if (typeof entry !== 'string' || entry.trim() === '') {
|
|
428
|
-
throw new ConfigError(`Config field "typecheck.projects[${
|
|
438
|
+
throw new ConfigError(`Config field "typecheck.projects[${i}]" must be a non-empty string`);
|
|
429
439
|
}
|
|
430
440
|
if (!isContainedRelativePath(entry)) {
|
|
431
|
-
throw new ConfigError(`Config field "typecheck.projects[${
|
|
441
|
+
throw new ConfigError(`Config field "typecheck.projects[${i}]" must be a project-relative path`);
|
|
432
442
|
}
|
|
433
443
|
projects.push(entry);
|
|
434
444
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Project configuration
|
|
2
|
+
* Project configuration barrel module.
|
|
3
3
|
*
|
|
4
4
|
* Re-exports from focused sub-modules:
|
|
5
|
-
* config-paths.ts
|
|
6
|
-
* config-validate.ts
|
|
7
|
-
* config-mutate.ts
|
|
8
|
-
* config-state.ts
|
|
5
|
+
* config-paths.ts: constants and project path derivation
|
|
6
|
+
* config-validate.ts: fireforge.json schema validation
|
|
7
|
+
* config-mutate.ts: immutable config mutation
|
|
8
|
+
* config-state.ts: state file management
|
|
9
9
|
*/
|
|
10
10
|
import type { FireForgeConfig } from '../types/config.js';
|
|
11
11
|
import type { JsonObject } from '../types/json.js';
|
|
12
12
|
export { mutateConfig } from './config-mutate.js';
|
|
13
|
-
export {
|
|
14
|
-
export { loadState,
|
|
13
|
+
export { FIREFORGE_DIR, getProjectPaths, SUPPORTED_CONFIG_PATHS, SUPPORTED_CONFIG_ROOT_KEYS, } from './config-paths.js';
|
|
14
|
+
export { loadState, updateState } from './config-state.js';
|
|
15
15
|
export { validateConfig } from './config-validate.js';
|
|
16
16
|
/**
|
|
17
17
|
* Checks if a fireforge.json exists in the given directory.
|
|
@@ -28,12 +28,12 @@ export declare function configExists(root: string): Promise<boolean>;
|
|
|
28
28
|
export declare function loadConfig(root: string): Promise<FireForgeConfig>;
|
|
29
29
|
/**
|
|
30
30
|
* Reads the raw `fireforge.json` document without running it through
|
|
31
|
-
* {@link validateConfig}. Returns every persisted key
|
|
31
|
+
* {@link validateConfig}. Returns every persisted key, including keys
|
|
32
32
|
* written via `fireforge config <key> --force` that `validateConfig`
|
|
33
33
|
* would strip from the typed result.
|
|
34
34
|
*
|
|
35
35
|
* Callers that need the validated, typed shape must still use
|
|
36
|
-
* {@link loadConfig}
|
|
36
|
+
* {@link loadConfig}. This helper exists specifically for the `config`
|
|
37
37
|
* read path so `fireforge config <key>` can surface keys the write path
|
|
38
38
|
* accepted under `--force`.
|
|
39
39
|
*
|
|
@@ -67,9 +67,9 @@ export declare function writeConfigDocument(root: string, config: FireForgeConfi
|
|
|
67
67
|
* Runs an operation while holding a sidecar lock on `fireforge.json`.
|
|
68
68
|
*
|
|
69
69
|
* Two concurrent `fireforge config <key> <value>` invocations each run
|
|
70
|
-
* load → mutate → writeJson against the same document
|
|
71
|
-
* second rename lands after the first and silently drops the first
|
|
72
|
-
* key, with both commands exiting 0.
|
|
70
|
+
* load → mutate → writeJson against the same document. Without this lock
|
|
71
|
+
* the second rename lands after the first and silently drops the first
|
|
72
|
+
* writer's key, with both commands exiting 0.
|
|
73
73
|
*
|
|
74
74
|
* Reads (`loadConfig`, `loadRawConfigDocument`) stay lock-free: writers
|
|
75
75
|
* always use `writeJson`'s atomic temp-file + rename, so a reader observes
|