@hominis/fireforge 0.47.1 → 0.48.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 +54 -0
- package/dist/bin/fireforge.js +5 -0
- package/dist/build-info.json +4 -4
- package/dist/src/commands/doctor-macos-sdk.d.ts +8 -0
- package/dist/src/commands/doctor-macos-sdk.js +156 -0
- package/dist/src/commands/doctor.js +2 -0
- package/dist/src/commands/download.js +64 -3
- package/dist/src/commands/import.js +5 -2
- package/dist/src/commands/lint-per-patch.js +44 -6
- package/dist/src/commands/lint-per-run-checkjs.d.ts +3 -0
- package/dist/src/commands/lint-per-run-checkjs.js +1 -0
- package/dist/src/commands/lint.js +10 -0
- package/dist/src/commands/re-export-lint.d.ts +17 -2
- package/dist/src/commands/re-export-lint.js +33 -4
- package/dist/src/commands/re-export.js +4 -2
- package/dist/src/commands/rebase/confirm.d.ts +12 -1
- package/dist/src/commands/rebase/confirm.js +6 -3
- package/dist/src/commands/rebase/index.js +77 -13
- package/dist/src/commands/run.js +43 -7
- package/dist/src/commands/status.js +5 -3
- package/dist/src/commands/typecheck.d.ts +5 -0
- package/dist/src/commands/typecheck.js +7 -1
- package/dist/src/core/build-prepare.d.ts +2 -0
- package/dist/src/core/build-prepare.js +67 -35
- package/dist/src/core/config-paths.d.ts +1 -1
- package/dist/src/core/config-paths.js +1 -0
- package/dist/src/core/config-validate.js +7 -0
- package/dist/src/core/discard-baseline.js +2 -1
- package/dist/src/core/forward-registrations.d.ts +33 -0
- package/dist/src/core/forward-registrations.js +16 -0
- package/dist/src/core/git-file-ops.d.ts +21 -0
- package/dist/src/core/git-file-ops.js +75 -0
- package/dist/src/core/git-status.d.ts +14 -0
- package/dist/src/core/git-status.js +41 -2
- package/dist/src/core/mach-mozconfig.d.ts +2 -1
- package/dist/src/core/mach-mozconfig.js +2 -0
- package/dist/src/core/patch-apply-fuzz.d.ts +12 -0
- package/dist/src/core/patch-apply-fuzz.js +27 -6
- package/dist/src/core/patch-apply.d.ts +13 -0
- package/dist/src/core/patch-apply.js +27 -2
- package/dist/src/core/patch-lint-checkjs-cache.d.ts +18 -0
- package/dist/src/core/patch-lint-checkjs-cache.js +45 -0
- package/dist/src/core/patch-lint-checkjs.d.ts +6 -0
- package/dist/src/core/patch-lint-checkjs.js +8 -1
- package/dist/src/core/patch-lint-cross.d.ts +7 -1
- package/dist/src/core/patch-lint-cross.js +13 -12
- package/dist/src/core/patch-lint-forward-registration-extended.d.ts +38 -0
- package/dist/src/core/patch-lint-forward-registration-extended.js +240 -0
- package/dist/src/core/patch-lint-forward-registration.d.ts +18 -5
- package/dist/src/core/patch-lint-forward-registration.js +83 -37
- package/dist/src/core/patch-lint.d.ts +11 -0
- package/dist/src/core/patch-lint.js +20 -2
- package/dist/src/core/patch-transform.d.ts +14 -13
- package/dist/src/core/patch-transform.js +29 -17
- package/dist/src/core/rebase-dry-run.d.ts +48 -0
- package/dist/src/core/rebase-dry-run.js +105 -0
- package/dist/src/core/run-profile.d.ts +50 -0
- package/dist/src/core/run-profile.js +131 -0
- package/dist/src/core/status-binary.d.ts +1 -1
- package/dist/src/core/status-binary.js +3 -1
- package/dist/src/core/status-classify.js +29 -2
- package/dist/src/core/toolchain-preflight.d.ts +6 -0
- package/dist/src/core/toolchain-preflight.js +1 -1
- package/dist/src/core/typecheck.d.ts +11 -1
- package/dist/src/core/typecheck.js +85 -11
- package/dist/src/errors/rebase.d.ts +9 -0
- package/dist/src/errors/rebase.js +20 -0
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.js +2 -1
- package/dist/src/types/commands/options.d.ts +15 -0
- package/dist/src/types/config.d.ts +10 -0
- package/dist/src/utils/process-input.d.ts +27 -0
- package/dist/src/utils/process-input.js +49 -0
- package/dist/src/utils/process.d.ts +2 -0
- package/dist/src/utils/process.js +2 -1
- package/dist/src/utils/validation.d.ts +11 -0
- package/dist/src/utils/validation.js +43 -0
- package/docs/configuration.md +81 -0
- package/docs/exit-codes.md +1 -1
- package/docs/lifecycle-invariants.md +4 -3
- package/docs/patch-workflow.md +35 -1
- package/package.json +7 -3
|
@@ -85,6 +85,8 @@ export interface SetupOptions {
|
|
|
85
85
|
export interface DownloadOptions {
|
|
86
86
|
/** Force re-download, deleting existing engine/ */
|
|
87
87
|
force?: boolean;
|
|
88
|
+
/** With `force`: skip the confirmation for an engine with changes to lose */
|
|
89
|
+
yes?: boolean;
|
|
88
90
|
}
|
|
89
91
|
/**
|
|
90
92
|
* Options for the source command.
|
|
@@ -497,6 +499,13 @@ export interface RebaseOptions {
|
|
|
497
499
|
export interface RunOptions {
|
|
498
500
|
/** Additional arguments to pass to the browser */
|
|
499
501
|
args?: string[];
|
|
502
|
+
/** Launch with this profile directory, passed to Firefox as `-profile`. */
|
|
503
|
+
profile?: string;
|
|
504
|
+
/**
|
|
505
|
+
* Launch with a fresh temporary profile, removed when the run ends.
|
|
506
|
+
* Implied by `smokeExit` unless `profile` is given.
|
|
507
|
+
*/
|
|
508
|
+
tempProfile?: boolean;
|
|
500
509
|
/**
|
|
501
510
|
* Enable smoke-run mode. Launches the browser, streams the console,
|
|
502
511
|
* sends SIGTERM to the whole process group after `smokeExit` seconds,
|
|
@@ -1115,4 +1124,10 @@ export interface LintCommandOptions {
|
|
|
1115
1124
|
* {@link perPatch}.
|
|
1116
1125
|
*/
|
|
1117
1126
|
report?: string;
|
|
1127
|
+
/**
|
|
1128
|
+
* With `--per-patch`: `'full'` (default) prints every NOTICE line;
|
|
1129
|
+
* `'summary'` prints one line per check with its count and patch count.
|
|
1130
|
+
* Errors and warnings always print in full.
|
|
1131
|
+
*/
|
|
1132
|
+
notices?: 'summary' | 'full';
|
|
1118
1133
|
}
|
|
@@ -355,6 +355,16 @@ export interface PatchLintConfig {
|
|
|
355
355
|
* scope for the per-patch tier.
|
|
356
356
|
*/
|
|
357
357
|
prettier?: PatchLintSeverityGate;
|
|
358
|
+
/**
|
|
359
|
+
* Which carriers the `forward-registration` queue rule checks for a line
|
|
360
|
+
* that names a file only a later patch creates. `'support-files'` (the
|
|
361
|
+
* default) checks test-manifest `support-files`. `'extended'` also checks
|
|
362
|
+
* jar.mn pair lines, moz.build path tokens, test-manifest sections and
|
|
363
|
+
* `head`, and customElements.js chrome URLs resolved through the queue's
|
|
364
|
+
* own jar.mn lines. Opt-in: a queue that predates the wider rule can carry
|
|
365
|
+
* such edges, and a new error on install would red its gate.
|
|
366
|
+
*/
|
|
367
|
+
forwardRegistration?: 'support-files' | 'extended';
|
|
358
368
|
/** Enforce JSDoc on class-method exports in patch-owned .sys.mjs files. Default: 'off'. */
|
|
359
369
|
jsdocClassMethods?: PatchLintSeverityGate;
|
|
360
370
|
/** Require ≥1 assertion in any patch-touched browser_*.js test file (new or modified). Default: 'off'. */
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Options for {@link execWithInput}. */
|
|
2
|
+
export interface ExecWithInputOptions {
|
|
3
|
+
/** Working directory for the command */
|
|
4
|
+
cwd?: string;
|
|
5
|
+
/** Environment variables merged over `process.env` */
|
|
6
|
+
env?: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
/** Result of {@link execWithInput}: stdout stays raw bytes. */
|
|
9
|
+
export interface ExecBufferResult {
|
|
10
|
+
/** Standard output, uncapped and undecoded */
|
|
11
|
+
stdout: Buffer;
|
|
12
|
+
/** Standard error, decoded as UTF-8 */
|
|
13
|
+
stderr: string;
|
|
14
|
+
/** Process exit code */
|
|
15
|
+
exitCode: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Runs a command, writes `input` to its stdin, and returns stdout as raw
|
|
19
|
+
* bytes. For batch protocols (`git cat-file --batch`) whose framing counts
|
|
20
|
+
* bytes: the decoded, 50 MB-capped collector `exec` uses would corrupt
|
|
21
|
+
* both. The caller bounds the input, and so the output.
|
|
22
|
+
* @param command - Command to execute
|
|
23
|
+
* @param args - Command arguments
|
|
24
|
+
* @param input - Bytes written to stdin, which is then closed
|
|
25
|
+
* @param options - Execution options
|
|
26
|
+
*/
|
|
27
|
+
export declare function execWithInput(command: string, args: string[], input: string | Buffer, options?: ExecWithInputOptions): Promise<ExecBufferResult>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* Stdin-fed command execution with byte-exact stdout.
|
|
4
|
+
*
|
|
5
|
+
* Its own module rather than a function in `process.ts` only because that
|
|
6
|
+
* file sits on a 500-line budget. The logic belongs to the exec layer.
|
|
7
|
+
*/
|
|
8
|
+
import { spawn } from 'node:child_process';
|
|
9
|
+
import { buildChildEnv } from './child-env.js';
|
|
10
|
+
import { exitCodeFromClose } from './process.js';
|
|
11
|
+
/**
|
|
12
|
+
* Runs a command, writes `input` to its stdin, and returns stdout as raw
|
|
13
|
+
* bytes. For batch protocols (`git cat-file --batch`) whose framing counts
|
|
14
|
+
* bytes: the decoded, 50 MB-capped collector `exec` uses would corrupt
|
|
15
|
+
* both. The caller bounds the input, and so the output.
|
|
16
|
+
* @param command - Command to execute
|
|
17
|
+
* @param args - Command arguments
|
|
18
|
+
* @param input - Bytes written to stdin, which is then closed
|
|
19
|
+
* @param options - Execution options
|
|
20
|
+
*/
|
|
21
|
+
export async function execWithInput(command, args, input, options = {}) {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
const child = spawn(command, args, {
|
|
24
|
+
cwd: options.cwd,
|
|
25
|
+
env: buildChildEnv(options),
|
|
26
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
27
|
+
});
|
|
28
|
+
const out = [];
|
|
29
|
+
const err = [];
|
|
30
|
+
child.stdout.on('data', (chunk) => {
|
|
31
|
+
out.push(chunk);
|
|
32
|
+
});
|
|
33
|
+
child.stderr.on('data', (chunk) => {
|
|
34
|
+
err.push(chunk);
|
|
35
|
+
});
|
|
36
|
+
// A child that exits before reading all of stdin (a bad ref, say) makes
|
|
37
|
+
// the write fail with EPIPE. The close handler reports the real outcome.
|
|
38
|
+
child.stdin.on('error', () => undefined);
|
|
39
|
+
child.stdin.end(input);
|
|
40
|
+
child.on('error', reject);
|
|
41
|
+
child.on('close', (code, signal) => {
|
|
42
|
+
resolve({
|
|
43
|
+
stdout: Buffer.concat(out),
|
|
44
|
+
stderr: Buffer.concat(err).toString('utf8'),
|
|
45
|
+
exitCode: exitCodeFromClose(code, signal),
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -104,6 +104,8 @@ export interface ProcessGroupOptions {
|
|
|
104
104
|
*/
|
|
105
105
|
postCloseSweep?: () => Promise<void>;
|
|
106
106
|
}
|
|
107
|
+
/** A child's exit code, with a signal death mapped to 128 + its number. */
|
|
108
|
+
export declare function exitCodeFromClose(code: number | null, signal: NodeJS.Signals | null): number;
|
|
107
109
|
/**
|
|
108
110
|
* Executes a command and returns its output.
|
|
109
111
|
* @param command - Command to execute
|
|
@@ -77,7 +77,8 @@ function collectedOutput(out, err) {
|
|
|
77
77
|
truncated: out.wasTruncated() || err.wasTruncated(),
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
|
-
|
|
80
|
+
/** A child's exit code, with a signal death mapped to 128 + its number. */
|
|
81
|
+
export function exitCodeFromClose(code, signal) {
|
|
81
82
|
if (code !== null) {
|
|
82
83
|
return code;
|
|
83
84
|
}
|
|
@@ -68,6 +68,17 @@ export declare function isJsonObject(value: JsonValue | undefined): value is Jso
|
|
|
68
68
|
* Accepts formats like "140.9.0", "140.9.1", "140.9.0esr", "147.0b1"
|
|
69
69
|
*/
|
|
70
70
|
export declare function isValidFirefoxVersion(version: string): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Orders two Firefox version strings semantically: major, minor and patch
|
|
73
|
+
* numerically, with a beta (`153.0b7`) before the release it precedes
|
|
74
|
+
* (`153.0`). An `esr` suffix does not change the order: `153.3.0esr` and
|
|
75
|
+
* `153.3.0` compare equal, since the product says which line it is. A
|
|
76
|
+
* lexical sort, which this replaces in `rebase`, put `153.10.0esr` before
|
|
77
|
+
* `153.2.0esr` and `99.0` after `140.0esr`. A string that is not a Firefox
|
|
78
|
+
* version sorts after every one that is, then lexically.
|
|
79
|
+
* @returns Negative when `a` is older, positive when newer, 0 when equal
|
|
80
|
+
*/
|
|
81
|
+
export declare function compareFirefoxVersions(a: string, b: string): number;
|
|
71
82
|
/**
|
|
72
83
|
* Validates a release-candidate build directory name.
|
|
73
84
|
* Accepts formats like "build1", "build2", "build12" (no leading zero).
|
|
@@ -100,6 +100,49 @@ export function isValidFirefoxVersion(version) {
|
|
|
100
100
|
// Beta: 147.0b1, 147.0b2
|
|
101
101
|
return /^[1-9]\d{0,2}\.\d+(?:b[1-9]\d*|\.\d+(?:esr)?|esr)?$/.test(version);
|
|
102
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Orders two Firefox version strings semantically: major, minor and patch
|
|
105
|
+
* numerically, with a beta (`153.0b7`) before the release it precedes
|
|
106
|
+
* (`153.0`). An `esr` suffix does not change the order: `153.3.0esr` and
|
|
107
|
+
* `153.3.0` compare equal, since the product says which line it is. A
|
|
108
|
+
* lexical sort, which this replaces in `rebase`, put `153.10.0esr` before
|
|
109
|
+
* `153.2.0esr` and `99.0` after `140.0esr`. A string that is not a Firefox
|
|
110
|
+
* version sorts after every one that is, then lexically.
|
|
111
|
+
* @returns Negative when `a` is older, positive when newer, 0 when equal
|
|
112
|
+
*/
|
|
113
|
+
export function compareFirefoxVersions(a, b) {
|
|
114
|
+
const left = parseFirefoxVersionOrder(a);
|
|
115
|
+
const right = parseFirefoxVersionOrder(b);
|
|
116
|
+
if (left === undefined || right === undefined) {
|
|
117
|
+
if (left !== undefined)
|
|
118
|
+
return -1;
|
|
119
|
+
if (right !== undefined)
|
|
120
|
+
return 1;
|
|
121
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
122
|
+
}
|
|
123
|
+
for (let i = 0; i < left.length; i++) {
|
|
124
|
+
const delta = (left[i] ?? 0) - (right[i] ?? 0);
|
|
125
|
+
if (delta !== 0)
|
|
126
|
+
return delta;
|
|
127
|
+
}
|
|
128
|
+
return 0;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* `[major, minor, patch, betaRank]`, where a release ranks above every beta
|
|
132
|
+
* of the same version.
|
|
133
|
+
*/
|
|
134
|
+
function parseFirefoxVersionOrder(version) {
|
|
135
|
+
const match = /^(\d+)\.(\d+)(?:\.(\d+))?(?:b(\d+))?(?:esr)?$/i.exec(version.trim());
|
|
136
|
+
if (!match)
|
|
137
|
+
return undefined;
|
|
138
|
+
const beta = match[4];
|
|
139
|
+
return [
|
|
140
|
+
Number(match[1]),
|
|
141
|
+
Number(match[2]),
|
|
142
|
+
Number(match[3] ?? 0),
|
|
143
|
+
beta === undefined ? Number.MAX_SAFE_INTEGER : Number(beta),
|
|
144
|
+
];
|
|
145
|
+
}
|
|
103
146
|
/**
|
|
104
147
|
* Validates a release-candidate build directory name.
|
|
105
148
|
* Accepts formats like "build1", "build2", "build12" (no leading zero).
|
package/docs/configuration.md
CHANGED
|
@@ -59,6 +59,19 @@ tool at
|
|
|
59
59
|
`/Applications/Xcode.app/Contents/Applications/Icon Composer.app/Contents/Executables/ictool`,
|
|
60
60
|
plus `actool` via `xcrun`, `sips`, and `iconutil`.
|
|
61
61
|
|
|
62
|
+
On macOS, `fireforge doctor` also checks that the bootstrapped clang
|
|
63
|
+
(`~/.mozbuild/clang`, or under `MOZBUILD_STATE_PATH`) can link against the
|
|
64
|
+
SDK the build will use. That is the SDK `engine/mozconfig` selects with
|
|
65
|
+
`--with-macos-sdk`, resolved by sourcing the mozconfig the way mach does,
|
|
66
|
+
or `xcrun --show-sdk-path` when it names none. The check links a trivial C
|
|
67
|
+
program through the toolchain's lld in a temp directory. When that fails, it
|
|
68
|
+
reports a warning with clang's first error and lists the SDKs installed
|
|
69
|
+
under the mozbuild state directory, the Command Line Tools and the active
|
|
70
|
+
Xcode. An Xcode update can ship an SDK the pinned toolchain cannot read, and
|
|
71
|
+
`mach configure` then dies at its linker probe with nothing but `config.log`
|
|
72
|
+
saying why. The check does nothing on other platforms and when no clang has
|
|
73
|
+
been bootstrapped.
|
|
74
|
+
|
|
62
75
|
## `patchLint`
|
|
63
76
|
|
|
64
77
|
Per-patch lint type-checks plain Firefox JS against a built-in
|
|
@@ -84,6 +97,28 @@ Firefox-globals shim that tracks upstream WebIDL additions per release.
|
|
|
84
97
|
project's, then `npx --no-install`. Left at `'off'`, formatting is out of
|
|
85
98
|
scope for the per-patch tier, and no other tier checks `.sys.mjs`
|
|
86
99
|
formatting either.
|
|
100
|
+
- `patchLint.forwardRegistration` (`'support-files'` or `'extended'`,
|
|
101
|
+
default `'support-files'`) picks which carriers the `forward-registration`
|
|
102
|
+
queue rule checks for a line naming a file that only a later patch
|
|
103
|
+
creates. The default checks test-manifest `support-files`. `'extended'`
|
|
104
|
+
also checks:
|
|
105
|
+
- jar.mn pair lines (the source in parentheses, relative to the jar.mn);
|
|
106
|
+
- moz.build path tokens (a quoted string with a `.` or `/`, relative to
|
|
107
|
+
the moz.build);
|
|
108
|
+
- test-manifest section headers and `head`;
|
|
109
|
+
- `customElements.js` `chrome://<pkg>/content/…` URLs, resolved through
|
|
110
|
+
the jar.mn lines the same queue adds.
|
|
111
|
+
|
|
112
|
+
A line whose target cannot be resolved without the build system is left
|
|
113
|
+
alone: a `%` or `@AB_CD@` substitution, `**`, `!`, a path that leaves the
|
|
114
|
+
tree, or a chrome URL no queue jar.mn line packages. Each finding prints
|
|
115
|
+
the same paste-and-run `patch staged-dependency --add --kind registration`
|
|
116
|
+
command as the `support-files` arm. The setting is opt-in because a queue
|
|
117
|
+
that predates it can carry many such edges, and a new error would red a
|
|
118
|
+
`--max-warnings 0` gate on install. The same census is on the public API as
|
|
119
|
+
`findForwardRegistrations(patchesDir, { scope })`, which defaults to
|
|
120
|
+
`'extended'`, for a consumer that keeps its own ratchet over these edges.
|
|
121
|
+
|
|
87
122
|
- `patchLint.fileSizeThresholds` tunes the `file-too-large` line counts per
|
|
88
123
|
file class:
|
|
89
124
|
|
|
@@ -105,6 +140,27 @@ Firefox-globals shim that tracks upstream WebIDL additions per release.
|
|
|
105
140
|
is a hard failure rather than a soft limit, which is what these thresholds
|
|
106
141
|
exist to let you move.
|
|
107
142
|
|
|
143
|
+
## `typecheck`
|
|
144
|
+
|
|
145
|
+
`typecheck.projects` lists the jsconfig files `fireforge typecheck` checks
|
|
146
|
+
as whole projects. `typecheck.extraShim` and `typecheck.projectOverrides`
|
|
147
|
+
add declarations to the Firefox-globals shim, for every project or for one.
|
|
148
|
+
When `patchLint.checkJs` is on, the same command also runs the per-patch
|
|
149
|
+
checkJs pass that `export` enforces, so a green `typecheck` means
|
|
150
|
+
export-clean types.
|
|
151
|
+
|
|
152
|
+
Each project keeps incremental build info in `.fireforge/typecheck/`, one
|
|
153
|
+
file per project. A warm run re-checks only the files whose content changed
|
|
154
|
+
since the last run. The file name carries a key over everything outside the
|
|
155
|
+
program's own files that can change a verdict: the composed shim, the
|
|
156
|
+
TypeScript version, the compiler options, `typecheck.undefinedIdentifiers`
|
|
157
|
+
and the FireForge version. A change to any of them selects a new file, so a
|
|
158
|
+
stale verdict is never replayed, and the project's other build-info files are
|
|
159
|
+
deleted. `fireforge typecheck --no-cache` checks every project from scratch
|
|
160
|
+
and neither reads nor writes the build info. A jsconfig's own `incremental`
|
|
161
|
+
and `tsBuildInfoFile` are still ignored, so nothing is written under
|
|
162
|
+
`engine/`.
|
|
163
|
+
|
|
108
164
|
## `patchPolicy`
|
|
109
165
|
|
|
110
166
|
`patchPolicy.ranges` makes `patch compact` range-aware, so closing ordinal
|
|
@@ -225,6 +281,31 @@ non-CI launches print a warning saying so. Exit codes 12 and 13 separate a
|
|
|
225
281
|
console regression from a launch failure. See
|
|
226
282
|
[`exit-codes.md`](exit-codes.md).
|
|
227
283
|
|
|
284
|
+
A smoke run starts on a fresh temporary profile by default (since 0.48.0).
|
|
285
|
+
The step exists to prove what the build does on a clean start. The
|
|
286
|
+
developer's `obj-*/tmp/profile-default` carries whatever the last session
|
|
287
|
+
left (a pre-reset database, a restored hand-made applet), and those reds
|
|
288
|
+
say nothing about the tree. FireForge creates the directory under the OS
|
|
289
|
+
temp dir, seeds the two prefs `mach run` writes into profiles it makes
|
|
290
|
+
itself (`browser.shell.checkDefaultBrowser` and
|
|
291
|
+
`browser.aboutConfig.showWarning`), and passes it to Firefox as
|
|
292
|
+
`-profile`. The directory is removed when the run ends. That includes a
|
|
293
|
+
failed run and a SIGINT/SIGTERM, which the signal handler removes after
|
|
294
|
+
the browser tree has shut down. A FireForge that was SIGKILLed cannot clean
|
|
295
|
+
up after itself, so the next `run` removes any temporary profile whose
|
|
296
|
+
owning process is gone.
|
|
297
|
+
|
|
298
|
+
- `--profile <path>` launches with a named profile directory and leaves it
|
|
299
|
+
in place. Under `--smoke-exit` it replaces the fresh default.
|
|
300
|
+
- `--temp-profile` gives a plain `run` the same fresh, removed-afterwards
|
|
301
|
+
profile.
|
|
302
|
+
|
|
303
|
+
A plain `run` without either flag keeps mach's `profile-default`. `mach run`'s
|
|
304
|
+
desktop parser has no `--profile` option (its `--profile/-P` belongs to the
|
|
305
|
+
Android parser), so the profile is always passed as a program parameter.
|
|
306
|
+
With an explicit profile, mach neither writes its `runprefs` from
|
|
307
|
+
`~/.mozbuild/machrc` nor accepts `--setpref`.
|
|
308
|
+
|
|
228
309
|
The allowlist (`--console-allow-file`) is count-blind by default: a line that
|
|
229
310
|
matches an entry never counts, however often it fires. A `# max-hits: N`
|
|
230
311
|
comment directly above an entry (other comments may sit between) caps how
|
package/docs/exit-codes.md
CHANGED
|
@@ -15,7 +15,7 @@ which error class produces each one.
|
|
|
15
15
|
| 3 | `DOWNLOAD_ERROR` | Could not download or extract Firefox source. | `DownloadError` and subclasses |
|
|
16
16
|
| 4 | `GIT_ERROR` | A git operation failed. | `GitError` and subclasses, except `GitNotFoundError` |
|
|
17
17
|
| 5 | `BUILD_ERROR` | `mach build` failed, or a test suite went red. | `BuildError` and subclasses, `TestFailureError` |
|
|
18
|
-
| 6 | `PATCH_ERROR` | A patch failed to apply, or the patch queue could not be mutated.
|
|
18
|
+
| 6 | `PATCH_ERROR` | A patch failed to apply (including a patch `rebase --dry-run` predicts will reject), or the patch queue could not be mutated. | `PatchError`, `PatchManifestCorruptError`, `RebaseError` and subclasses |
|
|
19
19
|
| 7 | `MISSING_DEPENDENCY` | A required tool (python3, git, tar) was not found. | `PythonNotFoundError`, `GitNotFoundError`, `MachNotFoundError` |
|
|
20
20
|
| 8 | `INVALID_ARGUMENT` | The flags were wrong. A usage problem, not an environment one. | `InvalidArgumentError`, plus commander usage errors (unknown command or option, missing argument) |
|
|
21
21
|
| 9 | `FURNACE_ERROR` | A Furnace component operation failed. | `FurnaceError` |
|
|
@@ -190,9 +190,10 @@ command, read the decision table at the bottom first.
|
|
|
190
190
|
stages and unstages for real. Each of those commands therefore runs its
|
|
191
191
|
whole body inside `withPrivateGitIndex`, which seeds a temp
|
|
192
192
|
`GIT_INDEX_FILE` from the repository's own index so that every refresh
|
|
193
|
-
lands there and is discarded. `typecheck` additionally
|
|
194
|
-
`incremental
|
|
195
|
-
under `engine/`.
|
|
193
|
+
lands there and is discarded. `typecheck` additionally ignores a
|
|
194
|
+
jsconfig's own `incremental` and `tsBuildInfoFile`, so no sidecar is
|
|
195
|
+
written under `engine/`. Its incremental build info (0.48.0) lives in the
|
|
196
|
+
project's `.fireforge/typecheck/`, outside the engine. The scope fails open, meaning an unresolvable git dir
|
|
196
197
|
simply does not install it, and it is not reentrant. This exists so that
|
|
197
198
|
invariant 8 stays evidential: a concurrent `fireforge test` must not be
|
|
198
199
|
invalidated by FireForge's own read-only lane. Enforced by
|
package/docs/patch-workflow.md
CHANGED
|
@@ -81,11 +81,23 @@ slugs, and bare slugs.
|
|
|
81
81
|
`lint --per-patch --max-warnings 0` is the warning-clean form for a release
|
|
82
82
|
gate.
|
|
83
83
|
|
|
84
|
+
`lint --per-patch --notices summary` prints one line per check in place of
|
|
85
|
+
every NOTICE row, for example `NOTICE [large-patch-lines]: 180 across 172
|
|
86
|
+
patch(es), 150 of them suppressed by lintIgnore (see --report)`. On a green
|
|
87
|
+
queue those rows are reviewed waivers and under-threshold measurements, and
|
|
88
|
+
there can be hundreds of them. The default, `--notices full`, prints them
|
|
89
|
+
as before. Errors and warnings always print in full, and the `--report`
|
|
90
|
+
JSON is the same in both modes.
|
|
91
|
+
|
|
84
92
|
`lint --per-patch --report <path>` writes a machine-readable JSON report with
|
|
85
93
|
each patch's line count, tier, active size thresholds, issues, and issues
|
|
86
94
|
suppressed by `lintIgnore`. The size metrics (`countNonBinaryDiffLines`,
|
|
87
95
|
`resolvePatchSizeTier`, `getPatchSizeThresholds`) are also exported on the
|
|
88
|
-
programmatic API.
|
|
96
|
+
programmatic API. So is `filesMeasuredByFileTooLarge(patchText)`, which
|
|
97
|
+
returns the files `file-too-large` measures in a patch: the JS files it
|
|
98
|
+
creates, and never a modified file or a new file of another kind. The rule
|
|
99
|
+
selects its files through that same function, so an audit that uses it
|
|
100
|
+
cannot drift from the rule.
|
|
89
101
|
|
|
90
102
|
Per-patch lint type-checks plain Firefox JS against a built-in
|
|
91
103
|
Firefox-globals shim that tracks upstream WebIDL additions per release. See
|
|
@@ -116,6 +128,28 @@ npx fireforge download --force
|
|
|
116
128
|
npx fireforge rebase
|
|
117
129
|
```
|
|
118
130
|
|
|
131
|
+
`download --force` is the destructive step of the three, not `rebase`. It
|
|
132
|
+
replaces `engine/` wholesale, so applied patches, unexported edits and
|
|
133
|
+
commits made in `engine/` are gone once the new tree is active. When the
|
|
134
|
+
engine it is about to replace has changed paths against HEAD, or HEAD has
|
|
135
|
+
moved off the recorded base commit, it names the loss (how many changed
|
|
136
|
+
paths match the patch queue and how many do not) and asks first. A
|
|
137
|
+
non-interactive run refuses unless `--yes` is given. A clean engine is
|
|
138
|
+
replaced without a prompt.
|
|
139
|
+
|
|
140
|
+
`npx fireforge rebase --dry-run` replays the queue onto the engine's HEAD
|
|
141
|
+
without touching `engine/`. It seeds a private index from HEAD and applies
|
|
142
|
+
each patch there with `git apply --cached`, in queue order, walking the same
|
|
143
|
+
context-reduction ladder as the real run (exact, then `-C2`, `-C1`, `-C0`,
|
|
144
|
+
bounded by `--max-fuzz`). Each patch is reported as `clean`, `reduced
|
|
145
|
+
context` (with the step it needed) or `reject` (with the files git named).
|
|
146
|
+
It exits 6 when anything rejects. A reject after an earlier one is marked
|
|
147
|
+
as possibly cascading from it, since the replay continues without the
|
|
148
|
+
rejected patch. Run it after the download, when HEAD is the new source. The
|
|
149
|
+
header names the oldest patch stamp as "from", compared as versions rather
|
|
150
|
+
than strings, prints the spread when the queue carries several stamps, and
|
|
151
|
+
warns when `engine/` is not yet on the pinned version.
|
|
152
|
+
|
|
119
153
|
If a patch fails, fix the reject inside `engine/`, then run
|
|
120
154
|
`npx fireforge rebase --continue`. A rebase leaves the engine mutated on
|
|
121
155
|
purpose, so its apply-and-persist pairs are held across a signal rather than
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hominis/fireforge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.0",
|
|
4
4
|
"description": "FireForge — a build tool for customizing Firefox",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
@@ -75,9 +75,9 @@
|
|
|
75
75
|
"eslint-plugin-simple-import-sort": "^14.0.0",
|
|
76
76
|
"fast-check": "^4.6.0",
|
|
77
77
|
"husky": "^9.1.7",
|
|
78
|
-
"knip": "6.
|
|
78
|
+
"knip": "6.37.0",
|
|
79
79
|
"lint-staged": "^17.0.4",
|
|
80
|
-
"prettier": "3.9.
|
|
80
|
+
"prettier": "3.9.8",
|
|
81
81
|
"tsx": "^4.7.0",
|
|
82
82
|
"typescript": "~6.0.0",
|
|
83
83
|
"typescript-eslint": "^8.0.0",
|
|
@@ -108,5 +108,9 @@
|
|
|
108
108
|
"publishConfig": {
|
|
109
109
|
"access": "public",
|
|
110
110
|
"provenance": true
|
|
111
|
+
},
|
|
112
|
+
"allowScripts": {
|
|
113
|
+
"esbuild@0.28.1": true,
|
|
114
|
+
"fsevents@2.3.3": true
|
|
111
115
|
}
|
|
112
116
|
}
|