Initial Commit
This commit is contained in:
100
packages/devtools/tooling/electrobun/src/cli/cli.md
Normal file
100
packages/devtools/tooling/electrobun/src/cli/cli.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# CLI — `cli.ts`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Owns the five command surfaces — `createCommand`, `devCommand`,
|
||||
`buildCommand`, `packageCommand`, `signCommand` — plus the
|
||||
`runCli(argv, deps?)` dispatcher that the published binary delegates to.
|
||||
Every command is a pure function: it validates its option struct against
|
||||
the matching Zod schema, runs the orchestrated work, and returns a typed
|
||||
report. `runCli` never calls `process.exit`; the only exit-call lives in
|
||||
`src/bin/suaveplan-electrobun.ts`, so the entire CLI is unit-testable
|
||||
without a child process.
|
||||
|
||||
`createCommand` is the scaffolder entry: it loads the layered config,
|
||||
applies CLI overrides, optionally runs the prompt flow, then hands off
|
||||
to `generate`. The other four commands are runner-only — they probe the
|
||||
upstream `electrobun` binary, raise `ELECTROBUN.BINARY_UNAVAILABLE` when
|
||||
missing, spawn the binary with the canonical argv, and return a
|
||||
`CommandReport` carrying exit code, stdout, stderr, and duration.
|
||||
|
||||
## Features
|
||||
|
||||
- Five command functions, each with Zod-validated options and structured
|
||||
reports.
|
||||
- Pure `runCli(argv)` dispatcher with `--help` / `-h` short-circuit and
|
||||
closed-set flag parsing.
|
||||
- Long-flag `--key=value` and `--key value` forms supported uniformly.
|
||||
- Unknown flags / subcommands raise `ELECTROBUN.UNKNOWN_FLAG`.
|
||||
- Missing required values raise `ELECTROBUN.INVALID_OPTIONS`.
|
||||
- `timeRunner` wrapper increments invocation + duration histograms per
|
||||
call and increments failure counters on `ElectrobunError` paths.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { runCli } from "@suaveplan/electrobun/cli";
|
||||
|
||||
const { code } = await runCli(process.argv.slice(2));
|
||||
process.exit(code);
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { buildCommand } from "@suaveplan/electrobun/cli";
|
||||
import type { CommandRunner } from "@suaveplan/electrobun/types";
|
||||
|
||||
const customRunner: CommandRunner = async (input) => {
|
||||
// ship the spawn to a remote CI worker
|
||||
return await postToWorker(input);
|
||||
};
|
||||
const report = await buildCommand(
|
||||
{ cwd: "/proj", target: "linux", update: true },
|
||||
{ runner: customRunner }
|
||||
);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `createCommand(opts: CreateCommandOptions, deps: CommandDeps & {
|
||||
prompter: Prompter }): Promise<GenerateReport>`.
|
||||
- `devCommand(opts: DevCommandOptions, deps?: { runner? }):
|
||||
Promise<CommandReport>`.
|
||||
- `buildCommand(opts: BuildCommandOptions, deps?: { runner? }):
|
||||
Promise<CommandReport>`.
|
||||
- `packageCommand(opts: PackageCommandOptions, deps?: { runner? }):
|
||||
Promise<CommandReport>`.
|
||||
- `signCommand(opts: SignCommandOptions, deps?: { runner? }):
|
||||
Promise<CommandReport>`.
|
||||
- `runCli(argv: readonly string[], deps?: RunCliOptions): Promise<{
|
||||
code: number }>`.
|
||||
- `HELP_TEXT: string` — the full help banner.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The arg parser uses a closed `ALL_KNOWN_FLAGS` set. New flags must be
|
||||
added to the set before the parser will accept them; an unknown flag
|
||||
fails the run with `ELECTROBUN.UNKNOWN_FLAG`, which keeps subtle typos
|
||||
from being silently swallowed. The `--help` and `-h` short forms are
|
||||
intercepted before subcommand dispatch so they work uniformly across
|
||||
every subcommand.
|
||||
|
||||
`runCli` catches every `ElectrobunError` and folds it into `code: 1`
|
||||
with a one-line stderr message. Any other thrown value re-propagates,
|
||||
on the principle that the runtime should not eat unexpected exceptions
|
||||
— if something other than a typed error escapes the call, the bin
|
||||
wrapper surfaces it with `code: 2`.
|
||||
|
||||
The `timeRunner` helper increments `electrobun_runner_invocations_total`
|
||||
on entry, records the duration histogram on every exit (success or
|
||||
failure), and records `electrobun_runner_failures_total` when the thrown
|
||||
`ElectrobunError` carries a numeric `details.exitCode`. The failure
|
||||
counter labels the exit code with `-1` when no numeric exit-code is
|
||||
available — for instance when the probe stage raises
|
||||
`BINARY_UNAVAILABLE` — so dashboards can still attribute the failure
|
||||
to the right command without inventing fake exit codes.
|
||||
Reference in New Issue
Block a user