|
| 1 | +--- |
| 2 | +packages: |
| 3 | +- name: cmdliner |
| 4 | + tested_version: "1.3.0" |
| 5 | + used_libraries: |
| 6 | + - cmdliner |
| 7 | +--- |
| 8 | +(* In this example, we define a parser for a command-line like this: |
| 9 | +
|
| 10 | + ``` |
| 11 | + mycmd --verbose input_file -o output_file |
| 12 | + ``` |
| 13 | +
|
| 14 | + `--verbose` and `-o` are optional, and the command should accept multiple |
| 15 | + input files. |
| 16 | +
|
| 17 | + We can find more examples on |
| 18 | + [this page](https://erratique.ch/software/cmdliner/doc/examples.html). |
| 19 | + *) |
| 20 | +let cmdliner_parser () = |
| 21 | + (* `Cmdliner` is a library that allows the declarative definition of |
| 22 | + command-line interfaces |
| 23 | + ([documentation page](https://erratique.ch/software/cmdliner/doc/index.html)). |
| 24 | + *) |
| 25 | + let open Cmdliner in |
| 26 | + (* First we declare the expected arguments of our command-line, and how |
| 27 | + `Cmdliner` should parse them. *) |
| 28 | + let verbose = |
| 29 | + let doc = "Output debug information" in |
| 30 | + (* `&` is a right associative composition operator |
| 31 | + ([documentation](https://erratique.ch/software/cmdliner/doc/Cmdliner/Arg/index.html#val-(&))). |
| 32 | + *) |
| 33 | + Arg.(value & flag & info ["v" ; "verbose"] ~doc) |
| 34 | + and input_files = |
| 35 | + let doc = "Input file(s)" in |
| 36 | + Arg.(non_empty & pos_all file [] |
| 37 | + & info [] ~docv:"INPUT" ~doc) |
| 38 | + and output_file = |
| 39 | + let doc = "Output file" |
| 40 | + and docv = "OUTPUT" in |
| 41 | + Arg.(value & opt (some string) None |
| 42 | + & info ["o"] ~docv ~doc) |
| 43 | + (* `mycmd` is the function that the program will apply to the parsed |
| 44 | + arguments. *) |
| 45 | + and mycmd verbose input_files output_file = |
| 46 | + Printf.printf "verbose: %b\n" verbose; |
| 47 | + Printf.printf "input files: %s\n" |
| 48 | + (input_files |> String.concat ", "); |
| 49 | + Printf.printf "output file: %s\n" |
| 50 | + (Option.value ~default:"" output_file) |
| 51 | + in |
| 52 | + (* Declaration of the complete command, including its man-like |
| 53 | + documentation. *) |
| 54 | + let cmd = |
| 55 | + let doc = "An example command" |
| 56 | + and man = [ |
| 57 | + `S Manpage.s_description; |
| 58 | + `P "A command that can take multiple files |
| 59 | + and outputs a file (optional)." |
| 60 | + ] |
| 61 | + in |
| 62 | + Cmd.v (Cmd.info "mycmd" ~doc ~man) |
| 63 | + Term.(const mycmd $ verbose $ input_files $ output_file) |
| 64 | + in |
| 65 | + Cmd.eval cmd |
| 66 | + |
| 67 | + |
| 68 | +(* Given a command-line like |
| 69 | + `mycmd --verbose -o somefile ./dune-project ./cmd_cookbook.opam`, we should |
| 70 | + expect the following output: |
| 71 | +
|
| 72 | + ``` |
| 73 | + verbose: true |
| 74 | + input files: ./dune-project, ./cmd_cookbook.opam |
| 75 | + output file: somefile |
| 76 | + ``` *) |
| 77 | +let () = |
| 78 | + exit @@ cmdliner_parser () |
0 commit comments