tegami 1.0.0-beta.4 → 1.0.1

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.
@@ -1,4 +1,4 @@
1
- import { O as Draft, _ as PublishPlan, t as Awaitable, u as Tegami } from "../types-DKZsadC8.js";
1
+ import { T as Draft, p as Tegami, t as Awaitable, y as PublishPlan } from "../types-DItu_YCc.js";
2
2
 
3
3
  //#region src/cli/index.d.ts
4
4
  interface TegamiCLIOptions {
package/dist/cli/index.js CHANGED
@@ -1,5 +1,6 @@
1
- import { i as renderChangelog, n as generateFromCommits, t as changelogFilename } from "../generate-BfYdNTFi.js";
2
- import { o as isCI, r as handlePluginError, t as CancelledError } from "../error-We7chQVJ.js";
1
+ import { n as generateFromCommits, t as changelogFilename } from "../generate-Rvz4Lu98.js";
2
+ import { o as isCI, r as handlePluginError, t as CancelledError } from "../error-BhMYq9iW.js";
3
+ import { n as renderChangelog } from "../shared-C92toqVI.js";
3
4
  import { mkdir, readFile, writeFile } from "node:fs/promises";
4
5
  import path, { join, relative } from "node:path";
5
6
  import { x } from "tinyexec";
@@ -349,10 +350,10 @@ function parseCommandArgs(command, args) {
349
350
  type: "boolean",
350
351
  short: "h"
351
352
  } };
352
- for (const option of command.options) optionConfig[option.name] = {
353
+ for (const option of command.options) optionConfig[option.name] = option.short ? {
353
354
  type: option.type,
354
355
  short: option.short
355
- };
356
+ } : { type: option.type };
356
357
  const parsed = parseArgs({
357
358
  args,
358
359
  options: optionConfig,
@@ -453,8 +454,14 @@ function registerCoreCommands(cli, tegami, options) {
453
454
  cli.command("", { description: "create changelog files interactively" }).action(async () => {
454
455
  await runChangelogTui(tegami);
455
456
  });
456
- cli.command("version", { description: "draft version changes and write the publish lock" }).action(async () => {
457
- await versionPackages(tegami, { cli: options });
457
+ cli.command("version", { description: "draft version changes and write the publish lock" }).option("no-checks", {
458
+ type: "boolean",
459
+ description: "skip checking whether the publish lock is still pending"
460
+ }).action(async ({ values }) => {
461
+ await versionPackages(tegami, {
462
+ cli: options,
463
+ noChecks: values["no-checks"]
464
+ });
458
465
  });
459
466
  cli.command("ci", { description: "version and publish packages" }).action(async () => {
460
467
  if (await versionPackages(tegami, { cli: options })) return;
@@ -499,7 +506,7 @@ async function versionPackages(tegami, options) {
499
506
  outro("No versions changed.");
500
507
  return false;
501
508
  }
502
- if (await tegami.publishStatus() === "pending") {
509
+ if (!options.noChecks && await tegami.publishStatus() === "pending") {
503
510
  note(`Publish lock at ${context.lockPath} is still pending. Publish it before applying a new draft.`);
504
511
  outro("Cannot apply.");
505
512
  return false;
@@ -1,6 +1,6 @@
1
1
  import { a as maxBump } from "./semver-EKJ8yK5U.js";
2
- import { i as renderChangelog, r as changelogFrontmatterSchema } from "./generate-BfYdNTFi.js";
3
- import { r as handlePluginError } from "./error-We7chQVJ.js";
2
+ import { r as handlePluginError } from "./error-BhMYq9iW.js";
3
+ import { n as renderChangelog, t as changelogFrontmatterSchema } from "./shared-C92toqVI.js";
4
4
  import { simpleGenerator } from "./generators/simple.js";
5
5
  import { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
6
6
  import path, { basename, dirname, join } from "node:path";
@@ -237,7 +237,7 @@ const packageStoreSchema = z.object({
237
237
  /** a draft describes all operations to perform before the actual publishing, such as version bumps. */
238
238
  var Draft = class {
239
239
  context;
240
- #applied = false;
240
+ #status = 0;
241
241
  /** package id -> draft */
242
242
  packages = /* @__PURE__ */ new Map();
243
243
  /** id -> changelog */
@@ -313,27 +313,36 @@ var Draft = class {
313
313
  }
314
314
  /** Apply version bumps, lock file, and changelog files. */
315
315
  async apply() {
316
- if (this.#applied) throw new Error("This draft has already been applied.");
317
- const { graph } = this.context;
318
- this.#applied = true;
319
- const snapshots = /* @__PURE__ */ new Map();
320
- for (const pkg of graph.getPackages()) snapshots.set(pkg.id, { version: pkg.version });
321
- for (const plugin of this.context.plugins) await handlePluginError(plugin, "applyDraft", () => plugin.applyDraft?.call(this.context, this));
322
- const updatedChangelogs = this.applyReplays(snapshots);
323
- const writes = [];
324
- for (const [id, packageDraft] of this.packages) {
325
- const pkg = graph.get(id);
326
- if (!pkg) continue;
327
- writes.push(this.appendChangelog(pkg, packageDraft));
316
+ switch (this.#status) {
317
+ case 1: throw new Error("This draft has already been applied.");
318
+ case 2: throw new Error("There is already a previous apply() run.");
319
+ case 3: throw new Error("The previous apply() run failed, please clear your local git changes and try again.");
328
320
  }
329
- for (const entry of this.changelogs.values()) {
330
- const updated = updatedChangelogs.get(entry.id);
331
- const filePath = path.join(this.context.changelogDir, entry.filename);
332
- if (updated) writes.push(mkdir(this.context.changelogDir, { recursive: true }).then(() => writeFile(filePath, updated.getRawContent())));
333
- else if (!entry.virtual) writes.push(rm(filePath, { force: true }));
321
+ const { graph } = this.context;
322
+ try {
323
+ const snapshots = /* @__PURE__ */ new Map();
324
+ for (const pkg of graph.getPackages()) snapshots.set(pkg.id, { version: pkg.version });
325
+ for (const plugin of this.context.plugins) await handlePluginError(plugin, "applyDraft", () => plugin.applyDraft?.call(this.context, this));
326
+ const updatedChangelogs = this.applyReplays(snapshots);
327
+ const writes = [];
328
+ for (const [id, packageDraft] of this.packages) {
329
+ const pkg = graph.get(id);
330
+ if (!pkg) continue;
331
+ writes.push(this.appendChangelog(pkg, packageDraft));
332
+ }
333
+ for (const entry of this.changelogs.values()) {
334
+ const updated = updatedChangelogs.get(entry.id);
335
+ const filePath = path.join(this.context.changelogDir, entry.filename);
336
+ if (updated) writes.push(mkdir(this.context.changelogDir, { recursive: true }).then(() => writeFile(filePath, updated.getRawContent())));
337
+ else if (!entry.virtual) writes.push(rm(filePath, { force: true }));
338
+ }
339
+ writes.push(this.writeLockFile(snapshots));
340
+ await Promise.all(writes);
341
+ this.#status = 1;
342
+ } catch (e) {
343
+ this.#status = 3;
344
+ throw e;
334
345
  }
335
- writes.push(this.writeLockFile(snapshots));
336
- await Promise.all(writes);
337
346
  }
338
347
  /** write persistent data to publish lock */
339
348
  async writeLockFile(snapshots) {
@@ -370,7 +379,7 @@ var Draft = class {
370
379
  if (idx !== -1) this.policies.splice(idx, 1);
371
380
  }
372
381
  canApply() {
373
- return !this.#applied;
382
+ return this.#status === 0;
374
383
  }
375
384
  /** Attach replaying changelog entries to packages (already bumped), and return the updated changelog entries. */
376
385
  applyReplays(snapshots) {
@@ -20,6 +20,19 @@ async function somePromise(promises, fn) {
20
20
  }
21
21
  });
22
22
  }
23
+ function joinPath(...paths) {
24
+ let out = "";
25
+ for (const path of paths) {
26
+ if (path.length === 0) continue;
27
+ if (!out) {
28
+ out = path;
29
+ continue;
30
+ }
31
+ if (!out.endsWith("/") && !path.startsWith("/")) out += "/";
32
+ out += path;
33
+ }
34
+ return out;
35
+ }
23
36
  function cached(cacheKey, fn, cacheMap = /* @__PURE__ */ new Map()) {
24
37
  return (...args) => {
25
38
  const key = cacheKey(...args);
@@ -73,4 +86,4 @@ async function handlePluginError(plugin, hookName, callback) {
73
86
  }
74
87
  }
75
88
  //#endregion
76
- export { cached as a, isNodeError as i, execFailure as n, isCI as o, handlePluginError as r, somePromise as s, CancelledError as t };
89
+ export { cached as a, somePromise as c, isNodeError as i, execFailure as n, isCI as o, handlePluginError as r, joinPath as s, CancelledError as t };
@@ -1,8 +1,7 @@
1
1
  import { a as maxBump, t as bumpDepth } from "./semver-EKJ8yK5U.js";
2
- import { n as execFailure } from "./error-We7chQVJ.js";
2
+ import { n as execFailure } from "./error-BhMYq9iW.js";
3
+ import { n as renderChangelog } from "./shared-C92toqVI.js";
3
4
  import { x } from "tinyexec";
4
- import z from "zod";
5
- import { dump } from "js-yaml";
6
5
  //#region src/utils/conventional-commit.ts
7
6
  /**
8
7
  * Conventional commit header per conventionalcommits.org and semantic-release defaults.
@@ -68,35 +67,6 @@ function conventionalCommitToBump(type, breaking) {
68
67
  }
69
68
  }
70
69
  //#endregion
71
- //#region src/changelog/shared.ts
72
- const bumpTypeSchema = z.enum([
73
- "major",
74
- "minor",
75
- "patch"
76
- ]);
77
- const changelogPackageConfigSchema = z.object({
78
- type: bumpTypeSchema.optional(),
79
- replay: z.array(z.string().min(1)).optional()
80
- });
81
- const changelogFrontmatterSchema = z.object({
82
- subject: z.string().optional(),
83
- packages: z.union([z.array(z.string()), z.record(z.string(), z.union([
84
- bumpTypeSchema,
85
- z.null(),
86
- changelogPackageConfigSchema
87
- ]))]).optional()
88
- });
89
- function renderChangelog(frontmatter, body) {
90
- return [
91
- "---",
92
- dump(frontmatter).trim(),
93
- "---",
94
- "",
95
- body.trim(),
96
- ""
97
- ].join("\n");
98
- }
99
- //#endregion
100
70
  //#region src/changelog/generate.ts
101
71
  async function generateFromCommits(context, { from, to } = {}) {
102
72
  const commits = await readConventionalCommits(context, from, to);
@@ -171,4 +141,4 @@ function changelogFilename(disambiguator = 0) {
171
141
  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}-${(Date.now() + disambiguator).toString(36)}.md`;
172
142
  }
173
143
  //#endregion
174
- export { renderChangelog as i, generateFromCommits as n, changelogFrontmatterSchema as r, changelogFilename as t };
144
+ export { generateFromCommits as n, changelogFilename as t };
@@ -1,4 +1,4 @@
1
- import { r as LogGenerator } from "../types-DKZsadC8.js";
1
+ import { r as LogGenerator } from "../types-DItu_YCc.js";
2
2
 
3
3
  //#region src/generators/simple.d.ts
4
4
  declare function simpleGenerator(): LogGenerator;
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { A as PackageDraft, D as WorkspacePackage, E as PackageGroup, O as Draft, T as PackageGraph, _ as PublishPlan, a as PublishPreflight, c as TegamiPluginOption, d as tegami, f as CommitChangelog, g as PublishOptions, h as PackagePublishResult, i as PackageOptions, k as DraftPolicy, l as GenerateChangelogOptions, m as PackagePublishPlan, n as GroupOptions, o as TegamiOptions, p as PublishLock, r as LogGenerator, s as TegamiPlugin, u as Tegami } from "./types-DKZsadC8.js";
2
- export { type CommitChangelog, type Draft, type DraftPolicy, GenerateChangelogOptions, type GroupOptions, type LogGenerator, type PackageDraft, type PackageGraph, type PackageGroup, type PackageOptions, type PackagePublishPlan, type PackagePublishResult, type PublishLock, type PublishOptions, type PublishPlan, type PublishPreflight, Tegami, type TegamiOptions, type TegamiPlugin, type TegamiPluginOption, type WorkspacePackage, tegami };
1
+ import { C as PackageGroup, D as PackageDraft, E as DraftPolicy, O as BumpType, S as PackageGraph, T as Draft, _ as PackagePublishResult, a as PublishPreflight, b as CommitChangelog, c as TegamiPluginOption, f as GenerateChangelogOptions, g as PackagePublishPlan, h as PublishLock, i as PackageOptions, m as tegami, n as GroupOptions, o as TegamiOptions, p as Tegami, r as LogGenerator, s as TegamiPlugin, v as PublishOptions, w as WorkspacePackage, x as TegamiContext, y as PublishPlan } from "./types-DItu_YCc.js";
2
+ export { type BumpType, type CommitChangelog, type Draft, type DraftPolicy, GenerateChangelogOptions, type GroupOptions, type LogGenerator, type PackageDraft, PackageGraph, type PackageGroup, type PackageOptions, type PackagePublishPlan, type PackagePublishResult, type PublishLock, type PublishOptions, type PublishPlan, type PublishPreflight, Tegami, type TegamiContext, type TegamiOptions, type TegamiPlugin, type TegamiPluginOption, WorkspacePackage, tegami };
package/dist/index.js CHANGED
@@ -1,10 +1,9 @@
1
- import { n as generateFromCommits } from "./generate-BfYdNTFi.js";
2
- import { r as handlePluginError, s as somePromise } from "./error-We7chQVJ.js";
3
- import { t as PackageGraph } from "./graph-gThXu8Cz.js";
4
- import { cargo } from "./providers/cargo.js";
5
- import { n as npm } from "./npm-CMOyacwf.js";
6
- import { a as parseChangelogFile, i as parsePublishLock, n as createDraft, o as readChangelogEntries, r as packageStoreSchema, t as changelogStoreSchema } from "./draft-DtFyGxe8.js";
7
- import fs, { mkdir, rm, writeFile } from "node:fs/promises";
1
+ import { n as generateFromCommits } from "./generate-Rvz4Lu98.js";
2
+ import { r as handlePluginError } from "./error-BhMYq9iW.js";
3
+ import { a as runPreflights, i as publishPlanStatus, n as npm, o as runPublishPlan, r as initPublishPlan } from "./npm-1iEegfHg.js";
4
+ import { n as WorkspacePackage, t as PackageGraph } from "./graph-gThXu8Cz.js";
5
+ import { a as parseChangelogFile, n as createDraft, o as readChangelogEntries } from "./draft-BqHcSCeX.js";
6
+ import { mkdir, rm, writeFile } from "node:fs/promises";
8
7
  import path, { join } from "node:path";
9
8
  //#region src/context.ts
10
9
  async function createTegamiContext(options = {}) {
@@ -15,11 +14,7 @@ async function createTegamiContext(options = {}) {
15
14
  changelogDir,
16
15
  lockPath: options.lockPath ? path.resolve(cwd, options.lockPath) : path.join(changelogDir, "publish-lock.yaml"),
17
16
  options,
18
- plugins: resolvePlugins([
19
- npm(options.npm),
20
- cargo(options.cargo),
21
- ...options.plugins ?? []
22
- ]),
17
+ plugins: resolvePlugins([npm(options.npm), ...options.plugins ?? []]),
23
18
  graph: new PackageGraph()
24
19
  };
25
20
  for (const plugin of ctx.plugins) await handlePluginError(plugin, "init", () => plugin.init?.call(ctx));
@@ -59,136 +54,6 @@ function resolvePlugins(plugins = []) {
59
54
  return plugins.flat(Infinity).sort((a, b) => PLUGIN_ORDER[a.enforce ?? "default"] - PLUGIN_ORDER[b.enforce ?? "default"]);
60
55
  }
61
56
  //#endregion
62
- //#region src/plans/publish.ts
63
- async function initPublishPlan(context, options) {
64
- let lock;
65
- try {
66
- lock = parsePublishLock(await fs.readFile(context.lockPath, "utf8"));
67
- } catch {
68
- return;
69
- }
70
- let data;
71
- const packages = /* @__PURE__ */ new Map();
72
- const changelogs = /* @__PURE__ */ new Map();
73
- while (data = lock.read("core:changelogs")) {
74
- const entry = changelogStoreSchema.safeParse(data).data;
75
- if (!entry) continue;
76
- const parsed = parseChangelogFile(entry.filename, entry.content);
77
- if (!parsed) continue;
78
- changelogs.set(parsed.id, parsed);
79
- }
80
- while (data = lock.read("core:packages")) {
81
- const parsed = packageStoreSchema.safeParse(data).data;
82
- if (!parsed) continue;
83
- if (!context.graph.get(parsed.id)) continue;
84
- const pkgChangelogs = [];
85
- for (const id of parsed.changelogIds ?? []) {
86
- const entry = changelogs.get(id);
87
- if (entry) pkgChangelogs.push(entry);
88
- }
89
- packages.set(parsed.id, {
90
- changelogs: pkgChangelogs,
91
- updated: parsed.updated
92
- });
93
- }
94
- const plan = {
95
- options,
96
- changelogs,
97
- packages
98
- };
99
- for (const plugin of context.plugins) await handlePluginError(plugin, "initPublishPlan", () => plugin.initPublishPlan?.call(context, {
100
- lock,
101
- plan
102
- }));
103
- return plan;
104
- }
105
- function resolvePublishTargets(plan) {
106
- const ordered = [];
107
- function scan(id, stack = /* @__PURE__ */ new Set()) {
108
- const preflight = plan.packages.get(id)?.preflight;
109
- if (!preflight || !preflight.shouldPublish) return;
110
- if (stack.has(id)) throw new Error(`circular reference of deps: ${[...stack, id].join(" -> ")}`);
111
- if (ordered.includes(id)) return;
112
- if (preflight.wait) {
113
- stack.add(id);
114
- for (const dep of preflight.wait) scan(dep, stack);
115
- stack.delete(id);
116
- }
117
- ordered.push(id);
118
- }
119
- for (const id of plan.packages.keys()) scan(id);
120
- return ordered;
121
- }
122
- async function runPublishPlan(context, plan) {
123
- const { dryRun = false } = plan.options;
124
- const onPublishResult = async (pkg, publishResult) => {
125
- const packagePlan = plan.packages.get(pkg.id);
126
- if (!packagePlan) return;
127
- packagePlan.publishResult = publishResult;
128
- if (publishResult.type === "skipped") return;
129
- for (const plugin of context.plugins) await handlePluginError(plugin, "afterPublish", () => plugin.afterPublish?.call(context, {
130
- pkg,
131
- plan
132
- }));
133
- };
134
- publishLoop: for (const id of resolvePublishTargets(plan)) {
135
- const pkg = context.graph.get(id);
136
- if (dryRun) {
137
- await onPublishResult(pkg, { type: "published" });
138
- continue;
139
- }
140
- for (const plugin of context.plugins) if (await handlePluginError(plugin, "willPublish", () => plugin.willPublish?.call(context, { pkg })) === false) continue publishLoop;
141
- for (const plugin of context.plugins) {
142
- const publishResult = await handlePluginError(plugin, "publish", () => plugin.publish?.call(context, {
143
- pkg,
144
- plan
145
- }));
146
- if (publishResult) {
147
- await onPublishResult(pkg, publishResult);
148
- continue publishLoop;
149
- }
150
- }
151
- await onPublishResult(pkg, {
152
- type: "failed",
153
- error: `There is no plugin to publish package "${pkg.id}", please make sure the package has a supported provider plugin.`
154
- });
155
- }
156
- for (const packagePlan of plan.packages.values()) packagePlan.publishResult ??= { type: "skipped" };
157
- for (const plugin of context.plugins) await handlePluginError(plugin, "afterPublishAll", () => plugin.afterPublishAll?.call(context, { plan }));
158
- }
159
- async function runPreflights(context, plan) {
160
- const promises = [];
161
- const runPreflight = async (pkg) => {
162
- for (const plugin of context.plugins) {
163
- const res = await handlePluginError(plugin, "publishPreflight", () => plugin.publishPreflight?.call(context, {
164
- pkg,
165
- plan
166
- }));
167
- if (res) return res;
168
- }
169
- return { shouldPublish: false };
170
- };
171
- for (const [id, packagePlan] of plan.packages) {
172
- const pkg = context.graph.get(id);
173
- if (!packagePlan.updated) {
174
- packagePlan.preflight = { shouldPublish: false };
175
- continue;
176
- }
177
- promises.push(runPreflight(pkg).then((preflight) => {
178
- packagePlan.preflight = preflight;
179
- }));
180
- }
181
- await Promise.all(promises);
182
- }
183
- async function publishPlanStatus(plan, context) {
184
- for (const plugin of context.plugins) {
185
- const status = await handlePluginError(plugin, "resolvePlanStatus", () => plugin.resolvePlanStatus?.call(context, { plan }));
186
- if (Array.isArray(status) && await somePromise(status, (v) => v === "pending")) return "pending";
187
- if (status === "pending") return "pending";
188
- }
189
- return "success";
190
- }
191
- //#endregion
192
57
  //#region src/index.ts
193
58
  /** Create a Tegami project handle. */
194
59
  function tegami(options = {}) {
@@ -268,4 +133,4 @@ function tegami(options = {}) {
268
133
  };
269
134
  }
270
135
  //#endregion
271
- export { tegami };
136
+ export { PackageGraph, WorkspacePackage, tegami };