std/cli/command

std/cli/src/command.trb

Command: a tree of commands declared once, with the flags, options and positional arguments of each, and what reads a command line against it. command builds the tree on receiver closures; Command.parse reads a list of strings and touches nothing, so a test hands it an argument list.

type FlagSpec

type FlagSpec

A switch that is there or is not: --statistics. Declared by flag.

field name

name: String

The name without dashes.

field help

help: String

The line of the help text.

type OptionSpec

type OptionSpec

A named value: --jobs 8 or --jobs=8. Declared by option.

field name

name: String

The name without dashes.

field help

help: String

The line of the help text.

field typeName

typeName: String

What the type is called in the help text, as in --jobs <integer>.

field defaultText

defaultText: String?

The default as text, where there is one; an option that is neither optional nor repeatable and has none is required.

field check

check: (String) => String?

Why a text is not a value of the type, and nothing where it is one.

field optional

optional: Bool

The option may be left out and has no default. Declared by optional.

field repeatable

repeatable: Bool

The option may be given any number of times. Declared by repeatable.

type ArgumentsSpec

type ArgumentsSpec

The positional arguments of a command, collected as a list. Declared by arguments.

field name

name: String

The name input.arguments(name) reads them by.

field help

help: String

The line of the help text.

field passthrough

passthrough: Bool

The first positional argument ends option parsing: it and everything behind it, flags too, are collected.

type CommandBuilder

type CommandBuilder

The receiver of a command block: everything a command can say about itself. A nested command block is a subcommand, run is what happens when the command is chosen.

field name

name: String

The name of the command: what the line says to choose it, and the first word of its usage.

field summary

protected var summary: String = ""

The sentence description set; empty where the command has none.

field flagSpecs

protected var flagSpecs: List<FlagSpec> = []

The flags declared so far, in the order of the declaration.

field optionSpecs

protected var optionSpecs: List<OptionSpec> = []

The options declared so far, in the order of the declaration.

field argumentsSpec

protected var argumentsSpec: ArgumentsSpec? = None

The positional arguments arguments declared, where it was called.

field subcommands

protected var subcommands: List<Command> = []

The subcommands declared so far, in the order of the declaration.

field action

protected var action: ((Input) => Void)? = None

What run set: the handler of the command, where it has one.

fn description

var fn description(text: String)

The sentence the help text starts with, and the line next to the command in its parent's list.

fn command

var fn command(name: String, configure: (var self: CommandBuilder) => Void)

Declares the subcommand name, configured by configure.

fn flag

var fn flag(name: String, help: String = "")

Declares the flag --name. The handler reads it with input.flag("name"): false where the line left it out.

fn option

var fn option<T: Argument>(name: String, help: String = "", default: T? = None)

Declares the option --name, of type T, read with input.option<T>("name"). With a default the option may be left out; without one it is required. A value that is no T is an error of the line.

fn optional

var fn optional<T: Argument>(name: String, help: String = "")

Declares the option --name, of type T, that may be left out and has no default, read with input.optional<T>("name"): None where the line left it out. A value that is no T is an error of the line.

fn repeatable

var fn repeatable<T: Argument>(name: String, help: String = "")

Declares the option --name, of type T, that may be given any number of times (--name a --name=b), read with input.repeated<T>("name"): the values in the order of the line, empty where the line left it out. Every value is checked against T like the value of an option.

fn arguments

var fn arguments(name: String, help: String = "", passthrough: Bool = false)

Declares the positional arguments, collected as a list and read with input.arguments("name"). With passthrough the first positional argument ends option parsing: it and everything behind it, flags included, go into the list unread, as in torb run tool.trb --emit-c. --help and -h are honoured before that point only.

fn run

var fn run(handler: (Input) => Void)

What happens when the line chooses this command. A command without one only groups its subcommands.

type Parsed

type Parsed

What Command.parse read: the command the line chose, its values, and whether the line asked for its help text.

field path

path: List<String>

The command that was chosen, from the program's own name down: ["torb", "check"].

field command

command: Command

The chosen command.

field input

input: Input

The values; empty where helpRequested.

field helpRequested

helpRequested: Bool

The line had --help or -h, or was help and the name of a command.

fn help

fn help(): String

The help text of the chosen command.

type Command

type Command

A command with its flags, options, positional arguments and subcommands: the tree command builds. Nothing in it is registered by scanning; a subcommand is part of it because a block named it.

field name

name: String

What the line says to choose it.

field summary

summary: String

The description.

field flags

flags: List<FlagSpec>

The flags, in the order of the declaration.

field options

options: List<OptionSpec>

The options, in the order of the declaration.

field positional

positional: ArgumentsSpec?

The positional arguments, where the command takes any.

field commands

commands: List<Command>

The subcommands, in the order of the declaration.

field handler

handler: ((Input) => Void)?

What run was given.

fn subcommand

fn subcommand(name: String): Command?

The subcommand called name.

fn parse

fn parse(arguments: List<String>): Result<Parsed, CliError>

Reads a command line against the declaration and answers what it said, or why it is wrong. arguments is the line without the program's name. A flag or an option is written --name, an option's value --name value or --name=value, -- ends the flags and options, --help and -h ask for the help text, and help followed by the names of a command asks for the help text of that one.

Flags and options are looked up in the command the line has chosen so far, so they stand after the name of the subcommand they belong to.

fn help

fn help(path: List<String>): String

The help text of this command, generated from the declaration. path is how the line spelled the command, from the program's name down, and starts the usage line, which lists the options and then the commands or arguments.

The TorbScript toolchain

Usage: torb ...

Commands:
  check  Check projects, files or a whole workspace
  help   Show the help text of a command

Options:
  -h, --help  Show this help text

fn run

fn run(arguments: List<String>)

Reads arguments, then runs the handler of the command the line chose. The help text goes to the output; an error goes to the error output with a pointer to the help text and ends the process with exit code 2. This is the one place of the package that does anything: the usual call is cli.run Process.arguments().

fn names

fn names(): List<String>

The names of the subcommands.

fn command

fn command(name: String, configure: (var self: CommandBuilder) => Void): Command

Declares a program or a command: its description, its flags, options and positional arguments, its subcommands and what run does. The block is a receiver closure, so a name inside it is a member of CommandBuilder.

use command from "std/cli"

const cli = command "torb" {
  description "The TorbScript toolchain"
  command "check" {
    description "Check projects, files or a whole workspace"
    flag "statistics", help: "Print typed and deferred expressions per module"
    option<Int>("jobs", help: "How many files at once", default: 4)
    arguments "paths", help: "Projects, directories or files"
    run { input =>
      print "{input.arguments("paths")} {input.flag("statistics")} {input.option<Int>("jobs")}"
    }
  }
}

cli.run ["check", "--jobs=8", "src"]