Command Lines#
Status: slice 1 done, slice 2 under way — std/cli declares commands, flags, options
and positional arguments, and generates the help text and the errors. torb check, build, run and test are one
declaration (compiler/src/cli/declaration.trb), and so are manifest, ir, natives, parse, tokens, ast and
highlight; the other subcommands of torb still read their arguments in main.trb.
std/cli is the standard library's answer to Rust's clap: a program with several commands, flags, options and
positional arguments, its help text and its errors, declared once. Its first user is the compiler: torb has a dozen
subcommands, and every one of them parses its own arguments by hand today.
1. The direction#
The language has no annotations and no reflection, so the declaration is not a type with attributes on its fields. It
is a builder on receiver closures, the same means project.trb uses:
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"
arguments "paths", help: "Projects, directories or files"
run { input => check(input.arguments("paths"), statistics: input.flag("statistics")) }
}
}
cli.run Process.arguments()What follows from the direction, and is not open:
- the help text of every command and the error for a wrong argument are generated from the declaration, and a wrong argument exits with a message that names the command and the argument;
- nothing is registered by scanning: a subcommand is part of the tree because the builder names it;
- the package is pure except for
run, which reads the arguments it is given, so a test hands it a list of strings.
2. Decided and open#
- Typed options (decided).
option<Int>("jobs", default: 4)is read back asinput.option<Int>("jobs");Int,Float64,BoolandStringareArguments, and a type of the program joins them with anextend. Decoding the arguments of a command into a type of the program (input.decode<CheckOptions>()), throughDecodeas std/json does it, comes later: it keeps one declaration per option, and the derivedDescribe(ENCODING.md) would carry the documentation of each field into the help text. - Shell completion: later, generated from the same declaration.
3. Slices#
| # | Slice | Needs |
|---|---|---|
| 1 (done) | std/cli: commands, flags, options, positional arguments, help, errors; tests with argument lists | nothing |
2 (check, build, run, test, manifest, ir, natives, parse, tokens, ast, highlight done) | torb parses its command line with it | 1, and a seed refresh, because the compiler imports it |
| 3 | Shell completion scripts | 1 |