@hominis/fireforge 0.51.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 +46 -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-output.js +5 -1
- 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 +10 -0
- package/dist/src/commands/test-build-phase.js +51 -16
- 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 +83 -13
- package/dist/src/commands/test-multi-verdict.js +1 -0
- package/dist/src/commands/test-orchestrate.d.ts +11 -0
- package/dist/src/commands/test-orchestrate.js +33 -2
- 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 +47 -2
- package/dist/src/commands/test-verdict.d.ts +5 -3
- package/dist/src/commands/test.js +14 -1
- 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 +37 -3
- package/dist/src/core/build-baseline-validate.d.ts +30 -1
- package/dist/src/core/build-baseline-validate.js +134 -33
- package/dist/src/core/build-baseline.d.ts +8 -2
- package/dist/src/core/build-baseline.js +32 -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-config-validate-exceptions.d.ts +4 -3
- package/dist/src/core/furnace-config-validate-exceptions.js +26 -6
- 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/furnace-validate-accessibility.d.ts +1 -1
- package/dist/src/core/furnace-validate-accessibility.js +22 -11
- package/dist/src/core/furnace-validate-exceptions.d.ts +2 -1
- package/dist/src/core/furnace-validate-exceptions.js +31 -13
- 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 +22 -3
- package/dist/src/core/negative-control-compiled.js +41 -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-run-completeness.d.ts +12 -5
- package/dist/src/core/test-run-completeness.js +15 -8
- package/dist/src/core/test-stale-check.d.ts +48 -1
- package/dist/src/core/test-stale-check.js +97 -2
- 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.d.ts +2 -1
- package/dist/src/core/typecheck-shim.js +29 -5
- 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/types/furnace.d.ts +9 -0
- 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 +40 -26
- package/docs/exit-codes.md +8 -11
- package/docs/furnace.md +21 -3
- package/docs/lifecycle-invariants.md +36 -45
- package/docs/machine-output.md +43 -22
- package/docs/patch-workflow.md +129 -24
- package/docs/run-logs.md +8 -9
- package/docs/testing.md +118 -44
- package/package.json +1 -1
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Where the patch history log lives, and who wrote each record.
|
|
4
4
|
*
|
|
5
|
-
* The log
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* `fireforge
|
|
10
|
-
*
|
|
5
|
+
* The log defaults to `.fireforge/history.jsonl` (FireForge's own untracked
|
|
6
|
+
* data directory), or `fireforge.json#history.path` when a project sets one.
|
|
7
|
+
* It stays out of the tracked patch queue because it grows to tens of
|
|
8
|
+
* megabytes and would otherwise be committed with every export. A log found
|
|
9
|
+
* at `patches/.fireforge-history.jsonl`, inside the queue, is moved on the
|
|
10
|
+
* first append.
|
|
11
11
|
*
|
|
12
12
|
* Several sessions sharing one checkout all append to the same log, so each
|
|
13
13
|
* record carries the invocation that wrote it, plus a session hint, letting
|
|
@@ -21,7 +21,7 @@ import { ensureDir, pathExists } from '../utils/fs.js';
|
|
|
21
21
|
import { info, verbose } from '../utils/logger.js';
|
|
22
22
|
import { FIREFORGE_DIR } from './config-paths.js';
|
|
23
23
|
import { isValidHistoryPath } from './config-validate-history.js';
|
|
24
|
-
/** Filename of
|
|
24
|
+
/** Filename of a history log inside `patches/`, which is moved out of the queue. */
|
|
25
25
|
export const LEGACY_HISTORY_LOG_FILENAME = '.fireforge-history.jsonl';
|
|
26
26
|
/** Default history log location, relative to the project root. */
|
|
27
27
|
export const DEFAULT_HISTORY_LOG_PATH = join(FIREFORGE_DIR, 'history.jsonl');
|
|
@@ -87,24 +87,24 @@ export async function resolveHistoryLogPath(projectRoot) {
|
|
|
87
87
|
return resolve(projectRoot, configured ?? DEFAULT_HISTORY_LOG_PATH);
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
90
|
-
* Moves a history log
|
|
90
|
+
* Moves a history log found at the `patches/` path to `target`.
|
|
91
91
|
*
|
|
92
92
|
* Records are never dropped, whatever else is happening:
|
|
93
|
-
* - The
|
|
93
|
+
* - The in-queue file is first claimed by renaming it aside, so of two
|
|
94
94
|
* commands migrating at once exactly one does the work and neither
|
|
95
95
|
* duplicates it.
|
|
96
96
|
* - When `target` does not exist yet (the first run), the claimed file is
|
|
97
97
|
* hard-linked into place, which cannot overwrite a log another command
|
|
98
98
|
* created in the meantime, and keeps a large log a constant-time move.
|
|
99
|
-
* - When both exist (
|
|
100
|
-
*
|
|
99
|
+
* - When both exist (a log reappeared at the `patches/` path after a
|
|
100
|
+
* migration, or `history.path` changed), the in-queue records are
|
|
101
101
|
* appended to the target in one write. They then follow newer records;
|
|
102
102
|
* every record carries its own `ts`.
|
|
103
103
|
*
|
|
104
104
|
* A crash between the claim and the move leaves the records in a
|
|
105
|
-
* `.migrating-*` file next to the
|
|
105
|
+
* `.migrating-*` file next to the in-queue path, never deleted.
|
|
106
106
|
*
|
|
107
|
-
* @param patchesDir - The patches directory that may hold
|
|
107
|
+
* @param patchesDir - The patches directory that may hold an in-queue log
|
|
108
108
|
* @param target - Absolute path of the history log
|
|
109
109
|
*/
|
|
110
110
|
export async function migrateLegacyHistoryLog(patchesDir, target) {
|
|
@@ -149,8 +149,8 @@ export async function migrateLegacyHistoryLog(patchesDir, target) {
|
|
|
149
149
|
'Nothing reads it back; it is an audit trail only.');
|
|
150
150
|
}
|
|
151
151
|
/**
|
|
152
|
-
* Appends one serialized record to the project's history log,
|
|
153
|
-
*
|
|
152
|
+
* Appends one serialized record to the project's history log, first moving
|
|
153
|
+
* a log found inside `patches/`.
|
|
154
154
|
*
|
|
155
155
|
* @param patchesDir - The project's `patches/` directory; the project root is
|
|
156
156
|
* its parent, as every caller derives it from `getProjectPaths`
|
|
@@ -3,13 +3,13 @@ import type { HistoryEntry } from './destructive.js';
|
|
|
3
3
|
* Appends a history entry for a mutation that has already committed, degrading
|
|
4
4
|
* to a warning when the log cannot be written.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* This is the one `try { await appendHistory(...) } catch { warn(...) }`
|
|
7
|
+
* block for every call site across `export-flow` and the `patch` subcommands.
|
|
8
8
|
* The swallow is intentional: the patch files and the manifest
|
|
9
9
|
* are already on disk by the time this runs, so letting a failed log write
|
|
10
10
|
* reject would report a completed, irreversible mutation as a failure and send
|
|
11
11
|
* the operator looking for damage that is not there. Because that reasoning is
|
|
12
|
-
* easy to lose in a copy, it
|
|
12
|
+
* easy to lose in a copy, it lives in one place.
|
|
13
13
|
* @param patchesDir - The project's `patches/` directory (the log itself lives
|
|
14
14
|
* under `.fireforge/` or `history.path`; see `history-log-file.ts`).
|
|
15
15
|
* @param entry - The entry to append.
|
|
@@ -6,13 +6,13 @@ import { appendHistory } from './destructive.js';
|
|
|
6
6
|
* Appends a history entry for a mutation that has already committed, degrading
|
|
7
7
|
* to a warning when the log cannot be written.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* This is the one `try { await appendHistory(...) } catch { warn(...) }`
|
|
10
|
+
* block for every call site across `export-flow` and the `patch` subcommands.
|
|
11
11
|
* The swallow is intentional: the patch files and the manifest
|
|
12
12
|
* are already on disk by the time this runs, so letting a failed log write
|
|
13
13
|
* reject would report a completed, irreversible mutation as a failure and send
|
|
14
14
|
* the operator looking for damage that is not there. Because that reasoning is
|
|
15
|
-
* easy to lose in a copy, it
|
|
15
|
+
* easy to lose in a copy, it lives in one place.
|
|
16
16
|
* @param patchesDir - The project's `patches/` directory (the log itself lives
|
|
17
17
|
* under `.fireforge/` or `history.path`; see `history-log-file.ts`).
|
|
18
18
|
* @param entry - The entry to append.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Facts about the launchable build a test run will exercise: its build id
|
|
3
|
+
* and when its compiled code was last linked.
|
|
4
|
+
*
|
|
5
|
+
* A green or red against a binary older than the C++ under test reads as a
|
|
6
|
+
* verdict on that C++ unless the run says which binary it was. The
|
|
7
|
+
* build id goes on the verdict line (`build-id=`), and the link time anchors
|
|
8
|
+
* the stale-compiled preflight (`findCompiledSourcesNewerThanBinary` in
|
|
9
|
+
* `test-stale-check.ts`).
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* The `application.ini` beside a launchable binary: `Contents/Resources`
|
|
13
|
+
* of the `.app` bundle on macOS, the binary's own directory (`dist/bin`)
|
|
14
|
+
* elsewhere.
|
|
15
|
+
*
|
|
16
|
+
* @param binaryPath - Absolute launchable binary path
|
|
17
|
+
*/
|
|
18
|
+
export declare function applicationIniPath(binaryPath: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Reads the `BuildID=` of the launchable build (the `moz:buildID` the
|
|
21
|
+
* browser reports). Undefined when the file or the key is missing, so a
|
|
22
|
+
* caller can simply leave the attribute off.
|
|
23
|
+
*
|
|
24
|
+
* @param engineDir - Absolute engine directory
|
|
25
|
+
* @param launchablePath - Engine-relative launchable binary path
|
|
26
|
+
*/
|
|
27
|
+
export declare function readBuildId(engineDir: string, launchablePath: string): Promise<string | undefined>;
|
|
28
|
+
/**
|
|
29
|
+
* When the launchable build's compiled code was last linked: the newest
|
|
30
|
+
* mtime of the binary and the `libxul` beside it. Undefined when neither
|
|
31
|
+
* can be read.
|
|
32
|
+
*
|
|
33
|
+
* @param engineDir - Absolute engine directory
|
|
34
|
+
* @param launchablePath - Engine-relative launchable binary path
|
|
35
|
+
*/
|
|
36
|
+
export declare function readLinkedAt(engineDir: string, launchablePath: string): Promise<{
|
|
37
|
+
mtimeMs: number;
|
|
38
|
+
path: string;
|
|
39
|
+
} | undefined>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* Facts about the launchable build a test run will exercise: its build id
|
|
4
|
+
* and when its compiled code was last linked.
|
|
5
|
+
*
|
|
6
|
+
* A green or red against a binary older than the C++ under test reads as a
|
|
7
|
+
* verdict on that C++ unless the run says which binary it was. The
|
|
8
|
+
* build id goes on the verdict line (`build-id=`), and the link time anchors
|
|
9
|
+
* the stale-compiled preflight (`findCompiledSourcesNewerThanBinary` in
|
|
10
|
+
* `test-stale-check.ts`).
|
|
11
|
+
*/
|
|
12
|
+
import { stat } from 'node:fs/promises';
|
|
13
|
+
import { basename, dirname, join } from 'node:path';
|
|
14
|
+
import { getNodeErrorCode, toError } from '../utils/errors.js';
|
|
15
|
+
import { readText } from '../utils/fs.js';
|
|
16
|
+
import { verbose } from '../utils/logger.js';
|
|
17
|
+
/**
|
|
18
|
+
* The compiled libraries a build links next to the launchable binary.
|
|
19
|
+
* `libxul` carries nearly all compiled engine code (C++, Rust, generated
|
|
20
|
+
* bindings, prefs), so it, not the small launcher executable, is what a
|
|
21
|
+
* compiled-source edit relinks.
|
|
22
|
+
*/
|
|
23
|
+
const LINKED_LIBRARY_NAMES = ['XUL', 'libxul.so', 'xul.dll'];
|
|
24
|
+
/**
|
|
25
|
+
* The `application.ini` beside a launchable binary: `Contents/Resources`
|
|
26
|
+
* of the `.app` bundle on macOS, the binary's own directory (`dist/bin`)
|
|
27
|
+
* elsewhere.
|
|
28
|
+
*
|
|
29
|
+
* @param binaryPath - Absolute launchable binary path
|
|
30
|
+
*/
|
|
31
|
+
export function applicationIniPath(binaryPath) {
|
|
32
|
+
const binaryDir = dirname(binaryPath);
|
|
33
|
+
if (basename(binaryDir) === 'MacOS' && basename(dirname(binaryDir)) === 'Contents') {
|
|
34
|
+
return join(dirname(binaryDir), 'Resources', 'application.ini');
|
|
35
|
+
}
|
|
36
|
+
return join(binaryDir, 'application.ini');
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Reads the `BuildID=` of the launchable build (the `moz:buildID` the
|
|
40
|
+
* browser reports). Undefined when the file or the key is missing, so a
|
|
41
|
+
* caller can simply leave the attribute off.
|
|
42
|
+
*
|
|
43
|
+
* @param engineDir - Absolute engine directory
|
|
44
|
+
* @param launchablePath - Engine-relative launchable binary path
|
|
45
|
+
*/
|
|
46
|
+
export async function readBuildId(engineDir, launchablePath) {
|
|
47
|
+
const iniPath = applicationIniPath(join(engineDir, launchablePath));
|
|
48
|
+
let content;
|
|
49
|
+
try {
|
|
50
|
+
content = await readText(iniPath);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (getNodeErrorCode(error) !== 'ENOENT') {
|
|
54
|
+
verbose(`Build id: could not read ${iniPath} — ${toError(error).message}`);
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
const match = /^BuildID=(\S+)\s*$/m.exec(content);
|
|
59
|
+
return match?.[1];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* When the launchable build's compiled code was last linked: the newest
|
|
63
|
+
* mtime of the binary and the `libxul` beside it. Undefined when neither
|
|
64
|
+
* can be read.
|
|
65
|
+
*
|
|
66
|
+
* @param engineDir - Absolute engine directory
|
|
67
|
+
* @param launchablePath - Engine-relative launchable binary path
|
|
68
|
+
*/
|
|
69
|
+
export async function readLinkedAt(engineDir, launchablePath) {
|
|
70
|
+
const binary = join(engineDir, launchablePath);
|
|
71
|
+
const candidates = [binary, ...LINKED_LIBRARY_NAMES.map((name) => join(dirname(binary), name))];
|
|
72
|
+
let newest;
|
|
73
|
+
for (const path of candidates) {
|
|
74
|
+
try {
|
|
75
|
+
// stat follows the dist/bin symlinks to the linked objdir file.
|
|
76
|
+
const { mtimeMs } = await stat(path);
|
|
77
|
+
if (newest === undefined || mtimeMs > newest.mtimeMs)
|
|
78
|
+
newest = { mtimeMs, path };
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// A platform's other library names are simply absent.
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return newest;
|
|
85
|
+
}
|
|
@@ -247,9 +247,7 @@ async function probeWithLsof(port) {
|
|
|
247
247
|
catch {
|
|
248
248
|
// `lsof` missing, or its stdout did not parse. Either way the port state
|
|
249
249
|
// is unknown, and an unknown port is reported as free so the probe never
|
|
250
|
-
// blocks a run on its own uncertainty.
|
|
251
|
-
// here returned the same value as this fallthrough, so it decided
|
|
252
|
-
// nothing.)
|
|
250
|
+
// blocks a run on its own uncertainty.
|
|
253
251
|
return { inUse: false };
|
|
254
252
|
}
|
|
255
253
|
}
|
|
@@ -77,11 +77,12 @@ export function getRules(binaryName, createManifest = false) {
|
|
|
77
77
|
// scaffolded and wired via XPCSHELL_TESTS_MANIFESTS.
|
|
78
78
|
pattern: /^(?!browser\/base\/content\/test\/)(.+)\/(test_[^/]+\.js)$/,
|
|
79
79
|
isRegistered: (engineDir, dirRel, fileName) => isXpcshellTestRegistered(engineDir, dirRel, fileName),
|
|
80
|
-
register: (engineDir,
|
|
80
|
+
register: (engineDir, after, dryRun, dirRel, fileName) => registerXpcshellTest(engineDir, dirRel, fileName, dryRun, createManifest, after),
|
|
81
81
|
// Both groups are guaranteed by the pattern, so slice avoids dead
|
|
82
82
|
// fallback branches.
|
|
83
83
|
extractArgs: (m) => m.slice(1, 3),
|
|
84
|
-
|
|
84
|
+
// `--after <entry>` places the section after that entry's block.
|
|
85
|
+
supportsAfter: true,
|
|
85
86
|
},
|
|
86
87
|
];
|
|
87
88
|
}
|
|
@@ -6,18 +6,37 @@
|
|
|
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
|
|
10
|
-
* applied before the build so the binary under test carries it.
|
|
9
|
+
* is refused without `--build`, and with `--build` the control is
|
|
10
|
+
* applied before the build so the binary under test carries it. That build
|
|
11
|
+
* is a full `mach build`: the pre-test build is otherwise `mach build
|
|
12
|
+
* faster`, which compiles nothing, so the control would still miss.
|
|
11
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;
|
|
12
23
|
/**
|
|
13
24
|
* The engine-relative targets that reach the runtime only through a
|
|
14
25
|
* compile: a compiled-source extension and no install-manifest entry that
|
|
15
|
-
* ships the file itself.
|
|
26
|
+
* ships the file itself. Headers are always compiled, even when an
|
|
27
|
+
* `EXPORTS` manifest installs them into `dist/include`.
|
|
16
28
|
*
|
|
17
29
|
* @param engineDir - Absolute engine directory
|
|
18
30
|
* @param enginePaths - The control's engine-relative targets
|
|
19
31
|
*/
|
|
20
32
|
export declare function findCompiledControlTargets(engineDir: string, enginePaths: readonly string[]): Promise<string[]>;
|
|
33
|
+
/**
|
|
34
|
+
* The notice that explains why a compiled control's pre-test build is a
|
|
35
|
+
* full `mach build` instead of `mach build faster`.
|
|
36
|
+
*
|
|
37
|
+
* @param compiled - Engine-relative compiled targets
|
|
38
|
+
*/
|
|
39
|
+
export declare function formatCompiledControlBuildNotice(compiled: readonly string[]): string;
|
|
21
40
|
/**
|
|
22
41
|
* The refusal for a compiled control without `--build`, naming the manual
|
|
23
42
|
* procedure for a run that wants to keep its build out of FireForge.
|
|
@@ -7,8 +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
|
|
11
|
-
* applied before the build so the binary under test carries it.
|
|
10
|
+
* is refused without `--build`, and with `--build` the control is
|
|
11
|
+
* applied before the build so the binary under test carries it. That build
|
|
12
|
+
* is a full `mach build`: the pre-test build is otherwise `mach build
|
|
13
|
+
* faster`, which compiles nothing, so the control would still miss.
|
|
12
14
|
*/
|
|
13
15
|
import { extname } from 'node:path';
|
|
14
16
|
import { classifyRuntimeDelivery } from './objdir-install-manifests.js';
|
|
@@ -32,29 +34,63 @@ const COMPILED_EXTENSIONS = new Set([
|
|
|
32
34
|
'.yaml',
|
|
33
35
|
'.yml',
|
|
34
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
|
+
}
|
|
35
55
|
/**
|
|
36
56
|
* The engine-relative targets that reach the runtime only through a
|
|
37
57
|
* compile: a compiled-source extension and no install-manifest entry that
|
|
38
|
-
* ships the file itself.
|
|
58
|
+
* ships the file itself. Headers are always compiled, even when an
|
|
59
|
+
* `EXPORTS` manifest installs them into `dist/include`.
|
|
39
60
|
*
|
|
40
61
|
* @param engineDir - Absolute engine directory
|
|
41
62
|
* @param enginePaths - The control's engine-relative targets
|
|
42
63
|
*/
|
|
43
64
|
export async function findCompiledControlTargets(engineDir, enginePaths) {
|
|
44
|
-
const candidates = enginePaths.filter(
|
|
65
|
+
const candidates = enginePaths.filter(isCompiledSourcePath);
|
|
45
66
|
if (candidates.length === 0)
|
|
46
67
|
return [];
|
|
68
|
+
if (candidates.every((path) => HEADER_EXTENSIONS.has(extname(path))))
|
|
69
|
+
return candidates;
|
|
47
70
|
const index = await loadEngineInstallIndex(engineDir);
|
|
48
71
|
if (index === undefined)
|
|
49
72
|
return candidates;
|
|
50
73
|
const compiled = [];
|
|
51
74
|
for (const path of candidates) {
|
|
52
|
-
if ((
|
|
75
|
+
if (HEADER_EXTENSIONS.has(extname(path)) ||
|
|
76
|
+
(await classifyRuntimeDelivery(index, engineDir, path)) === 'unlisted') {
|
|
53
77
|
compiled.push(path);
|
|
54
78
|
}
|
|
55
79
|
}
|
|
56
80
|
return compiled;
|
|
57
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* The notice that explains why a compiled control's pre-test build is a
|
|
84
|
+
* full `mach build` instead of `mach build faster`.
|
|
85
|
+
*
|
|
86
|
+
* @param compiled - Engine-relative compiled targets
|
|
87
|
+
*/
|
|
88
|
+
export function formatCompiledControlBuildNotice(compiled) {
|
|
89
|
+
const files = compiled.map((path) => `engine/${path}`).join(', ');
|
|
90
|
+
return (`The negative control edits compiled source (${files}); escalating this pre-test build to ` +
|
|
91
|
+
'a full mach build, since mach build faster compiles nothing and the binary under test ' +
|
|
92
|
+
'would not carry the control.');
|
|
93
|
+
}
|
|
58
94
|
/**
|
|
59
95
|
* The refusal for a compiled control without `--build`, naming the manual
|
|
60
96
|
* procedure for a run that wants to keep its build out of FireForge.
|
|
@@ -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
|