tegami 0.1.0 → 0.1.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 { n as handlePluginError } from "./error-DBK-9uBa.js";
1
+ import { n as handlePluginError } from "./error-BaOQJtvf.js";
2
2
  import { n as jsonCodec, t as bumpTypeSchema } from "./schemas-CurBAaW5.js";
3
3
  import z$1 from "zod";
4
4
  import { readFile } from "fs/promises";
@@ -1,4 +1,4 @@
1
- import { C as PublishResult, O as DraftPlan, _ as Tegami, t as Awaitable } from "../types-UjsZkz42.js";
1
+ import { k as DraftPlan, t as Awaitable, v as Tegami, w as PublishResult } from "../types-Diwnh8Tn.js";
2
2
  import { Command } from "commander";
3
3
 
4
4
  //#region src/cli/index.d.ts
package/dist/cli/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as changelogFilename, t as assertPublishPlanFinished } from "../checks-BQISvt_o.js";
2
- import { n as handlePluginError } from "../error-DBK-9uBa.js";
1
+ import { a as changelogFilename, t as assertPublishPlanFinished } from "../checks-Bz3Rf2OX.js";
2
+ import { n as handlePluginError, t as execFailure } from "../error-BaOQJtvf.js";
3
3
  import { n as formatNpmDistTag } from "../semver-mWK2Khi2.js";
4
4
  import { t as isCI } from "../constants-B9qjNfvr.js";
5
5
  import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
@@ -144,7 +144,7 @@ async function postPrComment(body) {
144
144
  "--jq",
145
145
  `[.[] | select(.body | startswith("${COMMENT_MARKER}")) | .id][0] // empty`
146
146
  ]);
147
- if (listResult.exitCode !== 0) throw new Error(listResult.stderr || "Failed to list pull request comments.");
147
+ if (listResult.exitCode !== 0) throw execFailure("Failed to list pull request comments.", listResult);
148
148
  const existingId = listResult.stdout.trim();
149
149
  if (existingId) {
150
150
  const dir = await mkdtemp(join(tmpdir(), "tegami-pr-comment-"));
@@ -159,7 +159,7 @@ async function postPrComment(body) {
159
159
  "--input",
160
160
  inputPath
161
161
  ]);
162
- if (updateResult.exitCode !== 0) throw new Error(updateResult.stderr || "Failed to update pull request comment.");
162
+ if (updateResult.exitCode !== 0) throw execFailure("Failed to update pull request comment.", updateResult);
163
163
  } finally {
164
164
  await rm(dir, {
165
165
  recursive: true,
@@ -177,7 +177,7 @@ async function postPrComment(body) {
177
177
  "--repo",
178
178
  repo
179
179
  ]);
180
- if (createResult.exitCode !== 0) throw new Error(createResult.stderr || "Failed to create pull request comment.");
180
+ if (createResult.exitCode !== 0) throw execFailure("Failed to create pull request comment.", createResult);
181
181
  }
182
182
  async function readPullRequestNumberFromWorkflowRunEvent() {
183
183
  const eventPath = process.env.GITHUB_EVENT_PATH;
@@ -220,7 +220,7 @@ async function readPullRequestFromGh(repo, number) {
220
220
  "--json",
221
221
  "headRefName,baseRefOid,headRefOid,headRepository"
222
222
  ]);
223
- if (result.exitCode !== 0) throw new Error(result.stderr || `Failed to resolve pull request #${number}.`);
223
+ if (result.exitCode !== 0) throw execFailure(`Failed to resolve pull request #${number}.`, result);
224
224
  const data = JSON.parse(result.stdout);
225
225
  return {
226
226
  repo,
@@ -258,10 +258,7 @@ async function listPullRequestChangelogFiles(context, baseSha, headSha) {
258
258
  "--",
259
259
  `${dir}/`
260
260
  ], { nodeOptions: { cwd: context.cwd } });
261
- if (result.exitCode !== 0) {
262
- const detail = result.stderr.trim();
263
- throw new Error(detail ? `Failed to list pull request changelog files: ${detail}` : "Failed to list pull request changelog files.");
264
- }
261
+ if (result.exitCode !== 0) throw execFailure("Failed to list pull request changelog files.", result);
265
262
  const files = /* @__PURE__ */ new Set();
266
263
  for (const line of result.stdout.split("\n")) {
267
264
  const trimmed = line.trim();
@@ -1,11 +1,10 @@
1
1
  //#region src/utils/error.ts
2
- function commandOutput(result) {
3
- return [result.stdout, result.stderr].filter(Boolean).join("\n").trim();
4
- }
5
2
  function execFailure(context, result) {
6
3
  const lines = [context, `(exit ${result.exitCode})`];
7
- const output = commandOutput(result);
8
- if (output) lines.push(output);
4
+ const out = result.stdout.trim();
5
+ const err = result.stderr.trim();
6
+ if (out) lines.push(out);
7
+ if (err) lines.push(err);
9
8
  return new Error(lines.join("\n"));
10
9
  }
11
10
  function isNodeError(error) {
@@ -1,4 +1,4 @@
1
- import { r as LogGenerator } from "../types-UjsZkz42.js";
1
+ import { r as LogGenerator } from "../types-Diwnh8Tn.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 { C as PublishResult, D as WorkspacePackage, E as PackageGroup, O as DraftPlan, S as PublishOptions, T as PackageGraph, _ as Tegami, a as RegistryClient, b as CreatedChangelog, c as TegamiPluginOption, i as PackageOptions, k as PackagePlan, n as GroupOptions, o as TegamiOptions, r as LogGenerator, s as TegamiPlugin, v as tegami, x as PackagePublishResult, y as CreateChangelogOptions } from "./types-UjsZkz42.js";
2
- export { type CreateChangelogOptions, type CreatedChangelog, type DraftPlan, type GroupOptions, type LogGenerator, type PackageGraph, type PackageGroup, type PackageOptions, type PackagePlan, type PackagePublishResult, type PublishOptions, type PublishResult, type RegistryClient, Tegami, type TegamiOptions, type TegamiPlugin, type TegamiPluginOption, type WorkspacePackage, tegami };
1
+ import { A as PackagePlan, C as PublishOptions, D as PackageGroup, E as PackageGraph, O as WorkspacePackage, S as PackagePublishResult, a as PublishPreflight, b as CreateChangelogOptions, c as TegamiPlugin, i as PackageOptions, k as DraftPlan, l as TegamiPluginOption, n as GroupOptions, o as RegistryClient, r as LogGenerator, s as TegamiOptions, v as Tegami, w as PublishResult, x as CreatedChangelog, y as tegami } from "./types-Diwnh8Tn.js";
2
+ export { type CreateChangelogOptions, type CreatedChangelog, type DraftPlan, type GroupOptions, type LogGenerator, type PackageGraph, type PackageGroup, type PackageOptions, type PackagePlan, type PackagePublishResult, type PublishOptions, type PublishPreflight, type PublishResult, type RegistryClient, Tegami, type TegamiOptions, type TegamiPlugin, type TegamiPluginOption, type WorkspacePackage, tegami };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as changelogFilename, i as readPlanStore, n as publishPlanStatus, r as createPlanStore, t as assertPublishPlanFinished } from "./checks-BQISvt_o.js";
2
- import { n as handlePluginError, t as execFailure } from "./error-DBK-9uBa.js";
1
+ import { a as changelogFilename, i as readPlanStore, n as publishPlanStatus, r as createPlanStore, t as assertPublishPlanFinished } from "./checks-Bz3Rf2OX.js";
2
+ import { n as handlePluginError, t as execFailure } from "./error-BaOQJtvf.js";
3
3
  import { i as maxBump } from "./semver-mWK2Khi2.js";
4
4
  import { t as PackageGraph } from "./graph-CUgwuRW5.js";
5
5
  import { cargo } from "./providers/cargo.js";
@@ -490,14 +490,48 @@ function headingToBump(depth) {
490
490
  }
491
491
  //#endregion
492
492
  //#region src/publish.ts
493
+ async function resolvePublishTargets(context, store) {
494
+ const targets = [];
495
+ const preflightPromises = [];
496
+ for (const [id, plan] of Object.entries(store.packages)) {
497
+ if (!plan.publish) continue;
498
+ const pkg = context.graph.get(id);
499
+ if (!pkg) continue;
500
+ targets.push(pkg.id);
501
+ preflightPromises.push(context.getRegistryClient(pkg).publishPreflight?.(pkg, {
502
+ store,
503
+ packageStore: plan
504
+ }));
505
+ }
506
+ const preflights = await Promise.all(preflightPromises);
507
+ const children = /* @__PURE__ */ new Map();
508
+ for (let i = 0; i < targets.length; i++) {
509
+ const id = targets[i];
510
+ children.set(id, preflights[i]?.wait);
511
+ }
512
+ const ordered = [];
513
+ function scan(id, stack = /* @__PURE__ */ new Set()) {
514
+ if (stack.has(id)) throw new Error(`circular reference of deps: ${[...stack, id].join(" -> ")}`);
515
+ if (ordered.includes(id)) return;
516
+ const deps = children.get(id);
517
+ if (deps) {
518
+ stack.add(id);
519
+ for (const dep of deps) scan(dep, stack);
520
+ stack.delete(id);
521
+ }
522
+ ordered.push(id);
523
+ }
524
+ for (const id of targets) scan(id);
525
+ return ordered;
526
+ }
493
527
  async function publishFromPlan(context, store, options) {
494
528
  const { dryRun = false } = options;
495
529
  const packages = [];
496
530
  if ((await publishPlanStatus(store, context)).state !== "pending") return { state: "skipped" };
497
- for (const [id, plan] of Object.entries(store.packages)) {
498
- if (!plan.publish) continue;
531
+ const orderedIds = await resolvePublishTargets(context, store);
532
+ for (const id of orderedIds) {
533
+ const plan = store.packages[id];
499
534
  const pkg = context.graph.get(id);
500
- if (!pkg) continue;
501
535
  const registryClient = context.getRegistryClient(pkg);
502
536
  const changelogs = [];
503
537
  for (const id of plan.changelogIds ?? []) {
@@ -1,4 +1,4 @@
1
- import { s as TegamiPlugin } from "../types-UjsZkz42.js";
1
+ import { c as TegamiPlugin } from "../types-Diwnh8Tn.js";
2
2
 
3
3
  //#region src/plugins/git.d.ts
4
4
  interface GitPluginOptions {
@@ -1,4 +1,4 @@
1
- import { t as execFailure } from "../error-DBK-9uBa.js";
1
+ import { t as execFailure } from "../error-BaOQJtvf.js";
2
2
  import { t as isCI } from "../constants-B9qjNfvr.js";
3
3
  import { x } from "tinyexec";
4
4
  //#region src/plugins/git.ts
@@ -1,4 +1,4 @@
1
- import { O as DraftPlan, s as TegamiPlugin, t as Awaitable, w as TegamiContext, x as PackagePublishResult } from "../types-UjsZkz42.js";
1
+ import { S as PackagePublishResult, T as TegamiContext, c as TegamiPlugin, k as DraftPlan, t as Awaitable } from "../types-Diwnh8Tn.js";
2
2
  import { GitPluginOptions } from "./git.js";
3
3
 
4
4
  //#region src/plugins/github.d.ts
@@ -1,4 +1,4 @@
1
- import { t as execFailure } from "../error-DBK-9uBa.js";
1
+ import { t as execFailure } from "../error-BaOQJtvf.js";
2
2
  import { n as formatNpmDistTag, r as formatPackageVersion } from "../semver-mWK2Khi2.js";
3
3
  import { t as isCI } from "../constants-B9qjNfvr.js";
4
4
  import { git } from "./git.js";
@@ -1,2 +1,2 @@
1
- import { d as CargoRegistryClient, f as cargo, l as CargoPackage, u as CargoPluginOptions } from "../types-UjsZkz42.js";
1
+ import { d as CargoPluginOptions, f as CargoRegistryClient, p as cargo, u as CargoPackage } from "../types-Diwnh8Tn.js";
2
2
  export { CargoPackage, CargoPluginOptions, CargoRegistryClient, cargo };
@@ -1,4 +1,4 @@
1
- import { r as isNodeError } from "../error-DBK-9uBa.js";
1
+ import { r as isNodeError, t as execFailure } from "../error-BaOQJtvf.js";
2
2
  import { n as WorkspacePackage } from "../graph-CUgwuRW5.js";
3
3
  import { readFile, writeFile } from "node:fs/promises";
4
4
  import { join, normalize } from "node:path";
@@ -55,9 +55,12 @@ var CargoPackage = class extends WorkspacePackage {
55
55
  }
56
56
  };
57
57
  var CargoRegistryClient = class {
58
+ graph;
58
59
  id = "cargo";
59
60
  #versionMap = /* @__PURE__ */ new Map();
60
- constructor(_graph) {}
61
+ constructor(graph) {
62
+ this.graph = graph;
63
+ }
61
64
  supports(pkg) {
62
65
  return pkg instanceof CargoPackage;
63
66
  }
@@ -74,14 +77,24 @@ var CargoRegistryClient = class {
74
77
  }
75
78
  return info;
76
79
  }
77
- async publish(pkg) {
78
- await x("cargo", ["publish"], {
79
- nodeOptions: { cwd: pkg.path },
80
- throwOnError: true
81
- });
80
+ publishPreflight(pkg, { store }) {
81
+ const wait = [];
82
+ for (const { table } of dependencyTables(pkg.manifest, "")) for (const [rawName, rawSpec] of Object.entries(table)) {
83
+ if (!isTableValue(rawSpec) || typeof rawSpec.path !== "string") continue;
84
+ const id = `cargo:${stringValue(rawSpec.package) ?? rawName}`;
85
+ if (!store.packages[id]?.publish) continue;
86
+ const linked = this.graph.get(id);
87
+ if (!linked || !(linked instanceof CargoPackage)) continue;
88
+ wait.push(id);
89
+ }
90
+ return { wait };
91
+ }
92
+ async publish(pkg, _env) {
93
+ const result = await x("cargo", ["publish"], { nodeOptions: { cwd: pkg.path } });
94
+ if (result.exitCode !== 0) throw execFailure(`Failed to publish ${pkg.name}@${pkg.version}.`, result);
82
95
  }
83
96
  };
84
- function cargo({ bumpDep: getBumpDepType = ({ kind }) => {
97
+ function cargo({ updateLockFile = false, bumpDep: getBumpDepType = ({ kind }) => {
85
98
  switch (kind) {
86
99
  case "dependencies": return "patch";
87
100
  case "build-dependencies":
@@ -159,7 +172,12 @@ function cargo({ bumpDep: getBumpDepType = ({ kind }) => {
159
172
  writes.push(pkg.write());
160
173
  }
161
174
  await Promise.all(writes);
162
- }
175
+ },
176
+ cli: { async publishPlanApplied() {
177
+ if (!updateLockFile) return;
178
+ const result = await x("cargo", ["update", "--workspace"], { nodeOptions: { cwd: this.cwd } });
179
+ if (result.exitCode !== 0) throw execFailure("Failed to update Cargo lock file", result);
180
+ } }
163
181
  };
164
182
  }
165
183
  async function discoverCargoPackages(cwd, add) {
@@ -1,2 +1,2 @@
1
- import { g as npm, h as NpmRegistryClient, m as NpmPluginOptions, p as NpmPackage } from "../types-UjsZkz42.js";
1
+ import { _ as npm, g as NpmRegistryClient, h as NpmPluginOptions, m as NpmPackage } from "../types-Diwnh8Tn.js";
2
2
  export { NpmPackage, NpmPluginOptions, NpmRegistryClient, npm };
@@ -1,4 +1,4 @@
1
- import { r as isNodeError, t as execFailure } from "../error-DBK-9uBa.js";
1
+ import { r as isNodeError, t as execFailure } from "../error-BaOQJtvf.js";
2
2
  import { n as WorkspacePackage } from "../graph-CUgwuRW5.js";
3
3
  import { i as pnpmWorkspaceSchema, r as packageManifestSchema } from "../schemas-CurBAaW5.js";
4
4
  import { readFile, writeFile } from "node:fs/promises";
@@ -70,9 +70,8 @@ var NpmRegistryClient = class {
70
70
  if (registry) args.push("--registry", registry);
71
71
  const result = await x(this.client === "pnpm" ? "pnpm" : "npm", args, { nodeOptions: { cwd: this.cwd } });
72
72
  if (result.exitCode === 0) return true;
73
- const output = commandOutput(result);
74
- if (isMissingRegistryEntry(output)) return false;
75
- throw new Error(`Unable to validate ${pkg.name}@${pkg.version} against the npm registry${registry ? ` "${registry}"` : ""}: ${output.trim() || `command exited with code ${result.exitCode}`}`);
73
+ if (isMissingRegistryEntry(commandOutput(result))) return false;
74
+ throw execFailure(`Unable to validate ${pkg.name}@${pkg.version} against the npm registry${registry ? ` "${registry}"` : ""}.`, result);
76
75
  };
77
76
  info = run();
78
77
  this.#versionMap.set(cacheKey, info);
@@ -377,13 +377,28 @@ declare class CargoPackage extends WorkspacePackage {
377
377
  }
378
378
  declare class CargoRegistryClient implements RegistryClient {
379
379
  #private;
380
+ private readonly graph;
380
381
  readonly id = "cargo";
381
- constructor(_graph: PackageGraph);
382
+ constructor(graph: PackageGraph);
382
383
  supports(pkg: WorkspacePackage): boolean;
383
384
  isPackagePublished(pkg: CargoPackage): Promise<boolean>;
384
- publish(pkg: CargoPackage): Promise<void>;
385
+ publishPreflight(pkg: CargoPackage, {
386
+ store
387
+ }: {
388
+ store: PlanStore;
389
+ }): PublishPreflight;
390
+ publish(pkg: CargoPackage, _env: {
391
+ store: PlanStore;
392
+ packageStore: PackagePlanStore;
393
+ }): Promise<void>;
385
394
  }
386
395
  interface CargoPluginOptions {
396
+ /**
397
+ * Update lock file after versioning.
398
+ *
399
+ * @default false
400
+ */
401
+ updateLockFile?: boolean;
387
402
  bumpDep?: (opts: {
388
403
  kind: (typeof DEP_FIELDS)[number];
389
404
  name: string;
@@ -391,6 +406,7 @@ interface CargoPluginOptions {
391
406
  }) => BumpType | false;
392
407
  }
393
408
  declare function cargo({
409
+ updateLockFile,
394
410
  bumpDep: getBumpDepType
395
411
  }?: CargoPluginOptions): TegamiPlugin;
396
412
  //#endregion
@@ -403,7 +419,7 @@ interface LogGenerator {
403
419
  version: string;
404
420
  changelogs: ChangelogEntry[];
405
421
  plan: PackagePlan;
406
- _draft: DraftPlan;
422
+ unstable_draft: DraftPlan;
407
423
  }): string | Promise<string>;
408
424
  }
409
425
  interface TegamiOptions<Groups extends string = string> {
@@ -486,14 +502,22 @@ type Awaitable<T> = T | Promise<T>;
486
502
  interface PublishPlanStatus {
487
503
  state: "pending" | "success" | "missing";
488
504
  }
505
+ interface PublishPreflight {
506
+ /** Package ids that must be published before this one, this will automatically disallow circular dependency. */
507
+ wait: string[];
508
+ }
489
509
  interface RegistryClient {
490
510
  id: string;
491
511
  supports(pkg: WorkspacePackage): boolean;
492
512
  isPackagePublished(pkg: WorkspacePackage): Promise<boolean>;
513
+ publishPreflight?(pkg: WorkspacePackage, env: {
514
+ store: PlanStore;
515
+ packageStore: PackagePlanStore;
516
+ }): Awaitable<PublishPreflight | void | undefined>;
493
517
  publish(pkg: WorkspacePackage, env: {
494
518
  store: PlanStore;
495
519
  packageStore: PackagePlanStore;
496
520
  }): Promise<void>;
497
521
  }
498
522
  //#endregion
499
- export { PublishResult as C, WorkspacePackage as D, PackageGroup as E, DraftPlan as O, PublishOptions as S, PackageGraph as T, Tegami as _, RegistryClient as a, CreatedChangelog as b, TegamiPluginOption as c, CargoRegistryClient as d, cargo as f, npm as g, NpmRegistryClient as h, PackageOptions as i, PackagePlan as k, CargoPackage as l, NpmPluginOptions as m, GroupOptions as n, TegamiOptions as o, NpmPackage as p, LogGenerator as r, TegamiPlugin as s, Awaitable as t, CargoPluginOptions as u, tegami as v, TegamiContext as w, PackagePublishResult as x, CreateChangelogOptions as y };
523
+ export { PackagePlan as A, PublishOptions as C, PackageGroup as D, PackageGraph as E, WorkspacePackage as O, PackagePublishResult as S, TegamiContext as T, npm as _, PublishPreflight as a, CreateChangelogOptions as b, TegamiPlugin as c, CargoPluginOptions as d, CargoRegistryClient as f, NpmRegistryClient as g, NpmPluginOptions as h, PackageOptions as i, DraftPlan as k, TegamiPluginOption as l, NpmPackage as m, GroupOptions as n, RegistryClient as o, cargo as p, LogGenerator as r, TegamiOptions as s, Awaitable as t, CargoPackage as u, Tegami as v, PublishResult as w, CreatedChangelog as x, tegami as y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tegami",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Utility for package versioning & publish",
5
5
  "license": "MIT",
6
6
  "author": "Fuma Nama",