@fairgarden/distribution 0.1.0-alpha.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/Readme.md +94 -0
- package/dist/add-module.d.ts +58 -0
- package/dist/add-module.d.ts.map +1 -0
- package/dist/add-module.js +250 -0
- package/dist/add-module.js.map +1 -0
- package/dist/canary.d.ts +58 -0
- package/dist/canary.d.ts.map +1 -0
- package/dist/canary.js +117 -0
- package/dist/canary.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +747 -0
- package/dist/cli.js.map +1 -0
- package/dist/config-edit.d.ts +18 -0
- package/dist/config-edit.d.ts.map +1 -0
- package/dist/config-edit.js +166 -0
- package/dist/config-edit.js.map +1 -0
- package/dist/extends.d.ts +59 -0
- package/dist/extends.d.ts.map +1 -0
- package/dist/extends.js +163 -0
- package/dist/extends.js.map +1 -0
- package/dist/extract.d.ts +31 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +177 -0
- package/dist/extract.js.map +1 -0
- package/dist/git-url.d.ts +19 -0
- package/dist/git-url.d.ts.map +1 -0
- package/dist/git-url.js +55 -0
- package/dist/git-url.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/overrides.d.ts +32 -0
- package/dist/overrides.d.ts.map +1 -0
- package/dist/overrides.js +81 -0
- package/dist/overrides.js.map +1 -0
- package/dist/readme.d.ts +58 -0
- package/dist/readme.d.ts.map +1 -0
- package/dist/readme.js +299 -0
- package/dist/readme.js.map +1 -0
- package/dist/release.d.ts +140 -0
- package/dist/release.d.ts.map +1 -0
- package/dist/release.js +409 -0
- package/dist/release.js.map +1 -0
- package/dist/scaffold.d.ts +46 -0
- package/dist/scaffold.d.ts.map +1 -0
- package/dist/scaffold.js +389 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/submodules.d.ts +95 -0
- package/dist/submodules.d.ts.map +1 -0
- package/dist/submodules.js +225 -0
- package/dist/submodules.js.map +1 -0
- package/dist/workflows.d.ts +57 -0
- package/dist/workflows.d.ts.map +1 -0
- package/dist/workflows.js +358 -0
- package/dist/workflows.js.map +1 -0
- package/package.json +51 -0
package/dist/extract.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { readFile, readdir, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { existsSync, statSync } from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { writeOverrides } from "./overrides.js";
|
|
6
|
+
import semver from 'semver';
|
|
7
|
+
import { repositoryRoot, submodules } from "./submodules.js";
|
|
8
|
+
import { toHttps } from "./git-url.js";
|
|
9
|
+
/**
|
|
10
|
+
* Turn a directory that grew inside a distribution into a module of its own.
|
|
11
|
+
*
|
|
12
|
+
* An app or package is easier to get working in place, where the workspace
|
|
13
|
+
* already resolves it and there is one repository to run. Once it works it
|
|
14
|
+
* wants its own history and its own version, which is what this does: the
|
|
15
|
+
* directory becomes a repository, and the distribution picks it back up as a
|
|
16
|
+
* submodule. Nothing is re-cloned, so it works before anything is pushed.
|
|
17
|
+
*/
|
|
18
|
+
const git = (cwd, args) => {
|
|
19
|
+
try {
|
|
20
|
+
return execFileSync('git', args, {
|
|
21
|
+
cwd,
|
|
22
|
+
encoding: 'utf8',
|
|
23
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
24
|
+
}).trim();
|
|
25
|
+
}
|
|
26
|
+
catch (cause) {
|
|
27
|
+
const stderr = cause instanceof Error && 'stderr' in cause ? String(cause.stderr).trim() : '';
|
|
28
|
+
throw new Error(`git ${args[0]} failed${stderr ? `: ${stderr}` : ''}`, { cause });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const quiet = (cwd, args) => {
|
|
32
|
+
try {
|
|
33
|
+
return execFileSync('git', args, {
|
|
34
|
+
cwd,
|
|
35
|
+
encoding: 'utf8',
|
|
36
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
37
|
+
}).trim();
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const isDirectory = (candidate) => {
|
|
44
|
+
try {
|
|
45
|
+
return statSync(candidate).isDirectory();
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const readManifest = async (root) => {
|
|
52
|
+
try {
|
|
53
|
+
return JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8'));
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return {};
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
export const extractModule = async (cwd, target, options) => {
|
|
60
|
+
const root = repositoryRoot(cwd);
|
|
61
|
+
if (!root)
|
|
62
|
+
throw new Error(`${cwd} is not inside a git repository.`);
|
|
63
|
+
const full = path.resolve(cwd, target);
|
|
64
|
+
const relativePath = path.relative(root, full);
|
|
65
|
+
if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) {
|
|
66
|
+
throw new Error(`${target} is outside ${root}.`);
|
|
67
|
+
}
|
|
68
|
+
if (!isDirectory(full)) {
|
|
69
|
+
throw new Error(`${relativePath} is not a directory.`);
|
|
70
|
+
}
|
|
71
|
+
if (submodules(root).some((module) => module.relativePath === relativePath)) {
|
|
72
|
+
throw new Error(`${relativePath} is already a submodule.`);
|
|
73
|
+
}
|
|
74
|
+
const recorded = options.ssh ? options.url : toHttps(options.url);
|
|
75
|
+
const { name, version } = await readManifest(full);
|
|
76
|
+
// An existing repository here is kept: it may already have the history.
|
|
77
|
+
// Looking for `.git` in the directory itself, because `rev-parse` walks up
|
|
78
|
+
// and would find the distribution's repository instead.
|
|
79
|
+
const alreadyRepository = existsSync(path.join(full, '.git'));
|
|
80
|
+
const initialised = !alreadyRepository;
|
|
81
|
+
if (initialised) {
|
|
82
|
+
git(full, ['init', '--quiet', '-b', 'main']);
|
|
83
|
+
}
|
|
84
|
+
// The distribution's .gitignore stops applying the moment this is its own
|
|
85
|
+
// repository, so without one of its own the first commit would carry
|
|
86
|
+
// node_modules and build output.
|
|
87
|
+
if (!existsSync(path.join(full, '.gitignore'))) {
|
|
88
|
+
await writeFile(path.join(full, '.gitignore'), 'node_modules\n.next\n.turbo\ndist\nout\nnext-env.d.ts\n*.tsbuildinfo\n');
|
|
89
|
+
}
|
|
90
|
+
// Nested packages — a docs site, most often — were members of the
|
|
91
|
+
// distribution's workspace. Out here nothing says so, and pnpm 10 links
|
|
92
|
+
// nothing across a workspace unless told to, so this repository needs the
|
|
93
|
+
// arrangement written down for itself.
|
|
94
|
+
const nested = await nestedPackages(full);
|
|
95
|
+
if (nested.length > 0 && !existsSync(path.join(full, 'pnpm-workspace.yaml'))) {
|
|
96
|
+
await writeFile(path.join(full, 'pnpm-workspace.yaml'), workspaceFile(nested));
|
|
97
|
+
}
|
|
98
|
+
// Commit whatever is there, so the submodule has something to point at.
|
|
99
|
+
if (quiet(full, ['status', '--porcelain']) !== '') {
|
|
100
|
+
git(full, ['add', '-A']);
|
|
101
|
+
git(full, ['commit', '--quiet', '-m', 'Initial commit']);
|
|
102
|
+
}
|
|
103
|
+
if (quiet(full, ['remote', 'get-url', 'origin']) === undefined) {
|
|
104
|
+
git(full, ['remote', 'add', 'origin', recorded]);
|
|
105
|
+
}
|
|
106
|
+
// A module is versioned by tags, so give it the one its manifest declares.
|
|
107
|
+
let tagged;
|
|
108
|
+
if (options.tag !== false && version && semver.valid(version)) {
|
|
109
|
+
const tag = `v${version}`;
|
|
110
|
+
if (quiet(full, ['rev-parse', '--verify', '--quiet', `refs/tags/${tag}`]) === undefined) {
|
|
111
|
+
quiet(full, ['tag', tag]);
|
|
112
|
+
tagged = tag;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Untrack the files, then let git adopt the repository that is already here.
|
|
116
|
+
// `submodule add` clones only when the path is empty, so nothing is refetched
|
|
117
|
+
// and this works before the remote exists.
|
|
118
|
+
// Tolerant, so a retry after a half-finished run still works: the files may
|
|
119
|
+
// already be untracked.
|
|
120
|
+
quiet(root, ['rm', '-r', '--quiet', '--cached', relativePath]);
|
|
121
|
+
git(root, ['submodule', 'add', recorded, relativePath]);
|
|
122
|
+
// Now that it is a submodule, the distribution resolves it from the tree
|
|
123
|
+
// rather than through whatever range its dependents declare. The repository
|
|
124
|
+
// is made and the submodule added by this point, so a workspace this cannot
|
|
125
|
+
// edit is reported rather than failing a job that is otherwise done.
|
|
126
|
+
const overridesError = await writeOverrides(root).then(() => undefined, (error) => (error instanceof Error ? error.message : String(error)));
|
|
127
|
+
return {
|
|
128
|
+
overridesError,
|
|
129
|
+
relativePath,
|
|
130
|
+
packageName: name,
|
|
131
|
+
version,
|
|
132
|
+
url: recorded,
|
|
133
|
+
rewritten: recorded !== options.url,
|
|
134
|
+
initialised,
|
|
135
|
+
tagged,
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
/** Directories one level down that are packages in their own right. */
|
|
139
|
+
const nestedPackages = async (root) => {
|
|
140
|
+
const entries = await readdir(root, { withFileTypes: true }).catch(() => []);
|
|
141
|
+
return entries
|
|
142
|
+
.filter((entry) => entry.isDirectory() &&
|
|
143
|
+
entry.name !== 'node_modules' &&
|
|
144
|
+
!entry.name.startsWith('.') &&
|
|
145
|
+
existsSync(path.join(root, entry.name, 'package.json')))
|
|
146
|
+
.map((entry) => entry.name)
|
|
147
|
+
.sort();
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* A workspace covering this repository and the packages inside it.
|
|
151
|
+
*
|
|
152
|
+
* The settings are not decoration: pnpm 10 defaults `linkWorkspacePackages` to
|
|
153
|
+
* false, so without it a nested package resolves its dependency on this one
|
|
154
|
+
* from the registry rather than from the checkout it is sitting in.
|
|
155
|
+
*/
|
|
156
|
+
export const workspaceFile = (nested) => [
|
|
157
|
+
'# For when this repository is cloned on its own.',
|
|
158
|
+
'#',
|
|
159
|
+
'# pnpm uses the nearest workspace file to where it is run, so inside a',
|
|
160
|
+
'# distribution this one applies to `pnpm install` run from THIS directory —',
|
|
161
|
+
'# which would build a second workspace with its own lockfile and without the',
|
|
162
|
+
'# distribution\'s overrides. Install from the distribution root instead.',
|
|
163
|
+
'packages:',
|
|
164
|
+
' # The workspace root — this module — is always a member; these are the',
|
|
165
|
+
' # additions.',
|
|
166
|
+
...nested.map((name) => ` - ${name}`),
|
|
167
|
+
'',
|
|
168
|
+
'# pnpm 10 defaults this to false, so without it the packages above resolve',
|
|
169
|
+
'# their dependency on this module from the registry instead of from the',
|
|
170
|
+
'# checkout next to them.',
|
|
171
|
+
'linkWorkspacePackages: true',
|
|
172
|
+
'# Keep plain semver ranges in package.json: the range is what a published',
|
|
173
|
+
'# module is installed by, and what a distribution reads to resolve versions.',
|
|
174
|
+
'saveWorkspaceProtocol: false',
|
|
175
|
+
'',
|
|
176
|
+
].join('\n');
|
|
177
|
+
//# sourceMappingURL=extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git remote URLs, normalised for hosts that clone submodules anonymously.
|
|
3
|
+
*
|
|
4
|
+
* A submodule URL is recorded in `.gitmodules` and committed, so whatever is
|
|
5
|
+
* written there is what every later clone uses — including builds on a host
|
|
6
|
+
* that has no SSH key. Vercel clones submodules over HTTPS and only public
|
|
7
|
+
* ones, so an `scp`-style or `ssh://` URL checks out fine locally and then
|
|
8
|
+
* fails in the build.
|
|
9
|
+
*/
|
|
10
|
+
export declare const isSsh: (url: string) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* The HTTPS form of a remote, or the URL unchanged when there is none.
|
|
13
|
+
*
|
|
14
|
+
* Local paths and URLs that already speak HTTP are left alone.
|
|
15
|
+
*/
|
|
16
|
+
export declare const toHttps: (url: string) => string;
|
|
17
|
+
/** `https://github.com/acme/widget.git` -> `acme/widget`, for messages. */
|
|
18
|
+
export declare const describeRemote: (url: string) => string;
|
|
19
|
+
//# sourceMappingURL=git-url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-url.d.ts","sourceRoot":"","sources":["../src/git-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAeH,eAAO,MAAM,KAAK,GAAI,KAAK,MAAM,KAAG,OAInC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,OAAO,GAAI,KAAK,MAAM,KAAG,MAsBrC,CAAA;AAED,2EAA2E;AAC3E,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,MACkC,CAAA"}
|
package/dist/git-url.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git remote URLs, normalised for hosts that clone submodules anonymously.
|
|
3
|
+
*
|
|
4
|
+
* A submodule URL is recorded in `.gitmodules` and committed, so whatever is
|
|
5
|
+
* written there is what every later clone uses — including builds on a host
|
|
6
|
+
* that has no SSH key. Vercel clones submodules over HTTPS and only public
|
|
7
|
+
* ones, so an `scp`-style or `ssh://` URL checks out fine locally and then
|
|
8
|
+
* fails in the build.
|
|
9
|
+
*/
|
|
10
|
+
/** `git@host:owner/repo.git` — git's scp-like shorthand, not a real URL. */
|
|
11
|
+
const SCP_LIKE = /^(?:([^@/]+)@)?([^:/]+):(?!\/)(.+)$/;
|
|
12
|
+
/** A path or a `file:` URL, which has no host to rewrite. */
|
|
13
|
+
const isLocal = (url) => url.startsWith('.') ||
|
|
14
|
+
url.startsWith('/') ||
|
|
15
|
+
url.startsWith('file:') ||
|
|
16
|
+
/^[A-Za-z]:[\\/]/.test(url);
|
|
17
|
+
/** `ssh://`, and git's own `git+ssh://` spelling. */
|
|
18
|
+
const SSH_SCHEME = /^(?:git\+)?ssh:\/\//i;
|
|
19
|
+
export const isSsh = (url) => {
|
|
20
|
+
if (isLocal(url))
|
|
21
|
+
return false;
|
|
22
|
+
if (SSH_SCHEME.test(url))
|
|
23
|
+
return true;
|
|
24
|
+
return !/^[a-z][a-z0-9+.-]*:\/\//i.test(url) && SCP_LIKE.test(url);
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The HTTPS form of a remote, or the URL unchanged when there is none.
|
|
28
|
+
*
|
|
29
|
+
* Local paths and URLs that already speak HTTP are left alone.
|
|
30
|
+
*/
|
|
31
|
+
export const toHttps = (url) => {
|
|
32
|
+
const trimmed = url.trim();
|
|
33
|
+
if (isLocal(trimmed))
|
|
34
|
+
return trimmed;
|
|
35
|
+
if (/^https?:\/\//i.test(trimmed))
|
|
36
|
+
return trimmed;
|
|
37
|
+
const scheme = SSH_SCHEME.exec(trimmed);
|
|
38
|
+
if (scheme) {
|
|
39
|
+
const rest = trimmed.slice(scheme[0].length);
|
|
40
|
+
const at = rest.indexOf('@');
|
|
41
|
+
const withoutUser = at === -1 ? rest : rest.slice(at + 1);
|
|
42
|
+
// Strip a port, which is an SSH port and means nothing over HTTPS.
|
|
43
|
+
const normalised = withoutUser.replace(/^([^/]+?):\d+\//, '$1/');
|
|
44
|
+
return `https://${normalised}`;
|
|
45
|
+
}
|
|
46
|
+
const scp = SCP_LIKE.exec(trimmed);
|
|
47
|
+
if (scp) {
|
|
48
|
+
const [, , host, path] = scp;
|
|
49
|
+
return `https://${host}/${path}`;
|
|
50
|
+
}
|
|
51
|
+
return trimmed;
|
|
52
|
+
};
|
|
53
|
+
/** `https://github.com/acme/widget.git` -> `acme/widget`, for messages. */
|
|
54
|
+
export const describeRemote = (url) => url.replace(/^[a-z]+:\/\//i, '').replace(/^[^@]+@/, '').replace(/\.git$/, '');
|
|
55
|
+
//# sourceMappingURL=git-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-url.js","sourceRoot":"","sources":["../src/git-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,4EAA4E;AAC5E,MAAM,QAAQ,GAAG,qCAAqC,CAAA;AAEtD,6DAA6D;AAC7D,MAAM,OAAO,GAAG,CAAC,GAAW,EAAW,EAAE,CACvC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;IACnB,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;IACnB,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;IACvB,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAE7B,qDAAqD;AACrD,MAAM,UAAU,GAAG,sBAAsB,CAAA;AAEzC,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,GAAW,EAAW,EAAE;IAC5C,IAAI,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAA;IAC9B,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IACrC,OAAO,CAAC,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACpE,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAW,EAAU,EAAE;IAC7C,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;IAC1B,IAAI,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAA;IACpC,IAAI,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAA;IAEjD,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACvC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;QAC5C,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAC5B,MAAM,WAAW,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;QACzD,mEAAmE;QACnE,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAA;QAChE,OAAO,WAAW,UAAU,EAAE,CAAA;IAChC,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAClC,IAAI,GAAG,EAAE,CAAC;QACR,MAAM,CAAC,EAAE,AAAD,EAAG,IAAI,EAAE,IAAI,CAAC,GAAG,GAAG,CAAA;QAC5B,OAAO,WAAW,IAAI,IAAI,IAAI,EAAE,CAAA;IAClC,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,2EAA2E;AAC3E,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAW,EAAU,EAAE,CACpD,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type { Files } from './scaffold.ts';
|
|
2
|
+
export { VERSIONS, distributionRepo, moduleRepo, monolithRepo, isEmpty, readPackageName, write, } from './scaffold.ts';
|
|
3
|
+
export { addModule, findMonolith, nameFromUrl } from './add-module.ts';
|
|
4
|
+
export type { AddModuleOptions, AddModuleResult } from './add-module.ts';
|
|
5
|
+
export { addMount, ConfigEditError } from './config-edit.ts';
|
|
6
|
+
export type { EditResult } from './config-edit.ts';
|
|
7
|
+
export { describeRemote, isSsh, toHttps } from './git-url.ts';
|
|
8
|
+
export { inspect, isPublic, moveTo, repositoryRoot, setUrl, submodules, target, } from './submodules.ts';
|
|
9
|
+
export type { ReleaseKind, Submodule, SubmoduleState } from './submodules.ts';
|
|
10
|
+
export { assertExtends, describeViolations, findFloorViolations, inspectExtends, readDistribution, readParent, } from './extends.ts';
|
|
11
|
+
export type { Distribution, ExtendsReport, FloorViolation } from './extends.ts';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,OAAO,EACP,eAAe,EACf,KAAK,GACN,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AACtE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAExE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAC5D,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE7D,OAAO,EACL,OAAO,EACP,QAAQ,EACR,MAAM,EACN,cAAc,EACd,MAAM,EACN,UAAU,EACV,MAAM,GACP,MAAM,iBAAiB,CAAA;AACxB,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAE7E,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,UAAU,GACX,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { VERSIONS, distributionRepo, moduleRepo, monolithRepo, isEmpty, readPackageName, write, } from "./scaffold.js";
|
|
2
|
+
export { addModule, findMonolith, nameFromUrl } from "./add-module.js";
|
|
3
|
+
export { addMount, ConfigEditError } from "./config-edit.js";
|
|
4
|
+
export { describeRemote, isSsh, toHttps } from "./git-url.js";
|
|
5
|
+
export { inspect, isPublic, moveTo, repositoryRoot, setUrl, submodules, target, } from "./submodules.js";
|
|
6
|
+
export { assertExtends, describeViolations, findFloorViolations, inspectExtends, readDistribution, readParent, } from "./extends.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,OAAO,EACP,eAAe,EACf,KAAK,GACN,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAGtE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAG5D,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE7D,OAAO,EACL,OAAO,EACP,QAAQ,EACR,MAAM,EACN,cAAc,EACd,MAAM,EACN,UAAU,EACV,MAAM,GACP,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,UAAU,GACX,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The block that makes a distribution's own checkouts win.
|
|
3
|
+
*
|
|
4
|
+
* Without it, a module resolves a sibling through its declared range, and the
|
|
5
|
+
* range stops matching the moment the sibling's submodule is bumped past it —
|
|
6
|
+
* at which point pnpm quietly installs the published copy instead of the
|
|
7
|
+
* checkout. `workspace:*` says what the distribution means: whatever is in the
|
|
8
|
+
* tree, whatever version it is at.
|
|
9
|
+
*
|
|
10
|
+
* Names, not versions. The version still comes from the submodule pin, which
|
|
11
|
+
* is the whole point of pinning it there.
|
|
12
|
+
*/
|
|
13
|
+
export declare const overridesBlock: (names: string[]) => string;
|
|
14
|
+
export declare class OverridesError extends Error {
|
|
15
|
+
}
|
|
16
|
+
export interface OverridesResult {
|
|
17
|
+
file: string;
|
|
18
|
+
names: string[];
|
|
19
|
+
changed: boolean;
|
|
20
|
+
/** True when there is no pnpm-workspace.yaml to write into. */
|
|
21
|
+
missing: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Point the distribution's overrides at every module it ships.
|
|
25
|
+
*
|
|
26
|
+
* A distribution with no submodules is left alone: there is nothing to
|
|
27
|
+
* override, and writing an empty block would only be noise.
|
|
28
|
+
*/
|
|
29
|
+
export declare const writeOverrides: (root: string, { check }?: {
|
|
30
|
+
check?: boolean;
|
|
31
|
+
}) => Promise<OverridesResult>;
|
|
32
|
+
//# sourceMappingURL=overrides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../src/overrides.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,EAAE,KAAG,MASnC,CAAA;AAEd,qBAAa,cAAe,SAAQ,KAAK;CAAG;AAwB5C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,+DAA+D;IAC/D,OAAO,EAAE,OAAO,CAAA;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,MAAM,EACZ,YAAmB;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,KAC1C,OAAO,CAAC,eAAe,CA8BzB,CAAA"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { submodules, uninitialised } from "./submodules.js";
|
|
4
|
+
import { readPackageName } from "./scaffold.js";
|
|
5
|
+
const MARKER = '# fg:overrides';
|
|
6
|
+
const WORKSPACE = 'pnpm-workspace.yaml';
|
|
7
|
+
/**
|
|
8
|
+
* The block that makes a distribution's own checkouts win.
|
|
9
|
+
*
|
|
10
|
+
* Without it, a module resolves a sibling through its declared range, and the
|
|
11
|
+
* range stops matching the moment the sibling's submodule is bumped past it —
|
|
12
|
+
* at which point pnpm quietly installs the published copy instead of the
|
|
13
|
+
* checkout. `workspace:*` says what the distribution means: whatever is in the
|
|
14
|
+
* tree, whatever version it is at.
|
|
15
|
+
*
|
|
16
|
+
* Names, not versions. The version still comes from the submodule pin, which
|
|
17
|
+
* is the whole point of pinning it there.
|
|
18
|
+
*/
|
|
19
|
+
export const overridesBlock = (names) => [
|
|
20
|
+
MARKER,
|
|
21
|
+
'# A distribution uses its own checkouts, whatever version they are at. The',
|
|
22
|
+
'# ranges in each module stay honest for publishing; this is what stops them',
|
|
23
|
+
'# being resolved from the registry once a submodule moves past them.',
|
|
24
|
+
'overrides:',
|
|
25
|
+
...names.map((name) => ` "${name}": "workspace:*"`),
|
|
26
|
+
`${MARKER}:end`,
|
|
27
|
+
].join('\n');
|
|
28
|
+
export class OverridesError extends Error {
|
|
29
|
+
}
|
|
30
|
+
/** Replace the block if it is there, otherwise put one at the end. */
|
|
31
|
+
const splice = (source, block) => {
|
|
32
|
+
const start = source.indexOf(`${MARKER}\n`);
|
|
33
|
+
const end = source.indexOf(`${MARKER}:end`);
|
|
34
|
+
if (start !== -1 && end !== -1) {
|
|
35
|
+
return source.slice(0, start) + block + source.slice(end + `${MARKER}:end`.length);
|
|
36
|
+
}
|
|
37
|
+
// A second `overrides:` key is not a merge, it is a YAML file pnpm will
|
|
38
|
+
// either reject or read half of. Whoever wrote the existing one meant it.
|
|
39
|
+
if (/^overrides:/m.test(source)) {
|
|
40
|
+
throw new OverridesError(`${WORKSPACE} already has an \`overrides:\` key that this did not write. ` +
|
|
41
|
+
`Put ${MARKER} and ${MARKER}:end around it, or fold the modules into it yourself.`);
|
|
42
|
+
}
|
|
43
|
+
const separator = source.endsWith('\n') ? '\n' : '\n\n';
|
|
44
|
+
return `${source}${separator}${block}\n`;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Point the distribution's overrides at every module it ships.
|
|
48
|
+
*
|
|
49
|
+
* A distribution with no submodules is left alone: there is nothing to
|
|
50
|
+
* override, and writing an empty block would only be noise.
|
|
51
|
+
*/
|
|
52
|
+
export const writeOverrides = async (root, { check = false } = {}) => {
|
|
53
|
+
const file = path.join(root, WORKSPACE);
|
|
54
|
+
// A submodule with no checkout has no package.json to read a name from, and
|
|
55
|
+
// dropping its entry would quietly let that module resolve from the registry
|
|
56
|
+
// — which is the exact thing these overrides exist to prevent.
|
|
57
|
+
const absent = uninitialised(root);
|
|
58
|
+
if (absent.length > 0) {
|
|
59
|
+
throw new OverridesError(`These submodules are not checked out, so their names cannot be read: ` +
|
|
60
|
+
`${absent.join(', ')}.\nRun \`git submodule update --init\` first.`);
|
|
61
|
+
}
|
|
62
|
+
const names = [];
|
|
63
|
+
for (const submodule of submodules(root)) {
|
|
64
|
+
const name = await readPackageName(submodule.path);
|
|
65
|
+
if (name)
|
|
66
|
+
names.push(name);
|
|
67
|
+
}
|
|
68
|
+
names.sort();
|
|
69
|
+
const existing = await readFile(file, 'utf8').catch(() => undefined);
|
|
70
|
+
if (existing === undefined)
|
|
71
|
+
return { file, names, changed: false, missing: true };
|
|
72
|
+
if (names.length === 0)
|
|
73
|
+
return { file, names, changed: false, missing: false };
|
|
74
|
+
const updated = splice(existing, overridesBlock(names));
|
|
75
|
+
if (updated === existing)
|
|
76
|
+
return { file, names, changed: false, missing: false };
|
|
77
|
+
if (!check)
|
|
78
|
+
await writeFile(file, updated);
|
|
79
|
+
return { file, names, changed: true, missing: false };
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=overrides.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overrides.js","sourceRoot":"","sources":["../src/overrides.ts"],"names":[],"mappings":"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"}
|
package/dist/readme.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replace the block a marker delimits, or add one.
|
|
3
|
+
*
|
|
4
|
+
* A new block goes after the first heading, which is where someone looking for
|
|
5
|
+
* a version would look first.
|
|
6
|
+
*/
|
|
7
|
+
export declare const updateSection: (source: string, marker: string, body: string,
|
|
8
|
+
/**
|
|
9
|
+
* Marker whose block this one belongs under, when it has to be inserted.
|
|
10
|
+
* Without it a new block goes straight after the first heading, which means
|
|
11
|
+
* whichever block is written last ends up on top.
|
|
12
|
+
*/
|
|
13
|
+
after?: string) => string;
|
|
14
|
+
export interface ModuleVersion {
|
|
15
|
+
name: string;
|
|
16
|
+
/** The version its own package.json declares. */
|
|
17
|
+
version: string;
|
|
18
|
+
relativePath: string;
|
|
19
|
+
/** The commit the distribution pins. */
|
|
20
|
+
pinned: string;
|
|
21
|
+
/** The version tag at that commit, or the newest one behind it. */
|
|
22
|
+
tag: string | undefined;
|
|
23
|
+
/** Whether the tag is the pinned commit rather than an ancestor of it. */
|
|
24
|
+
released: boolean;
|
|
25
|
+
/** Where the repository can be browsed, when it has a web address. */
|
|
26
|
+
url: string | undefined;
|
|
27
|
+
/** What the module is, from its own package.json. */
|
|
28
|
+
description: string | undefined;
|
|
29
|
+
}
|
|
30
|
+
/** What a distribution ships, read from the checkouts. */
|
|
31
|
+
export declare const moduleVersions: (root: string) => Promise<ModuleVersion[]>;
|
|
32
|
+
/**
|
|
33
|
+
* How to release this module, written into the module's own readme.
|
|
34
|
+
*
|
|
35
|
+
* The same words in every module, with this one's version and branch names
|
|
36
|
+
* filled in — so "how do I release this" is answered where someone is already
|
|
37
|
+
* standing, rather than in a document they have to know exists.
|
|
38
|
+
*/
|
|
39
|
+
export declare const releasingSection: (name: string, version: string) => string;
|
|
40
|
+
export interface ReadmeUpdate {
|
|
41
|
+
file: string;
|
|
42
|
+
changed: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface ReadmeResult {
|
|
45
|
+
updates: ReadmeUpdate[];
|
|
46
|
+
modules: ModuleVersion[];
|
|
47
|
+
/** What was found here: a distribution listing modules, or a module itself. */
|
|
48
|
+
kind: 'distribution' | 'module';
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Write the versions into the distribution's readme and each module's.
|
|
52
|
+
*
|
|
53
|
+
* Idempotent: running it again when nothing has moved rewrites nothing.
|
|
54
|
+
*/
|
|
55
|
+
export declare const writeReadmes: (root: string, { check }?: {
|
|
56
|
+
check?: boolean;
|
|
57
|
+
}) => Promise<ReadmeResult>;
|
|
58
|
+
//# sourceMappingURL=readme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readme.d.ts","sourceRoot":"","sources":["../src/readme.ts"],"names":[],"mappings":"AA2CA;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,QAAQ,MAAM,EACd,QAAQ,MAAM,EACd,MAAM,MAAM;AACZ;;;;GAIG;AACH,QAAQ,MAAM,KACb,MA2BF,CAAA;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAA;IACd,mEAAmE;IACnE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;IACvB,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAA;IACjB,sEAAsE;IACtE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;IACvB,qDAAqD;IACrD,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;CAChC;AAqCD,0DAA0D;AAC1D,eAAO,MAAM,cAAc,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,aAAa,EAAE,CAS1E,CAAA;AAkED;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,SAAS,MAAM,KAAG,MA4DhE,CAAA;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB,+EAA+E;IAC/E,IAAI,EAAE,cAAc,GAAG,QAAQ,CAAA;CAChC;AA8BD;;;;GAIG;AACH,eAAO,MAAM,YAAY,GACvB,MAAM,MAAM,EACZ,YAAmB;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,KAC1C,OAAO,CAAC,YAAY,CA6FtB,CAAA"}
|