@hominis/fireforge 0.35.0 → 0.37.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 +42 -0
- package/README.md +34 -9
- package/dist/bin/fireforge.js +21 -6
- package/dist/src/cli.js +22 -5
- package/dist/src/commands/bootstrap-checks.js +0 -1
- package/dist/src/commands/bootstrap.d.ts +2 -1
- package/dist/src/commands/bootstrap.js +16 -7
- package/dist/src/commands/build.js +5 -4
- package/dist/src/commands/config.js +30 -10
- package/dist/src/commands/discard.js +18 -3
- package/dist/src/commands/doctor/post-rebase-audit.js +0 -1
- package/dist/src/commands/doctor-check-core.js +0 -1
- package/dist/src/commands/doctor-external-toolchains.d.ts +3 -0
- package/dist/src/commands/doctor-external-toolchains.js +54 -0
- package/dist/src/commands/doctor-furnace-jar.js +0 -1
- package/dist/src/commands/doctor-furnace-manifest-sync.js +0 -1
- package/dist/src/commands/doctor-furnace.js +2 -2
- package/dist/src/commands/doctor-orphaned-harness.d.ts +52 -0
- package/dist/src/commands/doctor-orphaned-harness.js +132 -0
- package/dist/src/commands/doctor-working-tree.js +0 -1
- package/dist/src/commands/doctor.js +6 -1
- package/dist/src/commands/download.js +28 -13
- package/dist/src/commands/export-all.js +5 -3
- package/dist/src/commands/export-flow.js +12 -7
- package/dist/src/commands/export-placement-gate.js +0 -1
- package/dist/src/commands/export-placement-policy.js +0 -1
- package/dist/src/commands/export-shared.d.ts +5 -1
- package/dist/src/commands/export-shared.js +18 -6
- package/dist/src/commands/export.js +22 -10
- package/dist/src/commands/furnace/apply.js +22 -6
- package/dist/src/commands/furnace/chrome-doc-remove.js +0 -1
- package/dist/src/commands/furnace/chrome-doc-templates.js +0 -1
- package/dist/src/commands/furnace/chrome-doc-tests.js +0 -1
- package/dist/src/commands/furnace/chrome-doc.js +0 -1
- package/dist/src/commands/furnace/create-browser-test.js +0 -1
- package/dist/src/commands/furnace/create-dry-run.js +0 -1
- package/dist/src/commands/furnace/create-features.js +0 -1
- package/dist/src/commands/furnace/create-mochikit.js +0 -1
- package/dist/src/commands/furnace/create-readback.js +0 -1
- package/dist/src/commands/furnace/create-templates.js +0 -1
- package/dist/src/commands/furnace/create-validation.js +0 -1
- package/dist/src/commands/furnace/create-xpcshell.js +0 -1
- package/dist/src/commands/furnace/create.js +0 -1
- package/dist/src/commands/furnace/deploy.js +7 -83
- package/dist/src/commands/furnace/diff.js +0 -1
- package/dist/src/commands/furnace/index.js +59 -25
- package/dist/src/commands/furnace/init.js +0 -1
- package/dist/src/commands/furnace/list.js +0 -1
- package/dist/src/commands/furnace/override.js +0 -1
- package/dist/src/commands/furnace/preview.js +3 -3
- package/dist/src/commands/furnace/refresh.js +0 -1
- package/dist/src/commands/furnace/remove-state.d.ts +15 -0
- package/dist/src/commands/furnace/remove-state.js +47 -1
- package/dist/src/commands/furnace/remove.js +3 -9
- package/dist/src/commands/furnace/rename-browser-test.js +1 -5
- package/dist/src/commands/furnace/rename-helpers.d.ts +6 -0
- package/dist/src/commands/furnace/rename-helpers.js +30 -1
- package/dist/src/commands/furnace/rename-xpcshell.js +7 -6
- package/dist/src/commands/furnace/rename.js +15 -36
- package/dist/src/commands/furnace/scan.js +0 -1
- package/dist/src/commands/furnace/status.js +0 -1
- package/dist/src/commands/furnace/sync.js +76 -4
- package/dist/src/commands/furnace/validate.js +0 -1
- package/dist/src/commands/furnace/validation-output.js +0 -1
- package/dist/src/commands/import.js +35 -9
- package/dist/src/commands/lint-per-patch.js +19 -7
- package/dist/src/commands/lint.js +13 -3
- package/dist/src/commands/manifest.js +1 -2
- package/dist/src/commands/package.js +2 -1
- package/dist/src/commands/patch/compact.js +1 -1
- package/dist/src/commands/patch/delete.js +1 -1
- package/dist/src/commands/patch/index.js +1 -1
- package/dist/src/commands/patch/lint-ignore.js +21 -6
- package/dist/src/commands/patch/move-files.js +1 -1
- package/dist/src/commands/patch/patch-context.js +0 -1
- package/dist/src/commands/patch/rename.js +4 -4
- package/dist/src/commands/patch/reorder.js +3 -4
- package/dist/src/commands/patch/split-plan.js +2 -1
- package/dist/src/commands/patch/split.js +4 -4
- package/dist/src/commands/patch/staged-dependency.d.ts +1 -1
- package/dist/src/commands/patch/staged-dependency.js +114 -52
- package/dist/src/commands/patch/tier.js +18 -5
- package/dist/src/commands/re-export-bulk-scan.js +0 -1
- package/dist/src/commands/re-export-files.js +5 -1
- package/dist/src/commands/re-export-options.js +0 -1
- package/dist/src/commands/re-export-scan.js +0 -1
- package/dist/src/commands/re-export.js +14 -4
- package/dist/src/commands/rebase/abort.js +2 -9
- package/dist/src/commands/rebase/confirm.js +0 -1
- package/dist/src/commands/rebase/conflict-summary.js +0 -1
- package/dist/src/commands/rebase/continue.js +0 -1
- package/dist/src/commands/rebase/index.d.ts +1 -1
- package/dist/src/commands/rebase/index.js +10 -15
- package/dist/src/commands/rebase/patch-loop.js +38 -7
- package/dist/src/commands/rebase/summary.js +2 -3
- package/dist/src/commands/rebase.js +0 -1
- package/dist/src/commands/register.js +1 -1
- package/dist/src/commands/reset.js +16 -9
- package/dist/src/commands/resolve.js +2 -2
- package/dist/src/commands/run.js +4 -4
- package/dist/src/commands/setup-support.js +0 -1
- package/dist/src/commands/setup.js +1 -2
- package/dist/src/commands/source.js +1 -2
- package/dist/src/commands/status-output.js +1 -12
- package/dist/src/commands/status.js +147 -133
- package/dist/src/commands/test-appdir.js +0 -1
- package/dist/src/commands/test-diagnose.js +38 -3
- package/dist/src/commands/test-modes.d.ts +15 -0
- package/dist/src/commands/test-modes.js +61 -0
- package/dist/src/commands/test-register.d.ts +4 -0
- package/dist/src/commands/test-register.js +64 -0
- package/dist/src/commands/test-run.d.ts +23 -7
- package/dist/src/commands/test-run.js +15 -14
- package/dist/src/commands/test.d.ts +0 -4
- package/dist/src/commands/test.js +147 -96
- package/dist/src/commands/token-coverage.js +0 -1
- package/dist/src/commands/token.js +1 -2
- package/dist/src/commands/typecheck.js +1 -1
- package/dist/src/commands/verify.js +3 -9
- package/dist/src/commands/watch.js +5 -1
- package/dist/src/commands/wire.js +1 -1
- package/dist/src/core/ast-utils.js +0 -1
- package/dist/src/core/brand-validation.js +0 -1
- package/dist/src/core/branding.js +0 -1
- package/dist/src/core/browser-wire.js +0 -1
- package/dist/src/core/build-audit-platform.js +0 -1
- package/dist/src/core/build-audit-registration.js +0 -1
- package/dist/src/core/build-audit-resolve.js +0 -1
- package/dist/src/core/build-audit-transforms.js +0 -1
- package/dist/src/core/build-audit.js +0 -1
- package/dist/src/core/build-baseline-types.d.ts +24 -0
- package/dist/src/core/build-baseline-types.js +0 -1
- package/dist/src/core/build-baseline.d.ts +5 -2
- package/dist/src/core/build-baseline.js +5 -2
- package/dist/src/core/build-prepare.js +2 -2
- package/dist/src/core/config-mutate.js +0 -1
- package/dist/src/core/config-paths.d.ts +2 -2
- package/dist/src/core/config-paths.js +6 -1
- package/dist/src/core/config-state.js +0 -1
- package/dist/src/core/config-validate-patch-policy.js +0 -1
- package/dist/src/core/config-validate-test-toolchains.d.ts +8 -0
- package/dist/src/core/config-validate-test-toolchains.js +105 -0
- package/dist/src/core/config-validate.js +3 -1
- package/dist/src/core/config.js +0 -1
- package/dist/src/core/destructive.js +0 -1
- package/dist/src/core/diff-hunks.js +13 -7
- package/dist/src/core/engine-changes.js +0 -1
- package/dist/src/core/engine-session-lock.d.ts +12 -0
- package/dist/src/core/engine-session-lock.js +45 -0
- package/dist/src/core/file-lock.d.ts +8 -0
- package/dist/src/core/file-lock.js +157 -48
- package/dist/src/core/firefox-archive.d.ts +4 -0
- package/dist/src/core/firefox-archive.js +6 -1
- package/dist/src/core/firefox-cache.js +60 -4
- package/dist/src/core/firefox-download.js +0 -1
- package/dist/src/core/firefox-extract.js +75 -16
- package/dist/src/core/firefox-ignorefile.js +0 -1
- package/dist/src/core/firefox.d.ts +12 -0
- package/dist/src/core/firefox.js +64 -2
- package/dist/src/core/furnace-apply-dry-run.js +0 -1
- package/dist/src/core/furnace-apply-ftl.d.ts +7 -3
- package/dist/src/core/furnace-apply-ftl.js +10 -5
- package/dist/src/core/furnace-apply-helpers.js +0 -1
- package/dist/src/core/furnace-apply-output.js +2 -2
- package/dist/src/core/furnace-apply.d.ts +7 -1
- package/dist/src/core/furnace-apply.js +47 -13
- package/dist/src/core/furnace-checksum-utils.js +0 -1
- package/dist/src/core/furnace-config-array-utils.js +0 -1
- package/dist/src/core/furnace-config-custom.js +10 -1
- package/dist/src/core/furnace-config-order.js +0 -1
- package/dist/src/core/furnace-config-tokens.js +0 -1
- package/dist/src/core/furnace-config-validate.js +0 -1
- package/dist/src/core/furnace-config.d.ts +11 -0
- package/dist/src/core/furnace-config.js +37 -1
- package/dist/src/core/furnace-constants.js +0 -1
- package/dist/src/core/furnace-css-fragments.js +0 -1
- package/dist/src/core/furnace-graph-utils.js +0 -1
- package/dist/src/core/furnace-jsconfig.d.ts +2 -3
- package/dist/src/core/furnace-jsconfig.js +25 -18
- package/dist/src/core/furnace-marker.js +0 -1
- package/dist/src/core/furnace-operation.js +0 -1
- package/dist/src/core/furnace-refresh.js +0 -1
- package/dist/src/core/furnace-registration-ast.d.ts +14 -0
- package/dist/src/core/furnace-registration-ast.js +1 -2
- package/dist/src/core/furnace-registration-remove.js +0 -1
- package/dist/src/core/furnace-registration-validate.js +1 -5
- package/dist/src/core/furnace-registration.js +0 -1
- package/dist/src/core/furnace-rollback.js +0 -1
- package/dist/src/core/furnace-scanner.js +0 -1
- package/dist/src/core/furnace-stale-export.d.ts +59 -0
- package/dist/src/core/furnace-stale-export.js +123 -0
- package/dist/src/core/furnace-staleness.js +0 -1
- package/dist/src/core/furnace-state-persist.d.ts +72 -0
- package/dist/src/core/furnace-state-persist.js +118 -0
- package/dist/src/core/furnace-step-errors.d.ts +23 -0
- package/dist/src/core/furnace-step-errors.js +25 -0
- package/dist/src/core/furnace-stories.js +0 -1
- package/dist/src/core/furnace-validate-accessibility.js +0 -1
- package/dist/src/core/furnace-validate-checks.js +0 -1
- package/dist/src/core/furnace-validate-compatibility.js +9 -3
- package/dist/src/core/furnace-validate-helpers.js +0 -1
- package/dist/src/core/furnace-validate-registration.js +7 -7
- package/dist/src/core/furnace-validate-structure.d.ts +8 -0
- package/dist/src/core/furnace-validate-structure.js +14 -4
- package/dist/src/core/furnace-validate.js +0 -1
- package/dist/src/core/furnace-version-drift.d.ts +6 -3
- package/dist/src/core/furnace-version-drift.js +6 -4
- package/dist/src/core/git-base.js +0 -1
- package/dist/src/core/git-diff.js +0 -1
- package/dist/src/core/git-file-ops.js +0 -1
- package/dist/src/core/git-status.d.ts +13 -0
- package/dist/src/core/git-status.js +32 -2
- package/dist/src/core/git.d.ts +10 -1
- package/dist/src/core/git.js +63 -6
- package/dist/src/core/license-headers.js +0 -1
- package/dist/src/core/lint-cache.js +0 -1
- package/dist/src/core/lint-projection.js +0 -1
- package/dist/src/core/mach-build-artifacts.js +0 -1
- package/dist/src/core/mach-error-hints.js +0 -1
- package/dist/src/core/mach-known-noise-filter.d.ts +60 -0
- package/dist/src/core/mach-known-noise-filter.js +193 -0
- package/dist/src/core/mach-mozconfig.js +0 -1
- package/dist/src/core/mach-python.js +0 -1
- package/dist/src/core/mach-resource-shim.js +0 -1
- package/dist/src/core/mach.d.ts +8 -0
- package/dist/src/core/mach.js +36 -4
- package/dist/src/core/manifest-helpers.js +0 -1
- package/dist/src/core/manifest-register.js +0 -1
- package/dist/src/core/manifest-rules.js +0 -1
- package/dist/src/core/manifest-tokenizers.js +0 -1
- package/dist/src/core/marionette-port.d.ts +8 -0
- package/dist/src/core/marionette-port.js +34 -3
- package/dist/src/core/marionette-preflight.js +0 -1
- package/dist/src/core/markdown-table.js +0 -1
- package/dist/src/core/ownership-table.js +2 -9
- package/dist/src/core/parser-fallback.js +0 -1
- package/dist/src/core/patch-apply-fuzz.d.ts +27 -9
- package/dist/src/core/patch-apply-fuzz.js +71 -34
- package/dist/src/core/patch-apply.d.ts +30 -0
- package/dist/src/core/patch-apply.js +101 -18
- package/dist/src/core/patch-artifact-normalize.d.ts +18 -5
- package/dist/src/core/patch-artifact-normalize.js +19 -15
- package/dist/src/core/patch-export-coverage.js +0 -1
- package/dist/src/core/patch-export-metadata.js +0 -1
- package/dist/src/core/patch-export-update.js +2 -3
- package/dist/src/core/patch-export.d.ts +2 -6
- package/dist/src/core/patch-export.js +24 -48
- package/dist/src/core/patch-files.js +0 -1
- package/dist/src/core/patch-identifier-suggest.js +0 -1
- package/dist/src/core/patch-lint-checkjs.js +0 -1
- package/dist/src/core/patch-lint-chrome-jsdoc.js +0 -1
- package/dist/src/core/patch-lint-cross.js +80 -3
- package/dist/src/core/patch-lint-css.js +0 -1
- package/dist/src/core/patch-lint-diff-tag.js +0 -1
- package/dist/src/core/patch-lint-diff.d.ts +2 -1
- package/dist/src/core/patch-lint-diff.js +17 -32
- package/dist/src/core/patch-lint-imports.js +0 -1
- package/dist/src/core/patch-lint-jsdoc.js +0 -1
- package/dist/src/core/patch-lint-observer.js +0 -1
- package/dist/src/core/patch-lint-ownership.js +0 -1
- package/dist/src/core/patch-lint-reexports.js +0 -1
- package/dist/src/core/patch-lint.d.ts +37 -2
- package/dist/src/core/patch-lint.js +47 -34
- package/dist/src/core/patch-lock.js +0 -1
- package/dist/src/core/patch-manifest-consistency.js +9 -1
- package/dist/src/core/patch-manifest-io.d.ts +19 -2
- package/dist/src/core/patch-manifest-io.js +57 -21
- package/dist/src/core/patch-manifest-query.js +18 -10
- package/dist/src/core/patch-manifest-resolve.js +0 -1
- package/dist/src/core/patch-manifest-validate.js +24 -1
- package/dist/src/core/patch-manifest.d.ts +1 -1
- package/dist/src/core/patch-manifest.js +1 -2
- package/dist/src/core/patch-parse.d.ts +59 -0
- package/dist/src/core/patch-parse.js +209 -92
- package/dist/src/core/patch-policy.js +0 -1
- package/dist/src/core/patch-registration-refs.js +16 -26
- package/dist/src/core/patch-source-metadata.js +0 -1
- package/dist/src/core/patch-transform.d.ts +4 -0
- package/dist/src/core/patch-transform.js +30 -38
- package/dist/src/core/rebase-session.js +0 -1
- package/dist/src/core/register-browser-content.js +0 -1
- package/dist/src/core/register-module.js +0 -1
- package/dist/src/core/register-result.js +0 -1
- package/dist/src/core/register-scaffold.js +0 -1
- package/dist/src/core/register-shared-css.js +0 -1
- package/dist/src/core/register-test-manifest.js +0 -1
- package/dist/src/core/register-xpcshell-test.js +0 -1
- package/dist/src/core/shared-ftl.js +0 -1
- package/dist/src/core/signal-critical.js +0 -1
- package/dist/src/core/smoke-patterns.js +0 -1
- package/dist/src/core/state-file.js +0 -1
- package/dist/src/core/status-classify.d.ts +16 -0
- package/dist/src/core/status-classify.js +24 -16
- package/dist/src/core/test-harness-crash.d.ts +80 -7
- package/dist/src/core/test-harness-crash.js +251 -15
- package/dist/src/core/test-harness-output.js +0 -1
- package/dist/src/core/test-path-scope.d.ts +21 -13
- package/dist/src/core/test-path-scope.js +43 -28
- package/dist/src/core/test-stale-check.d.ts +29 -1
- package/dist/src/core/test-stale-check.js +59 -1
- package/dist/src/core/test-stale-symlink.js +0 -1
- package/dist/src/core/test-xpcshell-retry.js +0 -1
- package/dist/src/core/token-coverage.js +0 -1
- package/dist/src/core/token-dark-mode.js +0 -1
- package/dist/src/core/token-docs.js +0 -1
- package/dist/src/core/token-manager.js +0 -1
- package/dist/src/core/token-scaffold.js +0 -1
- package/dist/src/core/token-variant.js +0 -1
- package/dist/src/core/toolchain-preflight.d.ts +31 -10
- package/dist/src/core/toolchain-preflight.js +97 -36
- package/dist/src/core/typecheck-shim.js +13 -1
- package/dist/src/core/typecheck.js +0 -1
- package/dist/src/core/wire-destroy.js +0 -1
- package/dist/src/core/wire-dom-fragment.js +0 -1
- package/dist/src/core/wire-init.js +0 -1
- package/dist/src/core/wire-subscript.js +0 -1
- package/dist/src/core/wire-targets.js +0 -1
- package/dist/src/core/wire-utils.js +0 -1
- package/dist/src/core/xpcshell-appdir.js +1 -4
- package/dist/src/errors/base.d.ts +29 -0
- package/dist/src/errors/base.js +35 -1
- package/dist/src/errors/build.js +0 -1
- package/dist/src/errors/codes.d.ts +6 -0
- package/dist/src/errors/codes.js +6 -1
- package/dist/src/errors/config.js +0 -1
- package/dist/src/errors/download.js +0 -1
- package/dist/src/errors/furnace.d.ts +11 -1
- package/dist/src/errors/furnace.js +6 -5
- package/dist/src/errors/git.js +0 -1
- package/dist/src/errors/patch.d.ts +17 -0
- package/dist/src/errors/patch.js +29 -1
- package/dist/src/errors/rebase.js +0 -1
- package/dist/src/errors/run.js +1 -1
- package/dist/src/index.js +0 -1
- package/dist/src/types/cli.js +0 -1
- package/dist/src/types/commands/index.d.ts +1 -1
- package/dist/src/types/commands/index.js +0 -1
- package/dist/src/types/commands/options.d.ts +40 -9
- package/dist/src/types/commands/options.js +0 -1
- package/dist/src/types/commands/patches.d.ts +37 -0
- package/dist/src/types/commands/patches.js +0 -1
- package/dist/src/types/commands/project.d.ts +11 -2
- package/dist/src/types/commands/project.js +0 -1
- package/dist/src/types/config.d.ts +32 -0
- package/dist/src/types/config.js +0 -1
- package/dist/src/types/furnace.d.ts +23 -0
- package/dist/src/types/furnace.js +0 -1
- package/dist/src/types/index.js +0 -1
- package/dist/src/types/typecheck.js +0 -1
- package/dist/src/utils/elapsed.js +0 -1
- package/dist/src/utils/errors.js +0 -1
- package/dist/src/utils/fs.js +37 -5
- package/dist/src/utils/logger.d.ts +7 -0
- package/dist/src/utils/logger.js +85 -3
- package/dist/src/utils/options.d.ts +15 -0
- package/dist/src/utils/options.js +25 -1
- package/dist/src/utils/package-root.js +11 -4
- package/dist/src/utils/parse.js +0 -1
- package/dist/src/utils/paths.js +0 -1
- package/dist/src/utils/platform.js +0 -1
- package/dist/src/utils/process-group.d.ts +33 -0
- package/dist/src/utils/process-group.js +161 -0
- package/dist/src/utils/process.d.ts +48 -4
- package/dist/src/utils/process.js +258 -59
- package/dist/src/utils/regex.d.ts +13 -3
- package/dist/src/utils/regex.js +53 -4
- package/dist/src/utils/validation.d.ts +0 -12
- package/dist/src/utils/validation.js +13 -26
- package/package.json +9 -8
|
@@ -5,7 +5,7 @@ import { pathExists, readText, writeText } from '../utils/fs.js';
|
|
|
5
5
|
import { warn } from '../utils/logger.js';
|
|
6
6
|
import { withPatchDirectoryLock } from './patch-apply.js';
|
|
7
7
|
import { normalizePatchArtifact } from './patch-artifact-normalize.js';
|
|
8
|
-
import {
|
|
8
|
+
import { loadPatchesManifestForWrite, mutatePatchRowsInManifest } from './patch-manifest.js';
|
|
9
9
|
import { buildProjectedManifest, enforcePatchPolicy } from './patch-policy.js';
|
|
10
10
|
/**
|
|
11
11
|
* Updates a patch file body and its manifest row under the same patch
|
|
@@ -14,7 +14,7 @@ import { buildProjectedManifest, enforcePatchPolicy } from './patch-policy.js';
|
|
|
14
14
|
*/
|
|
15
15
|
export async function updatePatchAndMetadata(patchesDir, filename, newContent, updates, onCommitted, policyGate) {
|
|
16
16
|
await withPatchDirectoryLock(patchesDir, async () => {
|
|
17
|
-
const manifest = await
|
|
17
|
+
const manifest = await loadPatchesManifestForWrite(patchesDir);
|
|
18
18
|
if (!manifest) {
|
|
19
19
|
throw new Error('Cannot update patch metadata: patches.json is missing.');
|
|
20
20
|
}
|
|
@@ -65,4 +65,3 @@ export async function updatePatchAndMetadata(patchesDir, filename, newContent, u
|
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
|
-
//# sourceMappingURL=patch-export-update.js.map
|
|
@@ -30,6 +30,8 @@ export declare function sanitizeName(name: string): string;
|
|
|
30
30
|
* double-prefix incident) also collapses. Exported for direct testing.
|
|
31
31
|
*/
|
|
32
32
|
export declare function stripRedundantCategoryPrefix(sanitizedName: string, category: string): string;
|
|
33
|
+
/** Sanitizes a patch name and drops redundant category/full-stem prefixes. */
|
|
34
|
+
export declare function patchNameSlug(name: string, category: string): string;
|
|
33
35
|
/**
|
|
34
36
|
* Generates the next patch filename with category.
|
|
35
37
|
* @param patchesDir - Path to the patches directory
|
|
@@ -99,12 +101,6 @@ export declare function findExistingPatchForFile(patchesDir: string, filePath: s
|
|
|
99
101
|
* @param newContent - New patch content
|
|
100
102
|
*/
|
|
101
103
|
export declare function updatePatch(patchPath: string, newContent: string): Promise<void>;
|
|
102
|
-
/**
|
|
103
|
-
* Deletes a patch file and removes it from the manifest.
|
|
104
|
-
* @param patchesDir - Path to the patches directory
|
|
105
|
-
* @param filename - Patch filename to delete
|
|
106
|
-
*/
|
|
107
|
-
export declare function deletePatch(patchesDir: string, filename: string): Promise<void>;
|
|
108
104
|
/**
|
|
109
105
|
* Fully computed plan for a pending export. Returned from
|
|
110
106
|
* {@link planExport} so that `--dry-run` previews can render the full
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
-
import { unlink } from 'node:fs/promises';
|
|
3
2
|
import { join } from 'node:path';
|
|
4
3
|
import { toError } from '../utils/errors.js';
|
|
5
4
|
import { pathExists, readText, removeFile, writeText } from '../utils/fs.js';
|
|
@@ -8,7 +7,7 @@ import { PATCH_CATEGORIES } from '../utils/validation.js';
|
|
|
8
7
|
import { discoverPatches, withPatchDirectoryLock } from './patch-apply.js';
|
|
9
8
|
import { normalizePatchArtifact } from './patch-artifact-normalize.js';
|
|
10
9
|
import { findAllPatchesForFilesWithDetails, } from './patch-export-coverage.js';
|
|
11
|
-
import { addPatchToManifest,
|
|
10
|
+
import { addPatchToManifest, loadPatchesManifestForWrite, PATCHES_MANIFEST, savePatchesManifest, } from './patch-manifest.js';
|
|
12
11
|
import { allocatePolicyOrder, enforcePatchPolicy } from './patch-policy.js';
|
|
13
12
|
export { findAllPatchesForFiles, findAllPatchesForFilesWithDetails, findSupersededPatches, isPatchFullyCovered, } from './patch-export-coverage.js';
|
|
14
13
|
export { mutatePatchMetadata, updatePatchMetadata, } from './patch-export-metadata.js';
|
|
@@ -46,6 +45,9 @@ export function sanitizeName(name) {
|
|
|
46
45
|
.replace(/^-+|-+$/g, '')
|
|
47
46
|
.slice(0, 50);
|
|
48
47
|
}
|
|
48
|
+
function escapeRegExp(value) {
|
|
49
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
50
|
+
}
|
|
49
51
|
/**
|
|
50
52
|
* Strips a leading `NNN-<category>-` prefix from a sanitized name slug.
|
|
51
53
|
* Operators frequently pass the DESIRED FILENAME stem to `--name`
|
|
@@ -56,15 +58,25 @@ export function sanitizeName(name) {
|
|
|
56
58
|
* double-prefix incident) also collapses. Exported for direct testing.
|
|
57
59
|
*/
|
|
58
60
|
export function stripRedundantCategoryPrefix(sanitizedName, category) {
|
|
59
|
-
const
|
|
61
|
+
const prefixes = [
|
|
62
|
+
new RegExp(`^\\d+-${escapeRegExp(category)}-`),
|
|
63
|
+
new RegExp(`^${escapeRegExp(category)}-`),
|
|
64
|
+
];
|
|
60
65
|
let stripped = sanitizedName;
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
let changed = true;
|
|
67
|
+
while (changed) {
|
|
68
|
+
changed = false;
|
|
69
|
+
for (const prefix of prefixes) {
|
|
70
|
+
if (prefix.test(stripped)) {
|
|
71
|
+
stripped = stripped.replace(prefix, '');
|
|
72
|
+
changed = true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
63
75
|
}
|
|
64
76
|
return stripped.length > 0 ? stripped : sanitizedName;
|
|
65
77
|
}
|
|
66
|
-
/** Sanitizes a patch name and drops
|
|
67
|
-
function patchNameSlug(name, category) {
|
|
78
|
+
/** Sanitizes a patch name and drops redundant category/full-stem prefixes. */
|
|
79
|
+
export function patchNameSlug(name, category) {
|
|
68
80
|
return stripRedundantCategoryPrefix(sanitizeName(name), category);
|
|
69
81
|
}
|
|
70
82
|
/**
|
|
@@ -221,45 +233,6 @@ export async function findExistingPatchForFile(patchesDir, filePath) {
|
|
|
221
233
|
export async function updatePatch(patchPath, newContent) {
|
|
222
234
|
await writeText(patchPath, normalizePatchArtifact(newContent));
|
|
223
235
|
}
|
|
224
|
-
/**
|
|
225
|
-
* Deletes a patch file and removes it from the manifest.
|
|
226
|
-
* @param patchesDir - Path to the patches directory
|
|
227
|
-
* @param filename - Patch filename to delete
|
|
228
|
-
*/
|
|
229
|
-
export async function deletePatch(patchesDir, filename) {
|
|
230
|
-
await withPatchDirectoryLock(patchesDir, async () => {
|
|
231
|
-
const patchPath = join(patchesDir, filename);
|
|
232
|
-
const manifest = await loadPatchesManifest(patchesDir);
|
|
233
|
-
const updatedManifest = manifest
|
|
234
|
-
? {
|
|
235
|
-
...manifest,
|
|
236
|
-
patches: manifest.patches.filter((patch) => patch.filename !== filename),
|
|
237
|
-
}
|
|
238
|
-
: null;
|
|
239
|
-
// Update manifest first so interrupted deletions leave an explicit repairable
|
|
240
|
-
// extra patch file rather than silently dropping metadata for an absent file.
|
|
241
|
-
if (updatedManifest) {
|
|
242
|
-
await savePatchesManifest(patchesDir, updatedManifest);
|
|
243
|
-
}
|
|
244
|
-
if (!(await pathExists(patchPath))) {
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
try {
|
|
248
|
-
await unlink(patchPath);
|
|
249
|
-
}
|
|
250
|
-
catch (error) {
|
|
251
|
-
if (manifest) {
|
|
252
|
-
try {
|
|
253
|
-
await savePatchesManifest(patchesDir, manifest);
|
|
254
|
-
}
|
|
255
|
-
catch (error) {
|
|
256
|
-
warn(`Failed to restore manifest after patch deletion error for "${filename}": ${toError(error).message}`);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
throw error;
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
236
|
/**
|
|
264
237
|
* Internal planning helper. Does NOT take the patch directory lock — the
|
|
265
238
|
* caller must already hold it — because the two public entry points
|
|
@@ -269,7 +242,11 @@ export async function deletePatch(patchesDir, filename) {
|
|
|
269
242
|
* instead of by parallel implementations that can drift.
|
|
270
243
|
*/
|
|
271
244
|
async function computeExportPlanUnderLock(input) {
|
|
272
|
-
|
|
245
|
+
// ForWrite: a corrupt manifest read as null here would produce a
|
|
246
|
+
// manifestAfter containing ONLY the new patch — committing that plan
|
|
247
|
+
// wipes the queue metadata, and the rollback path would then delete
|
|
248
|
+
// patches.json entirely because manifestBefore looked absent.
|
|
249
|
+
const manifestBefore = await loadPatchesManifestForWrite(input.patchesDir);
|
|
273
250
|
const policyOrder = input.config !== undefined
|
|
274
251
|
? allocatePolicyOrder(input.config, manifestBefore?.patches ?? [], input.category)
|
|
275
252
|
: null;
|
|
@@ -341,4 +318,3 @@ export async function planExport(input) {
|
|
|
341
318
|
};
|
|
342
319
|
});
|
|
343
320
|
}
|
|
344
|
-
//# sourceMappingURL=patch-export.js.map
|
|
@@ -343,6 +343,14 @@ function findMatchingStagedDependency(entry, sitePath, specifier, laterOwners) {
|
|
|
343
343
|
laterOwners.some((owner) => owner.fullPath === dependency.creates &&
|
|
344
344
|
(dependency.owner === undefined || dependency.owner === owner.filename)));
|
|
345
345
|
}
|
|
346
|
+
/**
|
|
347
|
+
* Later-in-apply-order predicate shared by the forward-import scan and the
|
|
348
|
+
* registration validation: strictly higher ordinal, or same ordinal with a
|
|
349
|
+
* lexicographically later filename (the apply loop's tiebreak).
|
|
350
|
+
*/
|
|
351
|
+
function isLaterOwner(owner, entry) {
|
|
352
|
+
return (owner.order > entry.order || (owner.order === entry.order && owner.filename > entry.filename));
|
|
353
|
+
}
|
|
346
354
|
/** Builds the basename → later-creators index used by the forward-import scan. */
|
|
347
355
|
function buildNewFileIndex(ctx) {
|
|
348
356
|
const newFileIndex = new Map();
|
|
@@ -382,8 +390,7 @@ function eachForwardImportSite(ctx, newFileIndex, visit) {
|
|
|
382
390
|
const owners = newFileIndex.get(leaf);
|
|
383
391
|
if (!owners)
|
|
384
392
|
continue;
|
|
385
|
-
const laterOwners = owners.filter((owner) => owner
|
|
386
|
-
(owner.order === entry.order && owner.filename > entry.filename));
|
|
393
|
+
const laterOwners = owners.filter((owner) => isLaterOwner(owner, entry));
|
|
387
394
|
if (laterOwners.length === 0)
|
|
388
395
|
continue;
|
|
389
396
|
visit(entry, sitePath, specifier, cleaned, laterOwners);
|
|
@@ -477,9 +484,80 @@ export function lintPatchQueueForwardImports(ctx) {
|
|
|
477
484
|
severity: 'warning',
|
|
478
485
|
});
|
|
479
486
|
}
|
|
487
|
+
// Registration-kind declarations (0.37.0 item 5): a jar.mn packaging
|
|
488
|
+
// line, customElements registration, or actor registration referencing
|
|
489
|
+
// a later-created file. There is no import specifier to match — the
|
|
490
|
+
// declaration is "used" when the declared line (whitespace-trimmed)
|
|
491
|
+
// appears among the lines this patch adds to the declaring file AND
|
|
492
|
+
// its `creates` resolves to a file a later-ordered patch actually
|
|
493
|
+
// creates (with `owner`, when set, naming that patch) — mirroring
|
|
494
|
+
// findMatchingStagedDependency for the import kind.
|
|
495
|
+
for (const registration of entry.metadata?.stagedDependencies?.registrations ?? []) {
|
|
496
|
+
const failure = findStagedRegistrationFailure(entry, registration, newFileIndex);
|
|
497
|
+
if (failure === undefined)
|
|
498
|
+
continue;
|
|
499
|
+
issues.push({
|
|
500
|
+
file: registration.file,
|
|
501
|
+
check: 'staged-dependency-unused',
|
|
502
|
+
fingerprint: `staged-dependency-unused|${entry.filename}|${registration.file}|reg:${registration.line}|${registration.creates}|${registration.owner ?? ''}`,
|
|
503
|
+
message: `${entry.filename} declares a staged registration in ${registration.file} ` +
|
|
504
|
+
`("${registration.line}") for ${registration.creates}, but ${describeRegistrationFailure(failure)} ` +
|
|
505
|
+
'Remove the stale declaration with "fireforge patch staged-dependency --remove --kind registration" or update it to match the patch and queue.',
|
|
506
|
+
severity: 'warning',
|
|
507
|
+
});
|
|
508
|
+
}
|
|
480
509
|
}
|
|
481
510
|
return issues;
|
|
482
511
|
}
|
|
512
|
+
/**
|
|
513
|
+
* Validates one registration-kind declaration against the patch content
|
|
514
|
+
* and the queue, mirroring {@link findMatchingStagedDependency}: the
|
|
515
|
+
* declared line must be added by this patch, `creates` must exactly match
|
|
516
|
+
* a file a LATER-ordered patch creates (an earlier-only creator means the
|
|
517
|
+
* dependency is already satisfied and the declaration is stale), and
|
|
518
|
+
* `owner`, when set, must name one of those creating patches. Returns
|
|
519
|
+
* undefined when valid.
|
|
520
|
+
*/
|
|
521
|
+
function findStagedRegistrationFailure(entry, registration, newFileIndex) {
|
|
522
|
+
if (!isRegistrationLinePresent(entry, registration))
|
|
523
|
+
return { kind: 'line-absent' };
|
|
524
|
+
const creators = (newFileIndex.get(basename(registration.creates)) ?? []).filter((owner) => owner.fullPath === registration.creates && isLaterOwner(owner, entry));
|
|
525
|
+
if (creators.length === 0)
|
|
526
|
+
return { kind: 'creates-unresolved' };
|
|
527
|
+
if (registration.owner !== undefined &&
|
|
528
|
+
!creators.some((owner) => owner.filename === registration.owner)) {
|
|
529
|
+
return { kind: 'owner-mismatch', creators };
|
|
530
|
+
}
|
|
531
|
+
return undefined;
|
|
532
|
+
}
|
|
533
|
+
/** Message tail for each {@link StagedRegistrationFailure} shape. */
|
|
534
|
+
function describeRegistrationFailure(failure) {
|
|
535
|
+
switch (failure.kind) {
|
|
536
|
+
case 'line-absent':
|
|
537
|
+
return 'the patch does not add that line.';
|
|
538
|
+
case 'creates-unresolved':
|
|
539
|
+
return ('no later-ordered patch creates that file — the declaration is stale, ' +
|
|
540
|
+
'or the queue order no longer stages it.');
|
|
541
|
+
case 'owner-mismatch':
|
|
542
|
+
return `that file is created by ${failure.creators.map((o) => o.filename).join(', ')}, not the declared owner.`;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* True when the declared registration/packaging line appears (trimmed)
|
|
547
|
+
* among the lines the patch introduces in the declaring file — either as a
|
|
548
|
+
* newly-created file's content or as added lines to an existing file
|
|
549
|
+
* (where jar.mn / customElements.js / actor-registration edits land).
|
|
550
|
+
*/
|
|
551
|
+
function isRegistrationLinePresent(entry, registration) {
|
|
552
|
+
const declared = registration.line.trim();
|
|
553
|
+
if (declared.length === 0)
|
|
554
|
+
return false;
|
|
555
|
+
const introduced = [
|
|
556
|
+
entry.newFiles.get(registration.file),
|
|
557
|
+
entry.modifiedFileAdditions.get(registration.file),
|
|
558
|
+
];
|
|
559
|
+
return introduced.some((content) => content !== undefined && content.split('\n').some((line) => line.trim() === declared));
|
|
560
|
+
}
|
|
483
561
|
/**
|
|
484
562
|
* Cross-patch lint orchestrator. Runs every cross-patch rule against the
|
|
485
563
|
* provided context and returns combined issues.
|
|
@@ -495,4 +573,3 @@ export function lintPatchQueueForwardImports(ctx) {
|
|
|
495
573
|
export function lintPatchQueue(ctx) {
|
|
496
574
|
return [...lintPatchQueueDuplicateCreations(ctx), ...lintPatchQueueForwardImports(ctx)];
|
|
497
575
|
}
|
|
498
|
-
//# sourceMappingURL=patch-lint-cross.js.map
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* cross-patch lint body (in `patch-lint-cross.ts`) can both depend on
|
|
7
7
|
* the same diff walkers without inducing a circular import. Callers
|
|
8
8
|
* should keep importing these through `patch-lint.ts` — this file is
|
|
9
|
-
* an implementation detail.
|
|
9
|
+
* an implementation detail. The actual line-walking lives in
|
|
10
|
+
* `parseDiffSections` (patch-parse.ts), the codebase's single diff walker.
|
|
10
11
|
*/
|
|
11
12
|
/**
|
|
12
13
|
* Extracts new-file paths from a unified diff by scanning for `new file mode` markers.
|
|
@@ -7,23 +7,18 @@
|
|
|
7
7
|
* cross-patch lint body (in `patch-lint-cross.ts`) can both depend on
|
|
8
8
|
* the same diff walkers without inducing a circular import. Callers
|
|
9
9
|
* should keep importing these through `patch-lint.ts` — this file is
|
|
10
|
-
* an implementation detail.
|
|
10
|
+
* an implementation detail. The actual line-walking lives in
|
|
11
|
+
* `parseDiffSections` (patch-parse.ts), the codebase's single diff walker.
|
|
11
12
|
*/
|
|
13
|
+
import { parseDiffSections } from './patch-parse.js';
|
|
12
14
|
/**
|
|
13
15
|
* Extracts new-file paths from a unified diff by scanning for `new file mode` markers.
|
|
14
16
|
*/
|
|
15
17
|
export function detectNewFilesInDiff(diffContent) {
|
|
16
18
|
const newFiles = new Set();
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (line.startsWith('diff --git')) {
|
|
21
|
-
const match = /^diff --git a\/.+ b\/(.+)$/.exec(line);
|
|
22
|
-
currentFile = match?.[1] ?? null;
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
if (line.startsWith('new file mode') && currentFile) {
|
|
26
|
-
newFiles.add(currentFile);
|
|
19
|
+
for (const section of parseDiffSections(diffContent)) {
|
|
20
|
+
if (section.isNewFile) {
|
|
21
|
+
newFiles.add(section.targetPath);
|
|
27
22
|
}
|
|
28
23
|
}
|
|
29
24
|
return newFiles;
|
|
@@ -34,27 +29,18 @@ export function detectNewFilesInDiff(diffContent) {
|
|
|
34
29
|
*/
|
|
35
30
|
export function extractAddedLinesPerFile(diffContent) {
|
|
36
31
|
const result = new Map();
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
inHunk = true;
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
if (inHunk && currentFile && line.startsWith('+') && !line.startsWith('+++')) {
|
|
52
|
-
let arr = result.get(currentFile);
|
|
53
|
-
if (!arr) {
|
|
54
|
-
arr = [];
|
|
55
|
-
result.set(currentFile, arr);
|
|
32
|
+
for (const section of parseDiffSections(diffContent)) {
|
|
33
|
+
for (const hunk of section.hunks) {
|
|
34
|
+
for (const line of hunk.lines) {
|
|
35
|
+
if (!line.startsWith('+'))
|
|
36
|
+
continue;
|
|
37
|
+
let arr = result.get(section.targetPath);
|
|
38
|
+
if (!arr) {
|
|
39
|
+
arr = [];
|
|
40
|
+
result.set(section.targetPath, arr);
|
|
41
|
+
}
|
|
42
|
+
arr.push(line.slice(1));
|
|
56
43
|
}
|
|
57
|
-
arr.push(line.slice(1));
|
|
58
44
|
}
|
|
59
45
|
}
|
|
60
46
|
return result;
|
|
@@ -81,4 +67,3 @@ export function buildModifiedFileAdditionsFromDiff(diff) {
|
|
|
81
67
|
}
|
|
82
68
|
return result;
|
|
83
69
|
}
|
|
84
|
-
//# sourceMappingURL=patch-lint-diff.js.map
|
|
@@ -67,4 +67,3 @@ export function resolvePatchOwnedSysMjs(currentNewFiles, patchQueueCtx) {
|
|
|
67
67
|
export function resolvePatchOwnedChromeScripts(currentNewFiles, patchQueueCtx) {
|
|
68
68
|
return resolveOwned(currentNewFiles, patchQueueCtx, (file) => file.endsWith('.js') && !file.endsWith('.sys.mjs'));
|
|
69
69
|
}
|
|
70
|
-
//# sourceMappingURL=patch-lint-ownership.js.map
|
|
@@ -5,4 +5,3 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { buildPatchQueueContext, collectForwardImportEdges, collectNewFileCreatorsByPath, extractImportSpecifiers, extractImportSpecifiersWithLines, findForwardImportIgnoreLines, FORWARD_IMPORT_IGNORE_MARKER, isForwardImportableFile, lintPatchQueue, lintPatchQueueDuplicateCreations, lintPatchQueueForwardImports, } from './patch-lint-cross.js';
|
|
7
7
|
export { buildModifiedFileAdditionsFromDiff, detectNewFilesInDiff } from './patch-lint-diff.js';
|
|
8
|
-
//# sourceMappingURL=patch-lint-reexports.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PatchLintIssue } from '../types/commands/index.js';
|
|
2
|
-
import type { FireForgeConfig } from '../types/config.js';
|
|
2
|
+
import type { FireForgeConfig, ProjectLicense } from '../types/config.js';
|
|
3
3
|
import { type CommentStyle } from './license-headers.js';
|
|
4
4
|
import { lintPatchedCss } from './patch-lint-css.js';
|
|
5
5
|
export * from './patch-lint-reexports.js';
|
|
@@ -26,7 +26,42 @@ export declare function isTestFile(file: string): boolean;
|
|
|
26
26
|
*/
|
|
27
27
|
export declare function commentStyleForFile(file: string): CommentStyle | null;
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* Decides whether a NEW file's leading header satisfies the
|
|
30
|
+
* `missing-license-header` rule. Single owner of the acceptance policy —
|
|
31
|
+
* `lintNewFileHeaders` (the rule) and `autoFixLicenseHeaders` (the
|
|
32
|
+
* interactive export fixer) must agree, or the fixer offers to stack a
|
|
33
|
+
* second header onto a file the lint already accepts.
|
|
34
|
+
*
|
|
35
|
+
* Accepted shapes, in order:
|
|
36
|
+
* - the project's own header for the file's comment style;
|
|
37
|
+
* - under `browser/branding/`, ANY recognised license header in the
|
|
38
|
+
* matching style: the setup-generated branding directory is copied
|
|
39
|
+
* from Firefox's `unofficial` template and arrives with Mozilla
|
|
40
|
+
* MPL-2.0 headers — legitimate for copyright purposes (the assets are
|
|
41
|
+
* Mozilla's) even when the fork's own code is 0BSD / EUPL-1.2 /
|
|
42
|
+
* GPL-2.0-or-later;
|
|
43
|
+
* - on an MPL-2.0 project, any recognised header in the matching style;
|
|
44
|
+
* - the verbatim upstream MPL-2.0 block header (`/* … *\/`, optionally
|
|
45
|
+
* behind a leading editor-directive comment) REGARDLESS of the
|
|
46
|
+
* project license, on any file whose comment syntax is the block form
|
|
47
|
+
* (JS and CSS): a file copied from the Firefox tree legitimately
|
|
48
|
+
* keeps Mozilla's header for provenance in an EUPL/GPL/0BSD project
|
|
49
|
+
* too. 0.35.0 accepted this on JS only; field verification showed a
|
|
50
|
+
* derived CSS file carrying the identical three-line block header
|
|
51
|
+
* still needed a patch-level lintIgnore. Only the block form is
|
|
52
|
+
* accepted — the `// `-style MPL header is FireForge-generated, not
|
|
53
|
+
* upstream provenance — and `hash`-style files (FTL) stay excluded
|
|
54
|
+
* because `/* … *\/` is not a comment there.
|
|
55
|
+
*
|
|
56
|
+
* @param file - Engine-relative path of the new file
|
|
57
|
+
* @param content - File content
|
|
58
|
+
* @param style - Comment style resolved for the file
|
|
59
|
+
* @param license - The project license
|
|
60
|
+
*/
|
|
61
|
+
export declare function isAcceptableNewFileHeader(file: string, content: string, style: CommentStyle, license: ProjectLicense): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Checks new files for required license headers (acceptance policy in
|
|
64
|
+
* {@link isAcceptableNewFileHeader}).
|
|
30
65
|
*
|
|
31
66
|
* @param repoDir - Absolute path to the engine directory
|
|
32
67
|
* @param newFiles - New file paths (relative to repoDir)
|
|
@@ -211,7 +211,52 @@ export function commentStyleForFile(file) {
|
|
|
211
211
|
// License header lint
|
|
212
212
|
// ---------------------------------------------------------------------------
|
|
213
213
|
/**
|
|
214
|
-
*
|
|
214
|
+
* Decides whether a NEW file's leading header satisfies the
|
|
215
|
+
* `missing-license-header` rule. Single owner of the acceptance policy —
|
|
216
|
+
* `lintNewFileHeaders` (the rule) and `autoFixLicenseHeaders` (the
|
|
217
|
+
* interactive export fixer) must agree, or the fixer offers to stack a
|
|
218
|
+
* second header onto a file the lint already accepts.
|
|
219
|
+
*
|
|
220
|
+
* Accepted shapes, in order:
|
|
221
|
+
* - the project's own header for the file's comment style;
|
|
222
|
+
* - under `browser/branding/`, ANY recognised license header in the
|
|
223
|
+
* matching style: the setup-generated branding directory is copied
|
|
224
|
+
* from Firefox's `unofficial` template and arrives with Mozilla
|
|
225
|
+
* MPL-2.0 headers — legitimate for copyright purposes (the assets are
|
|
226
|
+
* Mozilla's) even when the fork's own code is 0BSD / EUPL-1.2 /
|
|
227
|
+
* GPL-2.0-or-later;
|
|
228
|
+
* - on an MPL-2.0 project, any recognised header in the matching style;
|
|
229
|
+
* - the verbatim upstream MPL-2.0 block header (`/* … *\/`, optionally
|
|
230
|
+
* behind a leading editor-directive comment) REGARDLESS of the
|
|
231
|
+
* project license, on any file whose comment syntax is the block form
|
|
232
|
+
* (JS and CSS): a file copied from the Firefox tree legitimately
|
|
233
|
+
* keeps Mozilla's header for provenance in an EUPL/GPL/0BSD project
|
|
234
|
+
* too. 0.35.0 accepted this on JS only; field verification showed a
|
|
235
|
+
* derived CSS file carrying the identical three-line block header
|
|
236
|
+
* still needed a patch-level lintIgnore. Only the block form is
|
|
237
|
+
* accepted — the `// `-style MPL header is FireForge-generated, not
|
|
238
|
+
* upstream provenance — and `hash`-style files (FTL) stay excluded
|
|
239
|
+
* because `/* … *\/` is not a comment there.
|
|
240
|
+
*
|
|
241
|
+
* @param file - Engine-relative path of the new file
|
|
242
|
+
* @param content - File content
|
|
243
|
+
* @param style - Comment style resolved for the file
|
|
244
|
+
* @param license - The project license
|
|
245
|
+
*/
|
|
246
|
+
export function isAcceptableNewFileHeader(file, content, style, license) {
|
|
247
|
+
if (content.startsWith(getLicenseHeader(license, style)))
|
|
248
|
+
return true;
|
|
249
|
+
if (file.startsWith('browser/branding/') && hasAnyLicenseHeader(content, style))
|
|
250
|
+
return true;
|
|
251
|
+
if (license === 'MPL-2.0' && hasAnyLicenseHeader(content, style))
|
|
252
|
+
return true;
|
|
253
|
+
if ((style === 'js' || style === 'css') && hasUpstreamMplBlockHeader(content))
|
|
254
|
+
return true;
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Checks new files for required license headers (acceptance policy in
|
|
259
|
+
* {@link isAcceptableNewFileHeader}).
|
|
215
260
|
*
|
|
216
261
|
* @param repoDir - Absolute path to the engine directory
|
|
217
262
|
* @param newFiles - New file paths (relative to repoDir)
|
|
@@ -229,38 +274,7 @@ export async function lintNewFileHeaders(repoDir, newFiles, config) {
|
|
|
229
274
|
if (!(await pathExists(filePath)))
|
|
230
275
|
continue;
|
|
231
276
|
const content = await readText(filePath);
|
|
232
|
-
|
|
233
|
-
// Auto-exempt `browser/branding/` when the file carries ANY recognised
|
|
234
|
-
// license header in the matching comment style. The setup-generated
|
|
235
|
-
// branding directory is copied from Firefox's `unofficial` template,
|
|
236
|
-
// which arrives with Mozilla MPL-2.0 headers — those are legitimate
|
|
237
|
-
// for copyright purposes (the assets are Mozilla's) even when the
|
|
238
|
-
// fork's own code is 0BSD / EUPL-1.2 / GPL-2.0-or-later. The narrower
|
|
239
|
-
// license-match rule would force operators to either rewrite the
|
|
240
|
-
// copied headers (misrepresenting authorship) or suppress the lint
|
|
241
|
-
// with `--skip-lint` (hiding real issues elsewhere).
|
|
242
|
-
if (content.startsWith(expectedHeader))
|
|
243
|
-
continue;
|
|
244
|
-
if (file.startsWith('browser/branding/') && hasAnyLicenseHeader(content, style))
|
|
245
|
-
continue;
|
|
246
|
-
// Accept the MPL-2.0 block-comment form (`/* ... */` with leading `*`)
|
|
247
|
-
// for any JS file — that is the canonical upstream Firefox header
|
|
248
|
-
// shape, and `hasAnyLicenseHeader` above also recognises it. The
|
|
249
|
-
// explicit guard mirrors the branding carve-out so operators using the
|
|
250
|
-
// standard Mozilla header on a JS file (e.g. one copied from upstream
|
|
251
|
-
// browser/base/content) do not need `--skip-lint` to land it.
|
|
252
|
-
if (license === 'MPL-2.0' && hasAnyLicenseHeader(content, style))
|
|
253
|
-
continue;
|
|
254
|
-
// Accept the verbatim upstream MPL block header on new JS files
|
|
255
|
-
// REGARDLESS of the project license: a file copied from the Firefox
|
|
256
|
-
// tree legitimately keeps Mozilla's header for provenance in an
|
|
257
|
-
// EUPL/GPL/0BSD project too. The carve-out above is gated on the
|
|
258
|
-
// project being MPL-2.0 itself, which made this documented case dead
|
|
259
|
-
// code for every other license — consumers carried repo-side audit
|
|
260
|
-
// workarounds (recorded 2026-07-04 in the Hominis FORGE.md). Only
|
|
261
|
-
// the block-comment form is accepted; the `// `-style MPL header is
|
|
262
|
-
// FireForge-generated, not upstream provenance.
|
|
263
|
-
if (style === 'js' && hasUpstreamMplBlockHeader(content))
|
|
277
|
+
if (isAcceptableNewFileHeader(file, content, style, license))
|
|
264
278
|
continue;
|
|
265
279
|
issues.push({
|
|
266
280
|
file,
|
|
@@ -620,4 +634,3 @@ export async function lintExportedPatch(repoDir, affectedFiles, diffContent, con
|
|
|
620
634
|
}
|
|
621
635
|
return issues;
|
|
622
636
|
}
|
|
623
|
-
//# sourceMappingURL=patch-lint.js.map
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { stat } from 'node:fs/promises';
|
|
6
6
|
import { discoverPatches, getAllTargetFilesFromPatch } from './patch-files.js';
|
|
7
|
+
import { withPatchDirectoryLock } from './patch-lock.js';
|
|
7
8
|
import { loadPatchesManifestState, PATCHES_MANIFEST, savePatchesManifest, } from './patch-manifest-io.js';
|
|
8
9
|
import { inferPatchMetadataFromFilename } from './patch-manifest-validate.js';
|
|
9
10
|
/**
|
|
@@ -89,6 +90,14 @@ export async function validatePatchesManifestConsistency(patchesDir) {
|
|
|
89
90
|
* plus the filenames that were reconstructed from generic defaults.
|
|
90
91
|
*/
|
|
91
92
|
export async function rebuildPatchesManifest(patchesDir, fallbackSourceEsrVersion) {
|
|
93
|
+
// The whole read → discover → rebuild → save cycle runs under the shared
|
|
94
|
+
// patch-directory lock (invariant 2, docs/lifecycle-invariants.md):
|
|
95
|
+
// manifest writes serialize on this lock, and a repair racing a
|
|
96
|
+
// concurrent export/reorder used to be able to clobber the other
|
|
97
|
+
// writer's manifest. Not reentrant — callers must not already hold it.
|
|
98
|
+
return withPatchDirectoryLock(patchesDir, () => rebuildPatchesManifestUnderLock(patchesDir, fallbackSourceEsrVersion));
|
|
99
|
+
}
|
|
100
|
+
async function rebuildPatchesManifestUnderLock(patchesDir, fallbackSourceEsrVersion) {
|
|
92
101
|
const manifestState = await loadPatchesManifestState(patchesDir);
|
|
93
102
|
const existingEntries = new Map();
|
|
94
103
|
if (manifestState.manifest) {
|
|
@@ -162,4 +171,3 @@ function normalizeFiles(files) {
|
|
|
162
171
|
function sameStringArray(left, right) {
|
|
163
172
|
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
164
173
|
}
|
|
165
|
-
//# sourceMappingURL=patch-manifest-consistency.js.map
|
|
@@ -37,10 +37,26 @@ export interface PatchManifestRowMutationResult {
|
|
|
37
37
|
export declare function loadPatchesManifestState(patchesDir: string): Promise<LoadedManifestState>;
|
|
38
38
|
/**
|
|
39
39
|
* Loads the patches manifest if it exists.
|
|
40
|
+
*
|
|
41
|
+
* READ-ONLY callers only: this collapses "absent" and "corrupt" into null.
|
|
42
|
+
* Any code path that will WRITE the manifest (or delete patch files based
|
|
43
|
+
* on its content) must use {@link loadPatchesManifestForWrite} instead —
|
|
44
|
+
* treating a corrupt manifest as empty and then saving destroys every
|
|
45
|
+
* existing patch's metadata.
|
|
46
|
+
*
|
|
40
47
|
* @param patchesDir - Path to the patches directory
|
|
41
48
|
* @returns PatchesManifest or null if not found
|
|
42
49
|
*/
|
|
43
50
|
export declare function loadPatchesManifest(patchesDir: string): Promise<PatchesManifest | null>;
|
|
51
|
+
/**
|
|
52
|
+
* Loads the patches manifest for a mutating operation.
|
|
53
|
+
*
|
|
54
|
+
* Returns null only when the manifest genuinely does not exist; a manifest
|
|
55
|
+
* that exists but fails to parse/validate throws
|
|
56
|
+
* {@link PatchManifestCorruptError} so the caller aborts instead of
|
|
57
|
+
* rebuilding an empty queue over the top of the corrupt file.
|
|
58
|
+
*/
|
|
59
|
+
export declare function loadPatchesManifestForWrite(patchesDir: string): Promise<PatchesManifest | null>;
|
|
44
60
|
/**
|
|
45
61
|
* Saves the patches manifest.
|
|
46
62
|
* @param patchesDir - Path to the patches directory
|
|
@@ -86,8 +102,9 @@ export interface PatchRenameEntry {
|
|
|
86
102
|
newOrder: number;
|
|
87
103
|
}
|
|
88
104
|
/**
|
|
89
|
-
* Rewrites `stagedDependencies.forwardImports[].owner`
|
|
90
|
-
*
|
|
105
|
+
* Rewrites `stagedDependencies.forwardImports[].owner` and
|
|
106
|
+
* `stagedDependencies.registrations[].owner` references on one patch
|
|
107
|
+
* through a rename lookup. Owners embed exact patch filenames, so any
|
|
91
108
|
* renumber (compact, reorder, placement export, rename) that does not remap
|
|
92
109
|
* them leaves dangling references that surface as false forward-import
|
|
93
110
|
* errors on the next lint.
|