@hominis/fireforge 0.9.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 +7 -0
- package/LICENSE.md +294 -0
- package/README.md +435 -0
- package/dist/bin/fireforge.d.ts +10 -0
- package/dist/bin/fireforge.js +29 -0
- package/dist/src/cli.d.ts +33 -0
- package/dist/src/cli.js +180 -0
- package/dist/src/commands/bootstrap.d.ts +9 -0
- package/dist/src/commands/bootstrap.js +73 -0
- package/dist/src/commands/build.d.ts +11 -0
- package/dist/src/commands/build.js +102 -0
- package/dist/src/commands/config.d.ts +13 -0
- package/dist/src/commands/config.js +135 -0
- package/dist/src/commands/discard.d.ts +12 -0
- package/dist/src/commands/discard.js +84 -0
- package/dist/src/commands/doctor.d.ts +18 -0
- package/dist/src/commands/doctor.js +356 -0
- package/dist/src/commands/download.d.ts +11 -0
- package/dist/src/commands/download.js +127 -0
- package/dist/src/commands/export-all.d.ts +11 -0
- package/dist/src/commands/export-all.js +122 -0
- package/dist/src/commands/export-shared.d.ts +48 -0
- package/dist/src/commands/export-shared.js +208 -0
- package/dist/src/commands/export.d.ts +13 -0
- package/dist/src/commands/export.js +178 -0
- package/dist/src/commands/furnace/apply.d.ts +7 -0
- package/dist/src/commands/furnace/apply.js +80 -0
- package/dist/src/commands/furnace/create.d.ts +8 -0
- package/dist/src/commands/furnace/create.js +377 -0
- package/dist/src/commands/furnace/deploy.d.ts +8 -0
- package/dist/src/commands/furnace/deploy.js +338 -0
- package/dist/src/commands/furnace/diff.d.ts +7 -0
- package/dist/src/commands/furnace/diff.js +119 -0
- package/dist/src/commands/furnace/index.d.ts +16 -0
- package/dist/src/commands/furnace/index.js +121 -0
- package/dist/src/commands/furnace/list.d.ts +5 -0
- package/dist/src/commands/furnace/list.js +65 -0
- package/dist/src/commands/furnace/override.d.ts +8 -0
- package/dist/src/commands/furnace/override.js +188 -0
- package/dist/src/commands/furnace/preview.d.ts +7 -0
- package/dist/src/commands/furnace/preview.js +96 -0
- package/dist/src/commands/furnace/remove.d.ts +8 -0
- package/dist/src/commands/furnace/remove.js +159 -0
- package/dist/src/commands/furnace/scan.d.ts +5 -0
- package/dist/src/commands/furnace/scan.js +112 -0
- package/dist/src/commands/furnace/status.d.ts +7 -0
- package/dist/src/commands/furnace/status.js +137 -0
- package/dist/src/commands/furnace/validate.d.ts +6 -0
- package/dist/src/commands/furnace/validate.js +91 -0
- package/dist/src/commands/furnace/validation-output.d.ts +7 -0
- package/dist/src/commands/furnace/validation-output.js +22 -0
- package/dist/src/commands/import.d.ts +11 -0
- package/dist/src/commands/import.js +241 -0
- package/dist/src/commands/lint.d.ts +10 -0
- package/dist/src/commands/lint.js +118 -0
- package/dist/src/commands/package.d.ts +11 -0
- package/dist/src/commands/package.js +80 -0
- package/dist/src/commands/re-export.d.ts +12 -0
- package/dist/src/commands/re-export.js +242 -0
- package/dist/src/commands/rebase/abort.d.ts +7 -0
- package/dist/src/commands/rebase/abort.js +49 -0
- package/dist/src/commands/rebase/confirm.d.ts +18 -0
- package/dist/src/commands/rebase/confirm.js +33 -0
- package/dist/src/commands/rebase/continue.d.ts +7 -0
- package/dist/src/commands/rebase/continue.js +81 -0
- package/dist/src/commands/rebase/index.d.ts +22 -0
- package/dist/src/commands/rebase/index.js +127 -0
- package/dist/src/commands/rebase/patch-loop.d.ts +9 -0
- package/dist/src/commands/rebase/patch-loop.js +135 -0
- package/dist/src/commands/rebase/summary.d.ts +12 -0
- package/dist/src/commands/rebase/summary.js +43 -0
- package/dist/src/commands/rebase.d.ts +4 -0
- package/dist/src/commands/rebase.js +6 -0
- package/dist/src/commands/register.d.ts +13 -0
- package/dist/src/commands/register.js +67 -0
- package/dist/src/commands/reset.d.ts +11 -0
- package/dist/src/commands/reset.js +83 -0
- package/dist/src/commands/resolve.d.ts +9 -0
- package/dist/src/commands/resolve.js +124 -0
- package/dist/src/commands/run.d.ts +9 -0
- package/dist/src/commands/run.js +91 -0
- package/dist/src/commands/setup-support.d.ts +23 -0
- package/dist/src/commands/setup-support.js +310 -0
- package/dist/src/commands/setup.d.ts +11 -0
- package/dist/src/commands/setup.js +94 -0
- package/dist/src/commands/status.d.ts +11 -0
- package/dist/src/commands/status.js +268 -0
- package/dist/src/commands/test.d.ts +12 -0
- package/dist/src/commands/test.js +182 -0
- package/dist/src/commands/token-coverage.d.ts +5 -0
- package/dist/src/commands/token-coverage.js +57 -0
- package/dist/src/commands/token.d.ts +14 -0
- package/dist/src/commands/token.js +121 -0
- package/dist/src/commands/watch.d.ts +9 -0
- package/dist/src/commands/watch.js +112 -0
- package/dist/src/commands/wire.d.ts +13 -0
- package/dist/src/commands/wire.js +149 -0
- package/dist/src/core/ast-utils.d.ts +47 -0
- package/dist/src/core/ast-utils.js +57 -0
- package/dist/src/core/brand-validation.d.ts +7 -0
- package/dist/src/core/brand-validation.js +15 -0
- package/dist/src/core/branding.d.ts +49 -0
- package/dist/src/core/branding.js +229 -0
- package/dist/src/core/browser-wire.d.ts +40 -0
- package/dist/src/core/browser-wire.js +66 -0
- package/dist/src/core/build-prepare.d.ts +25 -0
- package/dist/src/core/build-prepare.js +93 -0
- package/dist/src/core/config-mutate.d.ts +15 -0
- package/dist/src/core/config-mutate.js +51 -0
- package/dist/src/core/config-paths.d.ts +28 -0
- package/dist/src/core/config-paths.js +65 -0
- package/dist/src/core/config-state.d.ts +28 -0
- package/dist/src/core/config-state.js +152 -0
- package/dist/src/core/config-validate.d.ts +11 -0
- package/dist/src/core/config-validate.js +141 -0
- package/dist/src/core/config.d.ts +39 -0
- package/dist/src/core/config.js +70 -0
- package/dist/src/core/file-lock.d.ts +11 -0
- package/dist/src/core/file-lock.js +80 -0
- package/dist/src/core/firefox-archive.d.ts +40 -0
- package/dist/src/core/firefox-archive.js +63 -0
- package/dist/src/core/firefox-cache.d.ts +23 -0
- package/dist/src/core/firefox-cache.js +134 -0
- package/dist/src/core/firefox-download.d.ts +21 -0
- package/dist/src/core/firefox-download.js +129 -0
- package/dist/src/core/firefox-extract.d.ts +21 -0
- package/dist/src/core/firefox-extract.js +53 -0
- package/dist/src/core/firefox.d.ts +34 -0
- package/dist/src/core/firefox.js +78 -0
- package/dist/src/core/furnace-apply-helpers.d.ts +21 -0
- package/dist/src/core/furnace-apply-helpers.js +244 -0
- package/dist/src/core/furnace-apply.d.ts +16 -0
- package/dist/src/core/furnace-apply.js +147 -0
- package/dist/src/core/furnace-config.d.ts +94 -0
- package/dist/src/core/furnace-config.js +372 -0
- package/dist/src/core/furnace-constants.d.ts +4 -0
- package/dist/src/core/furnace-constants.js +6 -0
- package/dist/src/core/furnace-registration-ast.d.ts +24 -0
- package/dist/src/core/furnace-registration-ast.js +218 -0
- package/dist/src/core/furnace-registration-remove.d.ts +14 -0
- package/dist/src/core/furnace-registration-remove.js +89 -0
- package/dist/src/core/furnace-registration-validate.d.ts +20 -0
- package/dist/src/core/furnace-registration-validate.js +40 -0
- package/dist/src/core/furnace-registration.d.ts +29 -0
- package/dist/src/core/furnace-registration.js +96 -0
- package/dist/src/core/furnace-rollback.d.ts +20 -0
- package/dist/src/core/furnace-rollback.js +66 -0
- package/dist/src/core/furnace-scanner.d.ts +40 -0
- package/dist/src/core/furnace-scanner.js +143 -0
- package/dist/src/core/furnace-stories.d.ts +37 -0
- package/dist/src/core/furnace-stories.js +185 -0
- package/dist/src/core/furnace-validate-accessibility.d.ts +6 -0
- package/dist/src/core/furnace-validate-accessibility.js +32 -0
- package/dist/src/core/furnace-validate-checks.d.ts +4 -0
- package/dist/src/core/furnace-validate-checks.js +7 -0
- package/dist/src/core/furnace-validate-compatibility.d.ts +6 -0
- package/dist/src/core/furnace-validate-compatibility.js +57 -0
- package/dist/src/core/furnace-validate-helpers.d.ts +28 -0
- package/dist/src/core/furnace-validate-helpers.js +129 -0
- package/dist/src/core/furnace-validate-registration.d.ts +37 -0
- package/dist/src/core/furnace-validate-registration.js +220 -0
- package/dist/src/core/furnace-validate-structure.d.ts +6 -0
- package/dist/src/core/furnace-validate-structure.js +66 -0
- package/dist/src/core/furnace-validate.d.ts +16 -0
- package/dist/src/core/furnace-validate.js +103 -0
- package/dist/src/core/git-base.d.ts +47 -0
- package/dist/src/core/git-base.js +50 -0
- package/dist/src/core/git-diff.d.ts +63 -0
- package/dist/src/core/git-diff.js +246 -0
- package/dist/src/core/git-file-ops.d.ts +65 -0
- package/dist/src/core/git-file-ops.js +141 -0
- package/dist/src/core/git-status.d.ts +65 -0
- package/dist/src/core/git-status.js +163 -0
- package/dist/src/core/git.d.ts +113 -0
- package/dist/src/core/git.js +363 -0
- package/dist/src/core/license-headers.d.ts +36 -0
- package/dist/src/core/license-headers.js +83 -0
- package/dist/src/core/mach-build-artifacts.d.ts +29 -0
- package/dist/src/core/mach-build-artifacts.js +117 -0
- package/dist/src/core/mach-mozconfig.d.ts +17 -0
- package/dist/src/core/mach-mozconfig.js +50 -0
- package/dist/src/core/mach-python.d.ts +16 -0
- package/dist/src/core/mach-python.js +126 -0
- package/dist/src/core/mach.d.ts +106 -0
- package/dist/src/core/mach.js +166 -0
- package/dist/src/core/manifest-helpers.d.ts +25 -0
- package/dist/src/core/manifest-helpers.js +96 -0
- package/dist/src/core/manifest-register.d.ts +30 -0
- package/dist/src/core/manifest-register.js +65 -0
- package/dist/src/core/manifest-rules.d.ts +39 -0
- package/dist/src/core/manifest-rules.js +151 -0
- package/dist/src/core/manifest-tokenizers.d.ts +34 -0
- package/dist/src/core/manifest-tokenizers.js +84 -0
- package/dist/src/core/parser-fallback.d.ts +36 -0
- package/dist/src/core/parser-fallback.js +43 -0
- package/dist/src/core/patch-apply-fuzz.d.ts +29 -0
- package/dist/src/core/patch-apply-fuzz.js +70 -0
- package/dist/src/core/patch-apply.d.ts +46 -0
- package/dist/src/core/patch-apply.js +235 -0
- package/dist/src/core/patch-export.d.ts +99 -0
- package/dist/src/core/patch-export.js +314 -0
- package/dist/src/core/patch-files.d.ts +11 -0
- package/dist/src/core/patch-files.js +51 -0
- package/dist/src/core/patch-lint.d.ts +72 -0
- package/dist/src/core/patch-lint.js +403 -0
- package/dist/src/core/patch-lock.d.ts +8 -0
- package/dist/src/core/patch-lock.js +29 -0
- package/dist/src/core/patch-manifest-consistency.d.ts +24 -0
- package/dist/src/core/patch-manifest-consistency.js +135 -0
- package/dist/src/core/patch-manifest-io.d.ts +36 -0
- package/dist/src/core/patch-manifest-io.js +77 -0
- package/dist/src/core/patch-manifest-query.d.ts +48 -0
- package/dist/src/core/patch-manifest-query.js +124 -0
- package/dist/src/core/patch-manifest-validate.d.ts +22 -0
- package/dist/src/core/patch-manifest-validate.js +72 -0
- package/dist/src/core/patch-manifest.d.ts +11 -0
- package/dist/src/core/patch-manifest.js +12 -0
- package/dist/src/core/patch-parse.d.ts +43 -0
- package/dist/src/core/patch-parse.js +143 -0
- package/dist/src/core/patch-transform.d.ts +21 -0
- package/dist/src/core/patch-transform.js +138 -0
- package/dist/src/core/rebase-session.d.ts +47 -0
- package/dist/src/core/rebase-session.js +65 -0
- package/dist/src/core/register-browser-content.d.ts +11 -0
- package/dist/src/core/register-browser-content.js +116 -0
- package/dist/src/core/register-module.d.ts +11 -0
- package/dist/src/core/register-module.js +76 -0
- package/dist/src/core/register-shared-css.d.ts +11 -0
- package/dist/src/core/register-shared-css.js +117 -0
- package/dist/src/core/register-test-manifest.d.ts +18 -0
- package/dist/src/core/register-test-manifest.js +99 -0
- package/dist/src/core/state-file.d.ts +4 -0
- package/dist/src/core/state-file.js +25 -0
- package/dist/src/core/token-coverage.d.ts +12 -0
- package/dist/src/core/token-coverage.js +74 -0
- package/dist/src/core/token-manager.d.ts +55 -0
- package/dist/src/core/token-manager.js +387 -0
- package/dist/src/core/wire-destroy.d.ts +21 -0
- package/dist/src/core/wire-destroy.js +103 -0
- package/dist/src/core/wire-dom-fragment.d.ts +23 -0
- package/dist/src/core/wire-dom-fragment.js +129 -0
- package/dist/src/core/wire-init.d.ts +23 -0
- package/dist/src/core/wire-init.js +201 -0
- package/dist/src/core/wire-subscript.d.ts +20 -0
- package/dist/src/core/wire-subscript.js +134 -0
- package/dist/src/core/wire-targets.d.ts +7 -0
- package/dist/src/core/wire-targets.js +9 -0
- package/dist/src/core/wire-utils.d.ts +88 -0
- package/dist/src/core/wire-utils.js +279 -0
- package/dist/src/errors/base.d.ts +60 -0
- package/dist/src/errors/base.js +87 -0
- package/dist/src/errors/build.d.ts +52 -0
- package/dist/src/errors/build.js +114 -0
- package/dist/src/errors/codes.d.ts +29 -0
- package/dist/src/errors/codes.js +30 -0
- package/dist/src/errors/config.d.ts +31 -0
- package/dist/src/errors/config.js +61 -0
- package/dist/src/errors/download.d.ts +42 -0
- package/dist/src/errors/download.js +95 -0
- package/dist/src/errors/furnace.d.ts +10 -0
- package/dist/src/errors/furnace.js +22 -0
- package/dist/src/errors/git.d.ts +41 -0
- package/dist/src/errors/git.js +99 -0
- package/dist/src/errors/patch.d.ts +10 -0
- package/dist/src/errors/patch.js +26 -0
- package/dist/src/errors/rebase.d.ts +20 -0
- package/dist/src/errors/rebase.js +30 -0
- package/dist/src/index.d.ts +21 -0
- package/dist/src/index.js +21 -0
- package/dist/src/types/cli.d.ts +14 -0
- package/dist/src/types/cli.js +2 -0
- package/dist/src/types/commands/index.d.ts +6 -0
- package/dist/src/types/commands/index.js +6 -0
- package/dist/src/types/commands/options.d.ts +239 -0
- package/dist/src/types/commands/options.js +6 -0
- package/dist/src/types/commands/patches.d.ts +89 -0
- package/dist/src/types/commands/patches.js +6 -0
- package/dist/src/types/commands/project.d.ts +71 -0
- package/dist/src/types/commands/project.js +6 -0
- package/dist/src/types/config.d.ts +101 -0
- package/dist/src/types/config.js +2 -0
- package/dist/src/types/furnace.d.ts +158 -0
- package/dist/src/types/furnace.js +2 -0
- package/dist/src/types/index.d.ts +6 -0
- package/dist/src/types/index.js +6 -0
- package/dist/src/utils/errors.d.ts +2 -0
- package/dist/src/utils/errors.js +15 -0
- package/dist/src/utils/fs.d.ts +72 -0
- package/dist/src/utils/fs.js +179 -0
- package/dist/src/utils/logger.d.ts +58 -0
- package/dist/src/utils/logger.js +120 -0
- package/dist/src/utils/options.d.ts +8 -0
- package/dist/src/utils/options.js +16 -0
- package/dist/src/utils/package-root.d.ts +10 -0
- package/dist/src/utils/package-root.js +53 -0
- package/dist/src/utils/parse.d.ts +110 -0
- package/dist/src/utils/parse.js +200 -0
- package/dist/src/utils/paths.d.ts +10 -0
- package/dist/src/utils/paths.js +43 -0
- package/dist/src/utils/platform.d.ts +38 -0
- package/dist/src/utils/platform.js +56 -0
- package/dist/src/utils/process.d.ts +80 -0
- package/dist/src/utils/process.js +188 -0
- package/dist/src/utils/regex.d.ts +24 -0
- package/dist/src/utils/regex.js +40 -0
- package/dist/src/utils/validation.d.ts +133 -0
- package/dist/src/utils/validation.js +250 -0
- package/package.json +106 -0
- package/templates/configs/common.mozconfig +24 -0
- package/templates/configs/darwin.mozconfig +10 -0
- package/templates/configs/linux.mozconfig +12 -0
- package/templates/configs/win32.mozconfig +14 -0
- package/templates/licenses/0BSD.md +14 -0
- package/templates/licenses/EUPL-1.2.md +294 -0
- package/templates/licenses/GPL-2.0-or-later.md +339 -0
- package/templates/licenses/MPL-2.0.md +383 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
export type { GitStatusEntry } from './git-base.js';
|
|
2
|
+
/**
|
|
3
|
+
* Checks if a directory is a git repository.
|
|
4
|
+
* @param dir - Directory to check
|
|
5
|
+
* @returns True if the directory is a git repository
|
|
6
|
+
*/
|
|
7
|
+
export declare function isGitRepository(dir: string): Promise<boolean>;
|
|
8
|
+
/**
|
|
9
|
+
* Ensures the repository has an "origin" remote.
|
|
10
|
+
*
|
|
11
|
+
* Firefox's mach bootstrap and build scripts shell out to
|
|
12
|
+
* `git remote get-url origin` and emit noisy errors when the remote is
|
|
13
|
+
* absent. This adds a local-only dummy remote so those scripts stay quiet.
|
|
14
|
+
* Nothing is ever fetched from or pushed to this remote.
|
|
15
|
+
*
|
|
16
|
+
* @param dir - Git working directory
|
|
17
|
+
*/
|
|
18
|
+
export declare function ensureOriginRemote(dir: string): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Stages all files in the repository.
|
|
21
|
+
* Tries a monolithic `git add -A` first; if that times out, falls back to
|
|
22
|
+
* directory-by-directory staged adds.
|
|
23
|
+
*/
|
|
24
|
+
export declare function stageAllFiles(dir: string, options?: {
|
|
25
|
+
onProgress?: (message: string) => void;
|
|
26
|
+
timeout?: number;
|
|
27
|
+
}): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Initializes a new git repository with an orphan branch.
|
|
30
|
+
* @param dir - Directory to initialize
|
|
31
|
+
* @param branchName - Name for the initial branch
|
|
32
|
+
*/
|
|
33
|
+
export declare function initRepository(dir: string, branchName?: string, options?: {
|
|
34
|
+
onProgress?: (message: string) => void;
|
|
35
|
+
}): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Resumes a partially initialized git repository (e.g. after a killed
|
|
38
|
+
* `git add -A` left an unborn HEAD). Re-applies performance settings,
|
|
39
|
+
* cleans up stale locks, stages all files, and creates the initial commit.
|
|
40
|
+
*/
|
|
41
|
+
export declare function resumeRepository(dir: string, options?: {
|
|
42
|
+
onProgress?: (message: string) => void;
|
|
43
|
+
}): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Applies a patch file using git apply.
|
|
46
|
+
* @param patchPath - Path to the patch file
|
|
47
|
+
* @param repoDir - Repository directory
|
|
48
|
+
* @param options - Application options
|
|
49
|
+
*/
|
|
50
|
+
export declare function applyPatch(patchPath: string, repoDir: string, options?: {
|
|
51
|
+
reject?: boolean;
|
|
52
|
+
}): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Applies a patch idempotently using reverse-forward pattern.
|
|
55
|
+
* First tries to reverse the patch (in case it's already applied),
|
|
56
|
+
* then applies it forward.
|
|
57
|
+
* @param patchPath - Path to the patch file
|
|
58
|
+
* @param repoDir - Repository directory
|
|
59
|
+
* @param options - Application options
|
|
60
|
+
*/
|
|
61
|
+
export declare function applyPatchIdempotent(patchPath: string, repoDir: string, options?: {
|
|
62
|
+
reject?: boolean;
|
|
63
|
+
}): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Reverses a previously applied patch.
|
|
66
|
+
* @param patchPath - Path to the patch file
|
|
67
|
+
* @param repoDir - Repository directory
|
|
68
|
+
*/
|
|
69
|
+
export declare function reversePatch(patchPath: string, repoDir: string): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Checks if the repository has uncommitted changes.
|
|
72
|
+
* @param repoDir - Repository directory
|
|
73
|
+
* @returns True if there are uncommitted changes
|
|
74
|
+
*/
|
|
75
|
+
export declare function hasChanges(repoDir: string): Promise<boolean>;
|
|
76
|
+
/**
|
|
77
|
+
* Checks whether an error indicates the repository has no HEAD (e.g. unborn branch).
|
|
78
|
+
* @param error - The error to check
|
|
79
|
+
* @returns True if the error is a missing-HEAD error
|
|
80
|
+
*/
|
|
81
|
+
export declare function isMissingHeadError(error: unknown): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Gets the current HEAD commit hash.
|
|
84
|
+
* @param repoDir - Repository directory
|
|
85
|
+
* @returns Commit hash
|
|
86
|
+
*/
|
|
87
|
+
export declare function getHead(repoDir: string): Promise<string>;
|
|
88
|
+
/**
|
|
89
|
+
* Gets the current branch name.
|
|
90
|
+
* @param repoDir - Repository directory
|
|
91
|
+
* @returns Branch name
|
|
92
|
+
*/
|
|
93
|
+
export declare function getCurrentBranch(repoDir: string): Promise<string>;
|
|
94
|
+
/**
|
|
95
|
+
* Resets all changes in the repository.
|
|
96
|
+
* @param repoDir - Repository directory
|
|
97
|
+
*/
|
|
98
|
+
export declare function resetChanges(repoDir: string): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Creates a commit with all current changes.
|
|
101
|
+
* @param repoDir - Repository directory
|
|
102
|
+
* @param message - Commit message
|
|
103
|
+
*/
|
|
104
|
+
export declare function commit(repoDir: string, message: string): Promise<void>;
|
|
105
|
+
/**
|
|
106
|
+
* Gets the status of files with their status codes.
|
|
107
|
+
* @param repoDir - Repository directory
|
|
108
|
+
* @returns Array of [status, filepath] tuples
|
|
109
|
+
*/
|
|
110
|
+
export declare function getStatusWithCodes(repoDir: string): Promise<Array<{
|
|
111
|
+
status: string;
|
|
112
|
+
file: string;
|
|
113
|
+
}>>;
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
import { readdir, stat } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { GitError, GitIndexLockError, PatchApplyError } from '../errors/git.js';
|
|
5
|
+
import { toError } from '../utils/errors.js';
|
|
6
|
+
import { pathExists, removeFile } from '../utils/fs.js';
|
|
7
|
+
import { verbose } from '../utils/logger.js';
|
|
8
|
+
import { exec } from '../utils/process.js';
|
|
9
|
+
import { configureGitPerformance, ensureGit, git, GIT_ADD_CHUNK_TIMEOUT_MS, GIT_ADD_TIMEOUT_MS, } from './git-base.js';
|
|
10
|
+
import { getWorkingTreeStatus } from './git-status.js';
|
|
11
|
+
// ── Functions that remain in this file ──
|
|
12
|
+
/**
|
|
13
|
+
* Checks if a directory is a git repository.
|
|
14
|
+
* @param dir - Directory to check
|
|
15
|
+
* @returns True if the directory is a git repository
|
|
16
|
+
*/
|
|
17
|
+
export async function isGitRepository(dir) {
|
|
18
|
+
const gitDir = join(dir, '.git');
|
|
19
|
+
return pathExists(gitDir);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Ensures the repository has an "origin" remote.
|
|
23
|
+
*
|
|
24
|
+
* Firefox's mach bootstrap and build scripts shell out to
|
|
25
|
+
* `git remote get-url origin` and emit noisy errors when the remote is
|
|
26
|
+
* absent. This adds a local-only dummy remote so those scripts stay quiet.
|
|
27
|
+
* Nothing is ever fetched from or pushed to this remote.
|
|
28
|
+
*
|
|
29
|
+
* @param dir - Git working directory
|
|
30
|
+
*/
|
|
31
|
+
export async function ensureOriginRemote(dir) {
|
|
32
|
+
const result = await exec('git', ['remote', 'get-url', 'origin'], { cwd: dir });
|
|
33
|
+
if (result.exitCode !== 0) {
|
|
34
|
+
await git(['remote', 'add', 'origin', 'https://github.com/mozilla-firefox/firefox'], dir);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// ── Large-tree staging helpers ──
|
|
38
|
+
const GIT_ADD_ENV = { GIT_INDEX_THREADS: '0' };
|
|
39
|
+
/**
|
|
40
|
+
* Returns true when the error looks like a process killed by the spawn timeout
|
|
41
|
+
* (SIGTERM → exit code 143).
|
|
42
|
+
*/
|
|
43
|
+
function isTimeoutError(error) {
|
|
44
|
+
if (!(error instanceof GitError))
|
|
45
|
+
return false;
|
|
46
|
+
return /SIGTERM|timed out|exit code 143/i.test(error.message);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Removes `.git/index.lock` left behind by a killed git process.
|
|
50
|
+
*/
|
|
51
|
+
async function cleanupIndexLock(dir) {
|
|
52
|
+
const lockPath = join(dir, '.git', 'index.lock');
|
|
53
|
+
if (await pathExists(lockPath)) {
|
|
54
|
+
await removeFile(lockPath);
|
|
55
|
+
verbose('Cleaned up stale .git/index.lock after timeout');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Stages every file by walking top-level directories one at a time.
|
|
60
|
+
* This avoids a single monolithic `git add -A` that may time out on
|
|
61
|
+
* very large (~300 K file) trees like Firefox.
|
|
62
|
+
*/
|
|
63
|
+
async function stageAllFilesChunked(dir, options = {}) {
|
|
64
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
65
|
+
const directories = entries
|
|
66
|
+
.filter((e) => e.isDirectory() && e.name !== '.git')
|
|
67
|
+
.map((e) => e.name)
|
|
68
|
+
.sort();
|
|
69
|
+
for (const dirName of directories) {
|
|
70
|
+
options.onProgress?.(`Staging directory: ${dirName}/...`);
|
|
71
|
+
await git(['add', '--', dirName], dir, {
|
|
72
|
+
timeout: GIT_ADD_CHUNK_TIMEOUT_MS,
|
|
73
|
+
env: GIT_ADD_ENV,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// Stage any top-level files
|
|
77
|
+
const topLevelFiles = entries.filter((e) => e.isFile()).map((e) => e.name);
|
|
78
|
+
if (topLevelFiles.length > 0) {
|
|
79
|
+
options.onProgress?.('Staging top-level files...');
|
|
80
|
+
await git(['add', '--', ...topLevelFiles], dir, {
|
|
81
|
+
timeout: GIT_ADD_CHUNK_TIMEOUT_MS,
|
|
82
|
+
env: GIT_ADD_ENV,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Stages all files in the repository.
|
|
88
|
+
* Tries a monolithic `git add -A` first; if that times out, falls back to
|
|
89
|
+
* directory-by-directory staged adds.
|
|
90
|
+
*/
|
|
91
|
+
export async function stageAllFiles(dir, options = {}) {
|
|
92
|
+
const timeout = options.timeout ?? GIT_ADD_TIMEOUT_MS;
|
|
93
|
+
try {
|
|
94
|
+
await git(['add', '-A'], dir, { timeout, env: GIT_ADD_ENV });
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
if (!isTimeoutError(error)) {
|
|
99
|
+
throw await maybeWrapIndexLockError(dir, error);
|
|
100
|
+
}
|
|
101
|
+
options.onProgress?.('Monolithic git add timed out; falling back to chunked staging...');
|
|
102
|
+
}
|
|
103
|
+
// The killed process may have left an index lock
|
|
104
|
+
await cleanupIndexLock(dir);
|
|
105
|
+
await stageAllFilesChunked(dir, options);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Initializes a new git repository with an orphan branch.
|
|
109
|
+
* @param dir - Directory to initialize
|
|
110
|
+
* @param branchName - Name for the initial branch
|
|
111
|
+
*/
|
|
112
|
+
export async function initRepository(dir, branchName = 'main', options = {}) {
|
|
113
|
+
await ensureGit();
|
|
114
|
+
const reportProgress = options.onProgress ?? (() => { });
|
|
115
|
+
// Initialize repository
|
|
116
|
+
reportProgress('Creating git repository...');
|
|
117
|
+
await git(['init'], dir);
|
|
118
|
+
// Create orphan branch
|
|
119
|
+
reportProgress(`Creating ${branchName} baseline branch...`);
|
|
120
|
+
await git(['checkout', '--orphan', branchName], dir);
|
|
121
|
+
// Configure git for the repository
|
|
122
|
+
reportProgress('Configuring git identity...');
|
|
123
|
+
await git(['config', 'user.email', 'fireforge@localhost'], dir);
|
|
124
|
+
await git(['config', 'user.name', 'FireForge'], dir);
|
|
125
|
+
// Enable performance settings for large trees
|
|
126
|
+
reportProgress('Configuring git performance settings...');
|
|
127
|
+
await configureGitPerformance(dir);
|
|
128
|
+
// Add a local-only origin remote so that Firefox's mach bootstrap and
|
|
129
|
+
// build scripts (which shell out to `git remote get-url origin`) don't
|
|
130
|
+
// fail. Nothing is ever fetched from or pushed to this remote.
|
|
131
|
+
reportProgress('Configuring origin remote for build compatibility...');
|
|
132
|
+
await git(['remote', 'add', 'origin', 'https://github.com/mozilla-firefox/firefox'], dir);
|
|
133
|
+
// Add all files
|
|
134
|
+
reportProgress('Indexing Firefox source with git add -A (this can take several minutes on large trees)...');
|
|
135
|
+
await assertNoGitIndexLock(dir);
|
|
136
|
+
try {
|
|
137
|
+
await stageAllFiles(dir, { onProgress: reportProgress });
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
throw await maybeWrapIndexLockError(dir, error);
|
|
141
|
+
}
|
|
142
|
+
// Create initial commit
|
|
143
|
+
reportProgress('Creating initial Firefox source commit...');
|
|
144
|
+
try {
|
|
145
|
+
await git(['commit', '-m', 'Initial Firefox source'], dir);
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
throw await maybeWrapIndexLockError(dir, error);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Resumes a partially initialized git repository (e.g. after a killed
|
|
153
|
+
* `git add -A` left an unborn HEAD). Re-applies performance settings,
|
|
154
|
+
* cleans up stale locks, stages all files, and creates the initial commit.
|
|
155
|
+
*/
|
|
156
|
+
export async function resumeRepository(dir, options = {}) {
|
|
157
|
+
await ensureGit();
|
|
158
|
+
const reportProgress = options.onProgress ?? (() => { });
|
|
159
|
+
if (!(await isGitRepository(dir))) {
|
|
160
|
+
throw new GitError('Not a git repository', 'resume');
|
|
161
|
+
}
|
|
162
|
+
reportProgress('Resuming interrupted repository initialization...');
|
|
163
|
+
// Ensure performance settings are in place (may not have been set)
|
|
164
|
+
reportProgress('Configuring git performance settings...');
|
|
165
|
+
await configureGitPerformance(dir);
|
|
166
|
+
// Clean up any stale index lock left by the killed process
|
|
167
|
+
await cleanupIndexLock(dir);
|
|
168
|
+
// Ensure origin remote exists (may have been added before the interrupt)
|
|
169
|
+
await ensureOriginRemote(dir);
|
|
170
|
+
// Stage all files
|
|
171
|
+
reportProgress('Indexing Firefox source (resuming)...');
|
|
172
|
+
await assertNoGitIndexLock(dir);
|
|
173
|
+
try {
|
|
174
|
+
await stageAllFiles(dir, { onProgress: reportProgress });
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
throw await maybeWrapIndexLockError(dir, error);
|
|
178
|
+
}
|
|
179
|
+
// Create initial commit
|
|
180
|
+
reportProgress('Creating initial Firefox source commit...');
|
|
181
|
+
try {
|
|
182
|
+
await git(['commit', '-m', 'Initial Firefox source'], dir);
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
throw await maybeWrapIndexLockError(dir, error);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
async function assertNoGitIndexLock(dir) {
|
|
189
|
+
const lockPath = join(dir, '.git', 'index.lock');
|
|
190
|
+
if (!(await pathExists(lockPath))) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
throw new GitIndexLockError(lockPath, await getLockAgeMs(lockPath));
|
|
194
|
+
}
|
|
195
|
+
async function getLockAgeMs(lockPath) {
|
|
196
|
+
try {
|
|
197
|
+
const stats = await stat(lockPath);
|
|
198
|
+
return Math.max(0, Date.now() - stats.mtimeMs);
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
void error;
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
async function maybeWrapIndexLockError(dir, error) {
|
|
206
|
+
const lockPath = join(dir, '.git', 'index.lock');
|
|
207
|
+
if (error instanceof GitError &&
|
|
208
|
+
/index\.lock/i.test(error.message) &&
|
|
209
|
+
/(unable to create|another git process seems to be running|file exists)/i.test(error.message)) {
|
|
210
|
+
return new GitIndexLockError(lockPath);
|
|
211
|
+
}
|
|
212
|
+
if (error instanceof GitError &&
|
|
213
|
+
/(unable to create|locked|lock file)/i.test(error.message) &&
|
|
214
|
+
(await pathExists(lockPath))) {
|
|
215
|
+
return new GitIndexLockError(lockPath, await getLockAgeMs(lockPath));
|
|
216
|
+
}
|
|
217
|
+
return toError(error);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Applies a patch file using git apply.
|
|
221
|
+
* @param patchPath - Path to the patch file
|
|
222
|
+
* @param repoDir - Repository directory
|
|
223
|
+
* @param options - Application options
|
|
224
|
+
*/
|
|
225
|
+
export async function applyPatch(patchPath, repoDir, options = {}) {
|
|
226
|
+
await ensureGit();
|
|
227
|
+
if (!options.reject) {
|
|
228
|
+
const checkArgs = ['apply', '--check', '--', patchPath];
|
|
229
|
+
const result = await exec('git', checkArgs, { cwd: repoDir });
|
|
230
|
+
if (result.exitCode !== 0) {
|
|
231
|
+
throw new PatchApplyError(patchPath, new Error(result.stderr));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// Actually apply the patch
|
|
235
|
+
const applyArgs = ['apply'];
|
|
236
|
+
if (options.reject) {
|
|
237
|
+
applyArgs.push('--reject');
|
|
238
|
+
}
|
|
239
|
+
applyArgs.push('--', patchPath);
|
|
240
|
+
const applyResult = await exec('git', applyArgs, { cwd: repoDir });
|
|
241
|
+
if (applyResult.exitCode !== 0) {
|
|
242
|
+
throw new PatchApplyError(patchPath, new Error(applyResult.stderr));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Applies a patch idempotently using reverse-forward pattern.
|
|
247
|
+
* First tries to reverse the patch (in case it's already applied),
|
|
248
|
+
* then applies it forward.
|
|
249
|
+
* @param patchPath - Path to the patch file
|
|
250
|
+
* @param repoDir - Repository directory
|
|
251
|
+
* @param options - Application options
|
|
252
|
+
*/
|
|
253
|
+
export async function applyPatchIdempotent(patchPath, repoDir, options = {}) {
|
|
254
|
+
await ensureGit();
|
|
255
|
+
// Try to reverse the patch (ignore errors if not applied)
|
|
256
|
+
const reverseResult = await exec('git', ['apply', '--reverse', '--', patchPath], {
|
|
257
|
+
cwd: repoDir,
|
|
258
|
+
});
|
|
259
|
+
// If reverse failed (patch wasn't applied), restore only the files the
|
|
260
|
+
// patch would have touched so that unrelated local edits are preserved.
|
|
261
|
+
if (reverseResult.exitCode !== 0) {
|
|
262
|
+
// Extract the set of files referenced in the patch
|
|
263
|
+
const listResult = await exec('git', ['apply', '--numstat', '--', patchPath], { cwd: repoDir });
|
|
264
|
+
const touchedFiles = listResult.stdout
|
|
265
|
+
.split('\n')
|
|
266
|
+
.map((line) => line.split('\t')[2])
|
|
267
|
+
.filter((f) => !!f);
|
|
268
|
+
if (touchedFiles.length > 0) {
|
|
269
|
+
// Restore only the files the patch touches
|
|
270
|
+
await exec('git', ['checkout', 'HEAD', '--', ...touchedFiles], { cwd: repoDir });
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
// Apply forward
|
|
274
|
+
await applyPatch(patchPath, repoDir, options);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Reverses a previously applied patch.
|
|
278
|
+
* @param patchPath - Path to the patch file
|
|
279
|
+
* @param repoDir - Repository directory
|
|
280
|
+
*/
|
|
281
|
+
export async function reversePatch(patchPath, repoDir) {
|
|
282
|
+
await ensureGit();
|
|
283
|
+
const result = await exec('git', ['apply', '--reverse', '--', patchPath], { cwd: repoDir });
|
|
284
|
+
if (result.exitCode !== 0) {
|
|
285
|
+
throw new PatchApplyError(patchPath, new Error(result.stderr));
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Checks if the repository has uncommitted changes.
|
|
290
|
+
* @param repoDir - Repository directory
|
|
291
|
+
* @returns True if there are uncommitted changes
|
|
292
|
+
*/
|
|
293
|
+
export async function hasChanges(repoDir) {
|
|
294
|
+
await ensureGit();
|
|
295
|
+
const entries = await getWorkingTreeStatus(repoDir);
|
|
296
|
+
return entries.length > 0;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Checks whether an error indicates the repository has no HEAD (e.g. unborn branch).
|
|
300
|
+
* @param error - The error to check
|
|
301
|
+
* @returns True if the error is a missing-HEAD error
|
|
302
|
+
*/
|
|
303
|
+
export function isMissingHeadError(error) {
|
|
304
|
+
return (error instanceof Error &&
|
|
305
|
+
/(ambiguous argument 'HEAD'|unknown revision or path not in the working tree)/i.test(error.message));
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Gets the current HEAD commit hash.
|
|
309
|
+
* @param repoDir - Repository directory
|
|
310
|
+
* @returns Commit hash
|
|
311
|
+
*/
|
|
312
|
+
export async function getHead(repoDir) {
|
|
313
|
+
await ensureGit();
|
|
314
|
+
const output = await git(['rev-parse', 'HEAD'], repoDir);
|
|
315
|
+
return output.trim();
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Gets the current branch name.
|
|
319
|
+
* @param repoDir - Repository directory
|
|
320
|
+
* @returns Branch name
|
|
321
|
+
*/
|
|
322
|
+
export async function getCurrentBranch(repoDir) {
|
|
323
|
+
await ensureGit();
|
|
324
|
+
const output = await git(['rev-parse', '--abbrev-ref', 'HEAD'], repoDir);
|
|
325
|
+
return output.trim();
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Resets all changes in the repository.
|
|
329
|
+
* @param repoDir - Repository directory
|
|
330
|
+
*/
|
|
331
|
+
export async function resetChanges(repoDir) {
|
|
332
|
+
await ensureGit();
|
|
333
|
+
try {
|
|
334
|
+
await git(['reset', '--hard', 'HEAD'], repoDir);
|
|
335
|
+
}
|
|
336
|
+
catch (error) {
|
|
337
|
+
throw await maybeWrapIndexLockError(repoDir, error);
|
|
338
|
+
}
|
|
339
|
+
await git(['clean', '-fd'], repoDir);
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Creates a commit with all current changes.
|
|
343
|
+
* @param repoDir - Repository directory
|
|
344
|
+
* @param message - Commit message
|
|
345
|
+
*/
|
|
346
|
+
export async function commit(repoDir, message) {
|
|
347
|
+
await ensureGit();
|
|
348
|
+
await stageAllFiles(repoDir);
|
|
349
|
+
await git(['commit', '-m', message], repoDir);
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Gets the status of files with their status codes.
|
|
353
|
+
* @param repoDir - Repository directory
|
|
354
|
+
* @returns Array of [status, filepath] tuples
|
|
355
|
+
*/
|
|
356
|
+
export async function getStatusWithCodes(repoDir) {
|
|
357
|
+
const entries = await getWorkingTreeStatus(repoDir);
|
|
358
|
+
return entries.map((entry) => ({
|
|
359
|
+
status: entry.status.trim(),
|
|
360
|
+
file: entry.file,
|
|
361
|
+
}));
|
|
362
|
+
}
|
|
363
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ProjectLicense } from '../types/config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Comment style for license header formatting.
|
|
4
|
+
* - `js` — `// ...` line comments
|
|
5
|
+
* - `css` — block comments
|
|
6
|
+
* - `hash` — `# ...` line comments (FTL, shell, etc.)
|
|
7
|
+
*/
|
|
8
|
+
export type CommentStyle = 'js' | 'css' | 'hash';
|
|
9
|
+
/** Default license when fireforge.json omits the license field. */
|
|
10
|
+
export declare const DEFAULT_LICENSE: ProjectLicense;
|
|
11
|
+
/**
|
|
12
|
+
* Returns a formatted license header comment for the given license and
|
|
13
|
+
* comment style.
|
|
14
|
+
*
|
|
15
|
+
* @param license - SPDX identifier of the project license
|
|
16
|
+
* @param style - Comment syntax to wrap the header in
|
|
17
|
+
* @returns Multi-line string ready to be placed at the top of a source file
|
|
18
|
+
*/
|
|
19
|
+
export declare function getLicenseHeader(license: ProjectLicense, style: CommentStyle): string;
|
|
20
|
+
/**
|
|
21
|
+
* Returns true if `content` starts with any known license header for the
|
|
22
|
+
* given comment style.
|
|
23
|
+
*
|
|
24
|
+
* @param content - File content to check
|
|
25
|
+
* @param style - Comment syntax of the file
|
|
26
|
+
*/
|
|
27
|
+
export declare function hasAnyLicenseHeader(content: string, style: CommentStyle): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Prepends the license header to a file on disk if it is not already present.
|
|
30
|
+
*
|
|
31
|
+
* @param filePath - Absolute path to the file
|
|
32
|
+
* @param license - SPDX identifier of the license to add
|
|
33
|
+
* @param style - Comment syntax matching the file type
|
|
34
|
+
* @returns true if the header was added, false if already present
|
|
35
|
+
*/
|
|
36
|
+
export declare function addLicenseHeaderToFile(filePath: string, license: ProjectLicense, style: CommentStyle): Promise<boolean>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { readText, writeText } from '../utils/fs.js';
|
|
2
|
+
/** Default license when fireforge.json omits the license field. */
|
|
3
|
+
export const DEFAULT_LICENSE = 'MPL-2.0';
|
|
4
|
+
/**
|
|
5
|
+
* Raw (unwrapped) header lines per license.
|
|
6
|
+
*
|
|
7
|
+
* Each entry uses the community-recommended file notice for the license.
|
|
8
|
+
*/
|
|
9
|
+
const HEADER_LINES = {
|
|
10
|
+
'MPL-2.0': [
|
|
11
|
+
'This Source Code Form is subject to the terms of the Mozilla Public',
|
|
12
|
+
'License, v. 2.0. If a copy of the MPL was not distributed with this',
|
|
13
|
+
'file, You can obtain one at http://mozilla.org/MPL/2.0/.',
|
|
14
|
+
],
|
|
15
|
+
'EUPL-1.2': ['SPDX-License-Identifier: EUPL-1.2'],
|
|
16
|
+
'GPL-2.0-or-later': [
|
|
17
|
+
'SPDX-License-Identifier: GPL-2.0-or-later',
|
|
18
|
+
'This file is free software; you can redistribute it and/or modify it',
|
|
19
|
+
'under the terms of the GNU General Public License as published by the',
|
|
20
|
+
'Free Software Foundation; either version 2 of the License, or (at your',
|
|
21
|
+
'option) any later version.',
|
|
22
|
+
],
|
|
23
|
+
'0BSD': ['SPDX-License-Identifier: 0BSD'],
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Returns a formatted license header comment for the given license and
|
|
27
|
+
* comment style.
|
|
28
|
+
*
|
|
29
|
+
* @param license - SPDX identifier of the project license
|
|
30
|
+
* @param style - Comment syntax to wrap the header in
|
|
31
|
+
* @returns Multi-line string ready to be placed at the top of a source file
|
|
32
|
+
*/
|
|
33
|
+
export function getLicenseHeader(license, style) {
|
|
34
|
+
const lines = HEADER_LINES[license];
|
|
35
|
+
switch (style) {
|
|
36
|
+
case 'js':
|
|
37
|
+
if (lines.length === 1) {
|
|
38
|
+
return `/* ${lines[0]} */`;
|
|
39
|
+
}
|
|
40
|
+
return lines.map((l) => `// ${l}`).join('\n');
|
|
41
|
+
case 'css':
|
|
42
|
+
if (lines.length === 1) {
|
|
43
|
+
return `/* ${lines[0]} */`;
|
|
44
|
+
}
|
|
45
|
+
return (`/* ${lines[0]}\n` +
|
|
46
|
+
lines
|
|
47
|
+
.slice(1, -1)
|
|
48
|
+
.map((l) => ` * ${l}`)
|
|
49
|
+
.join('\n') +
|
|
50
|
+
(lines.length > 2 ? '\n' : '') +
|
|
51
|
+
` * ${lines[lines.length - 1]} */`);
|
|
52
|
+
case 'hash':
|
|
53
|
+
return lines.map((l) => `# ${l}`).join('\n');
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Returns true if `content` starts with any known license header for the
|
|
58
|
+
* given comment style.
|
|
59
|
+
*
|
|
60
|
+
* @param content - File content to check
|
|
61
|
+
* @param style - Comment syntax of the file
|
|
62
|
+
*/
|
|
63
|
+
export function hasAnyLicenseHeader(content, style) {
|
|
64
|
+
const licenses = Object.keys(HEADER_LINES);
|
|
65
|
+
return licenses.some((license) => content.startsWith(getLicenseHeader(license, style)));
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Prepends the license header to a file on disk if it is not already present.
|
|
69
|
+
*
|
|
70
|
+
* @param filePath - Absolute path to the file
|
|
71
|
+
* @param license - SPDX identifier of the license to add
|
|
72
|
+
* @param style - Comment syntax matching the file type
|
|
73
|
+
* @returns true if the header was added, false if already present
|
|
74
|
+
*/
|
|
75
|
+
export async function addLicenseHeaderToFile(filePath, license, style) {
|
|
76
|
+
const content = await readText(filePath);
|
|
77
|
+
const header = getLicenseHeader(license, style);
|
|
78
|
+
if (content.startsWith(header))
|
|
79
|
+
return false;
|
|
80
|
+
await writeText(filePath, header + '\n' + content);
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=license-headers.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result of checking for build artifacts.
|
|
3
|
+
*/
|
|
4
|
+
export interface BuildArtifactCheck {
|
|
5
|
+
/** Whether build artifacts exist */
|
|
6
|
+
exists: boolean;
|
|
7
|
+
/** Name of the obj-* directory if found */
|
|
8
|
+
objDir?: string;
|
|
9
|
+
/** Whether multiple valid obj-* directories were found */
|
|
10
|
+
ambiguous?: boolean;
|
|
11
|
+
/** All candidate obj-* directories with build artifacts */
|
|
12
|
+
objDirs?: string[];
|
|
13
|
+
/** Build metadata points at a different source or objdir */
|
|
14
|
+
metadataMismatch?: {
|
|
15
|
+
objDir: string;
|
|
16
|
+
topsrcdir?: string;
|
|
17
|
+
topobjdir?: string;
|
|
18
|
+
mozconfig?: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Checks if build artifacts exist in the engine directory.
|
|
23
|
+
* Looks for obj-* directories with a dist subdirectory.
|
|
24
|
+
* @param engineDir - Path to the engine directory
|
|
25
|
+
* @returns Build artifact check result
|
|
26
|
+
*/
|
|
27
|
+
export declare function hasBuildArtifacts(engineDir: string): Promise<BuildArtifactCheck>;
|
|
28
|
+
/** Builds a user-facing explanation when detected build artifacts belong to another workspace. */
|
|
29
|
+
export declare function buildArtifactMismatchMessage(engineDir: string, buildCheck: BuildArtifactCheck, commandName: string): string | undefined;
|