package cmdlang

  1. Overview
  2. Docs

Declarative Command-line Parsing for OCaml.

Cmdlang is a library for creating command-line parsers in OCaml. Implemented as an OCaml EDSL, its declarative specification language lives at the intersection of other well-established similar libraries.

Cmdlang exposes a single module named Command, which contains the entire API to declare command line parsers.

Assuming Cmdlang.Command to be available in your scope as Command, the following is a minimalist command that does nothing:

let cmd : unit Command.t =
  Command.make
    ~summary:"A command that does nothing"
    (let open Command.Std in
     let+ () = Arg.return () in
     ())
;;

To get started with this API refers to this tutorial from cmdlang's documentation.

Terminology

The terminology used by cmdlang is inspired by climate.

Arguments

An Argument is a distinct piece of information passed to the program on the command line. For example, in the command make -td --jobs 4 all, there are 4 arguments: -t, -d, --jobs 4, and all. Arguments are declared using the module Arg.

Arguments can be either positional or named:

Positional arguments

Positional arguments are identified by their position (0-based) in the argument list rather than by name.

Named arguments

Named arguments can be either short or long:

  • Short named arguments begin with a single - followed by a single non - character, such as -l.
  • Long named arguments begin with -- followed by several non - characters, such as --jobs.

Parameters

A Parameter is a single value that is attached to a named argument on the command line. For example, in make --jobs 4, "jobs" is the argument name and 4 is its parameter. Parameters are declared using the module Param.

docv

The term docv is a convention in the API to denote the string that will be printed in the help messages in place of the value that is actually expected. This applies to both positional arguments and parameters of named arguments. For example, in the help message for a named argument, you might see --flag VALUE, where "VALUE" is the docv representing the expected parameter. Similarly, for positional arguments, you might see usage like ./main.exe VAL VAL, where "VAL" is the docv representing the expected positional argument. The name docv stands for "documentation value" and was inspired by cmdliner.

Supported Command Line Syntax

Not all syntaxes are supported by all backends, so you should check the documentation of the targeted backend for more information, and choose your execution engine according to your preferences.

For example, some backends may support combining a collection of short named arguments together with a single leading - followed by each short argument name (in which case ls -la is an alternative way of writing ls -l -a).

As another example, we list here the different ways supported by climate of passing a parameter to a named argument on the command line:

      make --jobs=4   (* long name with equals sign *)
      make --jobs 4   (* long name space delimited *)
      make -j 4       (* short name space delimited *)
      make -j4        (* short name without space *)

Utils

module Nonempty_list : sig ... end

A type to represent lists that are statically known to be non-empty.

Interfaces

These interfaces are convenient to use with the Param module, so you can apply its helpers to custom modules. For example, if your module My_enum implements the Enumerated_stringable interface, then you can build a parser for it with:

Param.enumerated (module My_enum)
module type Enumerated_stringable = sig ... end

An interface for types that have a finite number of inhabitants that all have a canonical string representation.

module type Stringable = sig ... end

An interface for types that can be parsed from strings, when parsing never results in failures.

module type Validated_string = sig ... end

An interface for types that can be parsed from strings, with the possibility of parsing failures.

Building Parameters

module Param : sig ... end

Refer to the Parameters terminology.

Building Arguments

module Arg : sig ... end

Refer to the Arguments terminology.

Building Commands

type 'a t
val make : ?readme:(unit -> string) -> 'a Arg.t -> summary:string -> 'a t

Create a command with the given argument specification and summary.

  • readme is an optional function that returns a detailed description of the command.
  • summary is a short description of what the command does.
  • The argument specification is provided by an 'a Arg.t.

Example:

let hello_cmd =
  Command.make
    ~summary:"Prints 'Hello, world!'"
    ~readme:(fun () ->
      {|
This would usually be a longer description of the command.
It can be written on multiple lines.
|})
    (let open Command.Std in
     let+ () = Arg.return () in
     print_endline "Hello, world!")
;;
val group : ?default:'a Arg.t -> ?readme:(unit -> string) -> summary:string -> (string * 'a t) list -> 'a t

Create a group of subcommands with a common summary.

  • default is an optional default command to run if no subcommand is specified.
  • readme is an optional function that returns a detailed description of the command group.
  • summary is a short description of what the command group does.
  • The subcommands are provided as a list of (name, command) pairs.

Example of a group with no default command:

let cmd_group =
  Command.group
    ~summary:"A group of related commands"
    [ "hello", hello_cmd; "goodbye", goodbye_cmd ]
;;

Each command in the group may itself be a group, allowing for hierarchical trees of commands.

module Utils : sig ... end

Utilities for handling commands.

Applicative operations

These operations are used to build command-line parsers in a declarative style.

module type Applicative_infix = sig ... end

For use with the ( let+ ) style.

module type Applicative_syntax = sig ... end

Let operators

For use with the ( let+ ) style:

let cmd : unit Command.t =
  Command.make
    ~summary:"A command that does nothing"
    (let open Command.Std in
     let+ () = Arg.return () in
     ())
;;
module Std : sig ... end

Ppx_let

For use with the ( let%map_open.Command ) style:

let cmd : unit Command.t =
  Command.make
    ~summary:"A command that does nothing"
    (let%map_open.Command () = Arg.return () in
     ())
;;
module Let_syntax : sig ... end

Private

This module is exported to be used by libraries with strong ties to cmdlang. Its signature may change in breaking ways at any time without prior notice, and outside of the guidelines set by semver.

module Private : sig ... end
OCaml

Innovation. Community. Security.