@hominis/fireforge 0.15.2 → 0.15.3
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 +25 -1
- package/README.md +54 -0
- package/dist/src/commands/build.js +29 -2
- package/dist/src/commands/furnace/chrome-doc-templates.d.ts +49 -0
- package/dist/src/commands/furnace/chrome-doc-templates.js +151 -0
- package/dist/src/commands/furnace/chrome-doc.d.ts +34 -0
- package/dist/src/commands/furnace/chrome-doc.js +168 -0
- package/dist/src/commands/furnace/create-mochikit.d.ts +30 -0
- package/dist/src/commands/furnace/create-mochikit.js +70 -0
- package/dist/src/commands/furnace/create-templates.d.ts +32 -0
- package/dist/src/commands/furnace/create-templates.js +69 -0
- package/dist/src/commands/furnace/create.d.ts +17 -0
- package/dist/src/commands/furnace/create.js +54 -16
- package/dist/src/commands/furnace/index.d.ts +2 -1
- package/dist/src/commands/furnace/index.js +20 -3
- package/dist/src/commands/lint.d.ts +13 -1
- package/dist/src/commands/lint.js +33 -7
- package/dist/src/core/build-audit.d.ts +46 -0
- package/dist/src/core/build-audit.js +251 -0
- package/dist/src/core/build-baseline.d.ts +59 -0
- package/dist/src/core/build-baseline.js +83 -0
- package/dist/src/core/build-prepare.d.ts +20 -1
- package/dist/src/core/build-prepare.js +89 -4
- package/dist/src/core/furnace-operation.d.ts +2 -1
- package/dist/src/core/furnace-operation.js +13 -7
- package/dist/src/core/mach-error-hints.d.ts +29 -0
- package/dist/src/core/mach-error-hints.js +43 -0
- package/dist/src/core/mach.d.ts +5 -2
- package/dist/src/core/mach.js +31 -4
- package/dist/src/core/patch-lint-diff-tag.d.ts +33 -0
- package/dist/src/core/patch-lint-diff-tag.js +83 -0
- package/dist/src/types/commands/options.d.ts +15 -0
- package/dist/src/types/commands/patches.d.ts +9 -0
- package/dist/src/types/furnace.d.ts +1 -1
- package/package.json +1 -1
package/dist/src/core/mach.d.ts
CHANGED
|
@@ -57,14 +57,17 @@ export declare function bootstrap(engineDir: string): Promise<number>;
|
|
|
57
57
|
*/
|
|
58
58
|
export declare function bootstrapWithOutput(engineDir: string): Promise<MachCommandResult>;
|
|
59
59
|
/**
|
|
60
|
-
* Runs a full mach build.
|
|
60
|
+
* Runs a full mach build. On a non-zero exit, any matched error hints are
|
|
61
|
+
* surfaced on top of the raw mach output so operators get an actionable
|
|
62
|
+
* nudge alongside the cryptic mozbuild traceback.
|
|
61
63
|
* @param engineDir - Path to the engine directory
|
|
62
64
|
* @param jobs - Number of parallel jobs (optional)
|
|
63
65
|
* @returns Exit code
|
|
64
66
|
*/
|
|
65
67
|
export declare function build(engineDir: string, jobs?: number): Promise<number>;
|
|
66
68
|
/**
|
|
67
|
-
* Runs a fast UI-only build.
|
|
69
|
+
* Runs a fast UI-only build. On a non-zero exit, any matched error hints are
|
|
70
|
+
* surfaced on top of the raw mach output.
|
|
68
71
|
* @param engineDir - Path to the engine directory
|
|
69
72
|
* @returns Exit code
|
|
70
73
|
*/
|
package/dist/src/core/mach.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { MachNotFoundError } from '../errors/build.js';
|
|
4
4
|
import { pathExists } from '../utils/fs.js';
|
|
5
|
+
import { warn } from '../utils/logger.js';
|
|
5
6
|
import { exec, execInherit, execInheritCapture, execStream } from '../utils/process.js';
|
|
7
|
+
import { explainMachError } from './mach-error-hints.js';
|
|
6
8
|
import { getPython } from './mach-python.js';
|
|
7
9
|
// Re-export sub-modules so existing `from './mach.js'` imports keep working.
|
|
8
10
|
export { buildArtifactMismatchMessage, hasBuildArtifacts, } from './mach-build-artifacts.js';
|
|
@@ -109,7 +111,23 @@ export async function bootstrapWithOutput(engineDir) {
|
|
|
109
111
|
return runMachInheritCapture(['bootstrap', '--application-choice', 'browser'], engineDir);
|
|
110
112
|
}
|
|
111
113
|
/**
|
|
112
|
-
*
|
|
114
|
+
* Prints any matched {@link MachErrorHint} hints for the captured stderr.
|
|
115
|
+
* No-op when nothing matches. Always called before a non-zero exit propagates
|
|
116
|
+
* so the hint sits immediately below the raw mach error in the operator's
|
|
117
|
+
* terminal.
|
|
118
|
+
*/
|
|
119
|
+
function surfaceMachErrorHints(stderr) {
|
|
120
|
+
const hints = explainMachError(stderr);
|
|
121
|
+
if (hints.length === 0)
|
|
122
|
+
return;
|
|
123
|
+
for (const hint of hints) {
|
|
124
|
+
warn(`Hint: ${hint}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Runs a full mach build. On a non-zero exit, any matched error hints are
|
|
129
|
+
* surfaced on top of the raw mach output so operators get an actionable
|
|
130
|
+
* nudge alongside the cryptic mozbuild traceback.
|
|
113
131
|
* @param engineDir - Path to the engine directory
|
|
114
132
|
* @param jobs - Number of parallel jobs (optional)
|
|
115
133
|
* @returns Exit code
|
|
@@ -119,15 +137,24 @@ export async function build(engineDir, jobs) {
|
|
|
119
137
|
if (jobs !== undefined) {
|
|
120
138
|
args.push('-j', String(jobs));
|
|
121
139
|
}
|
|
122
|
-
|
|
140
|
+
const result = await runMachInheritCapture(args, engineDir);
|
|
141
|
+
if (result.exitCode !== 0) {
|
|
142
|
+
surfaceMachErrorHints(result.stderr);
|
|
143
|
+
}
|
|
144
|
+
return result.exitCode;
|
|
123
145
|
}
|
|
124
146
|
/**
|
|
125
|
-
* Runs a fast UI-only build.
|
|
147
|
+
* Runs a fast UI-only build. On a non-zero exit, any matched error hints are
|
|
148
|
+
* surfaced on top of the raw mach output.
|
|
126
149
|
* @param engineDir - Path to the engine directory
|
|
127
150
|
* @returns Exit code
|
|
128
151
|
*/
|
|
129
152
|
export async function buildUI(engineDir) {
|
|
130
|
-
|
|
153
|
+
const result = await runMachInheritCapture(['build', 'faster'], engineDir);
|
|
154
|
+
if (result.exitCode !== 0) {
|
|
155
|
+
surfaceMachErrorHints(result.stderr);
|
|
156
|
+
}
|
|
157
|
+
return result.exitCode;
|
|
131
158
|
}
|
|
132
159
|
/**
|
|
133
160
|
* Runs the built browser.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diff-scoping for `fireforge lint`.
|
|
3
|
+
*
|
|
4
|
+
* Pre-existing patch-state errors and errors introduced by the current task
|
|
5
|
+
* print identically today, so triaging "is the diff I just produced clean?"
|
|
6
|
+
* requires mentally subtracting the pre-existing noise. This module
|
|
7
|
+
* classifies each lint issue as either `introduced` (the file was touched
|
|
8
|
+
* since the user-supplied git revision) or `cumulative` (pre-existing
|
|
9
|
+
* drift), without changing what the underlying rules emit.
|
|
10
|
+
*/
|
|
11
|
+
import type { PatchLintIssue } from '../types/commands/index.js';
|
|
12
|
+
/**
|
|
13
|
+
* Collects engine-relative paths that changed between `rev` and `HEAD`,
|
|
14
|
+
* plus any workdir modifications and untracked files. An empty set means
|
|
15
|
+
* "no diff we can prove" — downstream treats every issue as `cumulative`
|
|
16
|
+
* in that case (operator ran `lint --since HEAD` with no pending work).
|
|
17
|
+
* @param engineDir Path to the engine git repository.
|
|
18
|
+
* @param rev Git revision to diff against (e.g. `HEAD`, a branch, a SHA).
|
|
19
|
+
*/
|
|
20
|
+
export declare function collectDiffFilePaths(engineDir: string, rev: string): Promise<Set<string>>;
|
|
21
|
+
/**
|
|
22
|
+
* Annotates a list of lint issues with `introduced` / `cumulative` tags
|
|
23
|
+
* based on whether the issue's file is part of the supplied diff set.
|
|
24
|
+
* Mutates each issue in place AND returns the list for chaining.
|
|
25
|
+
*
|
|
26
|
+
* Issues with no file (`issue.file === ''`) — e.g. cross-patch rules that
|
|
27
|
+
* describe queue-wide state — are always `cumulative` under `--since`
|
|
28
|
+
* because they describe drift accumulated across many commits, not a
|
|
29
|
+
* single current-task edit.
|
|
30
|
+
* @param issues Issues returned by the lint orchestrator.
|
|
31
|
+
* @param diffFiles File paths touched since the user's revision.
|
|
32
|
+
*/
|
|
33
|
+
export declare function tagLintIssues(issues: PatchLintIssue[], diffFiles: Set<string>): PatchLintIssue[];
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* Diff-scoping for `fireforge lint`.
|
|
4
|
+
*
|
|
5
|
+
* Pre-existing patch-state errors and errors introduced by the current task
|
|
6
|
+
* print identically today, so triaging "is the diff I just produced clean?"
|
|
7
|
+
* requires mentally subtracting the pre-existing noise. This module
|
|
8
|
+
* classifies each lint issue as either `introduced` (the file was touched
|
|
9
|
+
* since the user-supplied git revision) or `cumulative` (pre-existing
|
|
10
|
+
* drift), without changing what the underlying rules emit.
|
|
11
|
+
*/
|
|
12
|
+
import { toError } from '../utils/errors.js';
|
|
13
|
+
import { verbose } from '../utils/logger.js';
|
|
14
|
+
import { isMissingHeadError } from './git.js';
|
|
15
|
+
import { git } from './git-base.js';
|
|
16
|
+
import { getUntrackedFiles } from './git-status.js';
|
|
17
|
+
/**
|
|
18
|
+
* Collects engine-relative paths that changed between `rev` and `HEAD`,
|
|
19
|
+
* plus any workdir modifications and untracked files. An empty set means
|
|
20
|
+
* "no diff we can prove" — downstream treats every issue as `cumulative`
|
|
21
|
+
* in that case (operator ran `lint --since HEAD` with no pending work).
|
|
22
|
+
* @param engineDir Path to the engine git repository.
|
|
23
|
+
* @param rev Git revision to diff against (e.g. `HEAD`, a branch, a SHA).
|
|
24
|
+
*/
|
|
25
|
+
export async function collectDiffFilePaths(engineDir, rev) {
|
|
26
|
+
const files = new Set();
|
|
27
|
+
try {
|
|
28
|
+
const commitDiff = await git(['diff', '--name-only', `${rev}...HEAD`], engineDir);
|
|
29
|
+
for (const line of commitDiff.split('\n')) {
|
|
30
|
+
const trimmed = line.trim();
|
|
31
|
+
if (trimmed)
|
|
32
|
+
files.add(trimmed);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (!isMissingHeadError(error)) {
|
|
37
|
+
verbose(`lint --since: could not diff against ${rev} — ${toError(error).message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const worktreeDiff = await git(['diff', '--name-only', 'HEAD'], engineDir);
|
|
42
|
+
for (const line of worktreeDiff.split('\n')) {
|
|
43
|
+
const trimmed = line.trim();
|
|
44
|
+
if (trimmed)
|
|
45
|
+
files.add(trimmed);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
verbose(`lint --since: could not enumerate workdir diff — ${toError(error).message}`);
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
for (const file of await getUntrackedFiles(engineDir)) {
|
|
53
|
+
files.add(file);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
verbose(`lint --since: could not list untracked files — ${toError(error).message}`);
|
|
58
|
+
}
|
|
59
|
+
return files;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Annotates a list of lint issues with `introduced` / `cumulative` tags
|
|
63
|
+
* based on whether the issue's file is part of the supplied diff set.
|
|
64
|
+
* Mutates each issue in place AND returns the list for chaining.
|
|
65
|
+
*
|
|
66
|
+
* Issues with no file (`issue.file === ''`) — e.g. cross-patch rules that
|
|
67
|
+
* describe queue-wide state — are always `cumulative` under `--since`
|
|
68
|
+
* because they describe drift accumulated across many commits, not a
|
|
69
|
+
* single current-task edit.
|
|
70
|
+
* @param issues Issues returned by the lint orchestrator.
|
|
71
|
+
* @param diffFiles File paths touched since the user's revision.
|
|
72
|
+
*/
|
|
73
|
+
export function tagLintIssues(issues, diffFiles) {
|
|
74
|
+
for (const issue of issues) {
|
|
75
|
+
if (!issue.file) {
|
|
76
|
+
issue.tag = 'cumulative';
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
issue.tag = diffFiles.has(issue.file) ? 'introduced' : 'cumulative';
|
|
80
|
+
}
|
|
81
|
+
return issues;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=patch-lint-diff-tag.js.map
|
|
@@ -281,6 +281,21 @@ export interface FurnaceCreateOptions {
|
|
|
281
281
|
* `XPCSHELL_TESTS_MANIFESTS`).
|
|
282
282
|
*/
|
|
283
283
|
xpcshell?: boolean;
|
|
284
|
+
/**
|
|
285
|
+
* Test harness style to scaffold when `--with-tests` is set.
|
|
286
|
+
*
|
|
287
|
+
* - `mochikit` (default when `--with-tests` is set alone) — a MochiKit
|
|
288
|
+
* test at `engine/toolkit/content/tests/widgets/test_<tag>.html` that
|
|
289
|
+
* loads the component module directly via `chrome://global/` and
|
|
290
|
+
* asserts against `customElements`. Runs today on forks whose
|
|
291
|
+
* top-level chrome document (e.g. `mybrowser.xhtml`) lacks a
|
|
292
|
+
* `tabbrowser`, because it doesn't go through `URILoadingHelper`.
|
|
293
|
+
* - `browser-chrome` — today's browser-mochitest scaffold, requires a
|
|
294
|
+
* working tabbrowser. Use for components that talk to the browser
|
|
295
|
+
* window or open URLs.
|
|
296
|
+
* - `xpcshell` — equivalent to setting `--xpcshell`; headless, storage-only.
|
|
297
|
+
*/
|
|
298
|
+
testStyle?: 'mochikit' | 'browser-chrome' | 'xpcshell';
|
|
284
299
|
/** Stock component tag names composed internally by this component */
|
|
285
300
|
compose?: string[];
|
|
286
301
|
}
|
|
@@ -96,4 +96,13 @@ export interface PatchLintIssue {
|
|
|
96
96
|
message: string;
|
|
97
97
|
/** Severity: errors block export, warnings are advisory, notices are informational (not counted) */
|
|
98
98
|
severity: 'error' | 'warning' | 'notice';
|
|
99
|
+
/**
|
|
100
|
+
* Diff-scoping tag populated by `lint --since <rev>`. Absent when the
|
|
101
|
+
* caller did not request diff-scoping.
|
|
102
|
+
*
|
|
103
|
+
* - `introduced` — the issue's file was touched in the diff since `<rev>`.
|
|
104
|
+
* - `cumulative` — the issue is pre-existing patch-state drift not
|
|
105
|
+
* introduced by the current task.
|
|
106
|
+
*/
|
|
107
|
+
tag?: 'introduced' | 'cumulative';
|
|
99
108
|
}
|
|
@@ -106,7 +106,7 @@ export interface FurnaceConfig {
|
|
|
106
106
|
* state before clearing authoring markers. The string is surfaced in doctor's
|
|
107
107
|
* failure message verbatim, so new entries should be self-explanatory.
|
|
108
108
|
*/
|
|
109
|
-
export type FurnacePendingRepairOperation = 'preview-teardown' | 'apply-rollback' | 'deploy-rollback' | 'remove-rollback' | 'create-rollback' | 'override-rollback' | 'scan-rollback' | 'rename-rollback' | 'refresh-rollback';
|
|
109
|
+
export type FurnacePendingRepairOperation = 'preview-teardown' | 'apply-rollback' | 'deploy-rollback' | 'remove-rollback' | 'create-rollback' | 'override-rollback' | 'scan-rollback' | 'rename-rollback' | 'refresh-rollback' | 'chrome-doc-rollback';
|
|
110
110
|
/**
|
|
111
111
|
* Marker persisted into `.fireforge/furnace-state.json` when a furnace
|
|
112
112
|
* mutation failed to roll back cleanly. Its presence tells the next
|