]>
Commit | Line | Data |
---|---|---|
8bb4bdeb XL |
1 | mod settings; |
2 | #[macro_use] | |
3 | mod macros; | |
4 | pub mod parser; | |
5 | mod meta; | |
6 | mod help; | |
041b39d2 XL |
7 | mod validator; |
8 | mod usage; | |
8bb4bdeb XL |
9 | |
10 | // Std | |
8bb4bdeb | 11 | use std::env; |
041b39d2 | 12 | use std::ffi::{OsStr, OsString}; |
8bb4bdeb XL |
13 | use std::fmt; |
14 | use std::io::{self, BufRead, BufWriter, Write}; | |
15 | use std::path::Path; | |
16 | use std::process; | |
17 | use std::rc::Rc; | |
18 | use std::result::Result as StdResult; | |
19 | ||
20 | // Third Party | |
8bb4bdeb XL |
21 | #[cfg(feature = "yaml")] |
22 | use yaml_rust::Yaml; | |
23 | ||
24 | // Internal | |
25 | use app::help::Help; | |
26 | use app::parser::Parser; | |
041b39d2 | 27 | use args::{AnyArg, Arg, ArgGroup, ArgMatcher, ArgMatches, ArgSettings}; |
8bb4bdeb XL |
28 | use errors::Result as ClapResult; |
29 | pub use self::settings::AppSettings; | |
30 | use completions::Shell; | |
abe05a73 | 31 | use map::{self, VecMap}; |
8bb4bdeb XL |
32 | |
33 | /// Used to create a representation of a command line program and all possible command line | |
34 | /// arguments. Application settings are set using the "builder pattern" with the | |
35 | /// [`App::get_matches`] family of methods being the terminal methods that starts the | |
36 | /// runtime-parsing process. These methods then return information about the user supplied | |
37 | /// arguments (or lack there of). | |
38 | /// | |
39 | /// **NOTE:** There aren't any mandatory "options" that one must set. The "options" may | |
40 | /// also appear in any order (so long as one of the [`App::get_matches`] methods is the last method | |
41 | /// called). | |
42 | /// | |
43 | /// # Examples | |
44 | /// | |
45 | /// ```no_run | |
46 | /// # use clap::{App, Arg}; | |
47 | /// let m = App::new("My Program") | |
48 | /// .author("Me, me@mail.com") | |
49 | /// .version("1.0.2") | |
50 | /// .about("Explains in brief what the program does") | |
51 | /// .arg( | |
52 | /// Arg::with_name("in_file").index(1) | |
53 | /// ) | |
041b39d2 | 54 | /// .after_help("Longer explanation to appear after the options when \ |
8bb4bdeb XL |
55 | /// displaying the help information from --help or -h") |
56 | /// .get_matches(); | |
57 | /// | |
58 | /// // Your program logic starts here... | |
59 | /// ``` | |
60 | /// [`App::get_matches`]: ./struct.App.html#method.get_matches | |
61 | #[allow(missing_debug_implementations)] | |
62 | pub struct App<'a, 'b> | |
63 | where 'a: 'b | |
64 | { | |
65 | #[doc(hidden)] | |
66 | pub p: Parser<'a, 'b>, | |
67 | } | |
68 | ||
69 | ||
70 | impl<'a, 'b> App<'a, 'b> { | |
71 | /// Creates a new instance of an application requiring a name. The name may be, but doesn't | |
72 | /// have to be same as the binary. The name will be displayed to the user when they request to | |
73 | /// print version or help and usage information. | |
74 | /// | |
75 | /// # Examples | |
76 | /// | |
77 | /// ```no_run | |
78 | /// # use clap::{App, Arg}; | |
79 | /// let prog = App::new("My Program") | |
80 | /// # ; | |
81 | /// ``` | |
82 | pub fn new<S: Into<String>>(n: S) -> Self { App { p: Parser::with_name(n.into()) } } | |
83 | ||
84 | /// Get the name of the app | |
85 | pub fn get_name(&self) -> &str { &self.p.meta.name } | |
86 | ||
87 | /// Get the name of the binary | |
88 | pub fn get_bin_name(&self) -> Option<&str> { self.p.meta.bin_name.as_ref().map(|s| s.as_str()) } | |
89 | ||
90 | /// Creates a new instance of an application requiring a name, but uses the [`crate_authors!`] | |
91 | /// and [`crate_version!`] macros to fill in the [`App::author`] and [`App::version`] fields. | |
92 | /// | |
93 | /// # Examples | |
94 | /// | |
95 | /// ```no_run | |
96 | /// # use clap::{App, Arg}; | |
97 | /// let prog = App::with_defaults("My Program") | |
98 | /// # ; | |
99 | /// ``` | |
100 | /// [`crate_authors!`]: ./macro.crate_authors!.html | |
101 | /// [`crate_version!`]: ./macro.crate_version!.html | |
102 | /// [`App::author`]: ./struct.App.html#method.author | |
103 | /// [`App::version`]: ./struct.App.html#method.author | |
104 | #[deprecated(since="2.14.1", note="Can never work; use explicit App::author() and App::version() calls instead")] | |
105 | pub fn with_defaults<S: Into<String>>(n: S) -> Self { | |
106 | let mut a = App { p: Parser::with_name(n.into()) }; | |
041b39d2 XL |
107 | a.p.meta.author = Some("Kevin K. <kbknapp@gmail.com>"); |
108 | a.p.meta.version = Some("2.19.2"); | |
8bb4bdeb XL |
109 | a |
110 | } | |
111 | ||
041b39d2 | 112 | /// Creates a new instance of [`App`] from a .yml (YAML) file. A full example of supported YAML |
8bb4bdeb XL |
113 | /// objects can be found in [`examples/17_yaml.rs`] and [`examples/17_yaml.yml`]. One great use |
114 | /// for using YAML is when supporting multiple languages and dialects, as each language could | |
115 | /// be a distinct YAML file and determined at compiletime via `cargo` "features" in your | |
116 | /// `Cargo.toml` | |
117 | /// | |
118 | /// In order to use this function you must compile `clap` with the `features = ["yaml"]` in | |
119 | /// your settings for the `[dependencies.clap]` table of your `Cargo.toml` | |
120 | /// | |
121 | /// **NOTE:** Due to how the YAML objects are built there is a convenience macro for loading | |
122 | /// the YAML file at compile time (relative to the current file, like modules work). That YAML | |
123 | /// object can then be passed to this function. | |
124 | /// | |
125 | /// # Panics | |
126 | /// | |
127 | /// The YAML file must be properly formatted or this function will [`panic!`]. A good way to | |
128 | /// ensure this doesn't happen is to run your program with the `--help` switch. If this passes | |
129 | /// without error, you needn't worry because the YAML is properly formatted. | |
130 | /// | |
131 | /// # Examples | |
132 | /// | |
133 | /// The following example shows how to load a properly formatted YAML file to build an instance | |
134 | /// of an [`App`] struct. | |
135 | /// | |
136 | /// ```ignore | |
137 | /// # #[macro_use] | |
138 | /// # extern crate clap; | |
139 | /// # use clap::App; | |
140 | /// # fn main() { | |
141 | /// let yml = load_yaml!("app.yml"); | |
142 | /// let app = App::from_yaml(yml); | |
143 | /// | |
144 | /// // continued logic goes here, such as `app.get_matches()` etc. | |
145 | /// # } | |
146 | /// ``` | |
147 | /// [`App`]: ./struct.App.html | |
148 | /// [`examples/17_yaml.rs`]: https://github.com/kbknapp/clap-rs/blob/master/examples/17_yaml.rs | |
149 | /// [`examples/17_yaml.yml`]: https://github.com/kbknapp/clap-rs/blob/master/examples/17_yaml.yml | |
150 | /// [`panic!`]: https://doc.rust-lang.org/std/macro.panic!.html | |
151 | #[cfg(feature = "yaml")] | |
152 | pub fn from_yaml(yaml: &'a Yaml) -> App<'a, 'a> { App::from(yaml) } | |
153 | ||
154 | /// Sets a string of author(s) that will be displayed to the user when they | |
155 | /// request the help information with `--help` or `-h`. | |
156 | /// | |
157 | /// **Pro-tip:** Use `clap`s convenience macro [`crate_authors!`] to automatically set your | |
158 | /// application's author(s) to the same thing as your crate at compile time. See the [`examples/`] | |
159 | /// directory for more information | |
160 | /// | |
161 | /// See the [`examples/`] | |
162 | /// directory for more information | |
163 | /// | |
164 | /// # Examples | |
165 | /// | |
166 | /// ```no_run | |
167 | /// # use clap::{App, Arg}; | |
168 | /// App::new("myprog") | |
169 | /// .author("Me, me@mymain.com") | |
170 | /// # ; | |
171 | /// ``` | |
172 | /// [`crate_authors!`]: ./macro.crate_authors!.html | |
173 | /// [`examples/`]: https://github.com/kbknapp/clap-rs/tree/master/examples | |
174 | pub fn author<S: Into<&'b str>>(mut self, author: S) -> Self { | |
175 | self.p.meta.author = Some(author.into()); | |
176 | self | |
177 | } | |
178 | ||
179 | /// Overrides the system-determined binary name. This should only be used when absolutely | |
041b39d2 | 180 | /// necessary, such as when the binary name for your application is misleading, or perhaps |
8bb4bdeb XL |
181 | /// *not* how the user should invoke your program. |
182 | /// | |
183 | /// **Pro-tip:** When building things such as third party `cargo` subcommands, this setting | |
184 | /// **should** be used! | |
185 | /// | |
186 | /// **NOTE:** This command **should not** be used for [`SubCommand`]s. | |
187 | /// | |
188 | /// # Examples | |
189 | /// | |
190 | /// ```no_run | |
191 | /// # use clap::{App, Arg}; | |
192 | /// App::new("My Program") | |
193 | /// .bin_name("my_binary") | |
194 | /// # ; | |
195 | /// ``` | |
196 | /// [`SubCommand`]: ./struct.SubCommand.html | |
197 | pub fn bin_name<S: Into<String>>(mut self, name: S) -> Self { | |
198 | self.p.meta.bin_name = Some(name.into()); | |
199 | self | |
200 | } | |
201 | ||
202 | /// Sets a string describing what the program does. This will be displayed when displaying help | |
041b39d2 XL |
203 | /// information with `-h`. |
204 | /// | |
205 | /// **NOTE:** If only `about` is provided, and not [`App::long_about`] but the user requests | |
206 | /// `--help` clap will still display the contents of `about` appropriately | |
207 | /// | |
208 | /// **NOTE:** Only [`App::about`] is used in completion script generation in order to be | |
209 | /// concise | |
8bb4bdeb XL |
210 | /// |
211 | /// # Examples | |
212 | /// | |
213 | /// ```no_run | |
214 | /// # use clap::{App, Arg}; | |
215 | /// App::new("myprog") | |
216 | /// .about("Does really amazing things to great people") | |
217 | /// # ; | |
218 | /// ``` | |
041b39d2 | 219 | /// [`App::long_about`]: ./struct.App.html#method.long_about |
8bb4bdeb XL |
220 | pub fn about<S: Into<&'b str>>(mut self, about: S) -> Self { |
221 | self.p.meta.about = Some(about.into()); | |
222 | self | |
223 | } | |
224 | ||
041b39d2 XL |
225 | /// Sets a string describing what the program does. This will be displayed when displaying help |
226 | /// information. | |
227 | /// | |
228 | /// **NOTE:** If only `long_about` is provided, and not [`App::about`] but the user requests | |
229 | /// `-h` clap will still display the contents of `long_about` appropriately | |
230 | /// | |
231 | /// **NOTE:** Only [`App::about`] is used in completion script generation in order to be | |
232 | /// concise | |
233 | /// | |
234 | /// # Examples | |
235 | /// | |
236 | /// ```no_run | |
237 | /// # use clap::{App, Arg}; | |
238 | /// App::new("myprog") | |
239 | /// .long_about( | |
240 | /// "Does really amazing things to great people. Now let's talk a little | |
241 | /// more in depth about how this subcommand really works. It may take about | |
242 | /// a few lines of text, but that's ok!") | |
243 | /// # ; | |
244 | /// ``` | |
245 | /// [`App::about`]: ./struct.App.html#method.about | |
246 | pub fn long_about<S: Into<&'b str>>(mut self, about: S) -> Self { | |
247 | self.p.meta.long_about = Some(about.into()); | |
248 | self | |
249 | } | |
250 | ||
251 | /// Sets the program's name. This will be displayed when displaying help information. | |
252 | /// | |
253 | /// **Pro-top:** This function is particularly useful when configuring a program via | |
254 | /// [`App::from_yaml`] in conjunction with the [`crate_name!`] macro to derive the program's | |
255 | /// name from its `Cargo.toml`. | |
256 | /// | |
257 | /// # Examples | |
258 | /// ```ignore | |
259 | /// # #[macro_use] | |
260 | /// # extern crate clap; | |
261 | /// # use clap::App; | |
262 | /// # fn main() { | |
263 | /// let yml = load_yaml!("app.yml"); | |
264 | /// let app = App::from_yaml(yml) | |
265 | /// .name(crate_name!()); | |
266 | /// | |
267 | /// // continued logic goes here, such as `app.get_matches()` etc. | |
268 | /// # } | |
269 | /// ``` | |
270 | /// | |
271 | /// [`App::from_yaml`]: ./struct.App.html#method.from_yaml | |
272 | /// [`crate_name!`]: ./macro.crate_name.html | |
273 | pub fn name<S: Into<String>>(mut self, name: S) -> Self { | |
274 | self.p.meta.name = name.into(); | |
275 | self | |
276 | } | |
277 | ||
8bb4bdeb XL |
278 | /// Adds additional help information to be displayed in addition to auto-generated help. This |
279 | /// information is displayed **after** the auto-generated help information. This is often used | |
280 | /// to describe how to use the arguments, or caveats to be noted. | |
281 | /// | |
282 | /// # Examples | |
283 | /// | |
284 | /// ```no_run | |
285 | /// # use clap::App; | |
286 | /// App::new("myprog") | |
287 | /// .after_help("Does really amazing things to great people...but be careful with -R") | |
288 | /// # ; | |
289 | /// ``` | |
290 | pub fn after_help<S: Into<&'b str>>(mut self, help: S) -> Self { | |
291 | self.p.meta.more_help = Some(help.into()); | |
292 | self | |
293 | } | |
294 | ||
295 | /// Adds additional help information to be displayed in addition to auto-generated help. This | |
296 | /// information is displayed **before** the auto-generated help information. This is often used | |
297 | /// for header information. | |
298 | /// | |
299 | /// # Examples | |
300 | /// | |
301 | /// ```no_run | |
302 | /// # use clap::App; | |
303 | /// App::new("myprog") | |
304 | /// .before_help("Some info I'd like to appear before the help info") | |
305 | /// # ; | |
306 | /// ``` | |
307 | pub fn before_help<S: Into<&'b str>>(mut self, help: S) -> Self { | |
308 | self.p.meta.pre_help = Some(help.into()); | |
309 | self | |
310 | } | |
311 | ||
312 | /// Sets a string of the version number to be displayed when displaying version or help | |
3b2f2976 | 313 | /// information with `-V`. |
041b39d2 XL |
314 | /// |
315 | /// **NOTE:** If only `version` is provided, and not [`App::long_version`] but the user | |
316 | /// requests `--version` clap will still display the contents of `version` appropriately | |
8bb4bdeb XL |
317 | /// |
318 | /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to automatically set your | |
319 | /// application's version to the same thing as your crate at compile time. See the [`examples/`] | |
320 | /// directory for more information | |
321 | /// | |
322 | /// # Examples | |
323 | /// | |
324 | /// ```no_run | |
325 | /// # use clap::{App, Arg}; | |
326 | /// App::new("myprog") | |
327 | /// .version("v0.1.24") | |
328 | /// # ; | |
329 | /// ``` | |
330 | /// [`crate_version!`]: ./macro.crate_version!.html | |
331 | /// [`examples/`]: https://github.com/kbknapp/clap-rs/tree/master/examples | |
041b39d2 | 332 | /// [`App::long_version`]: ./struct.App.html#method.long_version |
8bb4bdeb XL |
333 | pub fn version<S: Into<&'b str>>(mut self, ver: S) -> Self { |
334 | self.p.meta.version = Some(ver.into()); | |
335 | self | |
336 | } | |
337 | ||
041b39d2 XL |
338 | /// Sets a string of the version number to be displayed when displaying version or help |
339 | /// information with `--version`. | |
340 | /// | |
341 | /// **NOTE:** If only `long_version` is provided, and not [`App::version`] but the user | |
342 | /// requests `-V` clap will still display the contents of `long_version` appropriately | |
343 | /// | |
344 | /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to automatically set your | |
345 | /// application's version to the same thing as your crate at compile time. See the [`examples/`] | |
346 | /// directory for more information | |
347 | /// | |
348 | /// # Examples | |
349 | /// | |
350 | /// ```no_run | |
351 | /// # use clap::{App, Arg}; | |
352 | /// App::new("myprog") | |
353 | /// .long_version( | |
354 | /// "v0.1.24 | |
355 | /// commit: abcdef89726d | |
356 | /// revision: 123 | |
357 | /// release: 2 | |
358 | /// binary: myprog") | |
359 | /// # ; | |
360 | /// ``` | |
361 | /// [`crate_version!`]: ./macro.crate_version!.html | |
362 | /// [`examples/`]: https://github.com/kbknapp/clap-rs/tree/master/examples | |
363 | /// [`App::version`]: ./struct.App.html#method.version | |
364 | pub fn long_version<S: Into<&'b str>>(mut self, ver: S) -> Self { | |
365 | self.p.meta.long_version = Some(ver.into()); | |
366 | self | |
367 | } | |
368 | ||
8bb4bdeb XL |
369 | /// Sets a custom usage string to override the auto-generated usage string. |
370 | /// | |
371 | /// This will be displayed to the user when errors are found in argument parsing, or when you | |
372 | /// call [`ArgMatches::usage`] | |
373 | /// | |
374 | /// **CAUTION:** Using this setting disables `clap`s "context-aware" usage strings. After this | |
375 | /// setting is set, this will be the only usage string displayed to the user! | |
376 | /// | |
377 | /// **NOTE:** You do not need to specify the "USAGE: \n\t" portion, as that will | |
378 | /// still be applied by `clap`, you only need to specify the portion starting | |
379 | /// with the binary name. | |
380 | /// | |
381 | /// **NOTE:** This will not replace the entire help message, *only* the portion | |
382 | /// showing the usage. | |
383 | /// | |
384 | /// # Examples | |
385 | /// | |
386 | /// ```no_run | |
387 | /// # use clap::{App, Arg}; | |
388 | /// App::new("myprog") | |
389 | /// .usage("myapp [-clDas] <some_file>") | |
390 | /// # ; | |
391 | /// ``` | |
392 | /// [`ArgMatches::usage`]: ./struct.ArgMatches.html#method.usage | |
393 | pub fn usage<S: Into<&'b str>>(mut self, usage: S) -> Self { | |
394 | self.p.meta.usage_str = Some(usage.into()); | |
395 | self | |
396 | } | |
397 | ||
398 | /// Sets a custom help message and overrides the auto-generated one. This should only be used | |
399 | /// when the auto-generated message does not suffice. | |
400 | /// | |
401 | /// This will be displayed to the user when they use `--help` or `-h` | |
402 | /// | |
403 | /// **NOTE:** This replaces the **entire** help message, so nothing will be auto-generated. | |
404 | /// | |
405 | /// **NOTE:** This **only** replaces the help message for the current command, meaning if you | |
406 | /// are using subcommands, those help messages will still be auto-generated unless you | |
407 | /// specify a [`Arg::help`] for them as well. | |
408 | /// | |
409 | /// # Examples | |
410 | /// | |
411 | /// ```no_run | |
412 | /// # use clap::{App, Arg}; | |
413 | /// App::new("myapp") | |
414 | /// .help("myapp v1.0\n\ | |
415 | /// Does awesome things\n\ | |
416 | /// (C) me@mail.com\n\n\ | |
417 | /// | |
418 | /// USAGE: myapp <opts> <comamnd>\n\n\ | |
419 | /// | |
420 | /// Options:\n\ | |
421 | /// -h, --helpe Dispay this message\n\ | |
422 | /// -V, --version Display version info\n\ | |
423 | /// -s <stuff> Do something with stuff\n\ | |
424 | /// -v Be verbose\n\n\ | |
425 | /// | |
426 | /// Commmands:\n\ | |
427 | /// help Prints this message\n\ | |
428 | /// work Do some work") | |
429 | /// # ; | |
430 | /// ``` | |
431 | /// [`Arg::help`]: ./struct.Arg.html#method.help | |
432 | pub fn help<S: Into<&'b str>>(mut self, help: S) -> Self { | |
433 | self.p.meta.help_str = Some(help.into()); | |
434 | self | |
435 | } | |
436 | ||
437 | /// Sets the [`short`] for the auto-generated `help` argument. | |
438 | /// | |
439 | /// By default `clap` automatically assigns `h`, but this can be overridden if you have a | |
440 | /// different argument which you'd prefer to use the `-h` short with. This can be done by | |
441 | /// defining your own argument with a lowercase `h` as the [`short`]. | |
442 | /// | |
443 | /// `clap` lazily generates these `help` arguments **after** you've defined any arguments of | |
444 | /// your own. | |
445 | /// | |
446 | /// **NOTE:** Any leading `-` characters will be stripped, and only the first | |
447 | /// non `-` character will be used as the [`short`] version | |
448 | /// | |
449 | /// # Examples | |
450 | /// | |
451 | /// ```no_run | |
452 | /// # use clap::{App, Arg}; | |
453 | /// App::new("myprog") | |
454 | /// .help_short("H") // Using an uppercase `H` instead of the default lowercase `h` | |
455 | /// # ; | |
456 | /// ``` | |
457 | /// [`short`]: ./struct.Arg.html#method.short | |
458 | pub fn help_short<S: AsRef<str> + 'b>(mut self, s: S) -> Self { | |
459 | self.p.help_short(s.as_ref()); | |
460 | self | |
461 | } | |
462 | ||
463 | /// Sets the [`short`] for the auto-generated `version` argument. | |
464 | /// | |
465 | /// By default `clap` automatically assigns `V`, but this can be overridden if you have a | |
466 | /// different argument which you'd prefer to use the `-V` short with. This can be done by | |
467 | /// defining your own argument with an uppercase `V` as the [`short`]. | |
468 | /// | |
469 | /// `clap` lazily generates these `version` arguments **after** you've defined any arguments of | |
470 | /// your own. | |
471 | /// | |
472 | /// **NOTE:** Any leading `-` characters will be stripped, and only the first | |
473 | /// non `-` character will be used as the `short` version | |
474 | /// | |
475 | /// # Examples | |
476 | /// | |
477 | /// ```no_run | |
478 | /// # use clap::{App, Arg}; | |
479 | /// App::new("myprog") | |
480 | /// .version_short("v") // Using a lowercase `v` instead of the default capital `V` | |
481 | /// # ; | |
482 | /// ``` | |
483 | /// [`short`]: ./struct.Arg.html#method.short | |
484 | pub fn version_short<S: AsRef<str>>(mut self, s: S) -> Self { | |
485 | self.p.version_short(s.as_ref()); | |
486 | self | |
487 | } | |
488 | ||
041b39d2 XL |
489 | /// Sets the help text for the auto-generated `help` argument. |
490 | /// | |
491 | /// By default `clap` sets this to `"Prints help information"`, but if you're using a | |
492 | /// different convention for your help messages and would prefer a different phrasing you can | |
493 | /// override it. | |
494 | /// | |
495 | /// # Examples | |
496 | /// | |
497 | /// ```no_run | |
498 | /// # use clap::{App, Arg}; | |
499 | /// App::new("myprog") | |
500 | /// .help_message("Print help information") // Perhaps you want imperative help messages | |
501 | /// | |
502 | /// # ; | |
503 | /// ``` | |
504 | pub fn help_message<S: Into<&'a str>>(mut self, s: S) -> Self { | |
505 | self.p.help_message = Some(s.into()); | |
506 | self | |
507 | } | |
508 | ||
509 | /// Sets the help text for the auto-generated `version` argument. | |
510 | /// | |
511 | /// By default `clap` sets this to `"Prints version information"`, but if you're using a | |
512 | /// different convention for your help messages and would prefer a different phrasing then you | |
513 | /// can change it. | |
514 | /// | |
515 | /// # Examples | |
516 | /// ```no_run | |
517 | /// # use clap::{App, Arg}; | |
518 | /// App::new("myprog") | |
519 | /// .version_message("Print version information") // Perhaps you want imperative help messages | |
520 | /// # ; | |
521 | /// ``` | |
522 | pub fn version_message<S: Into<&'a str>>(mut self, s: S) -> Self { | |
523 | self.p.version_message = Some(s.into()); | |
524 | self | |
525 | } | |
526 | ||
8bb4bdeb XL |
527 | /// Sets the help template to be used, overriding the default format. |
528 | /// | |
529 | /// Tags arg given inside curly brackets. | |
530 | /// | |
531 | /// Valid tags are: | |
532 | /// | |
533 | /// * `{bin}` - Binary name. | |
534 | /// * `{version}` - Version number. | |
535 | /// * `{author}` - Author information. | |
041b39d2 | 536 | /// * `{about}` - General description (from [`App::about`]) |
8bb4bdeb XL |
537 | /// * `{usage}` - Automatically generated or given usage string. |
538 | /// * `{all-args}` - Help for all arguments (options, flags, positionals arguments, | |
539 | /// and subcommands) including titles. | |
3b2f2976 XL |
540 | /// * `{unified}` - Unified help for options and flags. Note, you must *also* set |
541 | /// [`AppSettings::UnifiedHelpMessage`] to fully merge both options and | |
041b39d2 | 542 | /// flags, otherwise the ordering is "best effort" |
8bb4bdeb XL |
543 | /// * `{flags}` - Help for flags. |
544 | /// * `{options}` - Help for options. | |
545 | /// * `{positionals}` - Help for positionals arguments. | |
546 | /// * `{subcommands}` - Help for subcommands. | |
041b39d2 XL |
547 | /// * `{after-help}` - Help from [`App::after_help`] |
548 | /// * `{before-help}` - Help from [`App::before_help`] | |
8bb4bdeb XL |
549 | /// |
550 | /// # Examples | |
551 | /// | |
552 | /// ```no_run | |
553 | /// # use clap::{App, Arg}; | |
554 | /// App::new("myprog") | |
555 | /// .version("1.0") | |
556 | /// .template("{bin} ({version}) - {usage}") | |
557 | /// # ; | |
558 | /// ``` | |
559 | /// **NOTE:**The template system is, on purpose, very simple. Therefore the tags have to writen | |
560 | /// in the lowercase and without spacing. | |
041b39d2 XL |
561 | /// [`App::about`]: ./struct.App.html#method.about |
562 | /// [`App::after_help`]: ./struct.App.html#method.after_help | |
563 | /// [`App::before_help`]: ./struct.App.html#method.before_help | |
564 | /// [`AppSettings::UnifiedHelpMessage`]: ./enum.AppSettings.html#variant.UnifiedHelpMessage | |
8bb4bdeb XL |
565 | pub fn template<S: Into<&'b str>>(mut self, s: S) -> Self { |
566 | self.p.meta.template = Some(s.into()); | |
567 | self | |
568 | } | |
569 | ||
570 | /// Enables a single command, or [`SubCommand`], level settings. | |
571 | /// | |
572 | /// See [`AppSettings`] for a full list of possibilities and examples. | |
573 | /// | |
574 | /// # Examples | |
575 | /// | |
576 | /// ```no_run | |
577 | /// # use clap::{App, Arg, AppSettings}; | |
578 | /// App::new("myprog") | |
579 | /// .setting(AppSettings::SubcommandRequired) | |
580 | /// .setting(AppSettings::WaitOnError) | |
581 | /// # ; | |
582 | /// ``` | |
583 | /// [`SubCommand`]: ./struct.SubCommand.html | |
584 | /// [`AppSettings`]: ./enum.AppSettings.html | |
585 | pub fn setting(mut self, setting: AppSettings) -> Self { | |
586 | self.p.set(setting); | |
587 | self | |
588 | } | |
589 | ||
590 | /// Enables multiple command, or [`SubCommand`], level settings | |
591 | /// | |
592 | /// See [`AppSettings`] for a full list of possibilities and examples. | |
593 | /// | |
594 | /// # Examples | |
595 | /// | |
596 | /// ```no_run | |
597 | /// # use clap::{App, Arg, AppSettings}; | |
598 | /// App::new("myprog") | |
599 | /// .settings(&[AppSettings::SubcommandRequired, | |
600 | /// AppSettings::WaitOnError]) | |
601 | /// # ; | |
602 | /// ``` | |
603 | /// [`SubCommand`]: ./struct.SubCommand.html | |
604 | /// [`AppSettings`]: ./enum.AppSettings.html | |
605 | pub fn settings(mut self, settings: &[AppSettings]) -> Self { | |
606 | for s in settings { | |
607 | self.p.set(*s); | |
608 | } | |
609 | self | |
610 | } | |
611 | ||
abe05a73 | 612 | /// Enables a single setting that is propagated down through all child [`SubCommand`]s. |
8bb4bdeb XL |
613 | /// |
614 | /// See [`AppSettings`] for a full list of possibilities and examples. | |
615 | /// | |
abe05a73 | 616 | /// **NOTE**: The setting is *only* propagated *down* and not up through parent commands. |
8bb4bdeb XL |
617 | /// |
618 | /// # Examples | |
619 | /// | |
620 | /// ```no_run | |
621 | /// # use clap::{App, Arg, AppSettings}; | |
622 | /// App::new("myprog") | |
623 | /// .global_setting(AppSettings::SubcommandRequired) | |
624 | /// # ; | |
625 | /// ``` | |
626 | /// [`SubCommand`]: ./struct.SubCommand.html | |
627 | /// [`AppSettings`]: ./enum.AppSettings.html | |
628 | pub fn global_setting(mut self, setting: AppSettings) -> Self { | |
629 | self.p.set(setting); | |
041b39d2 | 630 | self.p.g_settings.set(setting); |
8bb4bdeb XL |
631 | self |
632 | } | |
633 | ||
abe05a73 | 634 | /// Enables multiple settings which are propagated *down* through all child [`SubCommand`]s. |
8bb4bdeb XL |
635 | /// |
636 | /// See [`AppSettings`] for a full list of possibilities and examples. | |
637 | /// | |
abe05a73 | 638 | /// **NOTE**: The setting is *only* propagated *down* and not up through parent commands. |
8bb4bdeb XL |
639 | /// |
640 | /// # Examples | |
641 | /// | |
642 | /// ```no_run | |
643 | /// # use clap::{App, Arg, AppSettings}; | |
644 | /// App::new("myprog") | |
645 | /// .global_settings(&[AppSettings::SubcommandRequired, | |
646 | /// AppSettings::ColoredHelp]) | |
647 | /// # ; | |
648 | /// ``` | |
649 | /// [`SubCommand`]: ./struct.SubCommand.html | |
650 | /// [`AppSettings`]: ./enum.AppSettings.html | |
651 | pub fn global_settings(mut self, settings: &[AppSettings]) -> Self { | |
652 | for s in settings { | |
653 | self.p.set(*s); | |
041b39d2 | 654 | self.p.g_settings.set(*s) |
8bb4bdeb XL |
655 | } |
656 | self | |
657 | } | |
658 | ||
659 | /// Disables a single command, or [`SubCommand`], level setting. | |
660 | /// | |
661 | /// See [`AppSettings`] for a full list of possibilities and examples. | |
662 | /// | |
663 | /// # Examples | |
664 | /// | |
665 | /// ```no_run | |
666 | /// # use clap::{App, AppSettings}; | |
667 | /// App::new("myprog") | |
668 | /// .unset_setting(AppSettings::ColorAuto) | |
669 | /// # ; | |
670 | /// ``` | |
671 | /// [`SubCommand`]: ./struct.SubCommand.html | |
672 | /// [`AppSettings`]: ./enum.AppSettings.html | |
673 | pub fn unset_setting(mut self, setting: AppSettings) -> Self { | |
674 | self.p.unset(setting); | |
675 | self | |
676 | } | |
677 | ||
678 | /// Disables multiple command, or [`SubCommand`], level settings. | |
679 | /// | |
680 | /// See [`AppSettings`] for a full list of possibilities and examples. | |
681 | /// | |
682 | /// # Examples | |
683 | /// | |
684 | /// ```no_run | |
685 | /// # use clap::{App, AppSettings}; | |
686 | /// App::new("myprog") | |
687 | /// .unset_settings(&[AppSettings::ColorAuto, | |
688 | /// AppSettings::AllowInvalidUtf8]) | |
689 | /// # ; | |
690 | /// ``` | |
691 | /// [`SubCommand`]: ./struct.SubCommand.html | |
692 | /// [`AppSettings`]: ./enum.AppSettings.html | |
693 | pub fn unset_settings(mut self, settings: &[AppSettings]) -> Self { | |
694 | for s in settings { | |
695 | self.p.unset(*s); | |
696 | } | |
697 | self | |
698 | } | |
699 | ||
700 | /// Sets the terminal width at which to wrap help messages. Defaults to `120`. Using `0` will | |
701 | /// ignore terminal widths and use source formatting. | |
702 | /// | |
703 | /// `clap` automatically tries to determine the terminal width on Unix, Linux, OSX and Windows | |
704 | /// if the `wrap_help` cargo "feature" has been used while compiling. If the terminal width | |
705 | /// cannot be determined, `clap` defaults to `120`. | |
706 | /// | |
707 | /// **NOTE:** This setting applies globally and *not* on a per-command basis. | |
708 | /// | |
709 | /// **NOTE:** This setting must be set **before** any subcommands are added! | |
710 | /// | |
711 | /// # Platform Specific | |
712 | /// | |
713 | /// Only Unix, Linux, OSX and Windows support automatic determination of terminal width. | |
714 | /// Even on those platforms, this setting is useful if for any reason the terminal width | |
715 | /// cannot be determined. | |
716 | /// | |
717 | /// # Examples | |
718 | /// | |
719 | /// ```no_run | |
720 | /// # use clap::App; | |
721 | /// App::new("myprog") | |
722 | /// .set_term_width(80) | |
723 | /// # ; | |
724 | /// ``` | |
725 | pub fn set_term_width(mut self, width: usize) -> Self { | |
726 | self.p.meta.term_w = Some(width); | |
727 | self | |
728 | } | |
729 | ||
730 | /// Sets the max terminal width at which to wrap help messages. Using `0` will ignore terminal | |
731 | /// widths and use source formatting. | |
732 | /// | |
733 | /// `clap` automatically tries to determine the terminal width on Unix, Linux, OSX and Windows | |
734 | /// if the `wrap_help` cargo "feature" has been used while compiling, but one might want to | |
735 | /// limit the size (e.g. when the terminal is running fullscreen). | |
736 | /// | |
737 | /// **NOTE:** This setting applies globally and *not* on a per-command basis. | |
738 | /// | |
739 | /// **NOTE:** This setting must be set **before** any subcommands are added! | |
740 | /// | |
741 | /// # Platform Specific | |
742 | /// | |
743 | /// Only Unix, Linux, OSX and Windows support automatic determination of terminal width. | |
744 | /// | |
745 | /// # Examples | |
746 | /// | |
747 | /// ```no_run | |
748 | /// # use clap::App; | |
749 | /// App::new("myprog") | |
750 | /// .max_term_width(100) | |
751 | /// # ; | |
752 | /// ``` | |
753 | pub fn max_term_width(mut self, w: usize) -> Self { | |
754 | self.p.meta.max_w = Some(w); | |
755 | self | |
756 | } | |
757 | ||
041b39d2 | 758 | /// Adds an [argument] to the list of valid possibilities. |
8bb4bdeb XL |
759 | /// |
760 | /// # Examples | |
761 | /// | |
762 | /// ```no_run | |
763 | /// # use clap::{App, Arg}; | |
764 | /// App::new("myprog") | |
765 | /// // Adding a single "flag" argument with a short and help text, using Arg::with_name() | |
766 | /// .arg( | |
767 | /// Arg::with_name("debug") | |
768 | /// .short("d") | |
769 | /// .help("turns on debugging mode") | |
770 | /// ) | |
771 | /// // Adding a single "option" argument with a short, a long, and help text using the less | |
772 | /// // verbose Arg::from_usage() | |
773 | /// .arg( | |
774 | /// Arg::from_usage("-c --config=[CONFIG] 'Optionally sets a config file to use'") | |
775 | /// ) | |
776 | /// # ; | |
777 | /// ``` | |
778 | /// [argument]: ./struct.Arg.html | |
041b39d2 XL |
779 | pub fn arg<A: Into<Arg<'a, 'b>>>(mut self, a: A) -> Self { |
780 | self.p.add_arg(a.into()); | |
8bb4bdeb XL |
781 | self |
782 | } | |
783 | ||
784 | /// Adds multiple [arguments] to the list of valid possibilties | |
785 | /// | |
786 | /// # Examples | |
787 | /// | |
788 | /// ```no_run | |
789 | /// # use clap::{App, Arg}; | |
790 | /// App::new("myprog") | |
791 | /// .args( | |
792 | /// &[Arg::from_usage("[debug] -d 'turns on debugging info'"), | |
793 | /// Arg::with_name("input").index(1).help("the input file to use")] | |
794 | /// ) | |
795 | /// # ; | |
796 | /// ``` | |
797 | /// [arguments]: ./struct.Arg.html | |
798 | pub fn args(mut self, args: &[Arg<'a, 'b>]) -> Self { | |
799 | for arg in args { | |
041b39d2 | 800 | self.p.add_arg_ref(arg); |
8bb4bdeb XL |
801 | } |
802 | self | |
803 | } | |
804 | ||
805 | /// A convenience method for adding a single [argument] from a usage type string. The string | |
806 | /// used follows the same rules and syntax as [`Arg::from_usage`] | |
807 | /// | |
808 | /// **NOTE:** The downside to using this method is that you can not set any additional | |
809 | /// properties of the [`Arg`] other than what [`Arg::from_usage`] supports. | |
810 | /// | |
811 | /// # Examples | |
812 | /// | |
813 | /// ```no_run | |
814 | /// # use clap::{App, Arg}; | |
815 | /// App::new("myprog") | |
816 | /// .arg_from_usage("-c --config=<FILE> 'Sets a configuration file to use'") | |
817 | /// # ; | |
818 | /// ``` | |
819 | /// [arguments]: ./struct.Arg.html | |
820 | /// [`Arg`]: ./struct.Arg.html | |
821 | /// [`Arg::from_usage`]: ./struct.Arg.html#method.from_usage | |
822 | pub fn arg_from_usage(mut self, usage: &'a str) -> Self { | |
041b39d2 | 823 | self.p.add_arg(Arg::from_usage(usage)); |
8bb4bdeb XL |
824 | self |
825 | } | |
826 | ||
827 | /// Adds multiple [arguments] at once from a usage string, one per line. See | |
828 | /// [`Arg::from_usage`] for details on the syntax and rules supported. | |
829 | /// | |
830 | /// **NOTE:** Like [`App::arg_from_usage`] the downside is you only set properties for the | |
831 | /// [`Arg`]s which [`Arg::from_usage`] supports. | |
832 | /// | |
833 | /// # Examples | |
834 | /// | |
835 | /// ```no_run | |
836 | /// # use clap::{App, Arg}; | |
837 | /// App::new("myprog") | |
838 | /// .args_from_usage( | |
839 | /// "-c --config=[FILE] 'Sets a configuration file to use' | |
840 | /// [debug]... -d 'Sets the debugging level' | |
841 | /// <FILE> 'The input file to use'" | |
842 | /// ) | |
843 | /// # ; | |
844 | /// ``` | |
845 | /// [arguments]: ./struct.Arg.html | |
846 | /// [`Arg::from_usage`]: ./struct.Arg.html#method.from_usage | |
847 | /// [`App::arg_from_usage`]: ./struct.App.html#method.arg_from_usage | |
848 | /// [`Arg`]: ./struct.Arg.html | |
849 | pub fn args_from_usage(mut self, usage: &'a str) -> Self { | |
850 | for line in usage.lines() { | |
851 | let l = line.trim(); | |
852 | if l.is_empty() { | |
853 | continue; | |
854 | } | |
041b39d2 | 855 | self.p.add_arg(Arg::from_usage(l)); |
8bb4bdeb XL |
856 | } |
857 | self | |
858 | } | |
859 | ||
860 | /// Allows adding a [`SubCommand`] alias, which function as "hidden" subcommands that | |
861 | /// automatically dispatch as if this subcommand was used. This is more efficient, and easier | |
862 | /// than creating multiple hidden subcommands as one only needs to check for the existence of | |
863 | /// this command, and not all variants. | |
864 | /// | |
865 | /// # Examples | |
866 | /// | |
867 | /// ```no_run | |
868 | /// # use clap::{App, Arg, SubCommand}; | |
869 | /// let m = App::new("myprog") | |
870 | /// .subcommand(SubCommand::with_name("test") | |
871 | /// .alias("do-stuff")) | |
872 | /// .get_matches_from(vec!["myprog", "do-stuff"]); | |
873 | /// assert_eq!(m.subcommand_name(), Some("test")); | |
874 | /// ``` | |
875 | /// [`SubCommand`]: ./struct.SubCommand.html | |
876 | pub fn alias<S: Into<&'b str>>(mut self, name: S) -> Self { | |
877 | if let Some(ref mut als) = self.p.meta.aliases { | |
878 | als.push((name.into(), false)); | |
879 | } else { | |
880 | self.p.meta.aliases = Some(vec![(name.into(), false)]); | |
881 | } | |
882 | self | |
883 | } | |
884 | ||
885 | /// Allows adding [`SubCommand`] aliases, which function as "hidden" subcommands that | |
886 | /// automatically dispatch as if this subcommand was used. This is more efficient, and easier | |
887 | /// than creating multiple hidden subcommands as one only needs to check for the existence of | |
888 | /// this command, and not all variants. | |
889 | /// | |
890 | /// # Examples | |
891 | /// | |
892 | /// ```rust | |
893 | /// # use clap::{App, Arg, SubCommand}; | |
894 | /// let m = App::new("myprog") | |
895 | /// .subcommand(SubCommand::with_name("test") | |
896 | /// .aliases(&["do-stuff", "do-tests", "tests"])) | |
897 | /// .arg(Arg::with_name("input") | |
898 | /// .help("the file to add") | |
899 | /// .index(1) | |
900 | /// .required(false)) | |
901 | /// .get_matches_from(vec!["myprog", "do-tests"]); | |
902 | /// assert_eq!(m.subcommand_name(), Some("test")); | |
903 | /// ``` | |
904 | /// [`SubCommand`]: ./struct.SubCommand.html | |
905 | pub fn aliases(mut self, names: &[&'b str]) -> Self { | |
906 | if let Some(ref mut als) = self.p.meta.aliases { | |
907 | for n in names { | |
908 | als.push((n, false)); | |
909 | } | |
910 | } else { | |
911 | self.p.meta.aliases = Some(names.iter().map(|n| (*n, false)).collect::<Vec<_>>()); | |
912 | } | |
913 | self | |
914 | } | |
915 | ||
916 | /// Allows adding a [`SubCommand`] alias that functions exactly like those defined with | |
917 | /// [`App::alias`], except that they are visible inside the help message. | |
918 | /// | |
919 | /// # Examples | |
920 | /// | |
921 | /// ```no_run | |
922 | /// # use clap::{App, Arg, SubCommand}; | |
923 | /// let m = App::new("myprog") | |
924 | /// .subcommand(SubCommand::with_name("test") | |
925 | /// .visible_alias("do-stuff")) | |
926 | /// .get_matches_from(vec!["myprog", "do-stuff"]); | |
927 | /// assert_eq!(m.subcommand_name(), Some("test")); | |
928 | /// ``` | |
929 | /// [`SubCommand`]: ./struct.SubCommand.html | |
930 | /// [`App::alias`]: ./struct.App.html#method.alias | |
931 | pub fn visible_alias<S: Into<&'b str>>(mut self, name: S) -> Self { | |
932 | if let Some(ref mut als) = self.p.meta.aliases { | |
933 | als.push((name.into(), true)); | |
934 | } else { | |
935 | self.p.meta.aliases = Some(vec![(name.into(), true)]); | |
936 | } | |
937 | self | |
938 | } | |
939 | ||
940 | /// Allows adding multiple [`SubCommand`] aliases that functions exactly like those defined | |
941 | /// with [`App::aliases`], except that they are visible inside the help message. | |
942 | /// | |
943 | /// # Examples | |
944 | /// | |
945 | /// ```no_run | |
946 | /// # use clap::{App, Arg, SubCommand}; | |
947 | /// let m = App::new("myprog") | |
948 | /// .subcommand(SubCommand::with_name("test") | |
949 | /// .visible_aliases(&["do-stuff", "tests"])) | |
950 | /// .get_matches_from(vec!["myprog", "do-stuff"]); | |
951 | /// assert_eq!(m.subcommand_name(), Some("test")); | |
952 | /// ``` | |
953 | /// [`SubCommand`]: ./struct.SubCommand.html | |
954 | /// [`App::aliases`]: ./struct.App.html#method.aliases | |
955 | pub fn visible_aliases(mut self, names: &[&'b str]) -> Self { | |
956 | if let Some(ref mut als) = self.p.meta.aliases { | |
957 | for n in names { | |
958 | als.push((n, true)); | |
959 | } | |
960 | } else { | |
961 | self.p.meta.aliases = Some(names.iter().map(|n| (*n, true)).collect::<Vec<_>>()); | |
962 | } | |
963 | self | |
964 | } | |
965 | ||
966 | /// Adds an [`ArgGroup`] to the application. [`ArgGroup`]s are a family of related arguments. | |
967 | /// By placing them in a logical group, you can build easier requirement and exclusion rules. | |
968 | /// For instance, you can make an entire [`ArgGroup`] required, meaning that one (and *only* | |
969 | /// one) argument from that group must be present at runtime. | |
970 | /// | |
971 | /// You can also do things such as name an [`ArgGroup`] as a conflict to another argument. | |
972 | /// Meaning any of the arguments that belong to that group will cause a failure if present with | |
973 | /// the conflicting argument. | |
974 | /// | |
975 | /// Another added benfit of [`ArgGroup`]s is that you can extract a value from a group instead | |
976 | /// of determining exactly which argument was used. | |
977 | /// | |
978 | /// Finally, using [`ArgGroup`]s to ensure exclusion between arguments is another very common | |
979 | /// use | |
980 | /// | |
981 | /// # Examples | |
982 | /// | |
983 | /// The following example demonstrates using an [`ArgGroup`] to ensure that one, and only one, | |
984 | /// of the arguments from the specified group is present at runtime. | |
985 | /// | |
986 | /// ```no_run | |
987 | /// # use clap::{App, ArgGroup}; | |
988 | /// App::new("app") | |
989 | /// .args_from_usage( | |
990 | /// "--set-ver [ver] 'set the version manually' | |
991 | /// --major 'auto increase major' | |
992 | /// --minor 'auto increase minor' | |
993 | /// --patch 'auto increase patch'") | |
994 | /// .group(ArgGroup::with_name("vers") | |
995 | /// .args(&["set-ver", "major", "minor","patch"]) | |
996 | /// .required(true)) | |
997 | /// # ; | |
998 | /// ``` | |
999 | /// [`ArgGroup`]: ./struct.ArgGroup.html | |
1000 | pub fn group(mut self, group: ArgGroup<'a>) -> Self { | |
1001 | self.p.add_group(group); | |
1002 | self | |
1003 | } | |
1004 | ||
1005 | /// Adds multiple [`ArgGroup`]s to the [`App`] at once. | |
1006 | /// | |
1007 | /// # Examples | |
1008 | /// | |
1009 | /// ```no_run | |
1010 | /// # use clap::{App, ArgGroup}; | |
1011 | /// App::new("app") | |
1012 | /// .args_from_usage( | |
1013 | /// "--set-ver [ver] 'set the version manually' | |
1014 | /// --major 'auto increase major' | |
1015 | /// --minor 'auto increase minor' | |
1016 | /// --patch 'auto increase patch' | |
1017 | /// -c [FILE] 'a config file' | |
1018 | /// -i [IFACE] 'an interface'") | |
1019 | /// .groups(&[ | |
1020 | /// ArgGroup::with_name("vers") | |
1021 | /// .args(&["set-ver", "major", "minor","patch"]) | |
1022 | /// .required(true), | |
1023 | /// ArgGroup::with_name("input") | |
1024 | /// .args(&["c", "i"]) | |
1025 | /// ]) | |
1026 | /// # ; | |
1027 | /// ``` | |
1028 | /// [`ArgGroup`]: ./struct.ArgGroup.html | |
1029 | /// [`App`]: ./struct.App.html | |
1030 | pub fn groups(mut self, groups: &[ArgGroup<'a>]) -> Self { | |
1031 | for g in groups { | |
1032 | self = self.group(g.into()); | |
1033 | } | |
1034 | self | |
1035 | } | |
1036 | ||
041b39d2 | 1037 | /// Adds a [`SubCommand`] to the list of valid possibilities. Subcommands are effectively |
8bb4bdeb XL |
1038 | /// sub-[`App`]s, because they can contain their own arguments, subcommands, version, usage, |
1039 | /// etc. They also function just like [`App`]s, in that they get their own auto generated help, | |
1040 | /// version, and usage. | |
1041 | /// | |
1042 | /// # Examples | |
1043 | /// | |
1044 | /// ```no_run | |
1045 | /// # use clap::{App, Arg, SubCommand}; | |
1046 | /// App::new("myprog") | |
1047 | /// .subcommand(SubCommand::with_name("config") | |
1048 | /// .about("Controls configuration features") | |
1049 | /// .arg_from_usage("<config> 'Required configuration file to use'")) | |
1050 | /// # ; | |
1051 | /// ``` | |
1052 | /// [`SubCommand`]: ./struct.SubCommand.html | |
1053 | /// [`App`]: ./struct.App.html | |
1054 | pub fn subcommand(mut self, subcmd: App<'a, 'b>) -> Self { | |
1055 | self.p.add_subcommand(subcmd); | |
1056 | self | |
1057 | } | |
1058 | ||
041b39d2 | 1059 | /// Adds multiple subcommands to the list of valid possibilities by iterating over an |
8bb4bdeb XL |
1060 | /// [`IntoIterator`] of [`SubCommand`]s |
1061 | /// | |
1062 | /// # Examples | |
1063 | /// | |
1064 | /// ```rust | |
1065 | /// # use clap::{App, Arg, SubCommand}; | |
1066 | /// # App::new("myprog") | |
1067 | /// .subcommands( vec![ | |
1068 | /// SubCommand::with_name("config").about("Controls configuration functionality") | |
1069 | /// .arg(Arg::with_name("config_file").index(1)), | |
1070 | /// SubCommand::with_name("debug").about("Controls debug functionality")]) | |
1071 | /// # ; | |
1072 | /// ``` | |
1073 | /// [`SubCommand`]: ./struct.SubCommand.html | |
1074 | /// [`IntoIterator`]: https://doc.rust-lang.org/std/iter/trait.IntoIterator.html | |
1075 | pub fn subcommands<I>(mut self, subcmds: I) -> Self | |
1076 | where I: IntoIterator<Item = App<'a, 'b>> | |
1077 | { | |
1078 | for subcmd in subcmds { | |
1079 | self.p.add_subcommand(subcmd); | |
1080 | } | |
1081 | self | |
1082 | } | |
1083 | ||
1084 | /// Allows custom ordering of [`SubCommand`]s within the help message. Subcommands with a lower | |
1085 | /// value will be displayed first in the help message. This is helpful when one would like to | |
1086 | /// emphasise frequently used subcommands, or prioritize those towards the top of the list. | |
1087 | /// Duplicate values **are** allowed. Subcommands with duplicate display orders will be | |
1088 | /// displayed in alphabetical order. | |
1089 | /// | |
1090 | /// **NOTE:** The default is 999 for all subcommands. | |
1091 | /// | |
1092 | /// # Examples | |
1093 | /// | |
1094 | /// ```rust | |
1095 | /// # use clap::{App, SubCommand}; | |
1096 | /// let m = App::new("cust-ord") | |
1097 | /// .subcommand(SubCommand::with_name("alpha") // typically subcommands are grouped | |
1098 | /// // alphabetically by name. Subcommands | |
1099 | /// // without a display_order have a value of | |
1100 | /// // 999 and are displayed alphabetically with | |
1101 | /// // all other 999 subcommands | |
1102 | /// .about("Some help and text")) | |
1103 | /// .subcommand(SubCommand::with_name("beta") | |
1104 | /// .display_order(1) // In order to force this subcommand to appear *first* | |
1105 | /// // all we have to do is give it a value lower than 999. | |
1106 | /// // Any other subcommands with a value of 1 will be displayed | |
1107 | /// // alphabetically with this one...then 2 values, then 3, etc. | |
1108 | /// .about("I should be first!")) | |
1109 | /// .get_matches_from(vec![ | |
1110 | /// "cust-ord", "--help" | |
1111 | /// ]); | |
1112 | /// ``` | |
1113 | /// | |
1114 | /// The above example displays the following help message | |
1115 | /// | |
1116 | /// ```text | |
1117 | /// cust-ord | |
1118 | /// | |
1119 | /// USAGE: | |
1120 | /// cust-ord [FLAGS] [OPTIONS] | |
1121 | /// | |
1122 | /// FLAGS: | |
1123 | /// -h, --help Prints help information | |
1124 | /// -V, --version Prints version information | |
1125 | /// | |
1126 | /// SUBCOMMANDS: | |
1127 | /// beta I should be first! | |
1128 | /// alpha Some help and text | |
1129 | /// ``` | |
1130 | /// [`SubCommand`]: ./struct.SubCommand.html | |
1131 | pub fn display_order(mut self, ord: usize) -> Self { | |
1132 | self.p.meta.disp_ord = ord; | |
1133 | self | |
1134 | } | |
1135 | ||
041b39d2 XL |
1136 | /// Prints the full help message to [`io::stdout()`] using a [`BufWriter`] using the same |
1137 | /// method as if someone ran `-h` to request the help message | |
1138 | /// | |
1139 | /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages | |
1140 | /// depending on if the user ran [`-h` (short)] or [`--help` (long)] | |
8bb4bdeb XL |
1141 | /// |
1142 | /// # Examples | |
1143 | /// | |
1144 | /// ```rust | |
1145 | /// # use clap::App; | |
1146 | /// let mut app = App::new("myprog"); | |
1147 | /// app.print_help(); | |
1148 | /// ``` | |
1149 | /// [`io::stdout()`]: https://doc.rust-lang.org/std/io/fn.stdout.html | |
1150 | /// [`BufWriter`]: https://doc.rust-lang.org/std/io/struct.BufWriter.html | |
041b39d2 XL |
1151 | /// [`-h` (short)]: ./struct.Arg.html#method.help |
1152 | /// [`--help` (long)]: ./struct.Arg.html#method.long_help | |
8bb4bdeb | 1153 | pub fn print_help(&mut self) -> ClapResult<()> { |
041b39d2 XL |
1154 | // If there are global arguments, or settings we need to propgate them down to subcommands |
1155 | // before parsing incase we run into a subcommand | |
abe05a73 XL |
1156 | self.p.propagate_globals(); |
1157 | self.p.propagate_settings(); | |
041b39d2 XL |
1158 | self.p.derive_display_order(); |
1159 | ||
8bb4bdeb XL |
1160 | self.p.create_help_and_version(); |
1161 | let out = io::stdout(); | |
1162 | let mut buf_w = BufWriter::new(out.lock()); | |
1163 | self.write_help(&mut buf_w) | |
1164 | } | |
1165 | ||
041b39d2 | 1166 | /// Prints the full help message to [`io::stdout()`] using a [`BufWriter`] using the same |
3b2f2976 | 1167 | /// method as if someone ran `--help` to request the help message |
041b39d2 XL |
1168 | /// |
1169 | /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages | |
1170 | /// depending on if the user ran [`-h` (short)] or [`--help` (long)] | |
1171 | /// | |
1172 | /// # Examples | |
1173 | /// | |
1174 | /// ```rust | |
1175 | /// # use clap::App; | |
1176 | /// let mut app = App::new("myprog"); | |
1177 | /// app.print_long_help(); | |
1178 | /// ``` | |
1179 | /// [`io::stdout()`]: https://doc.rust-lang.org/std/io/fn.stdout.html | |
1180 | /// [`BufWriter`]: https://doc.rust-lang.org/std/io/struct.BufWriter.html | |
1181 | /// [`-h` (short)]: ./struct.Arg.html#method.help | |
1182 | /// [`--help` (long)]: ./struct.Arg.html#method.long_help | |
1183 | pub fn print_long_help(&mut self) -> ClapResult<()> { | |
1184 | // If there are global arguments, or settings we need to propgate them down to subcommands | |
1185 | // before parsing incase we run into a subcommand | |
abe05a73 XL |
1186 | self.p.propagate_globals(); |
1187 | self.p.propagate_settings(); | |
041b39d2 XL |
1188 | self.p.derive_display_order(); |
1189 | ||
1190 | self.p.create_help_and_version(); | |
1191 | let out = io::stdout(); | |
1192 | let mut buf_w = BufWriter::new(out.lock()); | |
1193 | self.write_long_help(&mut buf_w) | |
1194 | } | |
1195 | ||
1196 | /// Writes the full help message to the user to a [`io::Write`] object in the same method as if | |
1197 | /// the user ran `-h` | |
1198 | /// | |
1199 | /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages | |
1200 | /// depending on if the user ran [`-h` (short)] or [`--help` (long)] | |
1201 | /// | |
abe05a73 | 1202 | /// **NOTE:** There is a known bug where this method does not write propagated global arguments |
041b39d2 XL |
1203 | /// or autogenerated arguments (i.e. the default help/version args). Prefer |
1204 | /// [`App::write_long_help`] instead if possibe! | |
8bb4bdeb XL |
1205 | /// |
1206 | /// # Examples | |
1207 | /// | |
1208 | /// ```rust | |
1209 | /// # use clap::App; | |
1210 | /// use std::io; | |
1211 | /// let mut app = App::new("myprog"); | |
1212 | /// let mut out = io::stdout(); | |
1213 | /// app.write_help(&mut out).expect("failed to write to stdout"); | |
1214 | /// ``` | |
1215 | /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html | |
041b39d2 XL |
1216 | /// [`-h` (short)]: ./struct.Arg.html#method.help |
1217 | /// [`--help` (long)]: ./struct.Arg.html#method.long_help | |
8bb4bdeb | 1218 | pub fn write_help<W: Write>(&self, w: &mut W) -> ClapResult<()> { |
041b39d2 XL |
1219 | // PENDING ISSUE: 808 |
1220 | // https://github.com/kbknapp/clap-rs/issues/808 | |
1221 | // If there are global arguments, or settings we need to propgate them down to subcommands | |
1222 | // before parsing incase we run into a subcommand | |
abe05a73 XL |
1223 | // self.p.propagate_globals(); |
1224 | // self.p.propagate_settings(); | |
041b39d2 XL |
1225 | // self.p.derive_display_order(); |
1226 | // self.p.create_help_and_version(); | |
1227 | ||
1228 | Help::write_app_help(w, self, false) | |
8bb4bdeb XL |
1229 | } |
1230 | ||
041b39d2 XL |
1231 | /// Writes the full help message to the user to a [`io::Write`] object in the same method as if |
1232 | /// the user ran `--help` | |
1233 | /// | |
1234 | /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages | |
1235 | /// depending on if the user ran [`-h` (short)] or [`--help` (long)] | |
1236 | /// | |
1237 | /// # Examples | |
1238 | /// | |
1239 | /// ```rust | |
1240 | /// # use clap::App; | |
1241 | /// use std::io; | |
1242 | /// let mut app = App::new("myprog"); | |
1243 | /// let mut out = io::stdout(); | |
1244 | /// app.write_long_help(&mut out).expect("failed to write to stdout"); | |
1245 | /// ``` | |
1246 | /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html | |
1247 | /// [`-h` (short)]: ./struct.Arg.html#method.help | |
1248 | /// [`--help` (long)]: ./struct.Arg.html#method.long_help | |
1249 | pub fn write_long_help<W: Write>(&mut self, w: &mut W) -> ClapResult<()> { | |
abe05a73 XL |
1250 | self.p.propagate_globals(); |
1251 | self.p.propagate_settings(); | |
041b39d2 XL |
1252 | self.p.derive_display_order(); |
1253 | self.p.create_help_and_version(); | |
1254 | ||
1255 | Help::write_app_help(w, self, true) | |
1256 | } | |
1257 | ||
1258 | /// Writes the version message to the user to a [`io::Write`] object as if the user ran `-V`. | |
1259 | /// | |
1260 | /// **NOTE:** clap has the ability to distinguish between "short" and "long" version messages | |
1261 | /// depending on if the user ran [`-V` (short)] or [`--version` (long)] | |
8bb4bdeb XL |
1262 | /// |
1263 | /// # Examples | |
1264 | /// | |
1265 | /// ```rust | |
1266 | /// # use clap::App; | |
1267 | /// use std::io; | |
1268 | /// let mut app = App::new("myprog"); | |
1269 | /// let mut out = io::stdout(); | |
1270 | /// app.write_version(&mut out).expect("failed to write to stdout"); | |
1271 | /// ``` | |
1272 | /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html | |
041b39d2 XL |
1273 | /// [`-V` (short)]: ./struct.App.html#method.version |
1274 | /// [`--version` (long)]: ./struct.App.html#method.long_version | |
8bb4bdeb | 1275 | pub fn write_version<W: Write>(&self, w: &mut W) -> ClapResult<()> { |
041b39d2 | 1276 | self.p.write_version(w, false).map_err(From::from) |
8bb4bdeb XL |
1277 | } |
1278 | ||
041b39d2 XL |
1279 | /// Writes the version message to the user to a [`io::Write`] object |
1280 | /// | |
1281 | /// **NOTE:** clap has the ability to distinguish between "short" and "long" version messages | |
1282 | /// depending on if the user ran [`-V` (short)] or [`--version` (long)] | |
1283 | /// | |
1284 | /// # Examples | |
1285 | /// | |
1286 | /// ```rust | |
1287 | /// # use clap::App; | |
1288 | /// use std::io; | |
1289 | /// let mut app = App::new("myprog"); | |
1290 | /// let mut out = io::stdout(); | |
1291 | /// app.write_long_version(&mut out).expect("failed to write to stdout"); | |
1292 | /// ``` | |
1293 | /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html | |
1294 | /// [`-V` (short)]: ./struct.App.html#method.version | |
1295 | /// [`--version` (long)]: ./struct.App.html#method.long_version | |
1296 | pub fn write_long_version<W: Write>(&self, w: &mut W) -> ClapResult<()> { | |
1297 | self.p.write_version(w, true).map_err(From::from) | |
1298 | } | |
8bb4bdeb XL |
1299 | |
1300 | /// Generate a completions file for a specified shell at compile time. | |
1301 | /// | |
1302 | /// **NOTE:** to generate the this file at compile time you must use a `build.rs` "Build Script" | |
1303 | /// | |
1304 | /// # Examples | |
1305 | /// | |
1306 | /// The following example generates a bash completion script via a `build.rs` script. In this | |
1307 | /// simple example, we'll demo a very small application with only a single subcommand and two | |
1308 | /// args. Real applications could be many multiple levels deep in subcommands, and have tens or | |
041b39d2 | 1309 | /// potentially hundreds of arguments. |
8bb4bdeb | 1310 | /// |
041b39d2 | 1311 | /// First, it helps if we separate out our `App` definition into a separate file. Whether you |
8bb4bdeb XL |
1312 | /// do this as a function, or bare App definition is a matter of personal preference. |
1313 | /// | |
1314 | /// ``` | |
1315 | /// // src/cli.rs | |
1316 | /// | |
1317 | /// use clap::{App, Arg, SubCommand}; | |
1318 | /// | |
1319 | /// pub fn build_cli() -> App<'static, 'static> { | |
1320 | /// App::new("compl") | |
1321 | /// .about("Tests completions") | |
1322 | /// .arg(Arg::with_name("file") | |
1323 | /// .help("some input file")) | |
1324 | /// .subcommand(SubCommand::with_name("test") | |
1325 | /// .about("tests things") | |
1326 | /// .arg(Arg::with_name("case") | |
1327 | /// .long("case") | |
1328 | /// .takes_value(true) | |
1329 | /// .help("the case to test"))) | |
1330 | /// } | |
1331 | /// ``` | |
1332 | /// | |
1333 | /// In our regular code, we can simply call this `build_cli()` function, then call | |
1334 | /// `get_matches()`, or any of the other normal methods directly after. For example: | |
1335 | /// | |
1336 | /// ```ignore | |
1337 | /// // src/main.rs | |
1338 | /// | |
1339 | /// mod cli; | |
1340 | /// | |
1341 | /// fn main() { | |
1342 | /// let m = cli::build_cli().get_matches(); | |
1343 | /// | |
1344 | /// // normal logic continues... | |
1345 | /// } | |
1346 | /// ``` | |
1347 | /// | |
1348 | /// Next, we set up our `Cargo.toml` to use a `build.rs` build script. | |
1349 | /// | |
1350 | /// ```toml | |
1351 | /// # Cargo.toml | |
1352 | /// build = "build.rs" | |
1353 | /// | |
1354 | /// [build-dependencies] | |
041b39d2 | 1355 | /// clap = "2.23" |
8bb4bdeb XL |
1356 | /// ``` |
1357 | /// | |
1358 | /// Next, we place a `build.rs` in our project root. | |
1359 | /// | |
1360 | /// ```ignore | |
1361 | /// extern crate clap; | |
1362 | /// | |
1363 | /// use clap::Shell; | |
1364 | /// | |
1365 | /// include!("src/cli.rs"); | |
1366 | /// | |
1367 | /// fn main() { | |
1368 | /// let outdir = match env::var_os("OUT_DIR") { | |
1369 | /// None => return, | |
1370 | /// Some(outdir) => outdir, | |
1371 | /// }; | |
1372 | /// let mut app = build_cli(); | |
1373 | /// app.gen_completions("myapp", // We need to specify the bin name manually | |
1374 | /// Shell::Bash, // Then say which shell to build completions for | |
1375 | /// outdir); // Then say where write the completions to | |
1376 | /// } | |
1377 | /// ``` | |
1378 | /// Now, once we combile there will be a `{bin_name}.bash-completion` file in the directory. | |
1379 | /// Assuming we compiled with debug mode, it would be somewhere similar to | |
1380 | /// `<project>/target/debug/build/myapp-<hash>/out/myapp.bash-completion`. | |
1381 | /// | |
1382 | /// Fish shell completions will use the file format `{bin_name}.fish` | |
1383 | pub fn gen_completions<T: Into<OsString>, S: Into<String>>(&mut self, | |
1384 | bin_name: S, | |
1385 | for_shell: Shell, | |
1386 | out_dir: T) { | |
1387 | self.p.meta.bin_name = Some(bin_name.into()); | |
1388 | self.p.gen_completions(for_shell, out_dir.into()); | |
1389 | } | |
1390 | ||
1391 | ||
1392 | /// Generate a completions file for a specified shell at runtime. Until `cargo install` can | |
1393 | /// install extra files like a completion script, this may be used e.g. in a command that | |
1394 | /// outputs the contents of the completion script, to be redirected into a file by the user. | |
1395 | /// | |
1396 | /// # Examples | |
1397 | /// | |
1398 | /// Assuming a separate `cli.rs` like the [example above](./struct.App.html#method.gen_completions), | |
1399 | /// we can let users generate a completion script using a command: | |
1400 | /// | |
1401 | /// ```ignore | |
1402 | /// // src/main.rs | |
1403 | /// | |
1404 | /// mod cli; | |
1405 | /// use std::io; | |
1406 | /// | |
1407 | /// fn main() { | |
1408 | /// let matches = cli::build_cli().get_matches(); | |
1409 | /// | |
1410 | /// if matches.is_present("generate-bash-completions") { | |
1411 | /// cli::build_cli().gen_completions_to("myapp", Shell::Bash, &mut io::stdout()); | |
1412 | /// } | |
1413 | /// | |
1414 | /// // normal logic continues... | |
1415 | /// } | |
1416 | /// | |
1417 | /// ``` | |
1418 | /// | |
1419 | /// Usage: | |
1420 | /// | |
1421 | /// ```shell | |
1422 | /// $ myapp generate-bash-completions > /etc/bash_completion.d/myapp | |
1423 | /// ``` | |
1424 | pub fn gen_completions_to<W: Write, S: Into<String>>(&mut self, | |
1425 | bin_name: S, | |
1426 | for_shell: Shell, | |
1427 | buf: &mut W) { | |
1428 | self.p.meta.bin_name = Some(bin_name.into()); | |
1429 | self.p.gen_completions_to(for_shell, buf); | |
1430 | } | |
1431 | ||
1432 | /// Starts the parsing process, upon a failed parse an error will be displayed to the user and | |
1433 | /// the process will exit with the appropriate error code. By default this method gets all user | |
1434 | /// provided arguments from [`env::args_os`] in order to allow for invalid UTF-8 code points, | |
1435 | /// which are legal on many platforms. | |
1436 | /// | |
1437 | /// # Examples | |
1438 | /// | |
1439 | /// ```no_run | |
1440 | /// # use clap::{App, Arg}; | |
1441 | /// let matches = App::new("myprog") | |
1442 | /// // Args and options go here... | |
1443 | /// .get_matches(); | |
1444 | /// ``` | |
1445 | /// [`env::args_os`]: https://doc.rust-lang.org/std/env/fn.args_os.html | |
1446 | pub fn get_matches(self) -> ArgMatches<'a> { self.get_matches_from(&mut env::args_os()) } | |
1447 | ||
1448 | /// Starts the parsing process. This method will return a [`clap::Result`] type instead of exiting | |
1449 | /// the process on failed parse. By default this method gets matches from [`env::args_os`] | |
1450 | /// | |
1451 | /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are | |
1452 | /// used. It will return a [`clap::Error`], where the [`kind`] is a | |
1453 | /// [`ErrorKind::HelpDisplayed`] or [`ErrorKind::VersionDisplayed`] respectively. You must call | |
1454 | /// [`Error::exit`] or perform a [`std::process::exit`]. | |
1455 | /// | |
1456 | /// # Examples | |
1457 | /// | |
1458 | /// ```no_run | |
1459 | /// # use clap::{App, Arg}; | |
1460 | /// let matches = App::new("myprog") | |
1461 | /// // Args and options go here... | |
1462 | /// .get_matches_safe() | |
1463 | /// .unwrap_or_else( |e| e.exit() ); | |
1464 | /// ``` | |
1465 | /// [`env::args_os`]: https://doc.rust-lang.org/std/env/fn.args_os.html | |
1466 | /// [`ErrorKind::HelpDisplayed`]: ./enum.ErrorKind.html#variant.HelpDisplayed | |
1467 | /// [`ErrorKind::VersionDisplayed`]: ./enum.ErrorKind.html#variant.VersionDisplayed | |
1468 | /// [`Error::exit`]: ./struct.Error.html#method.exit | |
1469 | /// [`std::process::exit`]: https://doc.rust-lang.org/std/process/fn.exit.html | |
1470 | /// [`clap::Result`]: ./type.Result.html | |
1471 | /// [`clap::Error`]: ./struct.Error.html | |
1472 | /// [`kind`]: ./struct.Error.html | |
1473 | pub fn get_matches_safe(self) -> ClapResult<ArgMatches<'a>> { | |
1474 | // Start the parsing | |
1475 | self.get_matches_from_safe(&mut env::args_os()) | |
1476 | } | |
1477 | ||
1478 | /// Starts the parsing process. Like [`App::get_matches`] this method does not return a [`clap::Result`] | |
1479 | /// and will automatically exit with an error message. This method, however, lets you specify | |
1480 | /// what iterator to use when performing matches, such as a [`Vec`] of your making. | |
1481 | /// | |
1482 | /// **NOTE:** The first argument will be parsed as the binary name unless | |
1483 | /// [`AppSettings::NoBinaryName`] is used | |
1484 | /// | |
1485 | /// # Examples | |
1486 | /// | |
1487 | /// ```no_run | |
1488 | /// # use clap::{App, Arg}; | |
1489 | /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"]; | |
1490 | /// | |
1491 | /// let matches = App::new("myprog") | |
1492 | /// // Args and options go here... | |
1493 | /// .get_matches_from(arg_vec); | |
1494 | /// ``` | |
1495 | /// [`App::get_matches`]: ./struct.App.html#method.get_matches | |
1496 | /// [`clap::Result`]: ./type.Result.html | |
1497 | /// [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html | |
1498 | /// [`AppSettings::NoBinaryName`]: ./enum.AppSettings.html#variant.NoBinaryName | |
1499 | pub fn get_matches_from<I, T>(mut self, itr: I) -> ArgMatches<'a> | |
1500 | where I: IntoIterator<Item = T>, | |
1501 | T: Into<OsString> + Clone | |
1502 | { | |
1503 | self.get_matches_from_safe_borrow(itr).unwrap_or_else(|e| { | |
1504 | // Otherwise, write to stderr and exit | |
041b39d2 XL |
1505 | if e.use_stderr() { |
1506 | wlnerr!("{}", e.message); | |
1507 | if self.p.is_set(AppSettings::WaitOnError) { | |
1508 | wlnerr!("\nPress [ENTER] / [RETURN] to continue..."); | |
1509 | let mut s = String::new(); | |
1510 | let i = io::stdin(); | |
1511 | i.lock().read_line(&mut s).unwrap(); | |
1512 | } | |
1513 | drop(self); | |
1514 | drop(e); | |
1515 | process::exit(1); | |
1516 | } | |
1517 | ||
1518 | drop(self); | |
1519 | e.exit() | |
8bb4bdeb XL |
1520 | }) |
1521 | } | |
1522 | ||
1523 | /// Starts the parsing process. A combination of [`App::get_matches_from`], and | |
1524 | /// [`App::get_matches_safe`] | |
1525 | /// | |
1526 | /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are | |
1527 | /// used. It will return a [`clap::Error`], where the [`kind`] is a [`ErrorKind::HelpDisplayed`] | |
1528 | /// or [`ErrorKind::VersionDisplayed`] respectively. You must call [`Error::exit`] or | |
1529 | /// perform a [`std::process::exit`] yourself. | |
1530 | /// | |
1531 | /// **NOTE:** The first argument will be parsed as the binary name unless | |
1532 | /// [`AppSettings::NoBinaryName`] is used | |
1533 | /// | |
1534 | /// # Examples | |
1535 | /// | |
1536 | /// ```no_run | |
1537 | /// # use clap::{App, Arg}; | |
1538 | /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"]; | |
1539 | /// | |
1540 | /// let matches = App::new("myprog") | |
1541 | /// // Args and options go here... | |
1542 | /// .get_matches_from_safe(arg_vec) | |
1543 | /// .unwrap_or_else( |e| { panic!("An error occurs: {}", e) }); | |
1544 | /// ``` | |
1545 | /// [`App::get_matches_from`]: ./struct.App.html#method.get_matches_from | |
1546 | /// [`App::get_matches_safe`]: ./struct.App.html#method.get_matches_safe | |
1547 | /// [`ErrorKind::HelpDisplayed`]: ./enum.ErrorKind.html#variant.HelpDisplayed | |
1548 | /// [`ErrorKind::VersionDisplayed`]: ./enum.ErrorKind.html#variant.VersionDisplayed | |
1549 | /// [`Error::exit`]: ./struct.Error.html#method.exit | |
1550 | /// [`std::process::exit`]: https://doc.rust-lang.org/std/process/fn.exit.html | |
1551 | /// [`clap::Error`]: ./struct.Error.html | |
1552 | /// [`Error::exit`]: ./struct.Error.html#method.exit | |
1553 | /// [`kind`]: ./struct.Error.html | |
1554 | /// [`AppSettings::NoBinaryName`]: ./enum.AppSettings.html#variant.NoBinaryName | |
1555 | pub fn get_matches_from_safe<I, T>(mut self, itr: I) -> ClapResult<ArgMatches<'a>> | |
1556 | where I: IntoIterator<Item = T>, | |
1557 | T: Into<OsString> + Clone | |
1558 | { | |
1559 | self.get_matches_from_safe_borrow(itr) | |
1560 | } | |
1561 | ||
1562 | /// Starts the parsing process without consuming the [`App`] struct `self`. This is normally not | |
1563 | /// the desired functionality, instead prefer [`App::get_matches_from_safe`] which *does* | |
1564 | /// consume `self`. | |
1565 | /// | |
1566 | /// **NOTE:** The first argument will be parsed as the binary name unless | |
1567 | /// [`AppSettings::NoBinaryName`] is used | |
1568 | /// | |
1569 | /// # Examples | |
1570 | /// | |
1571 | /// ```no_run | |
1572 | /// # use clap::{App, Arg}; | |
1573 | /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"]; | |
1574 | /// | |
1575 | /// let mut app = App::new("myprog"); | |
1576 | /// // Args and options go here... | |
1577 | /// let matches = app.get_matches_from_safe_borrow(arg_vec) | |
1578 | /// .unwrap_or_else( |e| { panic!("An error occurs: {}", e) }); | |
1579 | /// ``` | |
1580 | /// [`App`]: ./struct.App.html | |
1581 | /// [`App::get_matches_from_safe`]: ./struct.App.html#method.get_matches_from_safe | |
1582 | /// [`AppSettings::NoBinaryName`]: ./enum.AppSettings.html#variant.NoBinaryName | |
1583 | pub fn get_matches_from_safe_borrow<I, T>(&mut self, itr: I) -> ClapResult<ArgMatches<'a>> | |
1584 | where I: IntoIterator<Item = T>, | |
1585 | T: Into<OsString> + Clone | |
1586 | { | |
1587 | // If there are global arguments, or settings we need to propgate them down to subcommands | |
1588 | // before parsing incase we run into a subcommand | |
abe05a73 XL |
1589 | if !self.p.is_set(AppSettings::Propagated) { |
1590 | self.p.propagate_globals(); | |
1591 | self.p.propagate_settings(); | |
1592 | self.p.derive_display_order(); | |
1593 | self.p.set(AppSettings::Propagated); | |
1594 | } | |
8bb4bdeb XL |
1595 | |
1596 | let mut matcher = ArgMatcher::new(); | |
1597 | ||
1598 | let mut it = itr.into_iter(); | |
1599 | // Get the name of the program (argument 1 of env::args()) and determine the | |
1600 | // actual file | |
1601 | // that was used to execute the program. This is because a program called | |
1602 | // ./target/release/my_prog -a | |
1603 | // will have two arguments, './target/release/my_prog', '-a' but we don't want | |
1604 | // to display | |
1605 | // the full path when displaying help messages and such | |
1606 | if !self.p.is_set(AppSettings::NoBinaryName) { | |
1607 | if let Some(name) = it.next() { | |
1608 | let bn_os = name.into(); | |
1609 | let p = Path::new(&*bn_os); | |
1610 | if let Some(f) = p.file_name() { | |
1611 | if let Some(s) = f.to_os_string().to_str() { | |
1612 | if self.p.meta.bin_name.is_none() { | |
1613 | self.p.meta.bin_name = Some(s.to_owned()); | |
1614 | } | |
1615 | } | |
1616 | } | |
1617 | } | |
1618 | } | |
1619 | ||
1620 | // do the real parsing | |
1621 | if let Err(e) = self.p.get_matches_with(&mut matcher, &mut it.peekable()) { | |
1622 | return Err(e); | |
1623 | } | |
1624 | ||
abe05a73 XL |
1625 | let global_arg_vec : Vec<&str> = (&self).p.global_args.iter().map(|ga| ga.b.name).collect(); |
1626 | matcher.propagate_globals(&global_arg_vec); | |
8bb4bdeb | 1627 | |
041b39d2 | 1628 | Ok(matcher.into()) |
8bb4bdeb | 1629 | } |
8bb4bdeb XL |
1630 | } |
1631 | ||
1632 | #[cfg(feature = "yaml")] | |
1633 | impl<'a> From<&'a Yaml> for App<'a, 'a> { | |
1634 | fn from(mut yaml: &'a Yaml) -> Self { | |
1635 | use args::SubCommand; | |
1636 | // We WANT this to panic on error...so expect() is good. | |
1637 | let mut is_sc = None; | |
1638 | let mut a = if let Some(name) = yaml["name"].as_str() { | |
1639 | App::new(name) | |
1640 | } else { | |
1641 | let yaml_hash = yaml.as_hash().unwrap(); | |
1642 | let sc_key = yaml_hash.keys().nth(0).unwrap(); | |
1643 | is_sc = Some(yaml_hash.get(sc_key).unwrap()); | |
1644 | App::new(sc_key.as_str().unwrap()) | |
1645 | }; | |
1646 | yaml = if let Some(sc) = is_sc { sc } else { yaml }; | |
1647 | ||
1648 | macro_rules! yaml_str { | |
1649 | ($a:ident, $y:ident, $i:ident) => { | |
1650 | if let Some(v) = $y[stringify!($i)].as_str() { | |
1651 | $a = $a.$i(v); | |
1652 | } else if $y[stringify!($i)] != Yaml::BadValue { | |
1653 | panic!("Failed to convert YAML value {:?} to a string", $y[stringify!($i)]); | |
1654 | } | |
1655 | }; | |
1656 | } | |
1657 | ||
1658 | yaml_str!(a, yaml, version); | |
041b39d2 | 1659 | yaml_str!(a, yaml, author); |
8bb4bdeb XL |
1660 | yaml_str!(a, yaml, bin_name); |
1661 | yaml_str!(a, yaml, about); | |
1662 | yaml_str!(a, yaml, before_help); | |
1663 | yaml_str!(a, yaml, after_help); | |
1664 | yaml_str!(a, yaml, template); | |
1665 | yaml_str!(a, yaml, usage); | |
1666 | yaml_str!(a, yaml, help); | |
1667 | yaml_str!(a, yaml, help_short); | |
1668 | yaml_str!(a, yaml, version_short); | |
041b39d2 XL |
1669 | yaml_str!(a, yaml, help_message); |
1670 | yaml_str!(a, yaml, version_message); | |
8bb4bdeb XL |
1671 | yaml_str!(a, yaml, alias); |
1672 | yaml_str!(a, yaml, visible_alias); | |
1673 | ||
1674 | if let Some(v) = yaml["display_order"].as_i64() { | |
1675 | a = a.display_order(v as usize); | |
1676 | } else if yaml["display_order"] != Yaml::BadValue { | |
1677 | panic!("Failed to convert YAML value {:?} to a u64", | |
1678 | yaml["display_order"]); | |
1679 | } | |
1680 | if let Some(v) = yaml["setting"].as_str() { | |
1681 | a = a.setting(v.parse().expect("unknown AppSetting found in YAML file")); | |
1682 | } else if yaml["setting"] != Yaml::BadValue { | |
1683 | panic!("Failed to convert YAML value {:?} to an AppSetting", | |
1684 | yaml["setting"]); | |
1685 | } | |
1686 | if let Some(v) = yaml["settings"].as_vec() { | |
1687 | for ys in v { | |
1688 | if let Some(s) = ys.as_str() { | |
1689 | a = a.setting(s.parse().expect("unknown AppSetting found in YAML file")); | |
1690 | } | |
1691 | } | |
1692 | } else if let Some(v) = yaml["settings"].as_str() { | |
1693 | a = a.setting(v.parse().expect("unknown AppSetting found in YAML file")); | |
1694 | } else if yaml["settings"] != Yaml::BadValue { | |
1695 | panic!("Failed to convert YAML value {:?} to a string", | |
1696 | yaml["settings"]); | |
1697 | } | |
1698 | if let Some(v) = yaml["global_setting"].as_str() { | |
1699 | a = a.setting(v.parse().expect("unknown AppSetting found in YAML file")); | |
1700 | } else if yaml["global_setting"] != Yaml::BadValue { | |
1701 | panic!("Failed to convert YAML value {:?} to an AppSetting", | |
1702 | yaml["setting"]); | |
1703 | } | |
1704 | if let Some(v) = yaml["global_settings"].as_vec() { | |
1705 | for ys in v { | |
1706 | if let Some(s) = ys.as_str() { | |
1707 | a = a.global_setting(s.parse() | |
1708 | .expect("unknown AppSetting found in YAML file")); | |
1709 | } | |
1710 | } | |
1711 | } else if let Some(v) = yaml["global_settings"].as_str() { | |
1712 | a = a.global_setting(v.parse().expect("unknown AppSetting found in YAML file")); | |
1713 | } else if yaml["global_settings"] != Yaml::BadValue { | |
1714 | panic!("Failed to convert YAML value {:?} to a string", | |
1715 | yaml["global_settings"]); | |
1716 | } | |
1717 | ||
1718 | macro_rules! vec_or_str { | |
1719 | ($a:ident, $y:ident, $as_vec:ident, $as_single:ident) => {{ | |
1720 | let maybe_vec = $y[stringify!($as_vec)].as_vec(); | |
1721 | if let Some(vec) = maybe_vec { | |
1722 | for ys in vec { | |
1723 | if let Some(s) = ys.as_str() { | |
1724 | $a = $a.$as_single(s); | |
1725 | } else { | |
1726 | panic!("Failed to convert YAML value {:?} to a string", ys); | |
1727 | } | |
1728 | } | |
1729 | } else { | |
1730 | if let Some(s) = $y[stringify!($as_vec)].as_str() { | |
1731 | $a = $a.$as_single(s); | |
1732 | } else if $y[stringify!($as_vec)] != Yaml::BadValue { | |
1733 | panic!("Failed to convert YAML value {:?} to either a vec or string", $y[stringify!($as_vec)]); | |
1734 | } | |
1735 | } | |
1736 | $a | |
1737 | } | |
1738 | }; | |
1739 | } | |
1740 | ||
1741 | a = vec_or_str!(a, yaml, aliases, alias); | |
1742 | a = vec_or_str!(a, yaml, visible_aliases, visible_alias); | |
1743 | ||
1744 | if let Some(v) = yaml["args"].as_vec() { | |
1745 | for arg_yaml in v { | |
1746 | a = a.arg(Arg::from_yaml(arg_yaml.as_hash().unwrap())); | |
1747 | } | |
1748 | } | |
1749 | if let Some(v) = yaml["subcommands"].as_vec() { | |
1750 | for sc_yaml in v { | |
1751 | a = a.subcommand(SubCommand::from_yaml(sc_yaml)); | |
1752 | } | |
1753 | } | |
1754 | if let Some(v) = yaml["groups"].as_vec() { | |
1755 | for ag_yaml in v { | |
1756 | a = a.group(ArgGroup::from(ag_yaml.as_hash().unwrap())); | |
1757 | } | |
1758 | } | |
1759 | ||
1760 | a | |
1761 | } | |
1762 | } | |
1763 | ||
1764 | impl<'a, 'b> Clone for App<'a, 'b> { | |
1765 | fn clone(&self) -> Self { App { p: self.p.clone() } } | |
1766 | } | |
1767 | ||
1768 | impl<'n, 'e> AnyArg<'n, 'e> for App<'n, 'e> { | |
1769 | fn name(&self) -> &'n str { | |
1770 | unreachable!("App struct does not support AnyArg::name, this is a bug!") | |
1771 | } | |
8bb4bdeb | 1772 | fn overrides(&self) -> Option<&[&'e str]> { None } |
041b39d2 | 1773 | fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> { None } |
8bb4bdeb XL |
1774 | fn blacklist(&self) -> Option<&[&'e str]> { None } |
1775 | fn required_unless(&self) -> Option<&[&'e str]> { None } | |
1776 | fn val_names(&self) -> Option<&VecMap<&'e str>> { None } | |
1777 | fn is_set(&self, _: ArgSettings) -> bool { false } | |
041b39d2 | 1778 | fn val_terminator(&self) -> Option<&'e str> { None } |
8bb4bdeb XL |
1779 | fn set(&mut self, _: ArgSettings) { |
1780 | unreachable!("App struct does not support AnyArg::set, this is a bug!") | |
1781 | } | |
1782 | fn has_switch(&self) -> bool { false } | |
1783 | fn max_vals(&self) -> Option<u64> { None } | |
1784 | fn num_vals(&self) -> Option<u64> { None } | |
1785 | fn possible_vals(&self) -> Option<&[&'e str]> { None } | |
1786 | fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> { None } | |
041b39d2 | 1787 | fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> { None } |
8bb4bdeb XL |
1788 | fn min_vals(&self) -> Option<u64> { None } |
1789 | fn short(&self) -> Option<char> { None } | |
1790 | fn long(&self) -> Option<&'e str> { None } | |
1791 | fn val_delim(&self) -> Option<char> { None } | |
1792 | fn takes_value(&self) -> bool { true } | |
1793 | fn help(&self) -> Option<&'e str> { self.p.meta.about } | |
041b39d2 XL |
1794 | fn long_help(&self) -> Option<&'e str> { self.p.meta.long_about } |
1795 | fn default_val(&self) -> Option<&'e OsStr> { None } | |
abe05a73 | 1796 | fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> { |
041b39d2 XL |
1797 | None |
1798 | } | |
abe05a73 | 1799 | fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> { None } |
8bb4bdeb XL |
1800 | fn longest_filter(&self) -> bool { true } |
1801 | fn aliases(&self) -> Option<Vec<&'e str>> { | |
1802 | if let Some(ref aliases) = self.p.meta.aliases { | |
1803 | let vis_aliases: Vec<_> = | |
1804 | aliases.iter().filter_map(|&(n, v)| if v { Some(n) } else { None }).collect(); | |
1805 | if vis_aliases.is_empty() { | |
1806 | None | |
1807 | } else { | |
1808 | Some(vis_aliases) | |
1809 | } | |
1810 | } else { | |
1811 | None | |
1812 | } | |
1813 | } | |
1814 | } | |
1815 | ||
1816 | impl<'n, 'e> fmt::Display for App<'n, 'e> { | |
1817 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.p.meta.name) } | |
1818 | } |