tegami 1.0.0-beta.3 → 1.0.0-beta.5
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/dist/cargo-hlZX2akE.js +292 -0
- package/dist/cli/index.d.ts +7 -5
- package/dist/cli/index.js +215 -222
- package/dist/draft-DtFyGxe8.js +455 -0
- package/dist/generators/simple.d.ts +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +30 -481
- package/dist/{npm-BzhclYfR.js → npm-CMOyacwf.js} +2 -2
- package/dist/plugins/git.d.ts +1 -1
- package/dist/plugins/git.js +21 -13
- package/dist/plugins/github.d.ts +1 -1
- package/dist/plugins/github.js +349 -45
- package/dist/plugins/gitlab.d.ts +1 -3
- package/dist/plugins/gitlab.js +264 -56
- package/dist/plugins/go.d.ts +1 -1
- package/dist/plugins/go.js +2 -2
- package/dist/providers/cargo.d.ts +1 -1
- package/dist/providers/cargo.js +1 -280
- package/dist/providers/npm.d.ts +1 -1
- package/dist/providers/npm.js +1 -1
- package/dist/{types-BHT_9k9p.d.ts → types-C1rEqeM4.d.ts} +153 -15
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.js +2 -0
- package/dist/{version-request-cFS0Suzd.js → version-request-DKvR3_xb.js} +3 -1
- package/package.json +4 -4
- package/dist/api-CGfXmmEM.js +0 -122
- package/dist/index-syNgzQTi.d.ts +0 -64
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { n as execFailure } from "./error-We7chQVJ.js";
|
|
2
|
+
import { n as WorkspacePackage } from "./graph-gThXu8Cz.js";
|
|
3
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
4
|
+
import { join, normalize } from "node:path";
|
|
5
|
+
import { x } from "tinyexec";
|
|
6
|
+
import * as semver$1 from "semver";
|
|
7
|
+
import z from "zod";
|
|
8
|
+
import initToml, { edit, parse as parse$1 } from "@rainbowatcher/toml-edit-js";
|
|
9
|
+
import { glob } from "tinyglobby";
|
|
10
|
+
//#region src/providers/cargo/schema.ts
|
|
11
|
+
const cargoDependencySchema = z.union([z.string(), z.object({
|
|
12
|
+
version: z.string(),
|
|
13
|
+
package: z.string().optional(),
|
|
14
|
+
path: z.string().optional()
|
|
15
|
+
})]);
|
|
16
|
+
const cargoTargetConfigSchema = z.object({
|
|
17
|
+
dependencies: z.record(z.string(), cargoDependencySchema).optional(),
|
|
18
|
+
"dev-dependencies": z.record(z.string(), cargoDependencySchema).optional(),
|
|
19
|
+
"build-dependencies": z.record(z.string(), cargoDependencySchema).optional()
|
|
20
|
+
});
|
|
21
|
+
const cargoPackageSchema = z.object({
|
|
22
|
+
name: z.string(),
|
|
23
|
+
version: z.string().optional(),
|
|
24
|
+
publish: z.boolean().optional()
|
|
25
|
+
});
|
|
26
|
+
const cargoWorkspaceSchema = z.object({
|
|
27
|
+
members: z.array(z.string()).optional(),
|
|
28
|
+
exclude: z.array(z.string()).optional(),
|
|
29
|
+
package: z.object({ version: z.string().optional() }).optional()
|
|
30
|
+
});
|
|
31
|
+
const cargoManifestSchema = z.object({
|
|
32
|
+
package: cargoPackageSchema,
|
|
33
|
+
workspace: cargoWorkspaceSchema.optional(),
|
|
34
|
+
dependencies: z.record(z.string(), cargoDependencySchema).optional(),
|
|
35
|
+
"dev-dependencies": z.record(z.string(), cargoDependencySchema).optional(),
|
|
36
|
+
"build-dependencies": z.record(z.string(), cargoDependencySchema).optional(),
|
|
37
|
+
target: z.record(z.string(), cargoTargetConfigSchema).optional()
|
|
38
|
+
});
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region src/providers/cargo.ts
|
|
41
|
+
const DEP_FIELDS = [
|
|
42
|
+
"dependencies",
|
|
43
|
+
"dev-dependencies",
|
|
44
|
+
"build-dependencies"
|
|
45
|
+
];
|
|
46
|
+
var CargoPackage = class extends WorkspacePackage {
|
|
47
|
+
path;
|
|
48
|
+
manifest;
|
|
49
|
+
content;
|
|
50
|
+
workspaceManifest;
|
|
51
|
+
manager = "cargo";
|
|
52
|
+
constructor(path, manifest, content, workspaceManifest) {
|
|
53
|
+
super();
|
|
54
|
+
this.path = path;
|
|
55
|
+
this.manifest = manifest;
|
|
56
|
+
this.content = content;
|
|
57
|
+
this.workspaceManifest = workspaceManifest;
|
|
58
|
+
}
|
|
59
|
+
get name() {
|
|
60
|
+
return this.packageInfo.name;
|
|
61
|
+
}
|
|
62
|
+
get version() {
|
|
63
|
+
return this.packageInfo.version ?? this.workspaceVersion;
|
|
64
|
+
}
|
|
65
|
+
setVersion(version) {
|
|
66
|
+
this.packageInfo.version = version;
|
|
67
|
+
this.patch("package.version", version);
|
|
68
|
+
}
|
|
69
|
+
async write() {
|
|
70
|
+
await writeFile(join(this.path, "Cargo.toml"), this.content + "\n");
|
|
71
|
+
}
|
|
72
|
+
patch(path, value) {
|
|
73
|
+
this.content = edit(this.content, path, value);
|
|
74
|
+
}
|
|
75
|
+
get packageInfo() {
|
|
76
|
+
return this.manifest.package;
|
|
77
|
+
}
|
|
78
|
+
get workspaceVersion() {
|
|
79
|
+
return this.workspaceManifest?.workspace?.package?.version;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
function cargo({ updateLockFile = true, bumpDep: getBumpDepType } = {}) {
|
|
83
|
+
let active = false;
|
|
84
|
+
return {
|
|
85
|
+
name: "cargo",
|
|
86
|
+
enforce: "pre",
|
|
87
|
+
async init() {
|
|
88
|
+
await initToml();
|
|
89
|
+
},
|
|
90
|
+
async resolve() {
|
|
91
|
+
await discoverCargoPackages(this.cwd, (pkg) => this.graph.add(pkg));
|
|
92
|
+
active = this.graph.getPackages().some((pkg) => pkg instanceof CargoPackage);
|
|
93
|
+
},
|
|
94
|
+
initDraft(plan) {
|
|
95
|
+
if (!active) return;
|
|
96
|
+
plan.addPolicy(depsPolicy(this, getBumpDepType));
|
|
97
|
+
},
|
|
98
|
+
async publishPreflight({ pkg }) {
|
|
99
|
+
if (!(pkg instanceof CargoPackage)) return;
|
|
100
|
+
const wait = [];
|
|
101
|
+
for (const { table } of dependencyTables(pkg.manifest, "")) for (const [rawName, dep] of Object.entries(table)) {
|
|
102
|
+
if (!dep || typeof dep === "string" || !dep.path) continue;
|
|
103
|
+
const id = `cargo:${dep.package ?? rawName}`;
|
|
104
|
+
const linked = this.graph.get(id);
|
|
105
|
+
if (!linked || !(linked instanceof CargoPackage)) continue;
|
|
106
|
+
wait.push(id);
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
shouldPublish: pkg.version !== void 0 && pkg.packageInfo.publish !== false,
|
|
110
|
+
wait
|
|
111
|
+
};
|
|
112
|
+
},
|
|
113
|
+
resolvePlanStatus({ plan }) {
|
|
114
|
+
return Array.from(plan.packages, async ([id, { preflight }]) => {
|
|
115
|
+
if (!preflight.shouldPublish) return;
|
|
116
|
+
const pkg = this.graph.get(id);
|
|
117
|
+
if (!(pkg instanceof CargoPackage) || !pkg.version) return;
|
|
118
|
+
if (!await isPackagePublished(pkg.name, pkg.version)) return "pending";
|
|
119
|
+
});
|
|
120
|
+
},
|
|
121
|
+
async publish({ pkg }) {
|
|
122
|
+
if (!(pkg instanceof CargoPackage)) return;
|
|
123
|
+
const result = await x("cargo", ["publish"], { nodeOptions: { cwd: pkg.path } });
|
|
124
|
+
if (result.exitCode !== 0) {
|
|
125
|
+
if (/already exists|already published/i.test(`${result.stdout}\n${result.stderr}`)) return { type: "skipped" };
|
|
126
|
+
return {
|
|
127
|
+
type: "failed",
|
|
128
|
+
error: execFailure(`Failed to publish ${pkg.name}@${pkg.version}.`, result).message
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return { type: "published" };
|
|
132
|
+
},
|
|
133
|
+
async applyDraft(draft) {
|
|
134
|
+
if (!active) return;
|
|
135
|
+
const { graph } = this;
|
|
136
|
+
const writes = [];
|
|
137
|
+
for (const pkg of graph.getPackages()) {
|
|
138
|
+
if (!(pkg instanceof CargoPackage)) continue;
|
|
139
|
+
const bumped = draft.getPackageDraft(pkg.id)?.bumpVersion(pkg);
|
|
140
|
+
if (bumped) pkg.setVersion(bumped);
|
|
141
|
+
}
|
|
142
|
+
for (const pkg of graph.getPackages()) {
|
|
143
|
+
if (!(pkg instanceof CargoPackage)) continue;
|
|
144
|
+
for (const { table, path: tablePath } of dependencyTables(pkg.manifest, "")) for (const [rawName, rawSpec] of Object.entries(table)) {
|
|
145
|
+
const spec = parseSpec(rawSpec);
|
|
146
|
+
if (!spec || !semver$1.validRange(spec.version)) continue;
|
|
147
|
+
const packageName = spec.package ?? rawName;
|
|
148
|
+
const linked = graph.get(`cargo:${packageName}`);
|
|
149
|
+
if (!linked || !(linked instanceof CargoPackage)) continue;
|
|
150
|
+
if (!linked.version || semver$1.satisfies(linked.version, spec.version)) continue;
|
|
151
|
+
let updatedRange;
|
|
152
|
+
if (spec.version.startsWith("^")) updatedRange = `^${linked.version}`;
|
|
153
|
+
else if (spec.version.startsWith("~")) updatedRange = `~${linked.version}`;
|
|
154
|
+
else updatedRange = linked.version;
|
|
155
|
+
table[rawName] = spec.setVersion(updatedRange);
|
|
156
|
+
pkg.patch(typeof rawSpec === "string" ? `${tablePath}.${rawName}` : `${tablePath}.${rawName}.version`, updatedRange);
|
|
157
|
+
}
|
|
158
|
+
writes.push(pkg.write());
|
|
159
|
+
}
|
|
160
|
+
await Promise.all(writes);
|
|
161
|
+
},
|
|
162
|
+
async applyCliDraft() {
|
|
163
|
+
if (!active || !updateLockFile) return;
|
|
164
|
+
const result = await x("cargo", ["update", "--workspace"], { nodeOptions: { cwd: this.cwd } });
|
|
165
|
+
if (result.exitCode !== 0) throw execFailure("Failed to update Cargo lock file", result);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function depsPolicy({ graph }, getBumpDepType = ({ kind }) => {
|
|
170
|
+
switch (kind) {
|
|
171
|
+
case "dependencies": return "patch";
|
|
172
|
+
case "build-dependencies":
|
|
173
|
+
case "dev-dependencies": return false;
|
|
174
|
+
}
|
|
175
|
+
}) {
|
|
176
|
+
return {
|
|
177
|
+
id: "cargo:deps",
|
|
178
|
+
onUpdate({ pkg, packageDraft: plan }) {
|
|
179
|
+
if (!(pkg instanceof CargoPackage)) return;
|
|
180
|
+
const group = graph.getPackageGroup(pkg.id);
|
|
181
|
+
for (const dependent of graph.getPackages()) {
|
|
182
|
+
if (!(dependent instanceof CargoPackage)) continue;
|
|
183
|
+
for (const { table, kind } of dependencyTables(dependent.manifest, "")) for (const [rawName, rawSpec] of Object.entries(table)) {
|
|
184
|
+
const spec = parseSpec(rawSpec);
|
|
185
|
+
if (!spec || !semver$1.validRange(spec.version)) continue;
|
|
186
|
+
if (pkg.id !== `cargo:${spec.package ?? rawName}`) continue;
|
|
187
|
+
if (group?.options.syncBump && graph.getPackageGroup(dependent.id) === group) continue;
|
|
188
|
+
const bumped = plan.bumpVersion(pkg);
|
|
189
|
+
if (!bumped || semver$1.satisfies(bumped, spec.version)) continue;
|
|
190
|
+
const bumpType = getBumpDepType({
|
|
191
|
+
kind,
|
|
192
|
+
dependent,
|
|
193
|
+
name: pkg.name,
|
|
194
|
+
version: spec.version
|
|
195
|
+
});
|
|
196
|
+
if (bumpType === false) continue;
|
|
197
|
+
this.bumpPackage(dependent, {
|
|
198
|
+
type: bumpType,
|
|
199
|
+
reason: `update dependency "${rawName}"`
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
async function isPackagePublished(name, version) {
|
|
207
|
+
const response = await fetch(`https://crates.io/api/v1/crates/${encodeURIComponent(name)}/${version}`);
|
|
208
|
+
if (response.status === 200) return true;
|
|
209
|
+
if (response.status === 404) return false;
|
|
210
|
+
throw new Error(`Unable to validate ${name}@${version} against crates.io: ${await response.text()}`);
|
|
211
|
+
}
|
|
212
|
+
async function buildEntry(path) {
|
|
213
|
+
try {
|
|
214
|
+
const content = await readFile(join(path, "Cargo.toml"), "utf8");
|
|
215
|
+
return {
|
|
216
|
+
manifest: cargoManifestSchema.parse(parse$1(content)),
|
|
217
|
+
content,
|
|
218
|
+
path
|
|
219
|
+
};
|
|
220
|
+
} catch {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
async function discoverCargoPackages(cwd, add) {
|
|
225
|
+
const root = await buildEntry(cwd);
|
|
226
|
+
if (!root) return;
|
|
227
|
+
if (root.manifest.package?.name) add(new CargoPackage(cwd, root.manifest, root.content, root.manifest));
|
|
228
|
+
const workspace = root.manifest.workspace;
|
|
229
|
+
if (!workspace?.members) return;
|
|
230
|
+
const paths = await expandWorkspaceMembers(cwd, workspace.members, workspace.exclude);
|
|
231
|
+
const manifests = await Promise.all(paths.map(buildEntry));
|
|
232
|
+
for (const entry of manifests) if (entry?.manifest.package?.name) add(new CargoPackage(entry.path, entry.manifest, entry.content, root.manifest));
|
|
233
|
+
}
|
|
234
|
+
async function expandWorkspaceMembers(cwd, members, exclude = []) {
|
|
235
|
+
const paths = members.includes(".") ? [cwd] : [];
|
|
236
|
+
const patterns = members.filter((member) => member !== ".");
|
|
237
|
+
if (patterns.length > 0) paths.push(...await glob(patterns, {
|
|
238
|
+
absolute: true,
|
|
239
|
+
cwd,
|
|
240
|
+
ignore: ["**/target/**", ...exclude],
|
|
241
|
+
onlyDirectories: true,
|
|
242
|
+
onlyFiles: false
|
|
243
|
+
}));
|
|
244
|
+
return paths.map(normalize);
|
|
245
|
+
}
|
|
246
|
+
function dependencyTables(manifest, prefix) {
|
|
247
|
+
const tables = [];
|
|
248
|
+
for (const field of DEP_FIELDS) {
|
|
249
|
+
const table = manifest[field];
|
|
250
|
+
if (table) {
|
|
251
|
+
const path = prefix ? `${prefix}.${field}` : field;
|
|
252
|
+
tables.push({
|
|
253
|
+
kind: field,
|
|
254
|
+
table,
|
|
255
|
+
path
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
const target = manifest.target;
|
|
260
|
+
if (target) for (const [targetKey, targetConfig] of Object.entries(target)) {
|
|
261
|
+
const targetPath = prefix ? `${prefix}.target.${targetKey}` : `target.${targetKey}`;
|
|
262
|
+
for (const field of DEP_FIELDS) {
|
|
263
|
+
const table = targetConfig[field];
|
|
264
|
+
if (table) tables.push({
|
|
265
|
+
kind: field,
|
|
266
|
+
table,
|
|
267
|
+
path: `${targetPath}.${field}`
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return tables;
|
|
272
|
+
}
|
|
273
|
+
function parseSpec(v) {
|
|
274
|
+
if (typeof v === "string") return {
|
|
275
|
+
version: v,
|
|
276
|
+
setVersion(version) {
|
|
277
|
+
return version;
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
return {
|
|
281
|
+
package: v.package,
|
|
282
|
+
version: v.version,
|
|
283
|
+
setVersion(version) {
|
|
284
|
+
return {
|
|
285
|
+
...v,
|
|
286
|
+
version
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
//#endregion
|
|
292
|
+
export { cargo as n, CargoPackage as t };
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as Tegami } from "../index-syNgzQTi.js";
|
|
3
|
-
import { Command } from "commander";
|
|
1
|
+
import { O as Draft, _ as PublishPlan, t as Awaitable, u as Tegami } from "../types-C1rEqeM4.js";
|
|
4
2
|
|
|
5
3
|
//#region src/cli/index.d.ts
|
|
6
4
|
interface TegamiCLIOptions {
|
|
@@ -8,6 +6,10 @@ interface TegamiCLIOptions {
|
|
|
8
6
|
version?: () => Awaitable<Draft>;
|
|
9
7
|
publish?: () => Awaitable<PublishPlan>;
|
|
10
8
|
}
|
|
11
|
-
|
|
9
|
+
interface TegamiCLI {
|
|
10
|
+
parseAsync(argv?: string[]): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
declare function createCli(tegami: Tegami, options?: TegamiCLIOptions): TegamiCLI;
|
|
13
|
+
declare function runCli(tegami: Tegami, options?: TegamiCLIOptions): Promise<void>;
|
|
12
14
|
//#endregion
|
|
13
|
-
export { TegamiCLIOptions, createCli };
|
|
15
|
+
export { TegamiCLI, TegamiCLIOptions, createCli, runCli };
|