-
Notifications
You must be signed in to change notification settings - Fork 2
/
Demo_subcmd_main.ml
160 lines (126 loc) · 3.2 KB
/
Demo_subcmd_main.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
(*
A minimal program demonstrating how to implement subcommands with cmdliner.
We're implementing two subcommands 'subcmd1' and 'subcmd2' to be used as:
$ cmdliner-demo-subcmd subcmd1 --foo # doesn't support '--bar'
$ cmdliner-demo-subcmd subcmd2 --bar # doesn't support '--foo'
For a generic template and examples on specifying different types
of arguments, consult 'Demo_arg_main.ml'.
*)
open Printf
(* Provide 'Term', 'Arg', and 'Manpage' modules. *)
open Cmdliner
type subcmd1_conf = {
foo: bool;
}
type subcmd2_conf = {
bar: bool;
}
(*
The result of parsing the command line successfully.
*)
type cmd_conf =
| Subcmd1 of subcmd1_conf
| Subcmd2 of subcmd2_conf
(*
Do something with the parsed command line.
*)
let run cmd_conf =
match cmd_conf with
| Subcmd1 conf ->
printf "\
subcmd1 configuration:
foo: %B
"
conf.foo
| Subcmd2 conf ->
printf "\
subcmd2 configuration:
bar: %B
"
conf.bar
(*** Define different kinds of arguments and options (see other demo) ***)
let foo_term =
let info =
Arg.info ["foo"]
~doc:"Enable the foo!"
in
Arg.value (Arg.flag info)
let bar_term =
let info =
Arg.info ["bar"]
~doc:"Enable the bar!"
in
Arg.value (Arg.flag info)
(*** Putting together subcommand 'subcmd1' ***)
let subcmd1_term run =
let combine foo =
Subcmd1 { foo } |> run
in
Term.(const combine
$ foo_term
)
let subcmd1_doc = "[some headline for subcmd1]"
let subcmd1_man = [
`S Manpage.s_description;
`P "[multiline overview of subcmd1]";
]
let subcmd1 run =
let info =
Cmd.info "subcmd1"
~doc:subcmd1_doc
~man:subcmd1_man
in
Cmd.v info (subcmd1_term run)
(*** Putting together subcommand 'subcmd2' ***)
let subcmd2_term run =
let combine bar =
Subcmd2 { bar } |> run
in
Term.(const combine
$ bar_term
)
let subcmd2_doc = "[some headline for subcmd2]"
let subcmd2_man = [
`S Manpage.s_description;
`P "[multiline overview of subcmd2]";
]
let subcmd2 run =
let info =
Cmd.info "subcmd2"
~doc:subcmd2_doc
~man:subcmd2_man
in
Cmd.v info (subcmd2_term run)
(*** Putting together the main command ***)
let root_doc = "[some headline for the main command]"
let root_man = [
`S Manpage.s_description;
`P "[multiline overview of the main command]";
]
(*
Use the built-in action consisting in displaying the help page.
*)
let root_term =
Term.ret (Term.const (`Help (`Pager, None)))
let root_info =
Cmd.info "cmdliner-demo-subcmd"
~doc:root_doc
~man:root_man
(*** Parse the command line and do something with it ***)
let subcommands run = [
subcmd1 run;
subcmd2 run;
]
(*
$ cmdliner-demo-subcmd -> parsed as root subcommand
$ cmdliner-demo-subcmd --help -> also parsed as root subcommand
$ cmdliner-demo-subcmd subcmd1 -> parsed as 'subcmd1' subcommand
If there is a request to display the help page, it displayed at this point,
returning '`Help'.
Otherwise, 'conf' is returned to the application.
*)
let parse_command_line_and_run (run : cmd_conf -> unit) =
Cmd.group root_info (subcommands run) |> Cmd.eval |> exit
let main () =
parse_command_line_and_run run
let () = main ()