Module Bos.OS.Arg

module Arg: sig .. end
Quick and dirty program arguments parsing.

This is for quick hacks and scripts. If your program evolves to a tool for end users you should rather use Cmdliner to parse your command lines: it generates man pages and its parsing is more flexible and user friendly. The syntax of command lines parsed by this module is a subset of what Cmdliner is able to parse so migrating there should not be a problem for existing invocations of your program.

This module supports short and long options with option arguments either glued to the option or specified as the next program argument. It also supports the -- program argument to notify that subsequent arguments have to be treated as positional arguments. Parsing functions always respond to the -h, -help or --help flags by showing the program's usage and command line options documentation.

See the basics.

Warning. This module is not thread-safe.



Executable name


val exec : string
exec is the name of the executable. This is Sys.argv.(0) if Sys.argv is non-empty or Sys.executable_name otherwise.

Argument converters

Argument converters transform string arguments of the command line to OCaml values. Consult the predefined converters.

type 'a conv 
The type for argument converters.
val conv : ?docv:string ->
(string -> ('a, Rresult.R.msg) Result.result) ->
(Format.formatter -> 'a -> unit) -> 'a conv
conv ~docv parse print is an argument converter parsing values with parse and printing them with print. docv is a documentation meta-variable used in the documentation to stand for the argument value, defaults to "VALUE".
val conv_parser : 'a conv -> string -> ('a, Rresult.R.msg) Result.result
conv_parser c is c's parser.
val conv_printer : 'a conv -> Format.formatter -> 'a -> unit
conv_printer c is c's printer.
val conv_docv : 'a conv -> string
conv_printer c is c's documentation meta-variable.
val parser_of_kind_of_string : kind:string ->
(string -> 'a option) -> string -> ('a, Rresult.R.msg) Result.result
parser_of_kind_of_string ~kind kind_of_string is an argument parser using the kind_of_string function for parsing and kind for errors (e.g. could be "an integer" for an int parser).
val some : ?none:string -> 'a conv -> 'a option conv
some none c is like the converter c but wraps its result in Some. This is used for command line arguments that default to None when absent. none is what should be printed by the printer for None (defaults to "").

Flag and option queries

Flag and option names. They are specified without dashes. A one character name defines a short option; "d" is -d. Longer names define long options "debug" is --debug.

Option argument specification. On the command line, option arguments are either specified as the next program argument or glued to the option. For short options gluing is done directly: -farchive.tar. For long options an "=" characters stands between the option and the value: --file=archive.tar.

Warning. These functions are effectful invoking them twice on the same option names will result in parse errors. All the following functions raise Invalid_argument if they are invoked after parsing.

val flag : ?doc:string -> ?env:string -> string list -> bool
flag ~doc ~env names is true if one of the flags in names is present on the command line at most once and false otherwise.

If there is no flag on the command line and env is specified and defined in the environment, its value is parsed with Bos.OS.Env.bool and the resulting value is used. doc is a documentation string.

val flag_all : ?doc:string -> ?env:string -> string list -> int
flag_all is like Bos.OS.Arg.flag but counts the number of occurences of the flag on the command line. If there is no flag on the command line and env is specified and defined in the environment, its value is parsed with Bos.OS.Env.bool and converted to an integer.
val opt : ?docv:string ->
?doc:string ->
?env:string -> string list -> 'a conv -> absent:'a -> 'a
opt ~docv ~doc ~env names c ~absent is a value defined by the value of an optional argument that may appear at most once on the command line under one of the names specified by names.

The argument of the option is converted with c and absent is used if the option is absent from the command line. If there is no option on the command line and env is specified and defined in the environment, its value is parsed with parse and that value is used instead of absent.

doc is is a documentation string. docv a documentation meta-variable used in the documentation to stand for the option argument, if unspecified c's Bos.OS.Arg.conv_docv is used. In doc occurences of the substring "$(docv)" in are replaced by the value of docv.

val opt_all : ?docv:string ->
?doc:string ->
?env:string -> string list -> 'a conv -> absent:'a list -> 'a list
opt_all is like Bos.OS.Arg.opt but the optional argument can be repeated.

Parsing

Note. Before parsing make sure you have invoked all the queries.

Warning. All the following functions raise Invalid_argument if they are reinvoked after parsing.

val parse_opts : ?doc:string -> ?usage:string -> unit -> unit
parse_opts () can:

A parsing error occurs either if an option parser failed, if a non repeatable option was specified more than once, if there is an unknown option on the line, if there is a positional argument on the command line (use Bos.OS.Arg.parse to parse them). usage is the command argument synopsis (default is automatically inferred). doc is a documentation string for the program.

val parse : ?doc:string -> ?usage:string -> pos:'a conv -> unit -> 'a list
parse ~pos is like Bos.OS.Arg.parse_opts but returns and converts the positional arguments with pos rather than error on them. Note that any thing that comes after a -- argument on the command line is deemed to be a positional argument.

Predefined argument converters


val string : string conv
string converts a string argument. This never errors.
val path : Fpath.t conv
path converts a path argument using Fpath.of_string.
val bin : Bos.Cmd.t conv
bin is Bos.OS.Arg.string mapped by Bos.Cmd.v.
val cmd : Bos.Cmd.t conv
cmd converts a non-empty command line with Bos.Cmd.of_string
val char : char conv
char converts a single character.
val bool : bool conv
bool converts a boolean with String.to_bool.
val int : int conv
int converts an integer with String.to_int.
val nativeint : nativeint conv
int converts a nativeint with String.to_nativeint.
val int32 : int32 conv
int32 converts an int32 with String.to_int32.
val int64 : int64 conv
int64 converts an int64 with String.to_int64.
val float : float conv
float converts an float with String.to_float.
val enum : (string * 'a) list -> 'a conv
enum l p converts values such that string names in l map to the corresponding value of type 'a.

Warning. The type 'a must be comparable with Pervasives.compare.
Raises Invalid_argument if l is empty.

val list : ?sep:string -> 'a conv -> 'a list conv
list ~sep c converts a list of c. For parsing the argument is first String.cuts ~sep and the resulting string list is converted using c.
val array : ?sep:string -> 'a conv -> 'a array conv
array ~sep c is like Bos.OS.Arg.list but returns an array instead.
val pair : ?sep:string ->
'a conv -> 'b conv -> ('a * 'b) conv
pair ~sep fst snd converts a pair of fst and snd. For parsing the argument is String.cut ~sep and the resulting strings are converted using fst and snd.

Basics

To parse a command line, first perform all the option queries and then invoke one of the parsing functions. Do not invoke any query after parsing has been done, this will raise Invalid_argument. This leads to the following program structure:

(* It is possible to define things at the toplevel as follows. But do not
   abuse this. The following flag, if unspecified on the command line, can
   also be specified with the DEBUG environment variable. *)
let debug = OS.Arg.(flag ["g""debug"] ~env:"DEBUG" ~doc:"debug mode.")
...

let main () =
  let depth =
    OS.Arg.(opt ["d""depth"] int ~absent:2 ~doc:"recurses $(docv) times.")
  in
  let pos_args = OS.Arg.(parse ~pos:string ()) in
  (* No command line error or help request occured, run the program. *)
  ...

let main () = main ()