1import * as Command from "effect/cli/Command"
2import * as Flag from "effect/cli/Flag"
3import * as Effect from "effect/Effect"
4import * as Option from "effect/Option"
5import { ApiDiff, type ApiDiffOptions } from "./ApiDiff.ts"
6
7const baseRef = Flag.String("base-ref").pipe(
8 Flag.withDescription("Explicit base Git ref"),
9 Flag.withDefault("v3")
10)
11
12const headRef = Flag.String("head-ref").pipe(
13 Flag.withDescription("Explicit head Git ref"),
14 Flag.withDefault("main")
15)
16
17const output = Flag.String("output").pipe(
18 Flag.withMetavar("DIRECTORY"),
19 Flag.withDescription("Report output directory"),
20 Flag.optional
21)
22
23const writeDoc = Flag.String("write-doc").pipe(
24 Flag.withMetavar("FILE"),
25 Flag.withDescription("Write the annotation-driven migration reference"),
26 Flag.optional
27)
28
29const check = Flag.Boolean("check").pipe(
30 Flag.withDescription("List APIs without migration annotations and fail if any remain"),
31 Flag.withDefault(false)
32)
33
34const runApiDiff = Effect.fnUntraced(function*(options: {
35 readonly baseRef: string
36 readonly headRef: string
37 readonly output: Option.Option<string>
38 readonly writeDoc: Option.Option<string>
39 readonly check: boolean
40}) {
41 const apiDiff = yield* ApiDiff
42 yield* apiDiff.run(
43 {
44 baseRef: options.baseRef,
45 headRef: options.headRef,
46 output: Option.getOrUndefined(options.output),
47 writeDoc: Option.getOrUndefined(options.writeDoc),
48 check: options.check
49 } satisfies ApiDiffOptions
50 )
51})
52
53export const cli = Command.make("api-diff", {
54 baseRef,
55 headRef,
56 output,
57 writeDoc,
58 check
59}).pipe(
60 Command.withDescription("Compare the consumer-visible TypeScript API of two repository revisions"),
61 Command.withHandler(runApiDiff)
62)