Standard library · The command line
cli/args
Imported as import "cli/args" as args, its names are then args.…. Every signature below is the one the checker infers.
Command-line arguments: what a program takes, said once, and then parsed, checked and explained from that one saying.
--port 80, --port=80 and -p 80 all set port; --verbose and -v set a switch; -- ends the options and everything after it is a slot. --help and -h answer with the usage text as the error, so a program that prints why has help for free.
spec = args.tool("serve", "serve a directory over HTTP") |> args.switch("verbose", "v", "say what is served") |> args.valued("port", "p", "PORT", "8080", "the port to listen on") |> args.slot("dir", "the directory to serve", true) got = args.parse(spec, Cons("serve", Cons("-v", Cons("--port=9000", Cons("www", Nil)))))? args.value(got, "port") # => 9000 args.on(got, "verbose") # => true args.slots(got) # => Cons(www, Nil) res_map(args.parse(spec, Cons("serve", Nil)), \g -> 0) # => Err(missing <dir>\nusage: serve [options] <dir>\n serve a directory over HTTP\n\n -v, --verbose say what is served\n -p, --port PORT the port to listen on (default 8080)\n <dir> the directory to serve\n -h, --help this)
Types
Item
Switch(long: Str, short: Str, help: Str)Valued(long: Str, short: Str, meta: Str, default: Str, help: Str)Slot(name: Str, help: Str, required: Bool)
Spec
Spec(name: Str, about: Str, items: List(Item))
Got
What a parse found: the switches given, the values (given or defaulted), and the slots in order.
Got(switches: Map(Str, Int), values: Map(Str, Str), slots: List(Str))
Functions
fn tool(name: Str, about: Str) -> Spec
args.usage(args.tool("hello", "greet someone")) # => usage: hello [options]\n greet someone\n\n -h, --help this
fn switch(s: Spec, long: Str, short: Str, help: Str) -> Spec
spec = args.tool("t", "") |> args.switch("quiet", "q", "say nothing") args.on(args.parse(spec, Cons("t", Cons("-q", Nil)))?, "quiet") # => true args.on(args.parse(spec, Cons("t", Nil))?, "quiet") # => false
fn valued(s: Spec, long: Str, short: Str, meta: Str, default: Str, help: Str) -> Spec
spec = args.tool("t", "") |> args.valued("name", "n", "NAME", "world", "whom to greet") args.value(args.parse(spec, Cons("t", Nil))?, "name") # => world args.value(args.parse(spec, Cons("t", Cons("-n", Cons("ada", Nil))))?, "name") # => ada
fn slot(s: Spec, name: Str, help: Str, required: Bool) -> Spec
spec = args.tool("t", "") |> args.slot("file", "the input", false) args.slots(args.parse(spec, Cons("t", Cons("a.txt", Nil)))?) # => Cons(a.txt, Nil) args.slots(args.parse(spec, Cons("t", Nil))?) # => Nil
fn on(g: Got, long: Str) -> Bool
spec = args.tool("t", "") |> args.switch("all", "a", "everything") args.on(args.parse(spec, Cons("t", Cons("--all", Nil)))?, "all") # => true
fn value(g: Got, long: Str) -> Str
The value given for long, or its default.
spec = args.tool("t", "") |> args.valued("port", "p", "PORT", "80", "") args.value(args.parse(spec, Cons("t", Cons("--port", Cons("8080", Nil))))?, "port") # => 8080
fn slots(g: Got) -> List(Str)
spec = args.tool("t", "") |> args.slot("x", "", false) |> args.slot("y", "", false) args.slots(args.parse(spec, Cons("t", Cons("--", Cons("-not-a-flag", Cons("b", Nil)))))?) # => Cons(-not-a-flag, Cons(b, Nil))
fn parse(s: Spec, argv: List(Str)) -> Result(Got, Str)
The program name is args()'s first, and is skipped.
spec = args.tool("t", "") |> args.switch("v", "v", "") res_map(args.parse(spec, Cons("t", Cons("--nope", Nil))), \g -> 0) # => Err(`--nope` is not an option of t\nusage: t [options]\n\n -v, --v \n -h, --help this) res_map(args.parse(spec, Cons("t", Cons("--help", Nil))), \g -> 0) # => Err(usage: t [options]\n\n -v, --v \n -h, --help this)
fn usage(s: Spec) -> Str
The tool's line, then one line per item, aligned.
spec = args.tool("cp", "copy a file") |> args.slot("from", "the source", true) |> args.slot("to", "the destination", true) args.usage(spec) # => usage: cp [options] <from> <to>\n copy a file\n\n <from> the source\n <to> the destination\n -h, --help this
Tests
test_options_and_slotstest_errors_and_help