@hominis/fireforge 0.52.0 → 0.53.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 +26 -0
- package/dist/build-info.json +4 -4
- package/dist/src/commands/bootstrap.js +2 -3
- package/dist/src/commands/build-prelock.d.ts +3 -3
- package/dist/src/commands/build-prelock.js +3 -3
- package/dist/src/commands/build.js +4 -0
- package/dist/src/commands/declarations-report.d.ts +9 -3
- package/dist/src/commands/declarations-report.js +18 -11
- package/dist/src/commands/discard.js +3 -3
- package/dist/src/commands/doctor-furnace-config-sync.js +4 -4
- package/dist/src/commands/doctor-furnace.js +5 -5
- package/dist/src/commands/export-adopt-check.d.ts +5 -6
- package/dist/src/commands/export-adopt-check.js +5 -6
- package/dist/src/commands/export-flow.js +6 -9
- package/dist/src/commands/export-staged-registration.d.ts +4 -4
- package/dist/src/commands/export-staged-registration.js +4 -4
- package/dist/src/commands/forward-import-remedy.d.ts +2 -3
- package/dist/src/commands/forward-import-remedy.js +2 -3
- package/dist/src/commands/furnace/create-dry-run.d.ts +2 -2
- package/dist/src/commands/furnace/deploy-fragment-includers.d.ts +2 -2
- package/dist/src/commands/furnace/deploy-fragment-includers.js +2 -2
- package/dist/src/commands/furnace/index.js +2 -2
- package/dist/src/commands/lint.js +4 -4
- package/dist/src/commands/patch/compact.js +1 -1
- package/dist/src/commands/patch/lint-ignore-from.d.ts +3 -4
- package/dist/src/commands/patch/lint-ignore-from.js +3 -4
- package/dist/src/commands/patch/move-files-adopt.d.ts +33 -0
- package/dist/src/commands/patch/move-files-adopt.js +65 -0
- package/dist/src/commands/patch/move-files-create.js +41 -20
- package/dist/src/commands/patch/move-files-into.d.ts +18 -0
- package/dist/src/commands/patch/move-files-into.js +125 -60
- package/dist/src/commands/patch/move-files-retire.d.ts +39 -0
- package/dist/src/commands/patch/move-files-retire.js +91 -0
- package/dist/src/commands/patch/move-files.d.ts +3 -0
- package/dist/src/commands/patch/move-files.js +42 -12
- package/dist/src/commands/patch/move-size-tier.d.ts +27 -0
- package/dist/src/commands/patch/move-size-tier.js +66 -0
- package/dist/src/commands/patch/rename.js +1 -1
- package/dist/src/commands/patch/reorder-projection.d.ts +17 -0
- package/dist/src/commands/patch/reorder-projection.js +49 -0
- package/dist/src/commands/patch/reorder-shift.d.ts +30 -0
- package/dist/src/commands/patch/reorder-shift.js +307 -0
- package/dist/src/commands/patch/reorder.d.ts +9 -15
- package/dist/src/commands/patch/reorder.js +52 -50
- package/dist/src/commands/patch/split-plan.d.ts +31 -3
- package/dist/src/commands/patch/split-plan.js +36 -12
- package/dist/src/commands/patch/split-staged.d.ts +2 -2
- package/dist/src/commands/patch/split-staged.js +2 -2
- package/dist/src/commands/patch/split.js +18 -5
- package/dist/src/commands/patch/staged-dependency-entries.d.ts +9 -1
- package/dist/src/commands/patch/staged-dependency-entries.js +32 -4
- package/dist/src/commands/patch/staged-dependency-from.js +15 -9
- package/dist/src/commands/patch/staged-dependency.js +13 -9
- package/dist/src/commands/patch/tier.js +2 -2
- package/dist/src/commands/patch-rename-map.d.ts +14 -3
- package/dist/src/commands/patch-rename-map.js +21 -3
- package/dist/src/commands/re-export-adjacent.d.ts +4 -5
- package/dist/src/commands/re-export-lint.d.ts +4 -3
- package/dist/src/commands/re-export-lint.js +4 -3
- package/dist/src/commands/re-export-preflight.js +1 -2
- package/dist/src/commands/re-export-purity-scope.d.ts +1 -1
- package/dist/src/commands/re-export-purity-scope.js +13 -7
- package/dist/src/commands/re-export-retired-declarations.d.ts +22 -0
- package/dist/src/commands/re-export-retired-declarations.js +113 -0
- package/dist/src/commands/re-export-single.js +2 -2
- package/dist/src/commands/re-export-stale-registrations.d.ts +27 -6
- package/dist/src/commands/re-export-stale-registrations.js +65 -21
- package/dist/src/commands/re-export.js +4 -0
- package/dist/src/commands/rebase/continue.js +3 -3
- package/dist/src/commands/register.js +5 -4
- package/dist/src/commands/status.js +1 -1
- package/dist/src/commands/test-build-furnace.d.ts +1 -2
- package/dist/src/commands/test-build-furnace.js +1 -2
- package/dist/src/commands/test-build-phase.d.ts +8 -0
- package/dist/src/commands/test-build-phase.js +42 -7
- package/dist/src/commands/test-control-restore.d.ts +40 -0
- package/dist/src/commands/test-control-restore.js +86 -0
- package/dist/src/commands/test-dispatch.js +68 -7
- package/dist/src/commands/test-multi-verdict.js +1 -0
- package/dist/src/commands/test-orchestrate.d.ts +6 -0
- package/dist/src/commands/test-orchestrate.js +28 -0
- package/dist/src/commands/test-perf-scope.d.ts +1 -1
- package/dist/src/commands/test-perf-scope.js +1 -1
- package/dist/src/commands/test-prelock.d.ts +7 -8
- package/dist/src/commands/test-prelock.js +15 -12
- package/dist/src/commands/test-register.js +2 -2
- package/dist/src/commands/test-results.d.ts +10 -1
- package/dist/src/commands/test-results.js +20 -3
- package/dist/src/commands/test-run.d.ts +6 -0
- package/dist/src/commands/test-run.js +23 -4
- package/dist/src/commands/test-shards.d.ts +7 -3
- package/dist/src/commands/test-shards.js +24 -7
- package/dist/src/commands/test-stale-gate.d.ts +6 -1
- package/dist/src/commands/test-stale-gate.js +40 -2
- package/dist/src/commands/test-verdict.d.ts +5 -3
- package/dist/src/commands/test.js +10 -0
- package/dist/src/commands/token.js +2 -2
- package/dist/src/commands/verify.js +1 -1
- package/dist/src/commands/watch.js +1 -1
- package/dist/src/commands/wire.js +1 -1
- package/dist/src/core/build-audit-resolve.d.ts +4 -5
- package/dist/src/core/build-audit-resolve.js +4 -5
- package/dist/src/core/build-audit-skip.d.ts +2 -2
- package/dist/src/core/build-audit.d.ts +3 -4
- package/dist/src/core/build-baseline-types.d.ts +24 -3
- package/dist/src/core/build-baseline-validate.d.ts +30 -1
- package/dist/src/core/build-baseline-validate.js +127 -35
- package/dist/src/core/build-baseline.d.ts +8 -2
- package/dist/src/core/build-baseline.js +25 -16
- package/dist/src/core/build-jar-escalation.d.ts +4 -4
- package/dist/src/core/build-jar-escalation.js +4 -4
- package/dist/src/core/build-prepare.js +4 -4
- package/dist/src/core/config-validate.js +4 -4
- package/dist/src/core/coverage-extend.d.ts +5 -3
- package/dist/src/core/coverage-extend.js +8 -3
- package/dist/src/core/coverage-records.d.ts +4 -5
- package/dist/src/core/coverage-records.js +4 -5
- package/dist/src/core/destructive.d.ts +2 -2
- package/dist/src/core/destructive.js +2 -2
- package/dist/src/core/discard-baseline.d.ts +2 -2
- package/dist/src/core/discard-baseline.js +3 -3
- package/dist/src/core/engine-session-lock.d.ts +1 -1
- package/dist/src/core/engine-session-lock.js +1 -1
- package/dist/src/core/file-lock-owner.d.ts +5 -5
- package/dist/src/core/file-lock-owner.js +5 -5
- package/dist/src/core/file-lock-queue.js +6 -8
- package/dist/src/core/file-lock-shared.d.ts +4 -4
- package/dist/src/core/file-lock-shared.js +4 -4
- package/dist/src/core/file-lock.js +7 -10
- package/dist/src/core/firefox.js +2 -2
- package/dist/src/core/furnace-apply-overwrite-warn.d.ts +1 -1
- package/dist/src/core/furnace-apply-overwrite-warn.js +1 -1
- package/dist/src/core/furnace-apply.js +3 -3
- package/dist/src/core/furnace-operation.js +5 -5
- package/dist/src/core/furnace-registration-jar-inplace.js +5 -6
- package/dist/src/core/furnace-registration-rename.d.ts +5 -5
- package/dist/src/core/furnace-registration-rename.js +5 -5
- package/dist/src/core/furnace-registration-validate.d.ts +2 -1
- package/dist/src/core/furnace-registration-validate.js +2 -1
- package/dist/src/core/furnace-registration.js +2 -2
- package/dist/src/core/git-base.js +4 -3
- package/dist/src/core/git-diff.js +1 -1
- package/dist/src/core/git.js +1 -1
- package/dist/src/core/harness-orphans.d.ts +6 -6
- package/dist/src/core/harness-orphans.js +6 -6
- package/dist/src/core/harness-port-reservation.d.ts +60 -0
- package/dist/src/core/harness-port-reservation.js +122 -0
- package/dist/src/core/history-log-file.d.ts +9 -9
- package/dist/src/core/history-log-file.js +15 -15
- package/dist/src/core/history-log.d.ts +3 -3
- package/dist/src/core/history-log.js +3 -3
- package/dist/src/core/launchable-build.d.ts +39 -0
- package/dist/src/core/launchable-build.js +85 -0
- package/dist/src/core/marionette-port.js +1 -3
- package/dist/src/core/moz-manifest-rules.js +3 -2
- package/dist/src/core/negative-control-compiled.d.ts +13 -3
- package/dist/src/core/negative-control-compiled.js +27 -5
- package/dist/src/core/parser-fallback.d.ts +5 -5
- package/dist/src/core/parser-fallback.js +5 -5
- package/dist/src/core/patch-identifier-suggest.d.ts +6 -0
- package/dist/src/core/patch-identifier-suggest.js +11 -4
- package/dist/src/core/patch-lint-checkjs.d.ts +1 -1
- package/dist/src/core/patch-lint-checkjs.js +1 -1
- package/dist/src/core/patch-lint-css.js +2 -2
- package/dist/src/core/patch-lint-file-size.d.ts +5 -7
- package/dist/src/core/patch-lint-file-size.js +5 -7
- package/dist/src/core/patch-lint-ignore.d.ts +3 -3
- package/dist/src/core/patch-lint-ignore.js +3 -3
- package/dist/src/core/patch-lint-prettier.d.ts +4 -6
- package/dist/src/core/patch-lint-prettier.js +4 -6
- package/dist/src/core/patch-lint-projection.d.ts +1 -1
- package/dist/src/core/patch-lint-projection.js +1 -1
- package/dist/src/core/patch-lint-queue-types.d.ts +2 -2
- package/dist/src/core/patch-lint-queue-types.js +2 -2
- package/dist/src/core/patch-manifest-consistency.d.ts +2 -2
- package/dist/src/core/patch-manifest-consistency.js +2 -2
- package/dist/src/core/patch-manifest-io.d.ts +5 -1
- package/dist/src/core/patch-manifest-io.js +12 -10
- package/dist/src/core/patch-manifest-key-order.d.ts +3 -4
- package/dist/src/core/patch-manifest-key-order.js +3 -4
- package/dist/src/core/patch-parse.d.ts +3 -3
- package/dist/src/core/patch-parse.js +3 -3
- package/dist/src/core/patch-policy.d.ts +1 -1
- package/dist/src/core/patch-policy.js +1 -1
- package/dist/src/core/patch-source-metadata.d.ts +1 -1
- package/dist/src/core/patch-source-metadata.js +1 -1
- package/dist/src/core/patch-subset.d.ts +5 -3
- package/dist/src/core/patch-subset.js +8 -7
- package/dist/src/core/patch-transform.d.ts +2 -2
- package/dist/src/core/patch-transform.js +2 -2
- package/dist/src/core/rebase-session.js +4 -6
- package/dist/src/core/register-xpcshell-test.d.ts +28 -7
- package/dist/src/core/register-xpcshell-test.js +76 -27
- package/dist/src/core/run-log.d.ts +8 -8
- package/dist/src/core/run-log.js +8 -8
- package/dist/src/core/status-classify.d.ts +1 -2
- package/dist/src/core/status-classify.js +1 -2
- package/dist/src/core/test-harness-crash.d.ts +5 -3
- package/dist/src/core/test-harness-crash.js +13 -14
- package/dist/src/core/test-harness-infra.d.ts +32 -0
- package/dist/src/core/test-harness-infra.js +69 -0
- package/dist/src/core/test-harness-signature.d.ts +6 -0
- package/dist/src/core/test-stale-check.d.ts +38 -0
- package/dist/src/core/test-stale-check.js +82 -1
- package/dist/src/core/test-stall-triage.js +5 -7
- package/dist/src/core/token-category.js +2 -2
- package/dist/src/core/token-inventory.js +3 -3
- package/dist/src/core/token-manager.d.ts +2 -2
- package/dist/src/core/token-manager.js +5 -7
- package/dist/src/core/token-variant.d.ts +6 -6
- package/dist/src/core/token-variant.js +7 -7
- package/dist/src/core/typecheck-shim.js +1 -1
- package/dist/src/core/wire-destroy.d.ts +1 -1
- package/dist/src/core/wire-destroy.js +1 -1
- package/dist/src/core/wire-dom-fragment.js +1 -1
- package/dist/src/core/wire-init.d.ts +1 -1
- package/dist/src/core/wire-init.js +1 -1
- package/dist/src/core/wire-subscript.d.ts +1 -1
- package/dist/src/core/wire-subscript.js +1 -1
- package/dist/src/core/wire-utils.d.ts +2 -2
- package/dist/src/core/wire-utils.js +3 -3
- package/dist/src/errors/base.d.ts +1 -1
- package/dist/src/errors/base.js +1 -1
- package/dist/src/errors/rebase.d.ts +1 -1
- package/dist/src/errors/rebase.js +1 -1
- package/dist/src/types/commands/options.d.ts +26 -3
- package/dist/src/types/config.d.ts +5 -7
- package/dist/src/utils/options.js +2 -2
- package/dist/src/utils/process.js +2 -2
- package/dist/src/utils/regex.d.ts +2 -2
- package/dist/src/utils/regex.js +3 -3
- package/dist/src/utils/sleep.d.ts +5 -6
- package/dist/src/utils/sleep.js +5 -6
- package/dist/src/utils/validation.js +2 -2
- package/docs/configuration.md +21 -23
- package/docs/exit-codes.md +8 -11
- package/docs/furnace.md +3 -3
- package/docs/lifecycle-invariants.md +36 -45
- package/docs/machine-output.md +41 -24
- package/docs/patch-workflow.md +129 -24
- package/docs/run-logs.md +8 -9
- package/docs/testing.md +105 -46
- package/package.json +1 -1
|
@@ -6,15 +6,25 @@
|
|
|
6
6
|
* objdir links to. A C++ (or Rust, IDL, …) source edited at that point is
|
|
7
7
|
* never compiled: the run tests the unmutated binary and reports
|
|
8
8
|
* `control=missed`, which reads as a test that cannot fail. Such a target
|
|
9
|
-
* is
|
|
9
|
+
* is refused without `--build`, and with `--build` the control is
|
|
10
10
|
* applied before the build so the binary under test carries it. That build
|
|
11
11
|
* is a full `mach build`: the pre-test build is otherwise `mach build
|
|
12
|
-
* faster`, which compiles nothing, so the control still
|
|
12
|
+
* faster`, which compiles nothing, so the control would still miss.
|
|
13
13
|
*/
|
|
14
|
+
/**
|
|
15
|
+
* Whether an engine-relative path has a compiled-source extension: a file
|
|
16
|
+
* the build compiles or code-generates into the binary. This is the
|
|
17
|
+
* extension test only. {@link findCompiledControlTargets} additionally
|
|
18
|
+
* drops non-header files an install manifest ships as-is.
|
|
19
|
+
*
|
|
20
|
+
* @param path - Engine-relative path
|
|
21
|
+
*/
|
|
22
|
+
export declare function isCompiledSourcePath(path: string): boolean;
|
|
14
23
|
/**
|
|
15
24
|
* The engine-relative targets that reach the runtime only through a
|
|
16
25
|
* compile: a compiled-source extension and no install-manifest entry that
|
|
17
|
-
* ships the file itself.
|
|
26
|
+
* ships the file itself. Headers are always compiled, even when an
|
|
27
|
+
* `EXPORTS` manifest installs them into `dist/include`.
|
|
18
28
|
*
|
|
19
29
|
* @param engineDir - Absolute engine directory
|
|
20
30
|
* @param enginePaths - The control's engine-relative targets
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
* objdir links to. A C++ (or Rust, IDL, …) source edited at that point is
|
|
8
8
|
* never compiled: the run tests the unmutated binary and reports
|
|
9
9
|
* `control=missed`, which reads as a test that cannot fail. Such a target
|
|
10
|
-
* is
|
|
10
|
+
* is refused without `--build`, and with `--build` the control is
|
|
11
11
|
* applied before the build so the binary under test carries it. That build
|
|
12
12
|
* is a full `mach build`: the pre-test build is otherwise `mach build
|
|
13
|
-
* faster`, which compiles nothing, so the control still
|
|
13
|
+
* faster`, which compiles nothing, so the control would still miss.
|
|
14
14
|
*/
|
|
15
15
|
import { extname } from 'node:path';
|
|
16
16
|
import { classifyRuntimeDelivery } from './objdir-install-manifests.js';
|
|
@@ -34,24 +34,46 @@ const COMPILED_EXTENSIONS = new Set([
|
|
|
34
34
|
'.yaml',
|
|
35
35
|
'.yml',
|
|
36
36
|
]);
|
|
37
|
+
/**
|
|
38
|
+
* Header extensions. An `EXPORTS` install manifest names many headers (it
|
|
39
|
+
* copies them into `dist/include`), but that copy only feeds other
|
|
40
|
+
* compiles: the runtime never reads a header, so a header edit reaches the
|
|
41
|
+
* binary through a compile whatever the manifests say.
|
|
42
|
+
*/
|
|
43
|
+
const HEADER_EXTENSIONS = new Set(['.h', '.hh', '.hpp', '.ipdlh']);
|
|
44
|
+
/**
|
|
45
|
+
* Whether an engine-relative path has a compiled-source extension: a file
|
|
46
|
+
* the build compiles or code-generates into the binary. This is the
|
|
47
|
+
* extension test only. {@link findCompiledControlTargets} additionally
|
|
48
|
+
* drops non-header files an install manifest ships as-is.
|
|
49
|
+
*
|
|
50
|
+
* @param path - Engine-relative path
|
|
51
|
+
*/
|
|
52
|
+
export function isCompiledSourcePath(path) {
|
|
53
|
+
return COMPILED_EXTENSIONS.has(extname(path));
|
|
54
|
+
}
|
|
37
55
|
/**
|
|
38
56
|
* The engine-relative targets that reach the runtime only through a
|
|
39
57
|
* compile: a compiled-source extension and no install-manifest entry that
|
|
40
|
-
* ships the file itself.
|
|
58
|
+
* ships the file itself. Headers are always compiled, even when an
|
|
59
|
+
* `EXPORTS` manifest installs them into `dist/include`.
|
|
41
60
|
*
|
|
42
61
|
* @param engineDir - Absolute engine directory
|
|
43
62
|
* @param enginePaths - The control's engine-relative targets
|
|
44
63
|
*/
|
|
45
64
|
export async function findCompiledControlTargets(engineDir, enginePaths) {
|
|
46
|
-
const candidates = enginePaths.filter(
|
|
65
|
+
const candidates = enginePaths.filter(isCompiledSourcePath);
|
|
47
66
|
if (candidates.length === 0)
|
|
48
67
|
return [];
|
|
68
|
+
if (candidates.every((path) => HEADER_EXTENSIONS.has(extname(path))))
|
|
69
|
+
return candidates;
|
|
49
70
|
const index = await loadEngineInstallIndex(engineDir);
|
|
50
71
|
if (index === undefined)
|
|
51
72
|
return candidates;
|
|
52
73
|
const compiled = [];
|
|
53
74
|
for (const path of candidates) {
|
|
54
|
-
if ((
|
|
75
|
+
if (HEADER_EXTENSIONS.has(extname(path)) ||
|
|
76
|
+
(await classifyRuntimeDelivery(index, engineDir, path)) === 'unlisted') {
|
|
55
77
|
compiled.push(path);
|
|
56
78
|
}
|
|
57
79
|
}
|
|
@@ -13,12 +13,12 @@ export declare function consumeParserFallbackEvents(): ParserFallbackEvent[];
|
|
|
13
13
|
* The `rethrowIf` predicate every AST-primary caller wants.
|
|
14
14
|
*
|
|
15
15
|
* Rethrows internal-invariant `GeneralError`s ("Unexpected empty …array"):
|
|
16
|
-
* those are programming bugs, and retrying the
|
|
16
|
+
* those are programming bugs, and retrying the fallback scanner cannot fix a
|
|
17
17
|
* broken invariant, it just buries the stack. Everything else still falls
|
|
18
18
|
* back, which matters: the AST path raises a raw acorn SyntaxError
|
|
19
19
|
* on chrome sources acorn cannot parse (preprocessor directives), and
|
|
20
20
|
* BuildError when the file's shape is unexpected. Both are exactly what the
|
|
21
|
-
*
|
|
21
|
+
* fallback scanner is here to handle.
|
|
22
22
|
*
|
|
23
23
|
* @param error - The error the primary parser threw
|
|
24
24
|
* @returns True when the error must propagate instead of falling back
|
|
@@ -33,15 +33,15 @@ export interface ParserResult<T> {
|
|
|
33
33
|
fallbackReason?: string;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
* Wraps a primary (AST/tokenizer) parser with a
|
|
36
|
+
* Wraps a primary (AST/tokenizer) parser with a regex/line-based
|
|
37
37
|
* fallback. If the primary throws, a warning is logged and the fallback is
|
|
38
38
|
* used instead.
|
|
39
39
|
*
|
|
40
40
|
* Returns a {@link ParserResult} so callers (and tests) can detect which
|
|
41
41
|
* code path was taken and surface it in logs or assertions.
|
|
42
42
|
*
|
|
43
|
-
* @param primary - The
|
|
44
|
-
* @param fallback - The
|
|
43
|
+
* @param primary - The primary parser implementation
|
|
44
|
+
* @param fallback - The regex/line-based fallback implementation
|
|
45
45
|
* @param context - File/context name used in the warning message
|
|
46
46
|
* @param rethrowIf - Optional predicate. If it returns true for the caught
|
|
47
47
|
* error the error is re-thrown instead of falling back (useful for
|
|
@@ -18,12 +18,12 @@ export function consumeParserFallbackEvents() {
|
|
|
18
18
|
* The `rethrowIf` predicate every AST-primary caller wants.
|
|
19
19
|
*
|
|
20
20
|
* Rethrows internal-invariant `GeneralError`s ("Unexpected empty …array"):
|
|
21
|
-
* those are programming bugs, and retrying the
|
|
21
|
+
* those are programming bugs, and retrying the fallback scanner cannot fix a
|
|
22
22
|
* broken invariant, it just buries the stack. Everything else still falls
|
|
23
23
|
* back, which matters: the AST path raises a raw acorn SyntaxError
|
|
24
24
|
* on chrome sources acorn cannot parse (preprocessor directives), and
|
|
25
25
|
* BuildError when the file's shape is unexpected. Both are exactly what the
|
|
26
|
-
*
|
|
26
|
+
* fallback scanner is here to handle.
|
|
27
27
|
*
|
|
28
28
|
* @param error - The error the primary parser threw
|
|
29
29
|
* @returns True when the error must propagate instead of falling back
|
|
@@ -32,15 +32,15 @@ export function isInternalInvariantFailure(error) {
|
|
|
32
32
|
return error instanceof GeneralError;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
* Wraps a primary (AST/tokenizer) parser with a
|
|
35
|
+
* Wraps a primary (AST/tokenizer) parser with a regex/line-based
|
|
36
36
|
* fallback. If the primary throws, a warning is logged and the fallback is
|
|
37
37
|
* used instead.
|
|
38
38
|
*
|
|
39
39
|
* Returns a {@link ParserResult} so callers (and tests) can detect which
|
|
40
40
|
* code path was taken and surface it in logs or assertions.
|
|
41
41
|
*
|
|
42
|
-
* @param primary - The
|
|
43
|
-
* @param fallback - The
|
|
42
|
+
* @param primary - The primary parser implementation
|
|
43
|
+
* @param fallback - The regex/line-based fallback implementation
|
|
44
44
|
* @param context - File/context name used in the warning message
|
|
45
45
|
* @param rethrowIf - Optional predicate. If it returns true for the caught
|
|
46
46
|
* error the error is re-thrown instead of falling back (useful for
|
|
@@ -18,3 +18,9 @@ import type { PatchMetadata } from '../types/commands/index.js';
|
|
|
18
18
|
* `InvalidArgumentError` body, never the full queue enumeration.
|
|
19
19
|
*/
|
|
20
20
|
export declare function formatPatchNotFoundError(identifier: string, patches: readonly PatchMetadata[]): string;
|
|
21
|
+
/**
|
|
22
|
+
* The nearest-match half of {@link formatPatchNotFoundError}: the closest
|
|
23
|
+
* accepted identifiers and the queue size, never the full queue. For
|
|
24
|
+
* callers that word their own lead, such as the `--patches` subset.
|
|
25
|
+
*/
|
|
26
|
+
export declare function formatPatchSuggestions(identifier: string, patches: readonly PatchMetadata[]): string;
|
|
@@ -118,11 +118,18 @@ function rankSuggestions(identifier, candidates) {
|
|
|
118
118
|
* `InvalidArgumentError` body, never the full queue enumeration.
|
|
119
119
|
*/
|
|
120
120
|
export function formatPatchNotFoundError(identifier, patches) {
|
|
121
|
-
const accepted = collectAcceptedIdentifiers(patches);
|
|
122
|
-
const suggestions = rankSuggestions(identifier, accepted);
|
|
123
121
|
const lead = `Patch "${identifier}" not found. Accepted identifiers: ordinal (e.g. 2), filename (e.g. 002-ui-foo.patch), or manifest name (e.g. ui-foo).`;
|
|
122
|
+
return `${lead} ${formatPatchSuggestions(identifier, patches)}`;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* The nearest-match half of {@link formatPatchNotFoundError}: the closest
|
|
126
|
+
* accepted identifiers and the queue size, never the full queue. For
|
|
127
|
+
* callers that word their own lead, such as the `--patches` subset.
|
|
128
|
+
*/
|
|
129
|
+
export function formatPatchSuggestions(identifier, patches) {
|
|
130
|
+
const suggestions = rankSuggestions(identifier, collectAcceptedIdentifiers(patches));
|
|
124
131
|
if (suggestions.length > 0) {
|
|
125
|
-
return
|
|
132
|
+
return `Did you mean: ${suggestions.join(', ')}? (${patches.length} patches in queue — run "fireforge patch list" for the full list.)`;
|
|
126
133
|
}
|
|
127
|
-
return
|
|
134
|
+
return `No close match found among ${patches.length} patches in the queue. Run "fireforge patch list" to see them.`;
|
|
128
135
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Separated from `patch-lint.ts` to keep both files within the
|
|
11
11
|
* project's per-file line budget. The shim itself and the suppressed
|
|
12
|
-
* diagnostic code list
|
|
12
|
+
* diagnostic code list live in `typecheck-shim.ts` and are shared
|
|
13
13
|
* with the whole-project `fireforge typecheck` command, keeping a
|
|
14
14
|
* single source of truth for the Firefox-globals coverage.
|
|
15
15
|
* `patchLint.checkJsStrict` only tightens `strict` / `noImplicitAny`
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Separated from `patch-lint.ts` to keep both files within the
|
|
12
12
|
* project's per-file line budget. The shim itself and the suppressed
|
|
13
|
-
* diagnostic code list
|
|
13
|
+
* diagnostic code list live in `typecheck-shim.ts` and are shared
|
|
14
14
|
* with the whole-project `fireforge typecheck` command, keeping a
|
|
15
15
|
* single source of truth for the Firefox-globals coverage.
|
|
16
16
|
* `patchLint.checkJsStrict` only tightens `strict` / `noImplicitAny`
|
|
@@ -65,7 +65,7 @@ const RAW_COLOR_IGNORE_MARKER = 'fireforge-ignore: raw-color-value';
|
|
|
65
65
|
* comment spanning the context/added boundary suppresses its hex, then
|
|
66
66
|
* only the patch's added line numbers are scanned. Returns undefined
|
|
67
67
|
* when any added line number falls outside the on-disk file (patch not
|
|
68
|
-
* applied / drifted). The caller then falls back to the
|
|
68
|
+
* applied / drifted). The caller then falls back to the
|
|
69
69
|
* joined-added-lines scan rather than misattributing lines.
|
|
70
70
|
*/
|
|
71
71
|
function buildAddedLinesScanSource(rawCss, addedNumbers) {
|
|
@@ -100,7 +100,7 @@ function checkRawColorValues(input) {
|
|
|
100
100
|
suppressedContent = buildAddedLinesScanSource(rawCss, addedNumbers);
|
|
101
101
|
}
|
|
102
102
|
if (suppressedContent === undefined) {
|
|
103
|
-
//
|
|
103
|
+
// Fallback scan: full file (no diff), or the joined added lines when
|
|
104
104
|
// the diff and on-disk file disagree. Waiver lines are filtered
|
|
105
105
|
// against the pre-strip text so the CSS comment marker is present.
|
|
106
106
|
const sourceForSuppression = addedLinesByFile
|
|
@@ -6,13 +6,11 @@
|
|
|
6
6
|
* `patch-lint.ts` from `config-validate.ts` for a constant would draw an
|
|
7
7
|
* import edge (and a cycle) between the rule bodies and config parsing.
|
|
8
8
|
*
|
|
9
|
-
* On the vocabulary: the bands
|
|
10
|
-
* middle one
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* says what the band is (a warning) and what a zero-warning gate does with
|
|
15
|
-
* it, and the thresholds are now tunable, so a project whose file-size
|
|
9
|
+
* On the vocabulary: the bands are `notice` / `warning` / `error`, and the
|
|
10
|
+
* middle one is not a "soft limit". Under the posture FireForge itself
|
|
11
|
+
* recommends for a release gate, `--max-warnings 0`, a warning is a hard
|
|
12
|
+
* failure. The message below therefore says what the band is (a warning)
|
|
13
|
+
* and what a zero-warning gate does with it, and the thresholds are tunable, so a project whose file-size
|
|
16
14
|
* policy differs has a dial instead of an argument. The notice band is the
|
|
17
15
|
* design target: advisory, and its message says so rather than borrowing
|
|
18
16
|
* the warning band's gate sentence.
|
|
@@ -7,13 +7,11 @@
|
|
|
7
7
|
* `patch-lint.ts` from `config-validate.ts` for a constant would draw an
|
|
8
8
|
* import edge (and a cycle) between the rule bodies and config parsing.
|
|
9
9
|
*
|
|
10
|
-
* On the vocabulary: the bands
|
|
11
|
-
* middle one
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* says what the band is (a warning) and what a zero-warning gate does with
|
|
16
|
-
* it, and the thresholds are now tunable, so a project whose file-size
|
|
10
|
+
* On the vocabulary: the bands are `notice` / `warning` / `error`, and the
|
|
11
|
+
* middle one is not a "soft limit". Under the posture FireForge itself
|
|
12
|
+
* recommends for a release gate, `--max-warnings 0`, a warning is a hard
|
|
13
|
+
* failure. The message below therefore says what the band is (a warning)
|
|
14
|
+
* and what a zero-warning gate does with it, and the thresholds are tunable, so a project whose file-size
|
|
17
15
|
* policy differs has a dial instead of an argument. The notice band is the
|
|
18
16
|
* design target: advisory, and its message says so rather than borrowing
|
|
19
17
|
* the warning band's gate sentence.
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* An entry is either a bare check ID, which suppresses that rule at any
|
|
5
5
|
* size, or a ceiling `{ rule, max, reason }`, which suppresses a size rule
|
|
6
|
-
* only while its measurement is at or below `max`. The bare form
|
|
7
|
-
* waived file grow without bound: nothing re-
|
|
8
|
-
*
|
|
6
|
+
* only while its measurement is at or below `max`. The bare form lets a
|
|
7
|
+
* waived file grow without bound: nothing re-examines the waiver once it
|
|
8
|
+
* is written, so a 950-line file waived at review time is still waived at
|
|
9
9
|
* 2,000 lines. The ceiling makes growth past the reviewed size fire again,
|
|
10
10
|
* and lets a gate say when the waiver is no longer needed at all.
|
|
11
11
|
*
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
*
|
|
5
5
|
* An entry is either a bare check ID, which suppresses that rule at any
|
|
6
6
|
* size, or a ceiling `{ rule, max, reason }`, which suppresses a size rule
|
|
7
|
-
* only while its measurement is at or below `max`. The bare form
|
|
8
|
-
* waived file grow without bound: nothing re-
|
|
9
|
-
*
|
|
7
|
+
* only while its measurement is at or below `max`. The bare form lets a
|
|
8
|
+
* waived file grow without bound: nothing re-examines the waiver once it
|
|
9
|
+
* is written, so a 950-line file waived at review time is still waived at
|
|
10
10
|
* 2,000 lines. The ceiling makes growth past the reviewed size fire again,
|
|
11
11
|
* and lets a gate say when the waiver is no longer needed at all.
|
|
12
12
|
*
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Optional Prettier pass over patch-owned `.sys.mjs` modules.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* module formatting drift
|
|
6
|
-
*
|
|
7
|
-
* direction: a fork's root `.prettierignore` typically excludes `engine/`,
|
|
4
|
+
* Without this pass no tier of the chain runs Prettier on `.sys.mjs`, so
|
|
5
|
+
* module formatting drift survives to a human reviewer. The obvious manual
|
|
6
|
+
* check is misleading in the same direction: a fork's root `.prettierignore` typically excludes `engine/`,
|
|
8
7
|
* so `prettier --check --config engine/.prettierrc.js <engine files>` run
|
|
9
8
|
* from the repo root reports "all files use Prettier code style" for files
|
|
10
|
-
* that fail the identical check run from inside `engine/`.
|
|
11
|
-
* spot-check falsely refuted a correct reviewer finding on exactly this.
|
|
9
|
+
* that fail the identical check run from inside `engine/`.
|
|
12
10
|
*
|
|
13
11
|
* This pass therefore runs prettier with `cwd` set to the engine directory,
|
|
14
12
|
* so the engine's own `.prettierrc*` and `.prettierignore` resolve the way
|
|
@@ -2,14 +2,12 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Optional Prettier pass over patch-owned `.sys.mjs` modules.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* module formatting drift
|
|
7
|
-
*
|
|
8
|
-
* direction: a fork's root `.prettierignore` typically excludes `engine/`,
|
|
5
|
+
* Without this pass no tier of the chain runs Prettier on `.sys.mjs`, so
|
|
6
|
+
* module formatting drift survives to a human reviewer. The obvious manual
|
|
7
|
+
* check is misleading in the same direction: a fork's root `.prettierignore` typically excludes `engine/`,
|
|
9
8
|
* so `prettier --check --config engine/.prettierrc.js <engine files>` run
|
|
10
9
|
* from the repo root reports "all files use Prettier code style" for files
|
|
11
|
-
* that fail the identical check run from inside `engine/`.
|
|
12
|
-
* spot-check falsely refuted a correct reviewer finding on exactly this.
|
|
10
|
+
* that fail the identical check run from inside `engine/`.
|
|
13
11
|
*
|
|
14
12
|
* This pass therefore runs prettier with `cwd` set to the engine directory,
|
|
15
13
|
* so the engine's own `.prettierrc*` and `.prettierignore` resolve the way
|
|
@@ -8,7 +8,7 @@ import type { PatchLintIssue } from '../types/commands/index.js';
|
|
|
8
8
|
* whose message text can drift between otherwise-equivalent runs (for
|
|
9
9
|
* example because the message embeds later-owner filenames or positional
|
|
10
10
|
* detail). Falling back to the full tuple keeps the helper conservative
|
|
11
|
-
* for
|
|
11
|
+
* for non-fingerprinted rules: if their message changes, we would
|
|
12
12
|
* rather surface a potential regression than silently swallow it.
|
|
13
13
|
*
|
|
14
14
|
* Consumption order within the projected list is stable (the input
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* whose message text can drift between otherwise-equivalent runs (for
|
|
8
8
|
* example because the message embeds later-owner filenames or positional
|
|
9
9
|
* detail). Falling back to the full tuple keeps the helper conservative
|
|
10
|
-
* for
|
|
10
|
+
* for non-fingerprinted rules: if their message changes, we would
|
|
11
11
|
* rather surface a potential regression than silently swallow it.
|
|
12
12
|
*
|
|
13
13
|
* Consumption order within the projected list is stable (the input
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* A leaf module by design: it imports nothing, so the individual rule
|
|
5
5
|
* modules can describe the slice of `PatchQueueContext` they read without
|
|
6
|
-
* importing `patch-lint-cross.ts` (which imports them back).
|
|
7
|
-
*
|
|
6
|
+
* importing `patch-lint-cross.ts` (which imports them back). Sharing them
|
|
7
|
+
* here instead of re-declaring a private `{ entries }` interface per rule
|
|
8
8
|
* keeps the dependency edge one-way and `dpdm` clean while stating the shape
|
|
9
9
|
* once.
|
|
10
10
|
*/
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*
|
|
5
5
|
* A leaf module by design: it imports nothing, so the individual rule
|
|
6
6
|
* modules can describe the slice of `PatchQueueContext` they read without
|
|
7
|
-
* importing `patch-lint-cross.ts` (which imports them back).
|
|
8
|
-
*
|
|
7
|
+
* importing `patch-lint-cross.ts` (which imports them back). Sharing them
|
|
8
|
+
* here instead of re-declaring a private `{ entries }` interface per rule
|
|
9
9
|
* keeps the dependency edge one-way and `dpdm` clean while stating the shape
|
|
10
10
|
* once.
|
|
11
11
|
*/
|
|
@@ -20,7 +20,7 @@ export declare function validatePatchesManifestConsistency(patchesDir: string):
|
|
|
20
20
|
*
|
|
21
21
|
* Drift that is only in `filesAffected` is a derived value disagreeing with
|
|
22
22
|
* the diff it describes, and the narrow repair fixes exactly that. Naming the
|
|
23
|
-
* whole-manifest rebuild for it
|
|
23
|
+
* whole-manifest rebuild for it puts
|
|
24
24
|
* an operator one keystroke from rewriting every row in the manifest to
|
|
25
25
|
* correct one list.
|
|
26
26
|
*/
|
|
@@ -80,7 +80,7 @@ export interface RebuildPatchesManifestOptions extends PatchDirectoryLockOptions
|
|
|
80
80
|
* becomes a whole-manifest reinvention. Pass `allowMetadataLoss` to accept it.
|
|
81
81
|
*
|
|
82
82
|
* @param patchesDir - Path to the patches directory
|
|
83
|
-
* @param fallbackSourceEsrVersion - source version to use for recovered
|
|
83
|
+
* @param fallbackSourceEsrVersion - source version to use for recovered entries that carry none
|
|
84
84
|
* @param options - Lock options plus `allowMetadataLoss` / `dryRun`
|
|
85
85
|
* @returns {@link RebuildPatchesManifestResult}: the rebuilt manifest, the
|
|
86
86
|
* filenames that were reconstructed from generic defaults, and the rows
|
|
@@ -87,7 +87,7 @@ export async function validatePatchesManifestConsistency(patchesDir) {
|
|
|
87
87
|
*
|
|
88
88
|
* Drift that is only in `filesAffected` is a derived value disagreeing with
|
|
89
89
|
* the diff it describes, and the narrow repair fixes exactly that. Naming the
|
|
90
|
-
* whole-manifest rebuild for it
|
|
90
|
+
* whole-manifest rebuild for it puts
|
|
91
91
|
* an operator one keystroke from rewriting every row in the manifest to
|
|
92
92
|
* correct one list.
|
|
93
93
|
*/
|
|
@@ -115,7 +115,7 @@ export function recommendManifestRepair(issues) {
|
|
|
115
115
|
* becomes a whole-manifest reinvention. Pass `allowMetadataLoss` to accept it.
|
|
116
116
|
*
|
|
117
117
|
* @param patchesDir - Path to the patches directory
|
|
118
|
-
* @param fallbackSourceEsrVersion - source version to use for recovered
|
|
118
|
+
* @param fallbackSourceEsrVersion - source version to use for recovered entries that carry none
|
|
119
119
|
* @param options - Lock options plus `allowMetadataLoss` / `dryRun`
|
|
120
120
|
* @returns {@link RebuildPatchesManifestResult}: the rebuilt manifest, the
|
|
121
121
|
* filenames that were reconstructed from generic defaults, and the rows
|
|
@@ -65,10 +65,14 @@ export declare function loadPatchesManifestForWrite(patchesDir: string): Promise
|
|
|
65
65
|
*/
|
|
66
66
|
export declare function savePatchesManifest(patchesDir: string, manifest: PatchesManifest): Promise<void>;
|
|
67
67
|
/**
|
|
68
|
-
* Mutates selected manifest rows while preserving the raw JSON
|
|
68
|
+
* Mutates selected manifest rows while preserving the raw JSON fields of every
|
|
69
69
|
* untouched row. This avoids serializing reader-only fallback fields, such as
|
|
70
70
|
* `sourceVersion` derived from legacy `sourceEsrVersion`, into unrelated patch
|
|
71
71
|
* entries during partial metadata updates.
|
|
72
|
+
*
|
|
73
|
+
* Every row's keys (and the manifest's own) are written in canonical order,
|
|
74
|
+
* not only the changed rows', so the working copy matches what `patch stage`
|
|
75
|
+
* and full saves write and no commit flips untouched rows' key order.
|
|
72
76
|
*/
|
|
73
77
|
export declare function mutatePatchRowsInManifest(patchesDir: string, filenames: readonly string[], mutator: (existing: PatchMetadata, rawExisting: Readonly<JsonObject>) => PatchManifestRowMutation | null): Promise<PatchManifestRowMutationResult[] | null>;
|
|
74
78
|
/**
|
|
@@ -19,7 +19,7 @@ import { pathExistsStrict, readJson, removeFile, writeJson } from '../utils/fs.j
|
|
|
19
19
|
import { warn } from '../utils/logger.js';
|
|
20
20
|
import { isArray, isObject } from '../utils/validation.js';
|
|
21
21
|
import { assertPatchDirectoryLockHeld } from './patch-lock.js';
|
|
22
|
-
import { canonicalizeManifest
|
|
22
|
+
import { canonicalizeManifest } from './patch-manifest-key-order.js';
|
|
23
23
|
import { validatePatchesManifest } from './patch-manifest-validate.js';
|
|
24
24
|
import { manifestWithRetiredSlots } from './patch-retired.js';
|
|
25
25
|
/** Filename for the patches manifest */
|
|
@@ -90,10 +90,14 @@ export async function savePatchesManifest(patchesDir, manifest) {
|
|
|
90
90
|
await writeJson(manifestPath, canonicalizeManifest(manifest));
|
|
91
91
|
}
|
|
92
92
|
/**
|
|
93
|
-
* Mutates selected manifest rows while preserving the raw JSON
|
|
93
|
+
* Mutates selected manifest rows while preserving the raw JSON fields of every
|
|
94
94
|
* untouched row. This avoids serializing reader-only fallback fields, such as
|
|
95
95
|
* `sourceVersion` derived from legacy `sourceEsrVersion`, into unrelated patch
|
|
96
96
|
* entries during partial metadata updates.
|
|
97
|
+
*
|
|
98
|
+
* Every row's keys (and the manifest's own) are written in canonical order,
|
|
99
|
+
* not only the changed rows', so the working copy matches what `patch stage`
|
|
100
|
+
* and full saves write and no commit flips untouched rows' key order.
|
|
97
101
|
*/
|
|
98
102
|
export async function mutatePatchRowsInManifest(patchesDir, filenames, mutator) {
|
|
99
103
|
const manifestPath = join(patchesDir, PATCHES_MANIFEST);
|
|
@@ -140,16 +144,14 @@ export async function mutatePatchRowsInManifest(patchesDir, filenames, mutator)
|
|
|
140
144
|
}
|
|
141
145
|
if (changedIndexes.length === 0)
|
|
142
146
|
return [];
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
//
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
const nextRawManifest = {
|
|
147
|
+
// Every row is put in canonical key order, not only the changed ones:
|
|
148
|
+
// `patch stage` and full saves canonicalize the whole manifest, so a
|
|
149
|
+
// row left in any other order flips back and forth between the
|
|
150
|
+
// working copy and the index. Reordering keys adds no field.
|
|
151
|
+
const nextRawManifest = canonicalizeManifest({
|
|
150
152
|
...rawManifest,
|
|
151
153
|
patches: rawPatches,
|
|
152
|
-
};
|
|
154
|
+
});
|
|
153
155
|
const afterManifest = validatePatchesManifest(nextRawManifest);
|
|
154
156
|
await writeJson(manifestPath, nextRawManifest);
|
|
155
157
|
return changedIndexes.map((index) => ({
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The one key order every `patches.json` writer uses for a patch row and
|
|
3
|
-
* for the manifest itself
|
|
4
|
-
* `
|
|
5
|
-
*
|
|
6
|
-
* the manifest.
|
|
3
|
+
* for the manifest itself, so that every writer (`export`, full-manifest
|
|
4
|
+
* saves, `patch stage`) agrees and a no-op rewrite leaves no key-order-only
|
|
5
|
+
* hunk in the manifest.
|
|
7
6
|
*/
|
|
8
7
|
/**
|
|
9
8
|
* Returns a copy of a patch row with its keys in canonical order.
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
/**
|
|
3
3
|
* The one key order every `patches.json` writer uses for a patch row and
|
|
4
|
-
* for the manifest itself
|
|
5
|
-
* `
|
|
6
|
-
*
|
|
7
|
-
* the manifest.
|
|
4
|
+
* for the manifest itself, so that every writer (`export`, full-manifest
|
|
5
|
+
* saves, `patch stage`) agrees and a no-op rewrite leaves no key-order-only
|
|
6
|
+
* hunk in the manifest.
|
|
8
7
|
*/
|
|
9
8
|
/** Patch-row keys in the order of the `PatchMetadata` interface. */
|
|
10
9
|
const PATCH_ROW_KEY_ORDER = [
|
|
@@ -34,10 +34,10 @@ export declare function extractOrder(filename: string): number;
|
|
|
34
34
|
* The write-side counterpart to {@link extractOrder}. That one answers
|
|
35
35
|
* `Infinity` for a prefix-less filename, which sorts such a patch last and
|
|
36
36
|
* is the right answer for a read: an unparseable name should not crash a
|
|
37
|
-
* status listing. Persisting `Infinity` (or
|
|
38
|
-
*
|
|
37
|
+
* status listing. Persisting `Infinity` (or a fallback `0`) is a different
|
|
38
|
+
* matter: it puts an order in the manifest
|
|
39
39
|
* that no filename on disk agrees with, and the queue then applies in an
|
|
40
|
-
* order the operator cannot see. Callers here have
|
|
40
|
+
* order the operator cannot see. Callers here have just built or
|
|
41
41
|
* looked up a real prefixed filename, so absence is a bug, not input.
|
|
42
42
|
*
|
|
43
43
|
* @param filename - Patch filename carrying a numeric order prefix
|
|
@@ -56,10 +56,10 @@ export function extractOrder(filename) {
|
|
|
56
56
|
* The write-side counterpart to {@link extractOrder}. That one answers
|
|
57
57
|
* `Infinity` for a prefix-less filename, which sorts such a patch last and
|
|
58
58
|
* is the right answer for a read: an unparseable name should not crash a
|
|
59
|
-
* status listing. Persisting `Infinity` (or
|
|
60
|
-
*
|
|
59
|
+
* status listing. Persisting `Infinity` (or a fallback `0`) is a different
|
|
60
|
+
* matter: it puts an order in the manifest
|
|
61
61
|
* that no filename on disk agrees with, and the queue then applies in an
|
|
62
|
-
* order the operator cannot see. Callers here have
|
|
62
|
+
* order the operator cannot see. Callers here have just built or
|
|
63
63
|
* looked up a real prefixed filename, so absence is a bug, not input.
|
|
64
64
|
*
|
|
65
65
|
* @param filename - Patch filename carrying a numeric order prefix
|
|
@@ -42,7 +42,7 @@ export interface PatchPolicyEnforcementInput {
|
|
|
42
42
|
}
|
|
43
43
|
/** Returns valid categories for prompts and CLI validation under the config. */
|
|
44
44
|
export declare function getPatchPolicyCategories(config: FireForgeConfig): string[];
|
|
45
|
-
/** Checks whether a category is accepted by
|
|
45
|
+
/** Checks whether a category is accepted by the built-in defaults or the policy ranges. */
|
|
46
46
|
export declare function isCategoryAllowedByConfig(config: FireForgeConfig, category: string): boolean;
|
|
47
47
|
/**
|
|
48
48
|
* Human-readable label for a category's configured ranges, e.g. `300-399`.
|
|
@@ -28,7 +28,7 @@ export function getPatchPolicyCategories(config) {
|
|
|
28
28
|
return [...PATCH_CATEGORIES];
|
|
29
29
|
return Array.from(new Set(cfg.ranges.map((range) => range.category))).sort((a, b) => a.localeCompare(b));
|
|
30
30
|
}
|
|
31
|
-
/** Checks whether a category is accepted by
|
|
31
|
+
/** Checks whether a category is accepted by the built-in defaults or the policy ranges. */
|
|
32
32
|
export function isCategoryAllowedByConfig(config, category) {
|
|
33
33
|
if (!/^[a-z][a-z0-9-]*$/.test(category))
|
|
34
34
|
return false;
|
|
@@ -2,5 +2,5 @@ import type { PatchMetadata } from '../types/commands/index.js';
|
|
|
2
2
|
import type { FirefoxConfig } from '../types/config.js';
|
|
3
3
|
/** Metadata fields stamped on new or refreshed patch entries. */
|
|
4
4
|
export declare function buildPatchSourceMetadata(firefox: Pick<FirefoxConfig, 'product' | 'version'>): Pick<PatchMetadata, 'sourceEsrVersion' | 'sourceProduct' | 'sourceVersion'>;
|
|
5
|
-
/**
|
|
5
|
+
/** Source version reader that also accepts rows carrying only `sourceEsrVersion`. */
|
|
6
6
|
export declare function getPatchSourceVersion(patch: Pick<PatchMetadata, 'sourceEsrVersion' | 'sourceVersion'>): string;
|
|
@@ -6,7 +6,7 @@ export function buildPatchSourceMetadata(firefox) {
|
|
|
6
6
|
sourceVersion: firefox.version,
|
|
7
7
|
};
|
|
8
8
|
}
|
|
9
|
-
/**
|
|
9
|
+
/** Source version reader that also accepts rows carrying only `sourceEsrVersion`. */
|
|
10
10
|
export function getPatchSourceVersion(patch) {
|
|
11
11
|
return patch.sourceVersion ?? patch.sourceEsrVersion;
|
|
12
12
|
}
|
|
@@ -3,12 +3,14 @@ import type { PatchesManifest, PatchMetadata } from '../types/commands/index.js'
|
|
|
3
3
|
* Resolves a `--patches <name…>` subset against the manifest, matching each
|
|
4
4
|
* requested name tolerantly (exact filename, filename ± `.patch`, the bare
|
|
5
5
|
* order number, the manifest `name` field, or the slug). Accepts repeated
|
|
6
|
-
* values and
|
|
6
|
+
* values and lists separated by commas or whitespace, so a list passed as
|
|
7
|
+
* one shell word (`--patches "$P"` under zsh) still splits. Throws when a
|
|
7
8
|
* requested name matches none, so a typo fails loud rather than silently
|
|
8
|
-
* judging nothing
|
|
9
|
+
* judging nothing; the refusal names that name and its nearest matches,
|
|
10
|
+
* not the whole queue.
|
|
9
11
|
*
|
|
10
12
|
* @param manifest - The loaded patch manifest
|
|
11
|
-
* @param requested - Raw `--patches` values (each may be a comma list)
|
|
13
|
+
* @param requested - Raw `--patches` values (each may be a comma or whitespace list)
|
|
12
14
|
* @param refusalHint - Sentence inserted into the no-match refusal, naming
|
|
13
15
|
* what the caller's flag selects
|
|
14
16
|
* @returns The matching manifest rows, de-duplicated, in request order
|