@loomcli/loom 0.0.0 → 0.7.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/LICENSE +21 -0
- package/README.md +24 -0
- package/dist/application.d.ts +2 -0
- package/dist/application.js +5 -0
- package/dist/build.d.ts +31 -0
- package/dist/build.js +37 -0
- package/dist/commands/changelog/command.d.ts +2 -0
- package/dist/commands/changelog/command.js +58 -0
- package/dist/commands/changelog/write.d.ts +2 -0
- package/dist/commands/changelog/write.js +98 -0
- package/dist/commands/pr/command.d.ts +2 -0
- package/dist/commands/pr/command.js +24 -0
- package/dist/commands/release/command.d.ts +2 -0
- package/dist/commands/release/command.js +78 -0
- package/dist/helpers/fragments.d.ts +5 -0
- package/dist/helpers/fragments.js +60 -0
- package/dist/helpers/github.d.ts +42 -0
- package/dist/helpers/github.js +97 -0
- package/dist/helpers/http.d.ts +17 -0
- package/dist/helpers/http.js +134 -0
- package/dist/helpers/markdown.d.ts +16 -0
- package/dist/helpers/markdown.js +40 -0
- package/dist/helpers/material.d.ts +4 -0
- package/dist/helpers/material.js +103 -0
- package/dist/helpers/pr-check.d.ts +6 -0
- package/dist/helpers/pr-check.js +65 -0
- package/dist/helpers/registry.d.ts +16 -0
- package/dist/helpers/registry.js +78 -0
- package/dist/helpers/release-check.d.ts +1 -0
- package/dist/helpers/release-check.js +76 -0
- package/dist/helpers/release-files.d.ts +13 -0
- package/dist/helpers/release-files.js +97 -0
- package/dist/helpers/release-plan.d.ts +39 -0
- package/dist/helpers/release-plan.js +221 -0
- package/dist/helpers/release-record.d.ts +12 -0
- package/dist/helpers/release-record.js +99 -0
- package/dist/helpers/release.d.ts +48 -0
- package/dist/helpers/release.js +111 -0
- package/dist/helpers/repository.d.ts +88 -0
- package/dist/helpers/repository.js +124 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +2 -0
- package/package.json +35 -3
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { lstatSync, readdirSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
const manifestSchema = z.looseObject({
|
|
6
|
+
dependencies: z.record(z.string(), z.string()).optional(),
|
|
7
|
+
devDependencies: z.record(z.string(), z.string()).optional(),
|
|
8
|
+
name: z.string().min(1),
|
|
9
|
+
optionalDependencies: z.record(z.string(), z.string()).optional(),
|
|
10
|
+
peerDependencies: z.record(z.string(), z.string()).optional(),
|
|
11
|
+
private: z.boolean().optional(),
|
|
12
|
+
version: z.string(),
|
|
13
|
+
});
|
|
14
|
+
function gitBytes(root, args) {
|
|
15
|
+
const result = spawnSync('git', ['--literal-pathspecs', ...args], {
|
|
16
|
+
cwd: root,
|
|
17
|
+
});
|
|
18
|
+
if (result.error) {
|
|
19
|
+
throw result.error;
|
|
20
|
+
}
|
|
21
|
+
if (result.status !== 0) {
|
|
22
|
+
throw new Error(`git ${args[0]} failed: ${result.stderr.toString('utf8').trim()}`);
|
|
23
|
+
}
|
|
24
|
+
return result.stdout;
|
|
25
|
+
}
|
|
26
|
+
export function git(root, args) {
|
|
27
|
+
return gitBytes(root, args).toString('utf8');
|
|
28
|
+
}
|
|
29
|
+
export function readDirectory(root, path, ref) {
|
|
30
|
+
if (ref === undefined) {
|
|
31
|
+
return readdirSync(join(root, path), { withFileTypes: true });
|
|
32
|
+
}
|
|
33
|
+
return git(root, ['ls-tree', '-z', `${ref}:${path}`])
|
|
34
|
+
.split('\0')
|
|
35
|
+
.filter(Boolean)
|
|
36
|
+
.map((entry) => {
|
|
37
|
+
const tab = entry.indexOf('\t');
|
|
38
|
+
const mode = entry.slice(0, 6);
|
|
39
|
+
return {
|
|
40
|
+
isDirectory: () => mode === '040000',
|
|
41
|
+
isFile: () => mode === '100644' || mode === '100755',
|
|
42
|
+
isSymbolicLink: () => mode === '120000',
|
|
43
|
+
name: entry.slice(tab + 1),
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export function readRegularFileBytes(root, path, ref) {
|
|
48
|
+
if (ref !== undefined) {
|
|
49
|
+
const entry = git(root, ['ls-tree', '-z', ref, '--', path]);
|
|
50
|
+
if (!/^100(?:644|755) blob /u.test(entry)) {
|
|
51
|
+
throw new Error(`${path}: expected a regular file.`);
|
|
52
|
+
}
|
|
53
|
+
return gitBytes(root, ['show', `${ref}:${path}`]);
|
|
54
|
+
}
|
|
55
|
+
const absolute = join(root, path);
|
|
56
|
+
if (!lstatSync(absolute).isFile()) {
|
|
57
|
+
throw new Error(`${path}: expected a regular file.`);
|
|
58
|
+
}
|
|
59
|
+
return readFileSync(absolute);
|
|
60
|
+
}
|
|
61
|
+
export function readRegularFile(root, path, ref) {
|
|
62
|
+
return readRegularFileBytes(root, path, ref).toString('utf8');
|
|
63
|
+
}
|
|
64
|
+
// A shallow clone hides the commits the material baseline and the release notes are derived from.
|
|
65
|
+
export function requireFullHistory(root) {
|
|
66
|
+
if (git(root, ['rev-parse', '--is-shallow-repository']).trim() === 'true') {
|
|
67
|
+
throw new Error('Release preparation requires full Git history.');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// The non-private manifests under packages/, empty when the ref carries no packages tree.
|
|
71
|
+
export function readParticipants(root, ref) {
|
|
72
|
+
if (ref !== undefined &&
|
|
73
|
+
!git(root, ['ls-tree', '-z', ref, '--', 'packages']).startsWith('040000 tree ')) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
return readDirectory(root, 'packages', ref).flatMap((entry) => {
|
|
77
|
+
if (entry.isSymbolicLink()) {
|
|
78
|
+
throw new Error(`packages/${entry.name}: symlinks are not supported.`);
|
|
79
|
+
}
|
|
80
|
+
if (!entry.isDirectory()) {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
const directory = `packages/${entry.name}`;
|
|
84
|
+
const path = `${directory}/package.json`;
|
|
85
|
+
const source = readRegularFile(root, path, ref);
|
|
86
|
+
const input = JSON.parse(source);
|
|
87
|
+
if (z.object({ private: z.boolean().optional() }).parse(input).private) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
const manifest = manifestSchema.parse(input);
|
|
91
|
+
return [{ directory, manifest, path, source }];
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
// Participating libraries share one name space and one version, because only a release cut moves them.
|
|
95
|
+
export function requireCoherentLibraries(libraries) {
|
|
96
|
+
if (new Set(libraries.map((library) => library.manifest.name)).size !== libraries.length) {
|
|
97
|
+
throw new Error('Publishable library names must be unique.');
|
|
98
|
+
}
|
|
99
|
+
const versions = new Set(libraries.map((library) => library.manifest.version));
|
|
100
|
+
if (versions.size !== 1) {
|
|
101
|
+
throw new Error('Publishable library versions must match.');
|
|
102
|
+
}
|
|
103
|
+
return libraries;
|
|
104
|
+
}
|
|
105
|
+
export function readLibraries(root, ref) {
|
|
106
|
+
const [first, ...rest] = readParticipants(root, ref);
|
|
107
|
+
if (first === undefined) {
|
|
108
|
+
throw new Error('No publishable libraries in packages/*.');
|
|
109
|
+
}
|
|
110
|
+
return requireCoherentLibraries([first, ...rest]);
|
|
111
|
+
}
|
|
112
|
+
export function currentVersion(libraries) {
|
|
113
|
+
const version = libraries[0]?.manifest.version;
|
|
114
|
+
const match = /^0\.(?<minor>0|[1-9]\d*)\.(?<patch>0|[1-9]\d*)$/u.exec(version ?? '');
|
|
115
|
+
if (!match) {
|
|
116
|
+
throw new Error('Library versions must be stable 0.x versions.');
|
|
117
|
+
}
|
|
118
|
+
const minor = Number(match.groups?.minor);
|
|
119
|
+
const patch = Number(match.groups?.patch);
|
|
120
|
+
if (!Number.isSafeInteger(minor + 1) || !Number.isSafeInteger(patch + 1)) {
|
|
121
|
+
throw new Error('Library version components are too large.');
|
|
122
|
+
}
|
|
123
|
+
return { minor, patch, text: `0.${minor}.${patch}` };
|
|
124
|
+
}
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/main.js
ADDED
package/package.json
CHANGED
|
@@ -1,10 +1,42 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loomcli/loom",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.7.0",
|
|
4
|
+
"description": "The Loom CLI toolchain. Provides the packet() Bun.build plugin that marks a bundled Loom CLI application as a distributed build.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/dbtlr/loomcli.git"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
14
|
+
"type": "module",
|
|
15
|
+
"exports": {
|
|
16
|
+
"./build": {
|
|
17
|
+
"types": "./dist/build.d.ts",
|
|
18
|
+
"import": "./dist/build.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@loomcli/core": "0.7.0",
|
|
23
|
+
"mdast-util-from-markdown": "^2.0.3",
|
|
24
|
+
"yaml": "^2.9.1",
|
|
25
|
+
"zod": "^4.6.5"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"pnpm": "12.8.1"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"pnpm": "12.8.1"
|
|
32
|
+
},
|
|
33
|
+
"peerDependenciesMeta": {
|
|
34
|
+
"pnpm": {
|
|
35
|
+
"optional": true
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"bun": ">=1.4.0",
|
|
40
|
+
"node": ">=22.23.2"
|
|
9
41
|
}
|
|
10
|
-
}
|
|
42
|
+
}
|