Climate

A declarative command-line parser for OCaml.
The API is documented here.
About
A library for parsing command-line arguments in a declarative style, where specifying the parser spec and assigning parsed arguments to variables in your program is done with the same code. Climate supports CLIs with nested subcommands, and can automatically generate help messages, manpages, and shell completion scripts.
Here's a tiny example:
let open Arg_parser in
let+ flag_foo = flag [ "foo" ] ~doc:"some flag"
and+ value_bar = named_opt [ "bar" ] string ~doc:"some string value"
in
(* ...do something with the parsed values... *)
Full Example
Here's a complete example program with built-in support for generating its own completion script.
open Climate
module Color = struct
type t =
| Red
| Green
| Blue
(* Tell climate how to handle colours *)
let conv =
let open Arg_parser in
enum ~default_value_name:"COLOR" [ "red", Red; "green", Green; "blue", Blue ]
;;
end
(* Ansi escape sequence to reset the termminal style *)
let ansi_reset = "\x1b[0m"
(* Returns the escape sequence to set the terminal style *)
let ansi_style ~bold ~underline ~color =
let effects =
List.append (if bold then [ ";1" ] else []) (if underline then [ ";4" ] else [])
in
let color_code =
match (color : Color.t option) with
| None -> 0
| Some Red -> 31
| Some Green -> 32
| Some Blue -> 34
in
Printf.sprintf "\x1b[%d%sm" color_code (String.concat "" effects)
;;
(* Print the words in the given style *)
let main ~bold ~underline ~color words =
print_string (ansi_style ~bold ~underline ~color);
print_string (String.concat " " words);
print_string ansi_reset;
print_newline ()
;;
let () =
let command =
Command.singleton ~doc:"Echo with style!"
@@
let open Arg_parser in
(* Describe and parse the command line arguments: *)
let+ bold = flag [ "bold" ] ~doc:"Make the text bold"
and+ underline = flag [ "underline" ] ~doc:"Underline the text"
and+ color = named_opt [ "color" ] Color.conv ~doc:"Set the text color"
and+ words = pos_all string
and+ completion =
flag [ "completion" ] ~doc:"Print this program's completion script and exit"
in
if completion
then `Completion
else `Main (fun () -> main ~bold ~underline ~color words)
in
(* Run the parser yielding either a main function to call or an indication
that we should print the completion script. *)
let help_style =
let open Help_style in
{ program_doc = { ansi_style_plain with color = Some `Green }
; usage = { ansi_style_plain with color = Some `Yellow }
; section_heading = { ansi_style_plain with color = Some `Red }
; arg_name = { ansi_style_plain with color = Some `Blue }
; arg_doc = { ansi_style_plain with color = Some `Cyan }
; error = { ansi_style_plain with color = Some `Red }
}
in
match
Command.run ~program_name:(Literal "echo-ansi") ~version:"0.0.1" ~help_style command
with
| `Completion -> print_endline (Command.completion_script_bash command)
| `Main main -> main ()
;;
This program lives in examples/echo_ansi.ml. Run it with dune exec examples/echo_ansi.exe -- <ARGS>. E.g.
$ dune exec examples/echo_ansi.exe -- --help
Echo with style!
Usage: echo-ansi [OPTION]… [STRING]…
Arguments:
[STRING]...
Options:
--bold Make the text bold
--underline Underline the text
--color <COLOR> Set the text color
--completion Print this program's completion script and exit
-h, --help Show this help message.
Shell Completion
The easiest way to setup the completion script is to first put the executable in a directory in your PATH. E.g.
$ mkdir -p ~/bin
$ export PATH=$HOME/bin:$PATH
$ dune build
$ cp _build/default/examples/echo_ansi.exe ~/bin/echo_ansi
You can ask echo_ansi to print out its own completion script with:
$ echo_ansi --completion
#!/usr/bin/env bash
# Completion script for echo_ansi. Generated by climate.
__climate_complete_1184462387__complete() {
__climate_complete_1184462387__comp_words_traverse_init
if [ "$COMP_CWORD" == "0" ]; then
...
Put the completion script in a file and then source that file in your shell to enable completions for echo_ansi:
$ echo_ansi --completion > /tmp/echo_ansi_completions.sh
$ source /tmp/echo_ansi_completions.sh
$ echo_ansi --color <TAB>
blue green red
Currently only bash is supported, though it also works in zsh if bash compatibility is enabled:
# put this in your ~/.zshrc
autoload -Uz compinit bashcompinit
compinit
bashcompinit
Manpages
To generate a manpage for a command, run the command with the hidden flag --manpage. This command will print the manpage in the troff format to stdout. To render the manpage during development, pipe the output to man -l -. E.g. dune exec myprog.exe -- --manpage | man -l -.