Skip to content

Commit

Permalink
Merge pull request #19 from mbarbin/climate.3
Browse files Browse the repository at this point in the history
Upgrade to climate.0.3.0
  • Loading branch information
mbarbin authored Nov 29, 2024
2 parents ab9f3e9 + dd6772c commit 5e1354a
Show file tree
Hide file tree
Showing 25 changed files with 709 additions and 187 deletions.
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"cmdlang",
"cmdliner",
"conv",
"docv",
"Fpath",
"groff",
"janestreet",
"odoc",
Expand Down
18 changes: 18 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
## 0.0.9 (unreleased)

### Added

### Changed

- Document presence in stdlib-runner help (required, default, etc.) (#19, @mbarbin).
- Minor refactor in stdlib-runner (#19, @mbarbin).
- Upgrade to `climate.0.3.0` (#19, @mbarbin).

### Deprecated

### Fixed

- Fix trailing dot additions in `to-cmdliner` for cases such as `?.` and `..` (#19, @mbarbin).

### Removed

## 0.0.8 (2024-11-14)

### Added
Expand Down
2 changes: 1 addition & 1 deletion cmdlang-tests.opam
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ depends: [
"ocamlformat" {with-dev-setup & = "0.26.2"}
"base" {>= "v0.17" & < "v0.18"}
"bisect_ppx" {with-dev-setup & >= "2.8.3"}
"climate" {>= "0.1.0~" & < "0.2"}
"climate" {>= "0.3.0"}
"cmdlang" {= version}
"cmdlang-stdlib-runner" {= version}
"cmdlang-to-base" {= version}
Expand Down
2 changes: 1 addition & 1 deletion cmdlang-to-climate.opam
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ bug-reports: "https://github.com/mbarbin/cmdlang/issues"
depends: [
"dune" {>= "3.16"}
"ocaml" {>= "4.14"}
"climate" {>= "0.1.0"}
"climate" {>= "0.3.0"}
"cmdlang" {= version}
"odoc" {with-doc}
]
Expand Down
17 changes: 5 additions & 12 deletions doc/docs/reference/odoc.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,13 @@ You can view the published odoc pages here: [https://mbarbin.github.io/cmdlang/o

## Release status

### Pending releases
We have released an initial set of packages to allow interested parties to experiment with cmdlang and provide early feedback.

We plan to release the following packages soon to allow interested parties to experiment with cmdlang and provide early feedback.

| package | released to opam |
|----------------------|:----------------:|
| cmdlang.opam | pending |
| cmdlang-to-cmdliner | pending |
| cmdlang-to-climate | pending |

### Planned releases
We plan to release the translation to `core.command` next. However, this will require additional work. Specifically, we aim to complete the coverage of that part of the code and exercise the translation using special configuration options in a tutorial.

| package | released to opam |
|----------------------|:----------------:|
| cmdlang.opam ||
| cmdlang-to-cmdliner ||
| cmdlang-to-climate ||
| cmdlang-to-base | planned |

We also plan to release the translation to `core.command`. However, this will require additional work. Specifically, we aim to complete the coverage of that part of the code and exercise the translation using special configuration options in a tutorial.
5 changes: 2 additions & 3 deletions dune-project
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
(>= 4.14))
(climate
(and
(>= 0.1.0)))
(>= 0.3.0)))
(cmdlang
(= :version))))

Expand Down Expand Up @@ -130,8 +130,7 @@
(>= 2.8.3)))
(climate
(and
(>= 0.1.0~)
(< 0.2)))
(>= 0.3.0)))
(cmdlang
(= :version))
(cmdlang-stdlib-runner
Expand Down
180 changes: 176 additions & 4 deletions lib/cmdlang/src/command.mli
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,72 @@
{{:https://mbarbin.github.io/cmdlang/docs/tutorials/getting-started/} tutorial}
from cmdlang's documentation. *)

(** {1 Terminology}
The terminology used by cmdlang is inspired by
{{:https://github.com/gridbugs/climate/} climate}.
{2:arguments Arguments}
An {e 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 {!module:Arg}.
Arguments can be either {e positional} or {e named}:
{3:positional_arguments Positional arguments}
{e Positional} arguments are identified by their position (0-based) in the
argument list rather than by name.
{3:named_arguments Named arguments}
{e Named} arguments can be either {e short} or {e long}:
- {e Short} named arguments begin with a single [-] followed by a single
non [-] character, such as [-l].
- {e Long} named arguments begin with [--] followed by several non [-]
characters, such as [--jobs].
{3:parameters Parameters}
A {e 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
{!module:Param}.
{2:docv docv}
The term {e 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 {e docv} representing the expected
parameter. Similarly, for positional arguments, you might see usage like
[./main.exe VAL VAL], where "VAL" is the {e docv} representing the expected
positional argument. The name {e docv} stands for "documentation value" and
was inspired by {i cmdliner}.
{2 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:
{v
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 *)
v} *)

(** {1 Utils} *)

module Nonempty_list : sig
Expand Down Expand Up @@ -104,17 +170,32 @@ module type Validated_string = sig
val to_string : t -> string
end

(** {1 Parameters} *)
(** {1 Building Parameters} *)

module Param : sig
type 'a t
(** Refer to the {{!parameters} Parameters} terminology. *)

(** Parsing parameters of type ['a] from the command line. *)
type 'a parse := string -> ('a, [ `Msg of string ]) result

(** Printing parameters of type ['a] back to their expected command line
syntax. Printing parameter is used for example when documenting default
values in the help messages. *)
type 'a print := Format.formatter -> 'a -> unit

(** A type to hold the capability of parsing and printing a parameter of
type ['a]. *)
type 'a t

val create : docv:string -> parse:'a parse -> print:'a print -> 'a t

(** {1 Basic types} *)

(** The API supports basic types with default {!docv} values. These defaults
can be overridden for each argument. The default {e docv} is used only
if none is specified at the argument level. The actual syntax used by
default depend on the targeted backend. *)

val string : string t
val int : int t
val float : float t
Expand All @@ -123,20 +204,52 @@ module Param : sig

(** {1 Helpers} *)

(** Helpers for creating parameters for custom types. These helpers also come
with default {e docv} values, which can be overridden as needed. *)

(** Create a parameter for an enumerated type. The module must implement the
[Enumerated_stringable] interface.
Example:
{[
module Color = struct
type t =
| Red
| Green
| Blue
let all = [ Red; Green; Blue ]
let to_string = function
| Red -> "red"
| Green -> "green"
| Blue -> "blue"
;;
end
let color_param = Param.enumerated ~docv:"COLOR" (module Color)
]}
The usage message will show the supported values for [COLOR]. *)
val enumerated : ?docv:string -> (module Enumerated_stringable with type t = 'a) -> 'a t

val stringable : ?docv:string -> (module Stringable with type t = 'a) -> 'a t

(** To be used with custom types when the parsing may fail. *)
val validated_string
: ?docv:string
-> (module Validated_string with type t = 'a)
-> 'a t

(** Parser for a list of values separated by commas. *)
val comma_separated : 'a t -> 'a list t
end

(** {1 Arguments} *)
(** {1 Building Arguments} *)

module Arg : sig
(** Refer to the {{!arguments} Arguments} terminology. *)

type 'a t

(** {1 Applicative operations} *)
Expand All @@ -148,24 +261,33 @@ module Arg : sig

(** {1 Named arguments} *)

(** A flag that may appear at most once on the command line. *)
val flag : string Nonempty_list.t -> doc:string -> bool t

(** A flag that may appear multiple times on the command line. Evaluates to
the number of times the flag appeared. *)
val flag_count : string Nonempty_list.t -> doc:string -> int t

(** A required named argument (must appear exactly once on the command line). *)
val named : ?docv:string -> string Nonempty_list.t -> 'a Param.t -> doc:string -> 'a t

(** A named argument that may appear multiple times on the command line. *)
val named_multi
: ?docv:string
-> string Nonempty_list.t
-> 'a Param.t
-> doc:string
-> 'a list t

(** An optional named argument (may appear at most once). *)
val named_opt
: ?docv:string
-> string Nonempty_list.t
-> 'a Param.t
-> doc:string
-> 'a option t

(** An optional named argument with a default value. *)
val named_with_default
: ?docv:string
-> string Nonempty_list.t
Expand All @@ -178,9 +300,16 @@ module Arg : sig

(** Positional argument start at index 0. *)

(** A required positional argument. It must appear exactly once at position
[i] on the command line. *)
val pos : ?docv:string -> pos:int -> 'a Param.t -> doc:string -> 'a t

(** An optional positional argument at position [i]. Optional positional
argument must not be followed by more positional argument as this
creates ambiguous specifications. *)
val pos_opt : ?docv:string -> pos:int -> 'a Param.t -> doc:string -> 'a option t

(** A optional positional argument with a default value. *)
val pos_with_default
: ?docv:string
-> pos:int
Expand All @@ -189,15 +318,58 @@ module Arg : sig
-> doc:string
-> 'a t

(** Return the list of all remaining positional arguments. *)
val pos_all : ?docv:string -> 'a Param.t -> doc:string -> 'a list t
end

(** {1 Commands} *)
(** {1 Building Commands} *)

type '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 make : ?readme:(unit -> string) -> 'a Arg.t -> summary:string -> '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. *)
val group
: ?default:'a Arg.t
-> ?readme:(unit -> string)
Expand Down
Loading

0 comments on commit 5e1354a

Please sign in to comment.