@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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
-
import { createHash } from 'node:crypto';
|
|
3
2
|
import { readFile } from 'node:fs/promises';
|
|
4
3
|
import { join, resolve } from 'node:path';
|
|
5
4
|
import { pathExists, readJson, writeJson } from '../utils/fs.js';
|
|
5
|
+
import { sha256Hex } from '../utils/hash.js';
|
|
6
6
|
import { getPackageVersion } from '../utils/package-root.js';
|
|
7
7
|
import { getFurnacePaths } from './furnace-config.js';
|
|
8
8
|
import { git } from './git-base.js';
|
|
@@ -42,10 +42,6 @@ function stableJson(value) {
|
|
|
42
42
|
.map(([key, item]) => `${JSON.stringify(key)}:${stableJson(item)}`)
|
|
43
43
|
.join(',')}}`;
|
|
44
44
|
}
|
|
45
|
-
/** Computes a SHA-256 hex digest for text or binary content. */
|
|
46
|
-
function sha256Hex(content) {
|
|
47
|
-
return createHash('sha256').update(content).digest('hex');
|
|
48
|
-
}
|
|
49
45
|
/** Computes a stable SHA-256 digest for JSON-compatible data. */
|
|
50
46
|
function stableHash(value) {
|
|
51
47
|
return sha256Hex(stableJson(value));
|
|
@@ -223,7 +219,8 @@ export function getCachedPerPatchLintIssues(cache, patchFilename, key, lintIgnor
|
|
|
223
219
|
};
|
|
224
220
|
}
|
|
225
221
|
/** Stores the per-patch lint payload after a successful lint calculation. */
|
|
226
|
-
export function setCachedPerPatchLintIssues(
|
|
222
|
+
export function setCachedPerPatchLintIssues(input) {
|
|
223
|
+
const { cache, patchFilename, key, issues, suppressed, lineCount, lintIgnore } = input;
|
|
227
224
|
cache.entries[patchFilename] = {
|
|
228
225
|
key,
|
|
229
226
|
patchFilename,
|
|
@@ -46,6 +46,37 @@ export interface GroupedCheckJsResult {
|
|
|
46
46
|
byFile: Map<string, PatchLintIssue[]>;
|
|
47
47
|
global: PatchLintIssue[];
|
|
48
48
|
}
|
|
49
|
+
/** Inputs for {@link runCheckJsGrouped}. */
|
|
50
|
+
export interface RunCheckJsGroupedInput {
|
|
51
|
+
/** Absolute engine (repository) directory. */
|
|
52
|
+
repoDir: string;
|
|
53
|
+
/**
|
|
54
|
+
* Patch-owned `.sys.mjs` paths (relative to `repoDir`) the program should
|
|
55
|
+
* see and resolve against.
|
|
56
|
+
*/
|
|
57
|
+
resolutionOwned: Set<string>;
|
|
58
|
+
/**
|
|
59
|
+
* Optional project-relative extra `.d.ts` appended to the built-in
|
|
60
|
+
* Firefox-globals shim (from `patchLint.checkJsExtraShim`).
|
|
61
|
+
*/
|
|
62
|
+
extraShimPath?: string;
|
|
63
|
+
/** Absolute project root for resolving `extraShimPath`. */
|
|
64
|
+
projectRoot?: string;
|
|
65
|
+
/** Strictness preset plus allowlisted compiler-option overrides. */
|
|
66
|
+
mode?: CheckJsMode;
|
|
67
|
+
/** Optional shim text appended AFTER the consumer shim. */
|
|
68
|
+
builtinShimSuffix?: string;
|
|
69
|
+
/**
|
|
70
|
+
* When set, only these repo-relative files become program ROOTS;
|
|
71
|
+
* resolution (and the host allowlist) still spans all of
|
|
72
|
+
* `resolutionOwned`, so a subset root's cross-patch imports type-check
|
|
73
|
+
* against the real owning sources while unrelated owned files are never
|
|
74
|
+
* parsed. `.mjs` files are module-scoped, so a root's diagnostics are
|
|
75
|
+
* identical whether other owned files are roots or mere resolution
|
|
76
|
+
* targets.
|
|
77
|
+
*/
|
|
78
|
+
rootScope?: ReadonlySet<string>;
|
|
79
|
+
}
|
|
49
80
|
/**
|
|
50
81
|
* Builds the checkJs program **once** over `resolutionOwned` and returns its
|
|
51
82
|
* diagnostics grouped by originating file. Callers slice the result by their
|
|
@@ -54,24 +85,10 @@ export interface GroupedCheckJsResult {
|
|
|
54
85
|
* every file in `resolutionOwned`, so cross-patch `resource:///`/`chrome://`
|
|
55
86
|
* imports resolve to real sources.
|
|
56
87
|
*
|
|
57
|
-
* @param
|
|
58
|
-
* @param resolutionOwned - Patch-owned `.sys.mjs` paths (relative to repoDir)
|
|
59
|
-
* the program should see and resolve against
|
|
60
|
-
* @param extraShimPath - Optional project-relative extra `.d.ts` appended to
|
|
61
|
-
* the built-in Firefox-globals shim (from `patchLint.checkJsExtraShim`)
|
|
62
|
-
* @param projectRoot - Absolute project root for resolving `extraShimPath`
|
|
63
|
-
* @param mode - Strictness preset plus allowlisted compiler-option overrides
|
|
64
|
-
* @param builtinShimSuffix - Optional shim text appended AFTER the consumer
|
|
65
|
-
* shim
|
|
66
|
-
* @param rootScope - When set, only these repo-relative files become program
|
|
67
|
-
* ROOTS; resolution (and the host allowlist) still spans all of
|
|
68
|
-
* `resolutionOwned`, so a subset root's cross-patch imports type-check
|
|
69
|
-
* against the real owning sources while unrelated owned files are never
|
|
70
|
-
* parsed. `.mjs` files are module-scoped, so a root's diagnostics are
|
|
71
|
-
* identical whether other owned files are roots or mere resolution targets.
|
|
88
|
+
* @param input - Program inputs; see {@link RunCheckJsGroupedInput}
|
|
72
89
|
* @returns Diagnostics grouped per owning file plus run-level errors
|
|
73
90
|
*/
|
|
74
|
-
export declare function runCheckJsGrouped(
|
|
91
|
+
export declare function runCheckJsGrouped(input: RunCheckJsGroupedInput): Promise<GroupedCheckJsResult>;
|
|
75
92
|
/**
|
|
76
93
|
* Flattens a {@link runCheckJsGrouped} run into a single issue list. When
|
|
77
94
|
* `reportScope` is supplied, only diagnostics from files in that set are
|
|
@@ -162,24 +162,11 @@ function createPathsResolver(ts, paths, baseDir, fileExists, onResolved) {
|
|
|
162
162
|
* every file in `resolutionOwned`, so cross-patch `resource:///`/`chrome://`
|
|
163
163
|
* imports resolve to real sources.
|
|
164
164
|
*
|
|
165
|
-
* @param
|
|
166
|
-
* @param resolutionOwned - Patch-owned `.sys.mjs` paths (relative to repoDir)
|
|
167
|
-
* the program should see and resolve against
|
|
168
|
-
* @param extraShimPath - Optional project-relative extra `.d.ts` appended to
|
|
169
|
-
* the built-in Firefox-globals shim (from `patchLint.checkJsExtraShim`)
|
|
170
|
-
* @param projectRoot - Absolute project root for resolving `extraShimPath`
|
|
171
|
-
* @param mode - Strictness preset plus allowlisted compiler-option overrides
|
|
172
|
-
* @param builtinShimSuffix - Optional shim text appended AFTER the consumer
|
|
173
|
-
* shim
|
|
174
|
-
* @param rootScope - When set, only these repo-relative files become program
|
|
175
|
-
* ROOTS; resolution (and the host allowlist) still spans all of
|
|
176
|
-
* `resolutionOwned`, so a subset root's cross-patch imports type-check
|
|
177
|
-
* against the real owning sources while unrelated owned files are never
|
|
178
|
-
* parsed. `.mjs` files are module-scoped, so a root's diagnostics are
|
|
179
|
-
* identical whether other owned files are roots or mere resolution targets.
|
|
165
|
+
* @param input - Program inputs; see {@link RunCheckJsGroupedInput}
|
|
180
166
|
* @returns Diagnostics grouped per owning file plus run-level errors
|
|
181
167
|
*/
|
|
182
|
-
export async function runCheckJsGrouped(
|
|
168
|
+
export async function runCheckJsGrouped(input) {
|
|
169
|
+
const { repoDir, resolutionOwned, extraShimPath, rootScope } = input;
|
|
183
170
|
const empty = { byFile: new Map(), global: [] };
|
|
184
171
|
if (resolutionOwned.size === 0)
|
|
185
172
|
return empty;
|
|
@@ -227,12 +214,14 @@ export async function runCheckJsGrouped(repoDir, resolutionOwned, extraShimPath,
|
|
|
227
214
|
// also undefined, so the resolution target is irrelevant.
|
|
228
215
|
let shimSource;
|
|
229
216
|
try {
|
|
230
|
-
const composed = await composeShimSource(projectRoot ?? repoDir, extraShimPath);
|
|
217
|
+
const composed = await composeShimSource(input.projectRoot ?? repoDir, extraShimPath);
|
|
231
218
|
// The suffix (e.g. the loose test-harness baseline) goes
|
|
232
219
|
// AFTER the consumer's extra shim: TypeScript resolves conflicting
|
|
233
220
|
// `declare var` redeclarations to the FIRST declaration, so a typed
|
|
234
221
|
// consumer declaration must precede the loose fallback to win.
|
|
235
|
-
shimSource =
|
|
222
|
+
shimSource = input.builtinShimSuffix
|
|
223
|
+
? `${composed.source}\n${input.builtinShimSuffix}`
|
|
224
|
+
: composed.source;
|
|
236
225
|
if (composed.extraShimAppended) {
|
|
237
226
|
verbose(`checkJs: extra shim ${extraShimPath ?? ''} appended to Firefox globals shim`);
|
|
238
227
|
}
|
|
@@ -252,7 +241,7 @@ export async function runCheckJsGrouped(repoDir, resolutionOwned, extraShimPath,
|
|
|
252
241
|
}
|
|
253
242
|
const shimPath = toTsPath(resolve(repoDir, SHIM_FILENAME));
|
|
254
243
|
rootFiles.push(shimPath);
|
|
255
|
-
const strict = mode?.strict === true;
|
|
244
|
+
const strict = input.mode?.strict === true;
|
|
256
245
|
const strictness = strict
|
|
257
246
|
? { strict: true, noImplicitAny: true }
|
|
258
247
|
: {
|
|
@@ -266,7 +255,7 @@ export async function runCheckJsGrouped(repoDir, resolutionOwned, extraShimPath,
|
|
|
266
255
|
// sources without a hand-generated ambient stub shim.
|
|
267
256
|
const overrides = {};
|
|
268
257
|
let pathsMapping;
|
|
269
|
-
const co = mode?.compilerOptions;
|
|
258
|
+
const co = input.mode?.compilerOptions;
|
|
270
259
|
if (co) {
|
|
271
260
|
for (const key of Object.keys(co)) {
|
|
272
261
|
const v = co[key];
|
|
@@ -351,7 +340,7 @@ export async function runCheckJsGrouped(repoDir, resolutionOwned, extraShimPath,
|
|
|
351
340
|
},
|
|
352
341
|
};
|
|
353
342
|
const program = ts.createProgram(rootFiles, options, host);
|
|
354
|
-
const byFile = groupOwnedDiagnostics(ts, [...program.getSemanticDiagnostics(), ...program.getSyntacticDiagnostics()], relByAbsolute, mode?.undefinedIdentifiers ?? 'warning');
|
|
343
|
+
const byFile = groupOwnedDiagnostics(ts, [...program.getSemanticDiagnostics(), ...program.getSyntacticDiagnostics()], relByAbsolute, input.mode?.undefinedIdentifiers ?? 'warning');
|
|
355
344
|
verbose(`checkJs: analyzed ${rootFiles.length - 1} file(s) across ${byFile.size} owning file(s)`);
|
|
356
345
|
return { byFile, global: [] };
|
|
357
346
|
}
|
|
@@ -417,7 +406,13 @@ function groupOwnedDiagnostics(ts, diagnostics, relByAbsolute, undefinedIdentifi
|
|
|
417
406
|
* @returns Array of lint issues from TS diagnostics
|
|
418
407
|
*/
|
|
419
408
|
export async function runCheckJs(repoDir, patchOwnedFiles, extraShimPath, projectRoot, mode, reportScope) {
|
|
420
|
-
const { byFile, global } = await runCheckJsGrouped(
|
|
409
|
+
const { byFile, global } = await runCheckJsGrouped({
|
|
410
|
+
repoDir,
|
|
411
|
+
resolutionOwned: patchOwnedFiles,
|
|
412
|
+
...(extraShimPath !== undefined ? { extraShimPath } : {}),
|
|
413
|
+
...(projectRoot !== undefined ? { projectRoot } : {}),
|
|
414
|
+
...(mode !== undefined ? { mode } : {}),
|
|
415
|
+
});
|
|
421
416
|
const issues = [...global];
|
|
422
417
|
for (const [rel, list] of byFile) {
|
|
423
418
|
if (reportScope && !reportScope.has(rel))
|
|
@@ -482,7 +477,16 @@ export async function runCheckJsTestFilesGrouped(repoDir, testFiles, patchLint,
|
|
|
482
477
|
roots.add(candidate);
|
|
483
478
|
}
|
|
484
479
|
}
|
|
485
|
-
const result = await runCheckJsGrouped(
|
|
480
|
+
const result = await runCheckJsGrouped({
|
|
481
|
+
repoDir,
|
|
482
|
+
resolutionOwned: roots,
|
|
483
|
+
...(patchLint.checkJsTestShim !== undefined
|
|
484
|
+
? { extraShimPath: patchLint.checkJsTestShim }
|
|
485
|
+
: {}),
|
|
486
|
+
projectRoot,
|
|
487
|
+
mode,
|
|
488
|
+
builtinShimSuffix: TEST_HARNESS_SHIM,
|
|
489
|
+
});
|
|
486
490
|
const own = result.byFile.get(file);
|
|
487
491
|
if (own && own.length > 0) {
|
|
488
492
|
merged.byFile.set(file, [
|
|
@@ -527,7 +531,16 @@ function modeFromPatchLintConfig(patchLint) {
|
|
|
527
531
|
* (`--patches`); resolution still spans the whole queue
|
|
528
532
|
*/
|
|
529
533
|
export async function invokePatchLintCheckJsGrouped(repoDir, patchOwnedFiles, patchLint, projectRoot, rootScope) {
|
|
530
|
-
return runCheckJsGrouped(
|
|
534
|
+
return runCheckJsGrouped({
|
|
535
|
+
repoDir,
|
|
536
|
+
resolutionOwned: patchOwnedFiles,
|
|
537
|
+
...(patchLint.checkJsExtraShim !== undefined
|
|
538
|
+
? { extraShimPath: patchLint.checkJsExtraShim }
|
|
539
|
+
: {}),
|
|
540
|
+
projectRoot,
|
|
541
|
+
mode: modeFromPatchLintConfig(patchLint),
|
|
542
|
+
...(rootScope !== undefined ? { rootScope } : {}),
|
|
543
|
+
});
|
|
531
544
|
}
|
|
532
545
|
/**
|
|
533
546
|
* Cheap probe reproducing the only run-level ("global") checkJs findings the
|
|
@@ -10,13 +10,9 @@
|
|
|
10
10
|
* so a discarded context frees its map; a caller that mutates a context
|
|
11
11
|
* entry in place must call {@link invalidateNewFileCreatorsCache}.
|
|
12
12
|
*/
|
|
13
|
+
import type { PatchQueueBodyEntry, PatchQueueView } from './patch-lint-queue-types.js';
|
|
13
14
|
/** The slice of a queue context the creators map is derived from. */
|
|
14
|
-
|
|
15
|
-
entries: {
|
|
16
|
-
filename: string;
|
|
17
|
-
diff: string;
|
|
18
|
-
}[];
|
|
19
|
-
}
|
|
15
|
+
type CreatorsContext = PatchQueueView<PatchQueueBodyEntry>;
|
|
20
16
|
/** Drops the memoised creators map after an in-place context entry update. */
|
|
21
17
|
export declare function invalidateNewFileCreatorsCache(ctx: CreatorsContext): void;
|
|
22
18
|
/**
|
|
@@ -34,6 +34,17 @@ export interface PatchQueueEntry {
|
|
|
34
34
|
* are not indexed here.
|
|
35
35
|
*/
|
|
36
36
|
newFiles: Map<string, string>;
|
|
37
|
+
/**
|
|
38
|
+
* Every path this patch CREATES, whatever the body kind — text, a
|
|
39
|
+
* reconstructable `GIT binary patch`, or a payload-less
|
|
40
|
+
* `Binary files … differ` stub. `newFiles` is text-only by design (a
|
|
41
|
+
* binary authors no imports, so the import rules gain nothing from it and
|
|
42
|
+
* `extractNewFileContent` correctly refuses to decode one), but "does a
|
|
43
|
+
* later patch create this path" is a question about existence after apply,
|
|
44
|
+
* not about content — and answering it from `newFiles` made every binary
|
|
45
|
+
* creation invisible to the staged-registration rules.
|
|
46
|
+
*/
|
|
47
|
+
createdFiles: Set<string>;
|
|
37
48
|
/**
|
|
38
49
|
* Map from existing-file path → concatenated added lines from the patch's
|
|
39
50
|
* hunks against that file (joined with `\n`). Populated for files the
|
|
@@ -109,13 +120,10 @@ export declare function isForwardImportableFile(path: string): boolean;
|
|
|
109
120
|
* Returns the raw specifier strings — callers should take the leaf basename
|
|
110
121
|
* to match against the newFileIndex, because we do not resolve `resource://`
|
|
111
122
|
* URLs to engine file paths.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
*
|
|
116
|
-
* (0-indexed) line number where each specifier was found. Used by the
|
|
117
|
-
* forward-import rule so it can correlate specifiers against the
|
|
118
|
-
* ignore-marker line set and skip suppressed matches.
|
|
123
|
+
*
|
|
124
|
+
* Also returns the (0-indexed) line number where each specifier was found, so
|
|
125
|
+
* the forward-import rule can correlate specifiers against the ignore-marker
|
|
126
|
+
* line set and skip suppressed matches.
|
|
119
127
|
*/
|
|
120
128
|
export interface ExtractedSpecifier {
|
|
121
129
|
specifier: string;
|
|
@@ -123,7 +131,7 @@ export interface ExtractedSpecifier {
|
|
|
123
131
|
}
|
|
124
132
|
/**
|
|
125
133
|
* Returns import specifiers plus 0-indexed line numbers, preserving the
|
|
126
|
-
* same matching behavior as {@link
|
|
134
|
+
* same matching behavior as {@link extractImportSpecifiersWithLines}.
|
|
127
135
|
*/
|
|
128
136
|
export declare function extractImportSpecifiersWithLines(source: string): ExtractedSpecifier[];
|
|
129
137
|
/**
|
|
@@ -19,7 +19,9 @@ import { discoverPatches } from './patch-files.js';
|
|
|
19
19
|
import { lintPatchQueueBinaryBodies } from './patch-lint-binary.js';
|
|
20
20
|
import { collectNewFileCreatorsByPath } from './patch-lint-creators.js';
|
|
21
21
|
import { detectNewFilesInDiff, extractAddedLinesPerFile } from './patch-lint-diff.js';
|
|
22
|
+
import { lintPatchQueueForwardRegistrations } from './patch-lint-forward-registration.js';
|
|
22
23
|
import { lintPatchQueueModuleRegistrations } from './patch-lint-module-registration.js';
|
|
24
|
+
import { describeRegistrationFailure, findStagedRegistrationFailure, isLaterOwner, quoteRegistrationLine, } from './patch-lint-staged-registration.js';
|
|
23
25
|
import { loadPatchesManifest } from './patch-manifest-io.js';
|
|
24
26
|
import { categoryRangeForOrder, categoryRangeLabel } from './patch-policy.js';
|
|
25
27
|
import { extractNewFileContent } from './patch-transform.js';
|
|
@@ -77,6 +79,9 @@ export async function buildPatchQueueContext(patchesDir, config) {
|
|
|
77
79
|
metadata: metadataByFilename.get(patch.filename) ?? null,
|
|
78
80
|
diff,
|
|
79
81
|
newFiles,
|
|
82
|
+
// Straight from the detector, before the text-extraction filter above
|
|
83
|
+
// drops the bodies it cannot decode.
|
|
84
|
+
createdFiles: newFilePaths,
|
|
80
85
|
modifiedFileAdditions,
|
|
81
86
|
});
|
|
82
87
|
}
|
|
@@ -125,24 +130,6 @@ const FORWARD_IMPORTABLE_EXTENSIONS = ['.mjs', '.sys.mjs', '.js', '.jsm'];
|
|
|
125
130
|
export function isForwardImportableFile(path) {
|
|
126
131
|
return FORWARD_IMPORTABLE_EXTENSIONS.some((ext) => path.endsWith(ext));
|
|
127
132
|
}
|
|
128
|
-
/**
|
|
129
|
-
* Regex-level extractor for module specifiers in ES module / subscript files.
|
|
130
|
-
*
|
|
131
|
-
* Intentionally conservative. Catches:
|
|
132
|
-
* - `import ... from "specifier"` (ES module static imports)
|
|
133
|
-
* - `import "specifier"` (side-effect imports — the `from`
|
|
134
|
-
* clause is optional in the regex)
|
|
135
|
-
* - `import("specifier")` (dynamic imports)
|
|
136
|
-
* - ChromeUtils.importESModule("specifier")
|
|
137
|
-
* - ChromeUtils.defineESModuleGetters(obj, { Name: "specifier", ... })
|
|
138
|
-
*
|
|
139
|
-
* Returns the raw specifier strings — callers should take the leaf basename
|
|
140
|
-
* to match against the newFileIndex, because we do not resolve `resource://`
|
|
141
|
-
* URLs to engine file paths.
|
|
142
|
-
*/
|
|
143
|
-
export function extractImportSpecifiers(source) {
|
|
144
|
-
return extractImportSpecifiersWithLines(source).map((item) => item.specifier);
|
|
145
|
-
}
|
|
146
133
|
function buildLineOffsets(source) {
|
|
147
134
|
const offsets = [0];
|
|
148
135
|
for (let i = 0; i < source.length; i++) {
|
|
@@ -236,7 +223,7 @@ function collectGetterSpecifiers(stripped, results, offsetToLine) {
|
|
|
236
223
|
}
|
|
237
224
|
/**
|
|
238
225
|
* Returns import specifiers plus 0-indexed line numbers, preserving the
|
|
239
|
-
* same matching behavior as {@link
|
|
226
|
+
* same matching behavior as {@link extractImportSpecifiersWithLines}.
|
|
240
227
|
*/
|
|
241
228
|
export function extractImportSpecifiersWithLines(source) {
|
|
242
229
|
// stripJsComments replaces comment bodies with space runs of equal
|
|
@@ -290,8 +277,8 @@ function extractBareGetterSpecifiers(source) {
|
|
|
290
277
|
const stripped = stripJsComments(source);
|
|
291
278
|
const results = [];
|
|
292
279
|
const lines = stripped.split('\n');
|
|
293
|
-
for (
|
|
294
|
-
const match = BARE_GETTER_PROPERTY_LINE.exec(
|
|
280
|
+
for (const [i, line] of lines.entries()) {
|
|
281
|
+
const match = BARE_GETTER_PROPERTY_LINE.exec(line);
|
|
295
282
|
if (match?.[1])
|
|
296
283
|
results.push({ specifier: match[1], line: i });
|
|
297
284
|
}
|
|
@@ -323,9 +310,8 @@ export const FORWARD_IMPORT_IGNORE_MARKER = 'fireforge-ignore: forward-import';
|
|
|
323
310
|
export function findForwardImportIgnoreLines(source) {
|
|
324
311
|
const lines = source.split('\n');
|
|
325
312
|
const ignored = new Set();
|
|
326
|
-
for (
|
|
327
|
-
|
|
328
|
-
if (line && line.includes(FORWARD_IMPORT_IGNORE_MARKER)) {
|
|
313
|
+
for (const [i, line] of lines.entries()) {
|
|
314
|
+
if (line.includes(FORWARD_IMPORT_IGNORE_MARKER)) {
|
|
329
315
|
ignored.add(i);
|
|
330
316
|
ignored.add(i + 1);
|
|
331
317
|
}
|
|
@@ -348,29 +334,44 @@ function findMatchingStagedDependency(entry, sitePath, specifier, laterOwners) {
|
|
|
348
334
|
laterOwners.some((owner) => owner.fullPath === dependency.creates &&
|
|
349
335
|
(dependency.owner === undefined || dependency.owner === owner.filename)));
|
|
350
336
|
}
|
|
351
|
-
/**
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
* lexicographically later filename (the apply loop's tiebreak).
|
|
355
|
-
*/
|
|
356
|
-
function isLaterOwner(owner, entry) {
|
|
357
|
-
return (owner.order > entry.order || (owner.order === entry.order && owner.filename > entry.filename));
|
|
358
|
-
}
|
|
359
|
-
/** Builds the basename → later-creators index used by the forward-import scan. */
|
|
360
|
-
function buildNewFileIndex(ctx) {
|
|
361
|
-
const newFileIndex = new Map();
|
|
337
|
+
/** Builds a basename → creators index from one path set per entry. */
|
|
338
|
+
function buildCreatorIndex(ctx, pathsOf) {
|
|
339
|
+
const index = new Map();
|
|
362
340
|
for (const entry of ctx.entries) {
|
|
363
|
-
for (const fullPath of entry
|
|
341
|
+
for (const fullPath of pathsOf(entry)) {
|
|
364
342
|
const leaf = basename(fullPath);
|
|
365
|
-
let owners =
|
|
343
|
+
let owners = index.get(leaf);
|
|
366
344
|
if (!owners) {
|
|
367
345
|
owners = [];
|
|
368
|
-
|
|
346
|
+
index.set(leaf, owners);
|
|
369
347
|
}
|
|
370
348
|
owners.push({ filename: entry.filename, order: entry.order, fullPath });
|
|
371
349
|
}
|
|
372
350
|
}
|
|
373
|
-
return
|
|
351
|
+
return index;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Basename → later-creators index for the forward-IMPORT scan.
|
|
355
|
+
*
|
|
356
|
+
* Keyed on `newFiles` deliberately: this index answers "which patch creates
|
|
357
|
+
* the module this specifier resolves to", and a binary is not a module.
|
|
358
|
+
*/
|
|
359
|
+
function buildNewFileIndex(ctx) {
|
|
360
|
+
return buildCreatorIndex(ctx, (entry) => entry.newFiles.keys());
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Basename → creators index for the staged-REGISTRATION rules.
|
|
364
|
+
*
|
|
365
|
+
* Keyed on `createdFiles`, which includes binary creations. A registration
|
|
366
|
+
* (`support-files`, a jar.mn line, an actor entry) points at a file that
|
|
367
|
+
* must EXIST after apply; whether its body was text or a `GIT binary patch`
|
|
368
|
+
* has nothing to do with it. Resolving this from `newFiles` made a declared
|
|
369
|
+
* dependency on a binary fixture report `creates-unresolved`, so the
|
|
370
|
+
* declaration read as stale on every lint run and removing it changed
|
|
371
|
+
* nothing either — the failure was symmetric and therefore invisible.
|
|
372
|
+
*/
|
|
373
|
+
function buildCreatedFileIndex(ctx) {
|
|
374
|
+
return buildCreatorIndex(ctx, (entry) => entry.createdFiles);
|
|
374
375
|
}
|
|
375
376
|
/**
|
|
376
377
|
* Visits every forward-import site (an import whose leaf is created by a
|
|
@@ -389,9 +390,9 @@ function eachForwardImportSite(ctx, newFileIndex, visit) {
|
|
|
389
390
|
// Dedupe by (specifier, line): a patch that adds the whole getter
|
|
390
391
|
// call carries both the opener (found by the balanced walk) and the
|
|
391
392
|
// property line (found here) — report each site once.
|
|
392
|
-
const seen = new Set(sites.map((site) => `${site.specifier}|${
|
|
393
|
+
const seen = new Set(sites.map((site) => `${site.specifier}|${site.line}`));
|
|
393
394
|
for (const extra of extractBareGetterSpecifiers(content)) {
|
|
394
|
-
if (!seen.has(`${extra.specifier}|${
|
|
395
|
+
if (!seen.has(`${extra.specifier}|${extra.line}`))
|
|
395
396
|
sites.push(extra);
|
|
396
397
|
}
|
|
397
398
|
}
|
|
@@ -453,6 +454,7 @@ export function collectForwardImportEdges(ctx) {
|
|
|
453
454
|
*/
|
|
454
455
|
export function lintPatchQueueForwardImports(ctx) {
|
|
455
456
|
const newFileIndex = buildNewFileIndex(ctx);
|
|
457
|
+
const createdFileIndex = buildCreatedFileIndex(ctx);
|
|
456
458
|
const issues = [];
|
|
457
459
|
const usedStagedDeclarations = new Set();
|
|
458
460
|
eachForwardImportSite(ctx, newFileIndex, (entry, sitePath, specifier, cleaned, laterOwners) => {
|
|
@@ -531,7 +533,7 @@ export function lintPatchQueueForwardImports(ctx) {
|
|
|
531
533
|
// (with `owner`, when set, naming that patch) — mirroring
|
|
532
534
|
// findMatchingStagedDependency for the import kind.
|
|
533
535
|
for (const registration of entry.metadata?.stagedDependencies?.registrations ?? []) {
|
|
534
|
-
const failure = findStagedRegistrationFailure(entry, registration,
|
|
536
|
+
const failure = findStagedRegistrationFailure(entry, registration, createdFileIndex);
|
|
535
537
|
if (failure === undefined)
|
|
536
538
|
continue;
|
|
537
539
|
issues.push({
|
|
@@ -541,62 +543,16 @@ export function lintPatchQueueForwardImports(ctx) {
|
|
|
541
543
|
fingerprint: `staged-dependency-unused|${entry.filename}|${registration.file}|reg:${registration.line}|${registration.creates}|${registration.owner ?? ''}`,
|
|
542
544
|
message: `${entry.filename} declares a staged registration in ${registration.file} ` +
|
|
543
545
|
`("${registration.line}") for ${registration.creates}, but ${describeRegistrationFailure(failure)} ` +
|
|
544
|
-
'Remove the stale declaration with
|
|
546
|
+
'Remove the stale declaration with: ' +
|
|
547
|
+
`fireforge patch staged-dependency ${entry.filename} --remove --kind registration ` +
|
|
548
|
+
`--file ${registration.file} --line "${quoteRegistrationLine(registration.line)}" ` +
|
|
549
|
+
`--creates ${registration.creates}; or update it to match the patch and queue.`,
|
|
545
550
|
severity: 'warning',
|
|
546
551
|
});
|
|
547
552
|
}
|
|
548
553
|
}
|
|
549
554
|
return issues;
|
|
550
555
|
}
|
|
551
|
-
/**
|
|
552
|
-
* Validates one registration-kind declaration against the patch content
|
|
553
|
-
* and the queue, mirroring {@link findMatchingStagedDependency}: the
|
|
554
|
-
* declared line must be added by this patch, `creates` must exactly match
|
|
555
|
-
* a file a LATER-ordered patch creates (an earlier-only creator means the
|
|
556
|
-
* dependency is already satisfied and the declaration is stale), and
|
|
557
|
-
* `owner`, when set, must name one of those creating patches. Returns
|
|
558
|
-
* undefined when valid.
|
|
559
|
-
*/
|
|
560
|
-
function findStagedRegistrationFailure(entry, registration, newFileIndex) {
|
|
561
|
-
if (!isRegistrationLinePresent(entry, registration))
|
|
562
|
-
return { kind: 'line-absent' };
|
|
563
|
-
const creators = (newFileIndex.get(basename(registration.creates)) ?? []).filter((owner) => owner.fullPath === registration.creates && isLaterOwner(owner, entry));
|
|
564
|
-
if (creators.length === 0)
|
|
565
|
-
return { kind: 'creates-unresolved' };
|
|
566
|
-
if (registration.owner !== undefined &&
|
|
567
|
-
!creators.some((owner) => owner.filename === registration.owner)) {
|
|
568
|
-
return { kind: 'owner-mismatch', creators };
|
|
569
|
-
}
|
|
570
|
-
return undefined;
|
|
571
|
-
}
|
|
572
|
-
/** Message tail for each {@link StagedRegistrationFailure} shape. */
|
|
573
|
-
function describeRegistrationFailure(failure) {
|
|
574
|
-
switch (failure.kind) {
|
|
575
|
-
case 'line-absent':
|
|
576
|
-
return 'the patch does not add that line.';
|
|
577
|
-
case 'creates-unresolved':
|
|
578
|
-
return ('no later-ordered patch creates that file — the declaration is stale, ' +
|
|
579
|
-
'or the queue order no longer stages it.');
|
|
580
|
-
case 'owner-mismatch':
|
|
581
|
-
return `that file is created by ${failure.creators.map((o) => o.filename).join(', ')}, not the declared owner.`;
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
/**
|
|
585
|
-
* True when the declared registration/packaging line appears (trimmed)
|
|
586
|
-
* among the lines the patch introduces in the declaring file — either as a
|
|
587
|
-
* newly-created file's content or as added lines to an existing file
|
|
588
|
-
* (where jar.mn / customElements.js / actor-registration edits land).
|
|
589
|
-
*/
|
|
590
|
-
function isRegistrationLinePresent(entry, registration) {
|
|
591
|
-
const declared = registration.line.trim();
|
|
592
|
-
if (declared.length === 0)
|
|
593
|
-
return false;
|
|
594
|
-
const introduced = [
|
|
595
|
-
entry.newFiles.get(registration.file),
|
|
596
|
-
entry.modifiedFileAdditions.get(registration.file),
|
|
597
|
-
];
|
|
598
|
-
return introduced.some((content) => content !== undefined && content.split('\n').some((line) => line.trim() === declared));
|
|
599
|
-
}
|
|
600
556
|
/**
|
|
601
557
|
* Cross-patch lint orchestrator. Runs every cross-patch rule against the
|
|
602
558
|
* provided context and returns combined issues.
|
|
@@ -614,6 +570,7 @@ export function lintPatchQueue(ctx) {
|
|
|
614
570
|
...lintPatchQueueDuplicateCreations(ctx),
|
|
615
571
|
...lintPatchQueueForwardImports(ctx),
|
|
616
572
|
...lintPatchQueueModuleRegistrations(ctx),
|
|
573
|
+
...lintPatchQueueForwardRegistrations(ctx),
|
|
617
574
|
...lintPatchQueueBinaryBodies(ctx),
|
|
618
575
|
];
|
|
619
576
|
}
|
|
@@ -73,11 +73,8 @@ function buildAddedLinesScanSource(rawCss, addedNumbers) {
|
|
|
73
73
|
.map((n) => maskedLines[n - 1] ?? '')
|
|
74
74
|
.join('\n');
|
|
75
75
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
* when diff context is available. Pushes onto `issues`.
|
|
79
|
-
*/
|
|
80
|
-
function checkRawColorValues(file, rawCss, addedLinesByFile, addedLineNumbersByFile, config, issues) {
|
|
76
|
+
function checkRawColorValues(input) {
|
|
77
|
+
const { file, rawCss, addedLinesByFile, addedLineNumbersByFile, config, issues } = input;
|
|
81
78
|
// Check only introduced raw color values when diff context is available.
|
|
82
79
|
// Skip files on the raw-color allowlist (exact path or basename match) and
|
|
83
80
|
// auto-exempt files under `browser/branding/` — those are the fork's
|
|
@@ -207,7 +204,14 @@ export async function lintPatchedCss(repoDir, affectedFiles, diffContent, config
|
|
|
207
204
|
const rawCss = await readText(filePath);
|
|
208
205
|
// Strip block comments before scanning
|
|
209
206
|
const cssContent = rawCss.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
210
|
-
checkRawColorValues(
|
|
207
|
+
checkRawColorValues({
|
|
208
|
+
file,
|
|
209
|
+
rawCss,
|
|
210
|
+
addedLinesByFile,
|
|
211
|
+
addedLineNumbersByFile,
|
|
212
|
+
config,
|
|
213
|
+
issues,
|
|
214
|
+
});
|
|
211
215
|
checkTokenPrefixViolations(file, cssContent, addedLinesByFile, tokenContext, issues);
|
|
212
216
|
}
|
|
213
217
|
return issues;
|
|
@@ -44,10 +44,10 @@ export function resolveFileSizeThresholds(overrides, isTest) {
|
|
|
44
44
|
export function formatFileTooLargeMessage(args) {
|
|
45
45
|
const { label, lineCount, thresholds, band, verb } = args;
|
|
46
46
|
if (band === 'error') {
|
|
47
|
-
return `${label} has ${
|
|
47
|
+
return `${label} has ${lineCount} lines (error threshold: ${thresholds.error}). Consider ${verb}.`;
|
|
48
48
|
}
|
|
49
|
-
return (`${label} has ${
|
|
50
|
-
`error threshold: ${
|
|
49
|
+
return (`${label} has ${lineCount} lines (warning threshold: ${thresholds.warning}, ` +
|
|
50
|
+
`error threshold: ${thresholds.error}). Consider ${verb}. ` +
|
|
51
51
|
`Reported as a ${band}, which a gate running --max-warnings 0 treats as a failure; ` +
|
|
52
52
|
`tune "patchLint.fileSizeThresholds" if these limits are wrong for this project.`);
|
|
53
53
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { PatchLintIssue } from '../types/commands/index.js';
|
|
2
|
+
import type { PatchQueueForwardRegistrationEntry, PatchQueueView } from './patch-lint-queue-types.js';
|
|
3
|
+
/**
|
|
4
|
+
* One `support-files` entry, with the line the patch actually adds it on.
|
|
5
|
+
*
|
|
6
|
+
* The entry alone is not enough for the discharge command the rule prints:
|
|
7
|
+
* `--line` is compared, whitespace-trimmed, against the lines the patch
|
|
8
|
+
* ADDS, and a synthesised `support-files = ["<entry>"]` only ever matches a
|
|
9
|
+
* manifest whose array is single-line and single-entry. Carrying the source
|
|
10
|
+
* line keeps the remedy and the validation talking about the same text.
|
|
11
|
+
*/
|
|
12
|
+
export interface SupportFileEntry {
|
|
13
|
+
/** The entry as written inside the manifest (e.g. `fixtures/*.sqlite`). */
|
|
14
|
+
entry: string;
|
|
15
|
+
/** The first added line, whitespace-trimmed, that spells the entry out. */
|
|
16
|
+
line: string;
|
|
17
|
+
/**
|
|
18
|
+
* How many distinct added lines spell it out. Above one, the printed
|
|
19
|
+
* command quotes the first and says so: one declaration covers the file
|
|
20
|
+
* either way, because the declared check keys on file + creates.
|
|
21
|
+
*/
|
|
22
|
+
occurrences: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Extracts the `support-files` entries declared in `content`, each paired
|
|
26
|
+
* with the manifest line it is written on.
|
|
27
|
+
*
|
|
28
|
+
* Handles the TOML array on one line and spread over several, and the
|
|
29
|
+
* whitespace-separated `.ini` spelling. Anything else — a computed value, a
|
|
30
|
+
* shape this does not recognise — yields nothing, because a rule that
|
|
31
|
+
* guesses at a manifest it cannot parse refuses correct queues.
|
|
32
|
+
*
|
|
33
|
+
* Quoted tokens are matched per physical line rather than over the whole
|
|
34
|
+
* accumulated array body, so a multi-line array attributes each element to
|
|
35
|
+
* its own line. Entries are deduplicated: a manifest that lists the same
|
|
36
|
+
* file under two per-test sections needs one declaration, not two.
|
|
37
|
+
*/
|
|
38
|
+
export declare function extractSupportFileEntries(content: string): SupportFileEntry[];
|
|
39
|
+
/**
|
|
40
|
+
* Resolves one `support-files` entry, relative to its manifest's directory,
|
|
41
|
+
* into a matcher over engine-relative paths.
|
|
42
|
+
*
|
|
43
|
+
* Only a `*` inside a single path segment is expanded — the shape the
|
|
44
|
+
* downstream report uses (`fixtures/*.sqlite`). `**`, `!` exclusions and
|
|
45
|
+
* absolute `/`-rooted entries return undefined: they either cross directory
|
|
46
|
+
* boundaries or subtract, and a matcher that guessed at them would attribute
|
|
47
|
+
* a creation to the wrong manifest.
|
|
48
|
+
*/
|
|
49
|
+
export declare function buildSupportFileMatcher(manifestPath: string, entry: string): ((candidate: string) => boolean) | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Flags every `support-files` registration a patch introduces that names a
|
|
52
|
+
* file only a later-ordered patch creates, unless the staged dependency is
|
|
53
|
+
* declared.
|
|
54
|
+
*
|
|
55
|
+
* @param ctx - Projected queue in application order
|
|
56
|
+
* @returns One issue per undeclared forward registration
|
|
57
|
+
*/
|
|
58
|
+
export declare function lintPatchQueueForwardRegistrations(ctx: PatchQueueView<PatchQueueForwardRegistrationEntry>): PatchLintIssue[];
|