Created
April 6, 2022 18:21
-
-
Save jtpaasch/8a0ec61203a1b224300967472e774e50 to your computer and use it in GitHub Desktop.
An example of subcommands with OCaml's Cmdliner
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(executable | |
(name main) | |
(libraries findlib.dynload bap)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(lang dune 3.0) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(** A simple example of using [Cmdliner] to make subcommands. *) | |
module C = Cmdliner | |
type config = { verbose : bool; dryrun : bool; } | |
module Common_cli = struct | |
let package_em (verbose : bool) (dryrun : bool) : config = | |
{ verbose; dryrun } | |
let docs = C.Manpage.s_common_options | |
let verbose = | |
let info = C.Arg.info ["v"; "verbose"] | |
~docs (* List under COMMON OPTIONS *) | |
~doc:"Print verbose output." | |
in | |
C.Arg.value (C.Arg.flag info) | |
let dryrun = | |
let info = C.Arg.info ["d"; "dryrun"] | |
~docs (* List under COMMON OPTIONS *) | |
~doc:"Do a dry run." | |
in | |
C.Arg.value (C.Arg.flag info) | |
let runner = C.Term.(const package_em $ verbose $ dryrun) | |
end | |
module Foo = struct | |
let run (conf : config) (a : string) : unit = | |
Printf.printf "Running Foo\n a: %s\n verbose: %b\n dryrun: %b\n%!" | |
a conf.verbose conf.dryrun | |
end | |
module Foo_cli = struct | |
let name = "foo" | |
let doc = "A simple 'foo' command" | |
let man = [ | |
`S C.Manpage.s_description; | |
`P "Here is a longer description of the 'foo' command."; | |
] | |
let info = C.Cmd.info name ~doc ~man | |
let a = | |
let info = C.Arg.info ["a"; "option-a"] | |
~docv:"A" | |
~doc:"A command-line option 'a'" | |
in | |
let parser = C.Arg.string in | |
let default = "" in | |
C.Arg.value (C.Arg.opt parser default info) | |
let runner = C.Term.(const Foo.run $ Common_cli.runner $ a) | |
let cmd = C.Cmd.v info runner | |
end | |
module Bar = struct | |
let run (conf : config) (p : int) : unit = | |
Printf.printf "Running Bar\n p: %d\n verbose: %b\n dryrun: %b\n%!" | |
p conf.verbose conf.dryrun | |
end | |
module Bar_cli = struct | |
let name = "bar" | |
let doc = "A simple 'bar' command" | |
let man = [ | |
`S C.Manpage.s_description; | |
`P "Here is a longer description of the 'bar' command."; | |
] | |
let info = C.Cmd.info name ~doc ~man | |
let b = | |
let info = C.Arg.info ["b"; "option-b"] | |
~docv:"B" | |
~doc:"A command-line option 'b'" | |
in | |
let parser = C.Arg.int in | |
let default = 0 in | |
C.Arg.value (C.Arg.opt parser default info) | |
let runner = C.Term.(const Bar.run $ Common_cli.runner $ b) | |
let cmd = C.Cmd.v info runner | |
end | |
module Main_cli = struct | |
let name = "main.exe" | |
let doc = "A simple command with some subcommands" | |
let info = C.Cmd.info name ~doc | |
let cmd = C.Cmd.group info [Foo_cli.cmd; Bar_cli.cmd] | |
end | |
let () = exit (C.Cmd.eval Main_cli.cmd) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TOOL := main.exe | |
##################################################### | |
# DEFAULT | |
##################################################### | |
.DEFAULT_GOAL := all | |
all: clean run | |
##################################################### | |
# THE TOOL | |
##################################################### | |
.PHONY: clean | |
clean: | |
dune clean | |
build: | |
dune build ./$(TOOL) | |
run: build | |
dune exec ./$(TOOL) -- foo -a "bizz bazz" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To run this, put the above files into a folder and run
make
.Try also:
./_build/default/main.exe --help
./_build/default/main.exe foo --help
./_build/default/main.exe bar --help