@tallyrelease/cli 0.1.0-beta.1 → 0.1.0-beta.3

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.
@@ -2,5 +2,9 @@
2
2
  export const check = async (session) => {
3
3
  const workspace = await session.workspace();
4
4
  session.warn(workspace.warnings);
5
- session.stdout.write(`ok: ${String(workspace.units.length)} units, ${String(workspace.graph.edges.length)} edges\n`);
5
+ const released = workspace.units
6
+ .filter((u) => u.version !== "none")
7
+ .map((u) => u.id);
8
+ const list = released.length > 0 ? `: ${released.join(", ")}` : "";
9
+ session.stdout.write(`ok: ${String(workspace.units.length)} units (${String(released.length)} released${list}), ${String(workspace.graph.edges.length)} edges\n`);
6
10
  };
@@ -1,5 +1,7 @@
1
1
  import type { Session } from "../session.js";
2
- /** Prints units and edges. */
3
- export declare const graph: (session: Session, flags: {
2
+ export interface GraphFlags {
3
+ format?: "text" | "json" | "mermaid";
4
4
  json?: boolean;
5
- }) => Promise<void>;
5
+ }
6
+ /** Prints units and edges. */
7
+ export declare const graph: (session: Session, flags: GraphFlags) => Promise<void>;
@@ -1,3 +1,4 @@
1
+ import { renderMermaid } from "../render/mermaid.js";
1
2
  /** Prints units and edges. */
2
3
  export const graph = async (session, flags) => {
3
4
  const workspace = await session.workspace();
@@ -14,12 +15,17 @@ export const graph = async (session, flags) => {
14
15
  pinned: e.pinned,
15
16
  reasons: e.reasons,
16
17
  }));
17
- if (flags.json) {
18
+ const format = flags.format ?? (flags.json ? "json" : "text");
19
+ if (format === "mermaid") {
20
+ session.stdout.write(renderMermaid(units, edges));
21
+ return;
22
+ }
23
+ if (format === "json") {
18
24
  session.stdout.write(`${JSON.stringify({ repo: workspace.repo, units, edges }, null, 2)}\n`);
19
25
  return;
20
26
  }
21
27
  for (const u of units) {
22
- session.stdout.write(`${u.id}\t${u.path}\t${u.plugin}\n`);
28
+ session.stdout.write(`${u.id}\t${u.path}\t${u.plugin}\t${u.version}\n`);
23
29
  }
24
30
  for (const e of edges) {
25
31
  session.stdout.write(`${e.from} -> ${e.to}${e.pinned ? " (pinned)" : ""}\n`);
@@ -3,6 +3,7 @@ import { z } from "zod";
3
3
  export declare const configSchema: z.ZodObject<{
4
4
  plugins: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>>;
5
5
  defaults: z.ZodExactOptional<z.ZodObject<{
6
+ release: z.ZodExactOptional<z.ZodBoolean>;
6
7
  tagFormat: z.ZodExactOptional<z.ZodString>;
7
8
  propagate: z.ZodExactOptional<z.ZodEnum<{
8
9
  auto: "auto";
@@ -14,9 +15,9 @@ export declare const configSchema: z.ZodObject<{
14
15
  id: z.ZodExactOptional<z.ZodString>;
15
16
  include: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
16
17
  exclude: z.ZodExactOptional<z.ZodArray<z.ZodString>>;
18
+ release: z.ZodExactOptional<z.ZodBoolean>;
17
19
  version: z.ZodExactOptional<z.ZodEnum<{
18
20
  file: "file";
19
- none: "none";
20
21
  tag: "tag";
21
22
  }>>;
22
23
  scheme: z.ZodExactOptional<z.ZodString>;
@@ -5,7 +5,14 @@ const unitOverlay = z.strictObject({
5
5
  id: z.string().exactOptional(),
6
6
  include: globs,
7
7
  exclude: globs,
8
- version: z.enum(["file", "tag", "none"]).exactOptional(),
8
+ release: z.boolean().exactOptional(),
9
+ version: z
10
+ .enum(["file", "tag"], {
11
+ error: (issue) => issue.input === "none"
12
+ ? 'version "none" is not supported, use release: false'
13
+ : undefined,
14
+ })
15
+ .exactOptional(),
9
16
  scheme: z.string().exactOptional(),
10
17
  tagFormat: z.string().exactOptional(),
11
18
  propagate: propagate.exactOptional(),
@@ -17,6 +24,7 @@ export const configSchema = z.strictObject({
17
24
  .default({}),
18
25
  defaults: z
19
26
  .strictObject({
27
+ release: z.boolean().exactOptional(),
20
28
  tagFormat: z.string().exactOptional(),
21
29
  propagate: propagate.exactOptional(),
22
30
  })
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CONFIG_FILE, TallyError } from "@tallyrelease/core";
2
- import { Command, CommanderError } from "commander";
2
+ import { Command, CommanderError, Option } from "commander";
3
3
  import { inspect } from "node:util";
4
4
  import { affected } from "./commands/affected.js";
5
5
  import { check } from "./commands/check.js";
@@ -30,8 +30,16 @@ export const main = async (argv, deps) => {
30
30
  program
31
31
  .command("graph")
32
32
  .description("print units and edges")
33
- .option("--json", "print JSON")
34
- .action(async (flags) => {
33
+ .option("--json", "print JSON (same as --format json)")
34
+ .addOption(new Option("--format <format>", "output format").choices([
35
+ "text",
36
+ "json",
37
+ "mermaid",
38
+ ]))
39
+ .action(async (flags, cmd) => {
40
+ if (flags.json && flags.format !== undefined) {
41
+ cmd.error("--json and --format cannot be combined", { exitCode: 2 });
42
+ }
35
43
  await graph(session(), flags);
36
44
  });
37
45
  program
@@ -0,0 +1,12 @@
1
+ interface MermaidUnit {
2
+ id: string;
3
+ version: string;
4
+ }
5
+ interface MermaidEdge {
6
+ from: string;
7
+ to: string;
8
+ pinned: boolean;
9
+ }
10
+ /** Renders units and edges as a Mermaid flowchart; inputs are already sorted. */
11
+ export declare const renderMermaid: (units: readonly MermaidUnit[], edges: readonly MermaidEdge[]) => string;
12
+ export {};
@@ -0,0 +1,18 @@
1
+ /** Renders units and edges as a Mermaid flowchart; inputs are already sorted. */
2
+ export const renderMermaid = (units, edges) => {
3
+ const index = new Map(units.map((u, i) => [u.id, `u${String(i)}`]));
4
+ const lines = ["flowchart LR"];
5
+ let released = false;
6
+ for (const u of units) {
7
+ const isReleased = u.version !== "none";
8
+ released ||= isReleased;
9
+ lines.push(` ${index.get(u.id) ?? ""}["${u.id}"]${isReleased ? ":::released" : ""}`);
10
+ }
11
+ for (const e of edges) {
12
+ lines.push(` ${index.get(e.from) ?? ""} ${e.pinned ? "-->" : "-.->"} ${index.get(e.to) ?? ""}`);
13
+ }
14
+ if (released) {
15
+ lines.push(" classDef released stroke:#333,stroke-width:3px");
16
+ }
17
+ return `${lines.join("\n")}\n`;
18
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tallyrelease/cli",
3
- "version": "0.1.0-beta.1",
3
+ "version": "0.1.0-beta.3",
4
4
  "description": "Command line interface of tallyrelease",
5
5
  "repository": {
6
6
  "type": "git",
@@ -47,7 +47,7 @@
47
47
  "prettier": "@abinnovision/prettier-config",
48
48
  "dependencies": {
49
49
  "@octokit/rest": "^22.0.1",
50
- "@tallyrelease/core": "^0.1.0-beta.1",
50
+ "@tallyrelease/core": "^0.1.0-beta.2",
51
51
  "commander": "^15.0.0",
52
52
  "tinyglobby": "^0.2.17",
53
53
  "yaml": "^2.9.1",