init
This commit is contained in:
commit
932d4ad420
46 changed files with 5800 additions and 0 deletions
71
lib/cli/CLI.ts
Normal file
71
lib/cli/CLI.ts
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// CLI dispatcher — recursively walks CLICommand tree and wires up yargs
|
||||
import yargs, { type Argv } from "yargs"
|
||||
import { hideBin } from "yargs/helpers"
|
||||
import { CLICommand } from "./CLICommand"
|
||||
|
||||
interface CLIOpts {
|
||||
prog: string
|
||||
description: string
|
||||
}
|
||||
|
||||
export class CLI {
|
||||
private prog: string
|
||||
private description: string
|
||||
|
||||
constructor(opts: CLIOpts) {
|
||||
this.prog = opts.prog
|
||||
this.description = opts.description
|
||||
}
|
||||
|
||||
private registerCommand(y: Argv, CommandClass: new () => CLICommand): void {
|
||||
const cmd = new CommandClass()
|
||||
const subcommands = (CommandClass as any)._subcommands as (new () => CLICommand)[] | undefined
|
||||
|
||||
if (subcommands?.length) {
|
||||
// Branch command with subcommands
|
||||
y.command(
|
||||
cmd.name,
|
||||
cmd.help,
|
||||
(sub) => {
|
||||
for (const Sub of subcommands) {
|
||||
this.registerCommand(sub, Sub)
|
||||
}
|
||||
return sub.demandCommand(1, `Please specify a ${cmd.name} subcommand`)
|
||||
},
|
||||
() => {}
|
||||
)
|
||||
} else {
|
||||
// Leaf command
|
||||
y.command(
|
||||
cmd.name,
|
||||
cmd.help,
|
||||
(sub) => cmd.addArguments(sub),
|
||||
async (args) => {
|
||||
const code = await cmd.execute(args)
|
||||
process.exit(code)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
bootstrap(commands: (new () => CLICommand)[]): void {
|
||||
const y = yargs(hideBin(process.argv))
|
||||
.scriptName(this.prog)
|
||||
.usage(`${this.description}\n\n$0 <command> [options]`)
|
||||
.option("verbose", {
|
||||
alias: "v",
|
||||
type: "boolean",
|
||||
description: "Enable verbose output",
|
||||
default: false,
|
||||
})
|
||||
.demandCommand(1, "Please specify a command")
|
||||
.strict()
|
||||
.help()
|
||||
|
||||
for (const Cmd of commands) {
|
||||
this.registerCommand(y, Cmd)
|
||||
}
|
||||
|
||||
y.parse()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue