]> git.proxmox.com Git - rustc.git/blob - vendor/clap_builder/src/builder/command.rs
New upstream version 1.75.0+dfsg1
[rustc.git] / vendor / clap_builder / src / builder / command.rs
1 #![cfg_attr(not(feature = "usage"), allow(unused_mut))]
2
3 // Std
4 use std::env;
5 use std::ffi::OsString;
6 use std::fmt;
7 use std::io;
8 use std::ops::Index;
9 use std::path::Path;
10
11 // Internal
12 use crate::builder::app_settings::{AppFlags, AppSettings};
13 use crate::builder::arg_settings::ArgSettings;
14 use crate::builder::ext::Extensions;
15 use crate::builder::ArgAction;
16 use crate::builder::IntoResettable;
17 use crate::builder::PossibleValue;
18 use crate::builder::Str;
19 use crate::builder::StyledStr;
20 use crate::builder::Styles;
21 use crate::builder::{Arg, ArgGroup, ArgPredicate};
22 use crate::error::ErrorKind;
23 use crate::error::Result as ClapResult;
24 use crate::mkeymap::MKeyMap;
25 use crate::output::fmt::Stream;
26 use crate::output::{fmt::Colorizer, write_help, Usage};
27 use crate::parser::{ArgMatcher, ArgMatches, Parser};
28 use crate::util::ChildGraph;
29 use crate::util::{color::ColorChoice, Id};
30 use crate::{Error, INTERNAL_ERROR_MSG};
31
32 #[cfg(debug_assertions)]
33 use crate::builder::debug_asserts::assert_app;
34
35 /// Build a command-line interface.
36 ///
37 /// This includes defining arguments, subcommands, parser behavior, and help output.
38 /// Once all configuration is complete,
39 /// the [`Command::get_matches`] family of methods starts the runtime-parsing
40 /// process. These methods then return information about the user supplied
41 /// arguments (or lack thereof).
42 ///
43 /// When deriving a [`Parser`][crate::Parser], you can use
44 /// [`CommandFactory::command`][crate::CommandFactory::command] to access the
45 /// `Command`.
46 ///
47 /// - [Basic API][crate::Command#basic-api]
48 /// - [Application-wide Settings][crate::Command#application-wide-settings]
49 /// - [Command-specific Settings][crate::Command#command-specific-settings]
50 /// - [Subcommand-specific Settings][crate::Command#subcommand-specific-settings]
51 /// - [Reflection][crate::Command#reflection]
52 ///
53 /// # Examples
54 ///
55 /// ```no_run
56 /// # use clap_builder as clap;
57 /// # use clap::{Command, Arg};
58 /// let m = Command::new("My Program")
59 /// .author("Me, me@mail.com")
60 /// .version("1.0.2")
61 /// .about("Explains in brief what the program does")
62 /// .arg(
63 /// Arg::new("in_file")
64 /// )
65 /// .after_help("Longer explanation to appear after the options when \
66 /// displaying the help information from --help or -h")
67 /// .get_matches();
68 ///
69 /// // Your program logic starts here...
70 /// ```
71 /// [`Command::get_matches`]: Command::get_matches()
72 #[derive(Debug, Clone)]
73 pub struct Command {
74 name: Str,
75 long_flag: Option<Str>,
76 short_flag: Option<char>,
77 display_name: Option<String>,
78 bin_name: Option<String>,
79 author: Option<Str>,
80 version: Option<Str>,
81 long_version: Option<Str>,
82 about: Option<StyledStr>,
83 long_about: Option<StyledStr>,
84 before_help: Option<StyledStr>,
85 before_long_help: Option<StyledStr>,
86 after_help: Option<StyledStr>,
87 after_long_help: Option<StyledStr>,
88 aliases: Vec<(Str, bool)>, // (name, visible)
89 short_flag_aliases: Vec<(char, bool)>, // (name, visible)
90 long_flag_aliases: Vec<(Str, bool)>, // (name, visible)
91 usage_str: Option<StyledStr>,
92 usage_name: Option<String>,
93 help_str: Option<StyledStr>,
94 disp_ord: Option<usize>,
95 #[cfg(feature = "help")]
96 template: Option<StyledStr>,
97 settings: AppFlags,
98 g_settings: AppFlags,
99 args: MKeyMap,
100 subcommands: Vec<Command>,
101 groups: Vec<ArgGroup>,
102 current_help_heading: Option<Str>,
103 current_disp_ord: Option<usize>,
104 subcommand_value_name: Option<Str>,
105 subcommand_heading: Option<Str>,
106 external_value_parser: Option<super::ValueParser>,
107 long_help_exists: bool,
108 deferred: Option<fn(Command) -> Command>,
109 app_ext: Extensions,
110 }
111
112 /// # Basic API
113 impl Command {
114 /// Creates a new instance of an `Command`.
115 ///
116 /// It is common, but not required, to use binary name as the `name`. This
117 /// name will only be displayed to the user when they request to print
118 /// version or help and usage information.
119 ///
120 /// See also [`command!`](crate::command!) and [`crate_name!`](crate::crate_name!).
121 ///
122 /// # Examples
123 ///
124 /// ```rust
125 /// # use clap_builder as clap;
126 /// # use clap::Command;
127 /// Command::new("My Program")
128 /// # ;
129 /// ```
130 pub fn new(name: impl Into<Str>) -> Self {
131 /// The actual implementation of `new`, non-generic to save code size.
132 ///
133 /// If we don't do this rustc will unnecessarily generate multiple versions
134 /// of this code.
135 fn new_inner(name: Str) -> Command {
136 Command {
137 name,
138 ..Default::default()
139 }
140 }
141
142 new_inner(name.into())
143 }
144
145 /// Adds an [argument] to the list of valid possibilities.
146 ///
147 /// # Examples
148 ///
149 /// ```rust
150 /// # use clap_builder as clap;
151 /// # use clap::{Command, arg, Arg};
152 /// Command::new("myprog")
153 /// // Adding a single "flag" argument with a short and help text, using Arg::new()
154 /// .arg(
155 /// Arg::new("debug")
156 /// .short('d')
157 /// .help("turns on debugging mode")
158 /// )
159 /// // Adding a single "option" argument with a short, a long, and help text using the less
160 /// // verbose Arg::from()
161 /// .arg(
162 /// arg!(-c --config <CONFIG> "Optionally sets a config file to use")
163 /// )
164 /// # ;
165 /// ```
166 /// [argument]: Arg
167 #[must_use]
168 pub fn arg(mut self, a: impl Into<Arg>) -> Self {
169 let arg = a.into();
170 self.arg_internal(arg);
171 self
172 }
173
174 fn arg_internal(&mut self, mut arg: Arg) {
175 if let Some(current_disp_ord) = self.current_disp_ord.as_mut() {
176 if !arg.is_positional() {
177 let current = *current_disp_ord;
178 arg.disp_ord.get_or_insert(current);
179 *current_disp_ord = current + 1;
180 }
181 }
182
183 arg.help_heading
184 .get_or_insert_with(|| self.current_help_heading.clone());
185 self.args.push(arg);
186 }
187
188 /// Adds multiple [arguments] to the list of valid possibilities.
189 ///
190 /// # Examples
191 ///
192 /// ```rust
193 /// # use clap_builder as clap;
194 /// # use clap::{Command, arg, Arg};
195 /// Command::new("myprog")
196 /// .args([
197 /// arg!(-d --debug "turns on debugging info"),
198 /// Arg::new("input").help("the input file to use")
199 /// ])
200 /// # ;
201 /// ```
202 /// [arguments]: Arg
203 #[must_use]
204 pub fn args(mut self, args: impl IntoIterator<Item = impl Into<Arg>>) -> Self {
205 for arg in args {
206 self = self.arg(arg);
207 }
208 self
209 }
210
211 /// Allows one to mutate an [`Arg`] after it's been added to a [`Command`].
212 ///
213 /// # Panics
214 ///
215 /// If the argument is undefined
216 ///
217 /// # Examples
218 ///
219 /// ```rust
220 /// # use clap_builder as clap;
221 /// # use clap::{Command, Arg, ArgAction};
222 ///
223 /// let mut cmd = Command::new("foo")
224 /// .arg(Arg::new("bar")
225 /// .short('b')
226 /// .action(ArgAction::SetTrue))
227 /// .mut_arg("bar", |a| a.short('B'));
228 ///
229 /// let res = cmd.try_get_matches_from_mut(vec!["foo", "-b"]);
230 ///
231 /// // Since we changed `bar`'s short to "B" this should err as there
232 /// // is no `-b` anymore, only `-B`
233 ///
234 /// assert!(res.is_err());
235 ///
236 /// let res = cmd.try_get_matches_from_mut(vec!["foo", "-B"]);
237 /// assert!(res.is_ok());
238 /// ```
239 #[must_use]
240 #[cfg_attr(debug_assertions, track_caller)]
241 pub fn mut_arg<F>(mut self, arg_id: impl AsRef<str>, f: F) -> Self
242 where
243 F: FnOnce(Arg) -> Arg,
244 {
245 let id = arg_id.as_ref();
246 let a = self
247 .args
248 .remove_by_name(id)
249 .unwrap_or_else(|| panic!("Argument `{id}` is undefined"));
250
251 self.args.push(f(a));
252 self
253 }
254
255 /// Allows one to mutate all [`Arg`]s after they've been added to a [`Command`].
256 ///
257 /// This does not affect the built-in `--help` or `--version` arguments.
258 ///
259 /// # Examples
260 ///
261 #[cfg_attr(feature = "string", doc = "```")]
262 #[cfg_attr(not(feature = "string"), doc = "```ignore")]
263 /// # use clap_builder as clap;
264 /// # use clap::{Command, Arg, ArgAction};
265 ///
266 /// let mut cmd = Command::new("foo")
267 /// .arg(Arg::new("bar")
268 /// .long("bar")
269 /// .action(ArgAction::SetTrue))
270 /// .arg(Arg::new("baz")
271 /// .long("baz")
272 /// .action(ArgAction::SetTrue))
273 /// .mut_args(|a| {
274 /// if let Some(l) = a.get_long().map(|l| format!("prefix-{l}")) {
275 /// a.long(l)
276 /// } else {
277 /// a
278 /// }
279 /// });
280 ///
281 /// let res = cmd.try_get_matches_from_mut(vec!["foo", "--bar"]);
282 ///
283 /// // Since we changed `bar`'s long to "prefix-bar" this should err as there
284 /// // is no `--bar` anymore, only `--prefix-bar`.
285 ///
286 /// assert!(res.is_err());
287 ///
288 /// let res = cmd.try_get_matches_from_mut(vec!["foo", "--prefix-bar"]);
289 /// assert!(res.is_ok());
290 /// ```
291 #[must_use]
292 #[cfg_attr(debug_assertions, track_caller)]
293 pub fn mut_args<F>(mut self, f: F) -> Self
294 where
295 F: FnMut(Arg) -> Arg,
296 {
297 self.args.mut_args(f);
298 self
299 }
300
301 /// Allows one to mutate a [`Command`] after it's been added as a subcommand.
302 ///
303 /// This can be useful for modifying auto-generated arguments of nested subcommands with
304 /// [`Command::mut_arg`].
305 ///
306 /// # Panics
307 ///
308 /// If the subcommand is undefined
309 ///
310 /// # Examples
311 ///
312 /// ```rust
313 /// # use clap_builder as clap;
314 /// # use clap::Command;
315 ///
316 /// let mut cmd = Command::new("foo")
317 /// .subcommand(Command::new("bar"))
318 /// .mut_subcommand("bar", |subcmd| subcmd.disable_help_flag(true));
319 ///
320 /// let res = cmd.try_get_matches_from_mut(vec!["foo", "bar", "--help"]);
321 ///
322 /// // Since we disabled the help flag on the "bar" subcommand, this should err.
323 ///
324 /// assert!(res.is_err());
325 ///
326 /// let res = cmd.try_get_matches_from_mut(vec!["foo", "bar"]);
327 /// assert!(res.is_ok());
328 /// ```
329 #[must_use]
330 pub fn mut_subcommand<F>(mut self, name: impl AsRef<str>, f: F) -> Self
331 where
332 F: FnOnce(Self) -> Self,
333 {
334 let name = name.as_ref();
335 let pos = self.subcommands.iter().position(|s| s.name == name);
336
337 let subcmd = if let Some(idx) = pos {
338 self.subcommands.remove(idx)
339 } else {
340 panic!("Command `{name}` is undefined")
341 };
342
343 self.subcommands.push(f(subcmd));
344 self
345 }
346
347 /// Adds an [`ArgGroup`] to the application.
348 ///
349 /// [`ArgGroup`]s are a family of related arguments.
350 /// By placing them in a logical group, you can build easier requirement and exclusion rules.
351 ///
352 /// Example use cases:
353 /// - Make an entire [`ArgGroup`] required, meaning that one (and *only*
354 /// one) argument from that group must be present at runtime.
355 /// - Name an [`ArgGroup`] as a conflict to another argument.
356 /// Meaning any of the arguments that belong to that group will cause a failure if present with
357 /// the conflicting argument.
358 /// - Ensure exclusion between arguments.
359 /// - Extract a value from a group instead of determining exactly which argument was used.
360 ///
361 /// # Examples
362 ///
363 /// The following example demonstrates using an [`ArgGroup`] to ensure that one, and only one,
364 /// of the arguments from the specified group is present at runtime.
365 ///
366 /// ```rust
367 /// # use clap_builder as clap;
368 /// # use clap::{Command, arg, ArgGroup};
369 /// Command::new("cmd")
370 /// .arg(arg!(--"set-ver" <ver> "set the version manually").required(false))
371 /// .arg(arg!(--major "auto increase major"))
372 /// .arg(arg!(--minor "auto increase minor"))
373 /// .arg(arg!(--patch "auto increase patch"))
374 /// .group(ArgGroup::new("vers")
375 /// .args(["set-ver", "major", "minor","patch"])
376 /// .required(true))
377 /// # ;
378 /// ```
379 #[inline]
380 #[must_use]
381 pub fn group(mut self, group: impl Into<ArgGroup>) -> Self {
382 self.groups.push(group.into());
383 self
384 }
385
386 /// Adds multiple [`ArgGroup`]s to the [`Command`] at once.
387 ///
388 /// # Examples
389 ///
390 /// ```rust
391 /// # use clap_builder as clap;
392 /// # use clap::{Command, arg, ArgGroup};
393 /// Command::new("cmd")
394 /// .arg(arg!(--"set-ver" <ver> "set the version manually").required(false))
395 /// .arg(arg!(--major "auto increase major"))
396 /// .arg(arg!(--minor "auto increase minor"))
397 /// .arg(arg!(--patch "auto increase patch"))
398 /// .arg(arg!(-c <FILE> "a config file").required(false))
399 /// .arg(arg!(-i <IFACE> "an interface").required(false))
400 /// .groups([
401 /// ArgGroup::new("vers")
402 /// .args(["set-ver", "major", "minor","patch"])
403 /// .required(true),
404 /// ArgGroup::new("input")
405 /// .args(["c", "i"])
406 /// ])
407 /// # ;
408 /// ```
409 #[must_use]
410 pub fn groups(mut self, groups: impl IntoIterator<Item = impl Into<ArgGroup>>) -> Self {
411 for g in groups.into_iter() {
412 self = self.group(g.into());
413 }
414 self
415 }
416
417 /// Adds a subcommand to the list of valid possibilities.
418 ///
419 /// Subcommands are effectively sub-[`Command`]s, because they can contain their own arguments,
420 /// subcommands, version, usage, etc. They also function just like [`Command`]s, in that they get
421 /// their own auto generated help, version, and usage.
422 ///
423 /// A subcommand's [`Command::name`] will be used for:
424 /// - The argument the user passes in
425 /// - Programmatically looking up the subcommand
426 ///
427 /// # Examples
428 ///
429 /// ```rust
430 /// # use clap_builder as clap;
431 /// # use clap::{Command, arg};
432 /// Command::new("myprog")
433 /// .subcommand(Command::new("config")
434 /// .about("Controls configuration features")
435 /// .arg(arg!(<config> "Required configuration file to use")))
436 /// # ;
437 /// ```
438 #[inline]
439 #[must_use]
440 pub fn subcommand(self, subcmd: impl Into<Command>) -> Self {
441 let subcmd = subcmd.into();
442 self.subcommand_internal(subcmd)
443 }
444
445 fn subcommand_internal(mut self, mut subcmd: Self) -> Self {
446 if let Some(current_disp_ord) = self.current_disp_ord.as_mut() {
447 let current = *current_disp_ord;
448 subcmd.disp_ord.get_or_insert(current);
449 *current_disp_ord = current + 1;
450 }
451 self.subcommands.push(subcmd);
452 self
453 }
454
455 /// Adds multiple subcommands to the list of valid possibilities.
456 ///
457 /// # Examples
458 ///
459 /// ```rust
460 /// # use clap_builder as clap;
461 /// # use clap::{Command, Arg, };
462 /// # Command::new("myprog")
463 /// .subcommands( [
464 /// Command::new("config").about("Controls configuration functionality")
465 /// .arg(Arg::new("config_file")),
466 /// Command::new("debug").about("Controls debug functionality")])
467 /// # ;
468 /// ```
469 /// [`IntoIterator`]: std::iter::IntoIterator
470 #[must_use]
471 pub fn subcommands(mut self, subcmds: impl IntoIterator<Item = impl Into<Self>>) -> Self {
472 for subcmd in subcmds {
473 self = self.subcommand(subcmd);
474 }
475 self
476 }
477
478 /// Delay initialization for parts of the `Command`
479 ///
480 /// This is useful for large applications to delay definitions of subcommands until they are
481 /// being invoked.
482 ///
483 /// # Examples
484 ///
485 /// ```rust
486 /// # use clap_builder as clap;
487 /// # use clap::{Command, arg};
488 /// Command::new("myprog")
489 /// .subcommand(Command::new("config")
490 /// .about("Controls configuration features")
491 /// .defer(|cmd| {
492 /// cmd.arg(arg!(<config> "Required configuration file to use"))
493 /// })
494 /// )
495 /// # ;
496 /// ```
497 pub fn defer(mut self, deferred: fn(Command) -> Command) -> Self {
498 self.deferred = Some(deferred);
499 self
500 }
501
502 /// Catch problems earlier in the development cycle.
503 ///
504 /// Most error states are handled as asserts under the assumption they are programming mistake
505 /// and not something to handle at runtime. Rather than relying on tests (manual or automated)
506 /// that exhaustively test your CLI to ensure the asserts are evaluated, this will run those
507 /// asserts in a way convenient for running as a test.
508 ///
509 /// **Note::** This will not help with asserts in [`ArgMatches`], those will need exhaustive
510 /// testing of your CLI.
511 ///
512 /// # Examples
513 ///
514 /// ```rust
515 /// # use clap_builder as clap;
516 /// # use clap::{Command, Arg, ArgAction};
517 /// fn cmd() -> Command {
518 /// Command::new("foo")
519 /// .arg(
520 /// Arg::new("bar").short('b').action(ArgAction::SetTrue)
521 /// )
522 /// }
523 ///
524 /// #[test]
525 /// fn verify_app() {
526 /// cmd().debug_assert();
527 /// }
528 ///
529 /// fn main() {
530 /// let m = cmd().get_matches_from(vec!["foo", "-b"]);
531 /// println!("{}", m.get_flag("bar"));
532 /// }
533 /// ```
534 pub fn debug_assert(mut self) {
535 self.build();
536 }
537
538 /// Custom error message for post-parsing validation
539 ///
540 /// # Examples
541 ///
542 /// ```rust
543 /// # use clap_builder as clap;
544 /// # use clap::{Command, error::ErrorKind};
545 /// let mut cmd = Command::new("myprog");
546 /// let err = cmd.error(ErrorKind::InvalidValue, "Some failure case");
547 /// ```
548 pub fn error(&mut self, kind: ErrorKind, message: impl std::fmt::Display) -> Error {
549 Error::raw(kind, message).format(self)
550 }
551
552 /// Parse [`env::args_os`], exiting on failure.
553 ///
554 /// # Panics
555 ///
556 /// If contradictory arguments or settings exist (debug builds).
557 ///
558 /// # Examples
559 ///
560 /// ```no_run
561 /// # use clap_builder as clap;
562 /// # use clap::{Command, Arg};
563 /// let matches = Command::new("myprog")
564 /// // Args and options go here...
565 /// .get_matches();
566 /// ```
567 /// [`env::args_os`]: std::env::args_os()
568 /// [`Command::try_get_matches_from_mut`]: Command::try_get_matches_from_mut()
569 #[inline]
570 pub fn get_matches(self) -> ArgMatches {
571 self.get_matches_from(env::args_os())
572 }
573
574 /// Parse [`env::args_os`], exiting on failure.
575 ///
576 /// Like [`Command::get_matches`] but doesn't consume the `Command`.
577 ///
578 /// # Panics
579 ///
580 /// If contradictory arguments or settings exist (debug builds).
581 ///
582 /// # Examples
583 ///
584 /// ```no_run
585 /// # use clap_builder as clap;
586 /// # use clap::{Command, Arg};
587 /// let mut cmd = Command::new("myprog")
588 /// // Args and options go here...
589 /// ;
590 /// let matches = cmd.get_matches_mut();
591 /// ```
592 /// [`env::args_os`]: std::env::args_os()
593 /// [`Command::get_matches`]: Command::get_matches()
594 pub fn get_matches_mut(&mut self) -> ArgMatches {
595 self.try_get_matches_from_mut(&mut env::args_os())
596 .unwrap_or_else(|e| e.exit())
597 }
598
599 /// Parse [`env::args_os`], returning a [`clap::Result`] on failure.
600 ///
601 /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are
602 /// used. It will return a [`clap::Error`], where the [`kind`] is a
603 /// [`ErrorKind::DisplayHelp`] or [`ErrorKind::DisplayVersion`] respectively. You must call
604 /// [`Error::exit`] or perform a [`std::process::exit`].
605 ///
606 /// # Panics
607 ///
608 /// If contradictory arguments or settings exist (debug builds).
609 ///
610 /// # Examples
611 ///
612 /// ```no_run
613 /// # use clap_builder as clap;
614 /// # use clap::{Command, Arg};
615 /// let matches = Command::new("myprog")
616 /// // Args and options go here...
617 /// .try_get_matches()
618 /// .unwrap_or_else(|e| e.exit());
619 /// ```
620 /// [`env::args_os`]: std::env::args_os()
621 /// [`Error::exit`]: crate::Error::exit()
622 /// [`std::process::exit`]: std::process::exit()
623 /// [`clap::Result`]: Result
624 /// [`clap::Error`]: crate::Error
625 /// [`kind`]: crate::Error
626 /// [`ErrorKind::DisplayHelp`]: crate::error::ErrorKind::DisplayHelp
627 /// [`ErrorKind::DisplayVersion`]: crate::error::ErrorKind::DisplayVersion
628 #[inline]
629 pub fn try_get_matches(self) -> ClapResult<ArgMatches> {
630 // Start the parsing
631 self.try_get_matches_from(env::args_os())
632 }
633
634 /// Parse the specified arguments, exiting on failure.
635 ///
636 /// **NOTE:** The first argument will be parsed as the binary name unless
637 /// [`Command::no_binary_name`] is used.
638 ///
639 /// # Panics
640 ///
641 /// If contradictory arguments or settings exist (debug builds).
642 ///
643 /// # Examples
644 ///
645 /// ```no_run
646 /// # use clap_builder as clap;
647 /// # use clap::{Command, Arg};
648 /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"];
649 ///
650 /// let matches = Command::new("myprog")
651 /// // Args and options go here...
652 /// .get_matches_from(arg_vec);
653 /// ```
654 /// [`Command::get_matches`]: Command::get_matches()
655 /// [`clap::Result`]: Result
656 /// [`Vec`]: std::vec::Vec
657 pub fn get_matches_from<I, T>(mut self, itr: I) -> ArgMatches
658 where
659 I: IntoIterator<Item = T>,
660 T: Into<OsString> + Clone,
661 {
662 self.try_get_matches_from_mut(itr).unwrap_or_else(|e| {
663 drop(self);
664 e.exit()
665 })
666 }
667
668 /// Parse the specified arguments, returning a [`clap::Result`] on failure.
669 ///
670 /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are
671 /// used. It will return a [`clap::Error`], where the [`kind`] is a [`ErrorKind::DisplayHelp`]
672 /// or [`ErrorKind::DisplayVersion`] respectively. You must call [`Error::exit`] or
673 /// perform a [`std::process::exit`] yourself.
674 ///
675 /// **NOTE:** The first argument will be parsed as the binary name unless
676 /// [`Command::no_binary_name`] is used.
677 ///
678 /// # Panics
679 ///
680 /// If contradictory arguments or settings exist (debug builds).
681 ///
682 /// # Examples
683 ///
684 /// ```no_run
685 /// # use clap_builder as clap;
686 /// # use clap::{Command, Arg};
687 /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"];
688 ///
689 /// let matches = Command::new("myprog")
690 /// // Args and options go here...
691 /// .try_get_matches_from(arg_vec)
692 /// .unwrap_or_else(|e| e.exit());
693 /// ```
694 /// [`Command::get_matches_from`]: Command::get_matches_from()
695 /// [`Command::try_get_matches`]: Command::try_get_matches()
696 /// [`Error::exit`]: crate::Error::exit()
697 /// [`std::process::exit`]: std::process::exit()
698 /// [`clap::Error`]: crate::Error
699 /// [`Error::exit`]: crate::Error::exit()
700 /// [`kind`]: crate::Error
701 /// [`ErrorKind::DisplayHelp`]: crate::error::ErrorKind::DisplayHelp
702 /// [`ErrorKind::DisplayVersion`]: crate::error::ErrorKind::DisplayVersion
703 /// [`clap::Result`]: Result
704 pub fn try_get_matches_from<I, T>(mut self, itr: I) -> ClapResult<ArgMatches>
705 where
706 I: IntoIterator<Item = T>,
707 T: Into<OsString> + Clone,
708 {
709 self.try_get_matches_from_mut(itr)
710 }
711
712 /// Parse the specified arguments, returning a [`clap::Result`] on failure.
713 ///
714 /// Like [`Command::try_get_matches_from`] but doesn't consume the `Command`.
715 ///
716 /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are
717 /// used. It will return a [`clap::Error`], where the [`kind`] is a [`ErrorKind::DisplayHelp`]
718 /// or [`ErrorKind::DisplayVersion`] respectively. You must call [`Error::exit`] or
719 /// perform a [`std::process::exit`] yourself.
720 ///
721 /// **NOTE:** The first argument will be parsed as the binary name unless
722 /// [`Command::no_binary_name`] is used.
723 ///
724 /// # Panics
725 ///
726 /// If contradictory arguments or settings exist (debug builds).
727 ///
728 /// # Examples
729 ///
730 /// ```no_run
731 /// # use clap_builder as clap;
732 /// # use clap::{Command, Arg};
733 /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"];
734 ///
735 /// let mut cmd = Command::new("myprog");
736 /// // Args and options go here...
737 /// let matches = cmd.try_get_matches_from_mut(arg_vec)
738 /// .unwrap_or_else(|e| e.exit());
739 /// ```
740 /// [`Command::try_get_matches_from`]: Command::try_get_matches_from()
741 /// [`clap::Result`]: Result
742 /// [`clap::Error`]: crate::Error
743 /// [`kind`]: crate::Error
744 pub fn try_get_matches_from_mut<I, T>(&mut self, itr: I) -> ClapResult<ArgMatches>
745 where
746 I: IntoIterator<Item = T>,
747 T: Into<OsString> + Clone,
748 {
749 let mut raw_args = clap_lex::RawArgs::new(itr);
750 let mut cursor = raw_args.cursor();
751
752 if self.settings.is_set(AppSettings::Multicall) {
753 if let Some(argv0) = raw_args.next_os(&mut cursor) {
754 let argv0 = Path::new(&argv0);
755 if let Some(command) = argv0.file_stem().and_then(|f| f.to_str()) {
756 // Stop borrowing command so we can get another mut ref to it.
757 let command = command.to_owned();
758 debug!("Command::try_get_matches_from_mut: Parsed command {command} from argv");
759
760 debug!("Command::try_get_matches_from_mut: Reinserting command into arguments so subcommand parser matches it");
761 raw_args.insert(&cursor, [&command]);
762 debug!("Command::try_get_matches_from_mut: Clearing name and bin_name so that displayed command name starts with applet name");
763 self.name = "".into();
764 self.bin_name = None;
765 return self._do_parse(&mut raw_args, cursor);
766 }
767 }
768 };
769
770 // Get the name of the program (argument 1 of env::args()) and determine the
771 // actual file
772 // that was used to execute the program. This is because a program called
773 // ./target/release/my_prog -a
774 // will have two arguments, './target/release/my_prog', '-a' but we don't want
775 // to display
776 // the full path when displaying help messages and such
777 if !self.settings.is_set(AppSettings::NoBinaryName) {
778 if let Some(name) = raw_args.next_os(&mut cursor) {
779 let p = Path::new(name);
780
781 if let Some(f) = p.file_name() {
782 if let Some(s) = f.to_str() {
783 if self.bin_name.is_none() {
784 self.bin_name = Some(s.to_owned());
785 }
786 }
787 }
788 }
789 }
790
791 self._do_parse(&mut raw_args, cursor)
792 }
793
794 /// Prints the short help message (`-h`) to [`io::stdout()`].
795 ///
796 /// See also [`Command::print_long_help`].
797 ///
798 /// # Examples
799 ///
800 /// ```rust
801 /// # use clap_builder as clap;
802 /// # use clap::Command;
803 /// let mut cmd = Command::new("myprog");
804 /// cmd.print_help();
805 /// ```
806 /// [`io::stdout()`]: std::io::stdout()
807 pub fn print_help(&mut self) -> io::Result<()> {
808 self._build_self(false);
809 let color = self.color_help();
810
811 let mut styled = StyledStr::new();
812 let usage = Usage::new(self);
813 write_help(&mut styled, self, &usage, false);
814
815 let c = Colorizer::new(Stream::Stdout, color).with_content(styled);
816 c.print()
817 }
818
819 /// Prints the long help message (`--help`) to [`io::stdout()`].
820 ///
821 /// See also [`Command::print_help`].
822 ///
823 /// # Examples
824 ///
825 /// ```rust
826 /// # use clap_builder as clap;
827 /// # use clap::Command;
828 /// let mut cmd = Command::new("myprog");
829 /// cmd.print_long_help();
830 /// ```
831 /// [`io::stdout()`]: std::io::stdout()
832 /// [`BufWriter`]: std::io::BufWriter
833 /// [`-h` (short)]: Arg::help()
834 /// [`--help` (long)]: Arg::long_help()
835 pub fn print_long_help(&mut self) -> io::Result<()> {
836 self._build_self(false);
837 let color = self.color_help();
838
839 let mut styled = StyledStr::new();
840 let usage = Usage::new(self);
841 write_help(&mut styled, self, &usage, true);
842
843 let c = Colorizer::new(Stream::Stdout, color).with_content(styled);
844 c.print()
845 }
846
847 /// Render the short help message (`-h`) to a [`StyledStr`]
848 ///
849 /// See also [`Command::render_long_help`].
850 ///
851 /// # Examples
852 ///
853 /// ```rust
854 /// # use clap_builder as clap;
855 /// # use clap::Command;
856 /// use std::io;
857 /// let mut cmd = Command::new("myprog");
858 /// let mut out = io::stdout();
859 /// let help = cmd.render_help();
860 /// println!("{help}");
861 /// ```
862 /// [`io::Write`]: std::io::Write
863 /// [`-h` (short)]: Arg::help()
864 /// [`--help` (long)]: Arg::long_help()
865 pub fn render_help(&mut self) -> StyledStr {
866 self._build_self(false);
867
868 let mut styled = StyledStr::new();
869 let usage = Usage::new(self);
870 write_help(&mut styled, self, &usage, false);
871 styled
872 }
873
874 /// Render the long help message (`--help`) to a [`StyledStr`].
875 ///
876 /// See also [`Command::render_help`].
877 ///
878 /// # Examples
879 ///
880 /// ```rust
881 /// # use clap_builder as clap;
882 /// # use clap::Command;
883 /// use std::io;
884 /// let mut cmd = Command::new("myprog");
885 /// let mut out = io::stdout();
886 /// let help = cmd.render_long_help();
887 /// println!("{help}");
888 /// ```
889 /// [`io::Write`]: std::io::Write
890 /// [`-h` (short)]: Arg::help()
891 /// [`--help` (long)]: Arg::long_help()
892 pub fn render_long_help(&mut self) -> StyledStr {
893 self._build_self(false);
894
895 let mut styled = StyledStr::new();
896 let usage = Usage::new(self);
897 write_help(&mut styled, self, &usage, true);
898 styled
899 }
900
901 #[doc(hidden)]
902 #[cfg_attr(
903 feature = "deprecated",
904 deprecated(since = "4.0.0", note = "Replaced with `Command::render_help`")
905 )]
906 pub fn write_help<W: io::Write>(&mut self, w: &mut W) -> io::Result<()> {
907 self._build_self(false);
908
909 let mut styled = StyledStr::new();
910 let usage = Usage::new(self);
911 write_help(&mut styled, self, &usage, false);
912 ok!(write!(w, "{styled}"));
913 w.flush()
914 }
915
916 #[doc(hidden)]
917 #[cfg_attr(
918 feature = "deprecated",
919 deprecated(since = "4.0.0", note = "Replaced with `Command::render_long_help`")
920 )]
921 pub fn write_long_help<W: io::Write>(&mut self, w: &mut W) -> io::Result<()> {
922 self._build_self(false);
923
924 let mut styled = StyledStr::new();
925 let usage = Usage::new(self);
926 write_help(&mut styled, self, &usage, true);
927 ok!(write!(w, "{styled}"));
928 w.flush()
929 }
930
931 /// Version message rendered as if the user ran `-V`.
932 ///
933 /// See also [`Command::render_long_version`].
934 ///
935 /// ### Coloring
936 ///
937 /// This function does not try to color the message nor it inserts any [ANSI escape codes].
938 ///
939 /// ### Examples
940 ///
941 /// ```rust
942 /// # use clap_builder as clap;
943 /// # use clap::Command;
944 /// use std::io;
945 /// let cmd = Command::new("myprog");
946 /// println!("{}", cmd.render_version());
947 /// ```
948 /// [`io::Write`]: std::io::Write
949 /// [`-V` (short)]: Command::version()
950 /// [`--version` (long)]: Command::long_version()
951 /// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code
952 pub fn render_version(&self) -> String {
953 self._render_version(false)
954 }
955
956 /// Version message rendered as if the user ran `--version`.
957 ///
958 /// See also [`Command::render_version`].
959 ///
960 /// ### Coloring
961 ///
962 /// This function does not try to color the message nor it inserts any [ANSI escape codes].
963 ///
964 /// ### Examples
965 ///
966 /// ```rust
967 /// # use clap_builder as clap;
968 /// # use clap::Command;
969 /// use std::io;
970 /// let cmd = Command::new("myprog");
971 /// println!("{}", cmd.render_long_version());
972 /// ```
973 /// [`io::Write`]: std::io::Write
974 /// [`-V` (short)]: Command::version()
975 /// [`--version` (long)]: Command::long_version()
976 /// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code
977 pub fn render_long_version(&self) -> String {
978 self._render_version(true)
979 }
980
981 /// Usage statement
982 ///
983 /// ### Examples
984 ///
985 /// ```rust
986 /// # use clap_builder as clap;
987 /// # use clap::Command;
988 /// use std::io;
989 /// let mut cmd = Command::new("myprog");
990 /// println!("{}", cmd.render_usage());
991 /// ```
992 pub fn render_usage(&mut self) -> StyledStr {
993 self.render_usage_().unwrap_or_default()
994 }
995
996 pub(crate) fn render_usage_(&mut self) -> Option<StyledStr> {
997 // If there are global arguments, or settings we need to propagate them down to subcommands
998 // before parsing incase we run into a subcommand
999 self._build_self(false);
1000
1001 Usage::new(self).create_usage_with_title(&[])
1002 }
1003 }
1004
1005 /// # Application-wide Settings
1006 ///
1007 /// These settings will apply to the top-level command and all subcommands, by default. Some
1008 /// settings can be overridden in subcommands.
1009 impl Command {
1010 /// Specifies that the parser should not assume the first argument passed is the binary name.
1011 ///
1012 /// This is normally the case when using a "daemon" style mode. For shells / REPLs, see
1013 /// [`Command::multicall`][Command::multicall].
1014 ///
1015 /// # Examples
1016 ///
1017 /// ```rust
1018 /// # use clap_builder as clap;
1019 /// # use clap::{Command, arg};
1020 /// let m = Command::new("myprog")
1021 /// .no_binary_name(true)
1022 /// .arg(arg!(<cmd> ... "commands to run"))
1023 /// .get_matches_from(vec!["command", "set"]);
1024 ///
1025 /// let cmds: Vec<_> = m.get_many::<String>("cmd").unwrap().collect();
1026 /// assert_eq!(cmds, ["command", "set"]);
1027 /// ```
1028 /// [`try_get_matches_from_mut`]: crate::Command::try_get_matches_from_mut()
1029 #[inline]
1030 pub fn no_binary_name(self, yes: bool) -> Self {
1031 if yes {
1032 self.global_setting(AppSettings::NoBinaryName)
1033 } else {
1034 self.unset_global_setting(AppSettings::NoBinaryName)
1035 }
1036 }
1037
1038 /// Try not to fail on parse errors, like missing option values.
1039 ///
1040 /// **NOTE:** This choice is propagated to all child subcommands.
1041 ///
1042 /// # Examples
1043 ///
1044 /// ```rust
1045 /// # use clap_builder as clap;
1046 /// # use clap::{Command, arg};
1047 /// let cmd = Command::new("cmd")
1048 /// .ignore_errors(true)
1049 /// .arg(arg!(-c --config <FILE> "Sets a custom config file"))
1050 /// .arg(arg!(-x --stuff <FILE> "Sets a custom stuff file"))
1051 /// .arg(arg!(f: -f "Flag"));
1052 ///
1053 /// let r = cmd.try_get_matches_from(vec!["cmd", "-c", "file", "-f", "-x"]);
1054 ///
1055 /// assert!(r.is_ok(), "unexpected error: {r:?}");
1056 /// let m = r.unwrap();
1057 /// assert_eq!(m.get_one::<String>("config").unwrap(), "file");
1058 /// assert!(m.get_flag("f"));
1059 /// assert_eq!(m.get_one::<String>("stuff"), None);
1060 /// ```
1061 #[inline]
1062 pub fn ignore_errors(self, yes: bool) -> Self {
1063 if yes {
1064 self.global_setting(AppSettings::IgnoreErrors)
1065 } else {
1066 self.unset_global_setting(AppSettings::IgnoreErrors)
1067 }
1068 }
1069
1070 /// Replace prior occurrences of arguments rather than error
1071 ///
1072 /// For any argument that would conflict with itself by default (e.g.
1073 /// [`ArgAction::Set`][ArgAction::Set], it will now override itself.
1074 ///
1075 /// This is the equivalent to saying the `foo` arg using [`Arg::overrides_with("foo")`] for all
1076 /// defined arguments.
1077 ///
1078 /// **NOTE:** This choice is propagated to all child subcommands.
1079 ///
1080 /// [`Arg::overrides_with("foo")`]: crate::Arg::overrides_with()
1081 #[inline]
1082 pub fn args_override_self(self, yes: bool) -> Self {
1083 if yes {
1084 self.global_setting(AppSettings::AllArgsOverrideSelf)
1085 } else {
1086 self.unset_global_setting(AppSettings::AllArgsOverrideSelf)
1087 }
1088 }
1089
1090 /// Disables the automatic delimiting of values after `--` or when [`Command::trailing_var_arg`]
1091 /// was used.
1092 ///
1093 /// **NOTE:** The same thing can be done manually by setting the final positional argument to
1094 /// [`Arg::value_delimiter(None)`]. Using this setting is safer, because it's easier to locate
1095 /// when making changes.
1096 ///
1097 /// **NOTE:** This choice is propagated to all child subcommands.
1098 ///
1099 /// # Examples
1100 ///
1101 /// ```no_run
1102 /// # use clap_builder as clap;
1103 /// # use clap::{Command, Arg};
1104 /// Command::new("myprog")
1105 /// .dont_delimit_trailing_values(true)
1106 /// .get_matches();
1107 /// ```
1108 ///
1109 /// [`Arg::value_delimiter(None)`]: crate::Arg::value_delimiter()
1110 #[inline]
1111 pub fn dont_delimit_trailing_values(self, yes: bool) -> Self {
1112 if yes {
1113 self.global_setting(AppSettings::DontDelimitTrailingValues)
1114 } else {
1115 self.unset_global_setting(AppSettings::DontDelimitTrailingValues)
1116 }
1117 }
1118
1119 /// Sets when to color output.
1120 ///
1121 /// **NOTE:** This choice is propagated to all child subcommands.
1122 ///
1123 /// **NOTE:** Default behaviour is [`ColorChoice::Auto`].
1124 ///
1125 /// # Examples
1126 ///
1127 /// ```no_run
1128 /// # use clap_builder as clap;
1129 /// # use clap::{Command, ColorChoice};
1130 /// Command::new("myprog")
1131 /// .color(ColorChoice::Never)
1132 /// .get_matches();
1133 /// ```
1134 /// [`ColorChoice::Auto`]: crate::ColorChoice::Auto
1135 #[cfg(feature = "color")]
1136 #[inline]
1137 #[must_use]
1138 pub fn color(self, color: ColorChoice) -> Self {
1139 let cmd = self
1140 .unset_global_setting(AppSettings::ColorAuto)
1141 .unset_global_setting(AppSettings::ColorAlways)
1142 .unset_global_setting(AppSettings::ColorNever);
1143 match color {
1144 ColorChoice::Auto => cmd.global_setting(AppSettings::ColorAuto),
1145 ColorChoice::Always => cmd.global_setting(AppSettings::ColorAlways),
1146 ColorChoice::Never => cmd.global_setting(AppSettings::ColorNever),
1147 }
1148 }
1149
1150 /// Sets the [`Styles`] for terminal output
1151 ///
1152 /// **NOTE:** This choice is propagated to all child subcommands.
1153 ///
1154 /// **NOTE:** Default behaviour is [`Styles::default`].
1155 ///
1156 /// # Examples
1157 ///
1158 /// ```no_run
1159 /// # use clap_builder as clap;
1160 /// # use clap::{Command, ColorChoice, builder::styling};
1161 /// let styles = styling::Styles::styled()
1162 /// .header(styling::AnsiColor::Green.on_default() | styling::Effects::BOLD)
1163 /// .usage(styling::AnsiColor::Green.on_default() | styling::Effects::BOLD)
1164 /// .literal(styling::AnsiColor::Blue.on_default() | styling::Effects::BOLD)
1165 /// .placeholder(styling::AnsiColor::Cyan.on_default());
1166 /// Command::new("myprog")
1167 /// .styles(styles)
1168 /// .get_matches();
1169 /// ```
1170 #[cfg(feature = "color")]
1171 #[inline]
1172 #[must_use]
1173 pub fn styles(mut self, styles: Styles) -> Self {
1174 self.app_ext.set(styles);
1175 self
1176 }
1177
1178 /// Sets the terminal width at which to wrap help messages.
1179 ///
1180 /// Using `0` will ignore terminal widths and use source formatting.
1181 ///
1182 /// Defaults to current terminal width when `wrap_help` feature flag is enabled. If current
1183 /// width cannot be determined, the default is 100.
1184 ///
1185 /// **`unstable-v5` feature**: Defaults to unbound, being subject to
1186 /// [`Command::max_term_width`].
1187 ///
1188 /// **NOTE:** This setting applies globally and *not* on a per-command basis.
1189 ///
1190 /// **NOTE:** This requires the `wrap_help` feature
1191 ///
1192 /// # Examples
1193 ///
1194 /// ```rust
1195 /// # use clap_builder as clap;
1196 /// # use clap::Command;
1197 /// Command::new("myprog")
1198 /// .term_width(80)
1199 /// # ;
1200 /// ```
1201 #[inline]
1202 #[must_use]
1203 #[cfg(any(not(feature = "unstable-v5"), feature = "wrap_help"))]
1204 pub fn term_width(mut self, width: usize) -> Self {
1205 self.app_ext.set(TermWidth(width));
1206 self
1207 }
1208
1209 /// Limit the line length for wrapping help when using the current terminal's width.
1210 ///
1211 /// This only applies when [`term_width`][Command::term_width] is unset so that the current
1212 /// terminal's width will be used. See [`Command::term_width`] for more details.
1213 ///
1214 /// Using `0` will ignore this, always respecting [`Command::term_width`] (default).
1215 ///
1216 /// **`unstable-v5` feature**: Defaults to 100.
1217 ///
1218 /// **NOTE:** This setting applies globally and *not* on a per-command basis.
1219 ///
1220 /// **NOTE:** This requires the `wrap_help` feature
1221 ///
1222 /// # Examples
1223 ///
1224 /// ```rust
1225 /// # use clap_builder as clap;
1226 /// # use clap::Command;
1227 /// Command::new("myprog")
1228 /// .max_term_width(100)
1229 /// # ;
1230 /// ```
1231 #[inline]
1232 #[must_use]
1233 #[cfg(any(not(feature = "unstable-v5"), feature = "wrap_help"))]
1234 pub fn max_term_width(mut self, width: usize) -> Self {
1235 self.app_ext.set(MaxTermWidth(width));
1236 self
1237 }
1238
1239 /// Disables `-V` and `--version` flag.
1240 ///
1241 /// # Examples
1242 ///
1243 /// ```rust
1244 /// # use clap_builder as clap;
1245 /// # use clap::{Command, error::ErrorKind};
1246 /// let res = Command::new("myprog")
1247 /// .version("1.0.0")
1248 /// .disable_version_flag(true)
1249 /// .try_get_matches_from(vec![
1250 /// "myprog", "--version"
1251 /// ]);
1252 /// assert!(res.is_err());
1253 /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
1254 /// ```
1255 ///
1256 /// You can create a custom version flag with [`ArgAction::Version`]
1257 /// ```rust
1258 /// # use clap_builder as clap;
1259 /// # use clap::{Command, Arg, ArgAction, error::ErrorKind};
1260 /// let mut cmd = Command::new("myprog")
1261 /// .version("1.0.0")
1262 /// // Remove the `-V` short flag
1263 /// .disable_version_flag(true)
1264 /// .arg(
1265 /// Arg::new("version")
1266 /// .long("version")
1267 /// .action(ArgAction::Version)
1268 /// .help("Print version")
1269 /// );
1270 ///
1271 /// let res = cmd.try_get_matches_from_mut(vec![
1272 /// "myprog", "-V"
1273 /// ]);
1274 /// assert!(res.is_err());
1275 /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
1276 ///
1277 /// let res = cmd.try_get_matches_from_mut(vec![
1278 /// "myprog", "--version"
1279 /// ]);
1280 /// assert!(res.is_err());
1281 /// assert_eq!(res.unwrap_err().kind(), ErrorKind::DisplayVersion);
1282 /// ```
1283 #[inline]
1284 pub fn disable_version_flag(self, yes: bool) -> Self {
1285 if yes {
1286 self.global_setting(AppSettings::DisableVersionFlag)
1287 } else {
1288 self.unset_global_setting(AppSettings::DisableVersionFlag)
1289 }
1290 }
1291
1292 /// Specifies to use the version of the current command for all [`subcommands`].
1293 ///
1294 /// Defaults to `false`; subcommands have independent version strings from their parents.
1295 ///
1296 /// **NOTE:** This choice is propagated to all child subcommands.
1297 ///
1298 /// # Examples
1299 ///
1300 /// ```no_run
1301 /// # use clap_builder as clap;
1302 /// # use clap::{Command, Arg};
1303 /// Command::new("myprog")
1304 /// .version("v1.1")
1305 /// .propagate_version(true)
1306 /// .subcommand(Command::new("test"))
1307 /// .get_matches();
1308 /// // running `$ myprog test --version` will display
1309 /// // "myprog-test v1.1"
1310 /// ```
1311 ///
1312 /// [`subcommands`]: crate::Command::subcommand()
1313 #[inline]
1314 pub fn propagate_version(self, yes: bool) -> Self {
1315 if yes {
1316 self.global_setting(AppSettings::PropagateVersion)
1317 } else {
1318 self.unset_global_setting(AppSettings::PropagateVersion)
1319 }
1320 }
1321
1322 /// Places the help string for all arguments and subcommands on the line after them.
1323 ///
1324 /// **NOTE:** This choice is propagated to all child subcommands.
1325 ///
1326 /// # Examples
1327 ///
1328 /// ```no_run
1329 /// # use clap_builder as clap;
1330 /// # use clap::{Command, Arg};
1331 /// Command::new("myprog")
1332 /// .next_line_help(true)
1333 /// .get_matches();
1334 /// ```
1335 #[inline]
1336 pub fn next_line_help(self, yes: bool) -> Self {
1337 if yes {
1338 self.global_setting(AppSettings::NextLineHelp)
1339 } else {
1340 self.unset_global_setting(AppSettings::NextLineHelp)
1341 }
1342 }
1343
1344 /// Disables `-h` and `--help` flag.
1345 ///
1346 /// **NOTE:** This choice is propagated to all child subcommands.
1347 ///
1348 /// # Examples
1349 ///
1350 /// ```rust
1351 /// # use clap_builder as clap;
1352 /// # use clap::{Command, error::ErrorKind};
1353 /// let res = Command::new("myprog")
1354 /// .disable_help_flag(true)
1355 /// .try_get_matches_from(vec![
1356 /// "myprog", "-h"
1357 /// ]);
1358 /// assert!(res.is_err());
1359 /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
1360 /// ```
1361 ///
1362 /// You can create a custom version flag with [`ArgAction::Help`], [`ArgAction::HelpShort`], or
1363 /// [`ArgAction::HelpLong`]
1364 /// ```rust
1365 /// # use clap_builder as clap;
1366 /// # use clap::{Command, Arg, ArgAction, error::ErrorKind};
1367 /// let mut cmd = Command::new("myprog")
1368 /// // Change help short flag to `?`
1369 /// .disable_help_flag(true)
1370 /// .arg(
1371 /// Arg::new("help")
1372 /// .short('?')
1373 /// .long("help")
1374 /// .action(ArgAction::Help)
1375 /// .help("Print help")
1376 /// );
1377 ///
1378 /// let res = cmd.try_get_matches_from_mut(vec![
1379 /// "myprog", "-h"
1380 /// ]);
1381 /// assert!(res.is_err());
1382 /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
1383 ///
1384 /// let res = cmd.try_get_matches_from_mut(vec![
1385 /// "myprog", "-?"
1386 /// ]);
1387 /// assert!(res.is_err());
1388 /// assert_eq!(res.unwrap_err().kind(), ErrorKind::DisplayHelp);
1389 /// ```
1390 #[inline]
1391 pub fn disable_help_flag(self, yes: bool) -> Self {
1392 if yes {
1393 self.global_setting(AppSettings::DisableHelpFlag)
1394 } else {
1395 self.unset_global_setting(AppSettings::DisableHelpFlag)
1396 }
1397 }
1398
1399 /// Disables the `help` [`subcommand`].
1400 ///
1401 /// **NOTE:** This choice is propagated to all child subcommands.
1402 ///
1403 /// # Examples
1404 ///
1405 /// ```rust
1406 /// # use clap_builder as clap;
1407 /// # use clap::{Command, error::ErrorKind};
1408 /// let res = Command::new("myprog")
1409 /// .disable_help_subcommand(true)
1410 /// // Normally, creating a subcommand causes a `help` subcommand to automatically
1411 /// // be generated as well
1412 /// .subcommand(Command::new("test"))
1413 /// .try_get_matches_from(vec![
1414 /// "myprog", "help"
1415 /// ]);
1416 /// assert!(res.is_err());
1417 /// assert_eq!(res.unwrap_err().kind(), ErrorKind::InvalidSubcommand);
1418 /// ```
1419 ///
1420 /// [`subcommand`]: crate::Command::subcommand()
1421 #[inline]
1422 pub fn disable_help_subcommand(self, yes: bool) -> Self {
1423 if yes {
1424 self.global_setting(AppSettings::DisableHelpSubcommand)
1425 } else {
1426 self.unset_global_setting(AppSettings::DisableHelpSubcommand)
1427 }
1428 }
1429
1430 /// Disables colorized help messages.
1431 ///
1432 /// **NOTE:** This choice is propagated to all child subcommands.
1433 ///
1434 /// # Examples
1435 ///
1436 /// ```no_run
1437 /// # use clap_builder as clap;
1438 /// # use clap::Command;
1439 /// Command::new("myprog")
1440 /// .disable_colored_help(true)
1441 /// .get_matches();
1442 /// ```
1443 #[inline]
1444 pub fn disable_colored_help(self, yes: bool) -> Self {
1445 if yes {
1446 self.global_setting(AppSettings::DisableColoredHelp)
1447 } else {
1448 self.unset_global_setting(AppSettings::DisableColoredHelp)
1449 }
1450 }
1451
1452 /// Panic if help descriptions are omitted.
1453 ///
1454 /// **NOTE:** When deriving [`Parser`][crate::Parser], you could instead check this at
1455 /// compile-time with `#![deny(missing_docs)]`
1456 ///
1457 /// **NOTE:** This choice is propagated to all child subcommands.
1458 ///
1459 /// # Examples
1460 ///
1461 /// ```rust
1462 /// # use clap_builder as clap;
1463 /// # use clap::{Command, Arg};
1464 /// Command::new("myprog")
1465 /// .help_expected(true)
1466 /// .arg(
1467 /// Arg::new("foo").help("It does foo stuff")
1468 /// // As required via `help_expected`, a help message was supplied
1469 /// )
1470 /// # .get_matches();
1471 /// ```
1472 ///
1473 /// # Panics
1474 ///
1475 /// On debug builds:
1476 /// ```rust,no_run
1477 /// # use clap_builder as clap;
1478 /// # use clap::{Command, Arg};
1479 /// Command::new("myapp")
1480 /// .help_expected(true)
1481 /// .arg(
1482 /// Arg::new("foo")
1483 /// // Someone forgot to put .about("...") here
1484 /// // Since the setting `help_expected` is activated, this will lead to
1485 /// // a panic (if you are in debug mode)
1486 /// )
1487 /// # .get_matches();
1488 ///```
1489 #[inline]
1490 pub fn help_expected(self, yes: bool) -> Self {
1491 if yes {
1492 self.global_setting(AppSettings::HelpExpected)
1493 } else {
1494 self.unset_global_setting(AppSettings::HelpExpected)
1495 }
1496 }
1497
1498 #[doc(hidden)]
1499 #[cfg_attr(
1500 feature = "deprecated",
1501 deprecated(since = "4.0.0", note = "This is now the default")
1502 )]
1503 pub fn dont_collapse_args_in_usage(self, _yes: bool) -> Self {
1504 self
1505 }
1506
1507 /// Tells `clap` *not* to print possible values when displaying help information.
1508 ///
1509 /// This can be useful if there are many values, or they are explained elsewhere.
1510 ///
1511 /// To set this per argument, see
1512 /// [`Arg::hide_possible_values`][crate::Arg::hide_possible_values].
1513 ///
1514 /// **NOTE:** This choice is propagated to all child subcommands.
1515 #[inline]
1516 pub fn hide_possible_values(self, yes: bool) -> Self {
1517 if yes {
1518 self.global_setting(AppSettings::HidePossibleValues)
1519 } else {
1520 self.unset_global_setting(AppSettings::HidePossibleValues)
1521 }
1522 }
1523
1524 /// Allow partial matches of long arguments or their [aliases].
1525 ///
1526 /// For example, to match an argument named `--test`, one could use `--t`, `--te`, `--tes`, and
1527 /// `--test`.
1528 ///
1529 /// **NOTE:** The match *must not* be ambiguous at all in order to succeed. i.e. to match
1530 /// `--te` to `--test` there could not also be another argument or alias `--temp` because both
1531 /// start with `--te`
1532 ///
1533 /// **NOTE:** This choice is propagated to all child subcommands.
1534 ///
1535 /// [aliases]: crate::Command::aliases()
1536 #[inline]
1537 pub fn infer_long_args(self, yes: bool) -> Self {
1538 if yes {
1539 self.global_setting(AppSettings::InferLongArgs)
1540 } else {
1541 self.unset_global_setting(AppSettings::InferLongArgs)
1542 }
1543 }
1544
1545 /// Allow partial matches of [subcommand] names and their [aliases].
1546 ///
1547 /// For example, to match a subcommand named `test`, one could use `t`, `te`, `tes`, and
1548 /// `test`.
1549 ///
1550 /// **NOTE:** The match *must not* be ambiguous at all in order to succeed. i.e. to match `te`
1551 /// to `test` there could not also be a subcommand or alias `temp` because both start with `te`
1552 ///
1553 /// **CAUTION:** This setting can interfere with [positional/free arguments], take care when
1554 /// designing CLIs which allow inferred subcommands and have potential positional/free
1555 /// arguments whose values could start with the same characters as subcommands. If this is the
1556 /// case, it's recommended to use settings such as [`Command::args_conflicts_with_subcommands`] in
1557 /// conjunction with this setting.
1558 ///
1559 /// **NOTE:** This choice is propagated to all child subcommands.
1560 ///
1561 /// # Examples
1562 ///
1563 /// ```no_run
1564 /// # use clap_builder as clap;
1565 /// # use clap::{Command, Arg};
1566 /// let m = Command::new("prog")
1567 /// .infer_subcommands(true)
1568 /// .subcommand(Command::new("test"))
1569 /// .get_matches_from(vec![
1570 /// "prog", "te"
1571 /// ]);
1572 /// assert_eq!(m.subcommand_name(), Some("test"));
1573 /// ```
1574 ///
1575 /// [subcommand]: crate::Command::subcommand()
1576 /// [positional/free arguments]: crate::Arg::index()
1577 /// [aliases]: crate::Command::aliases()
1578 #[inline]
1579 pub fn infer_subcommands(self, yes: bool) -> Self {
1580 if yes {
1581 self.global_setting(AppSettings::InferSubcommands)
1582 } else {
1583 self.unset_global_setting(AppSettings::InferSubcommands)
1584 }
1585 }
1586 }
1587
1588 /// # Command-specific Settings
1589 ///
1590 /// These apply only to the current command and are not inherited by subcommands.
1591 impl Command {
1592 /// (Re)Sets the program's name.
1593 ///
1594 /// See [`Command::new`] for more details.
1595 ///
1596 /// # Examples
1597 ///
1598 /// ```ignore
1599 /// let cmd = clap::command!()
1600 /// .name("foo");
1601 ///
1602 /// // continued logic goes here, such as `cmd.get_matches()` etc.
1603 /// ```
1604 #[must_use]
1605 pub fn name(mut self, name: impl Into<Str>) -> Self {
1606 self.name = name.into();
1607 self
1608 }
1609
1610 /// Overrides the runtime-determined name of the binary for help and error messages.
1611 ///
1612 /// This should only be used when absolutely necessary, such as when the binary name for your
1613 /// application is misleading, or perhaps *not* how the user should invoke your program.
1614 ///
1615 /// **Pro-tip:** When building things such as third party `cargo`
1616 /// subcommands, this setting **should** be used!
1617 ///
1618 /// **NOTE:** This *does not* change or set the name of the binary file on
1619 /// disk. It only changes what clap thinks the name is for the purposes of
1620 /// error or help messages.
1621 ///
1622 /// # Examples
1623 ///
1624 /// ```rust
1625 /// # use clap_builder as clap;
1626 /// # use clap::Command;
1627 /// Command::new("My Program")
1628 /// .bin_name("my_binary")
1629 /// # ;
1630 /// ```
1631 #[must_use]
1632 pub fn bin_name(mut self, name: impl IntoResettable<String>) -> Self {
1633 self.bin_name = name.into_resettable().into_option();
1634 self
1635 }
1636
1637 /// Overrides the runtime-determined display name of the program for help and error messages.
1638 ///
1639 /// # Examples
1640 ///
1641 /// ```rust
1642 /// # use clap_builder as clap;
1643 /// # use clap::Command;
1644 /// Command::new("My Program")
1645 /// .display_name("my_program")
1646 /// # ;
1647 /// ```
1648 #[must_use]
1649 pub fn display_name(mut self, name: impl IntoResettable<String>) -> Self {
1650 self.display_name = name.into_resettable().into_option();
1651 self
1652 }
1653
1654 /// Sets the author(s) for the help message.
1655 ///
1656 /// **Pro-tip:** Use `clap`s convenience macro [`crate_authors!`] to
1657 /// automatically set your application's author(s) to the same thing as your
1658 /// crate at compile time.
1659 ///
1660 /// **NOTE:** A custom [`help_template`][Command::help_template] is needed for author to show
1661 /// up.
1662 ///
1663 /// # Examples
1664 ///
1665 /// ```rust
1666 /// # use clap_builder as clap;
1667 /// # use clap::Command;
1668 /// Command::new("myprog")
1669 /// .author("Me, me@mymain.com")
1670 /// # ;
1671 /// ```
1672 #[must_use]
1673 pub fn author(mut self, author: impl IntoResettable<Str>) -> Self {
1674 self.author = author.into_resettable().into_option();
1675 self
1676 }
1677
1678 /// Sets the program's description for the short help (`-h`).
1679 ///
1680 /// If [`Command::long_about`] is not specified, this message will be displayed for `--help`.
1681 ///
1682 /// **NOTE:** Only `Command::about` (short format) is used in completion
1683 /// script generation in order to be concise.
1684 ///
1685 /// See also [`crate_description!`](crate::crate_description!).
1686 ///
1687 /// # Examples
1688 ///
1689 /// ```rust
1690 /// # use clap_builder as clap;
1691 /// # use clap::Command;
1692 /// Command::new("myprog")
1693 /// .about("Does really amazing things for great people")
1694 /// # ;
1695 /// ```
1696 #[must_use]
1697 pub fn about(mut self, about: impl IntoResettable<StyledStr>) -> Self {
1698 self.about = about.into_resettable().into_option();
1699 self
1700 }
1701
1702 /// Sets the program's description for the long help (`--help`).
1703 ///
1704 /// If [`Command::about`] is not specified, this message will be displayed for `-h`.
1705 ///
1706 /// **NOTE:** Only [`Command::about`] (short format) is used in completion
1707 /// script generation in order to be concise.
1708 ///
1709 /// # Examples
1710 ///
1711 /// ```rust
1712 /// # use clap_builder as clap;
1713 /// # use clap::Command;
1714 /// Command::new("myprog")
1715 /// .long_about(
1716 /// "Does really amazing things to great people. Now let's talk a little
1717 /// more in depth about how this subcommand really works. It may take about
1718 /// a few lines of text, but that's ok!")
1719 /// # ;
1720 /// ```
1721 /// [`Command::about`]: Command::about()
1722 #[must_use]
1723 pub fn long_about(mut self, long_about: impl IntoResettable<StyledStr>) -> Self {
1724 self.long_about = long_about.into_resettable().into_option();
1725 self
1726 }
1727
1728 /// Free-form help text for after auto-generated short help (`-h`).
1729 ///
1730 /// This is often used to describe how to use the arguments, caveats to be noted, or license
1731 /// and contact information.
1732 ///
1733 /// If [`Command::after_long_help`] is not specified, this message will be displayed for `--help`.
1734 ///
1735 /// # Examples
1736 ///
1737 /// ```rust
1738 /// # use clap_builder as clap;
1739 /// # use clap::Command;
1740 /// Command::new("myprog")
1741 /// .after_help("Does really amazing things for great people... but be careful with -R!")
1742 /// # ;
1743 /// ```
1744 ///
1745 #[must_use]
1746 pub fn after_help(mut self, help: impl IntoResettable<StyledStr>) -> Self {
1747 self.after_help = help.into_resettable().into_option();
1748 self
1749 }
1750
1751 /// Free-form help text for after auto-generated long help (`--help`).
1752 ///
1753 /// This is often used to describe how to use the arguments, caveats to be noted, or license
1754 /// and contact information.
1755 ///
1756 /// If [`Command::after_help`] is not specified, this message will be displayed for `-h`.
1757 ///
1758 /// # Examples
1759 ///
1760 /// ```rust
1761 /// # use clap_builder as clap;
1762 /// # use clap::Command;
1763 /// Command::new("myprog")
1764 /// .after_long_help("Does really amazing things to great people... but be careful with -R, \
1765 /// like, for real, be careful with this!")
1766 /// # ;
1767 /// ```
1768 #[must_use]
1769 pub fn after_long_help(mut self, help: impl IntoResettable<StyledStr>) -> Self {
1770 self.after_long_help = help.into_resettable().into_option();
1771 self
1772 }
1773
1774 /// Free-form help text for before auto-generated short help (`-h`).
1775 ///
1776 /// This is often used for header, copyright, or license information.
1777 ///
1778 /// If [`Command::before_long_help`] is not specified, this message will be displayed for `--help`.
1779 ///
1780 /// # Examples
1781 ///
1782 /// ```rust
1783 /// # use clap_builder as clap;
1784 /// # use clap::Command;
1785 /// Command::new("myprog")
1786 /// .before_help("Some info I'd like to appear before the help info")
1787 /// # ;
1788 /// ```
1789 #[must_use]
1790 pub fn before_help(mut self, help: impl IntoResettable<StyledStr>) -> Self {
1791 self.before_help = help.into_resettable().into_option();
1792 self
1793 }
1794
1795 /// Free-form help text for before auto-generated long help (`--help`).
1796 ///
1797 /// This is often used for header, copyright, or license information.
1798 ///
1799 /// If [`Command::before_help`] is not specified, this message will be displayed for `-h`.
1800 ///
1801 /// # Examples
1802 ///
1803 /// ```rust
1804 /// # use clap_builder as clap;
1805 /// # use clap::Command;
1806 /// Command::new("myprog")
1807 /// .before_long_help("Some verbose and long info I'd like to appear before the help info")
1808 /// # ;
1809 /// ```
1810 #[must_use]
1811 pub fn before_long_help(mut self, help: impl IntoResettable<StyledStr>) -> Self {
1812 self.before_long_help = help.into_resettable().into_option();
1813 self
1814 }
1815
1816 /// Sets the version for the short version (`-V`) and help messages.
1817 ///
1818 /// If [`Command::long_version`] is not specified, this message will be displayed for `--version`.
1819 ///
1820 /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to
1821 /// automatically set your application's version to the same thing as your
1822 /// crate at compile time.
1823 ///
1824 /// # Examples
1825 ///
1826 /// ```rust
1827 /// # use clap_builder as clap;
1828 /// # use clap::Command;
1829 /// Command::new("myprog")
1830 /// .version("v0.1.24")
1831 /// # ;
1832 /// ```
1833 #[must_use]
1834 pub fn version(mut self, ver: impl IntoResettable<Str>) -> Self {
1835 self.version = ver.into_resettable().into_option();
1836 self
1837 }
1838
1839 /// Sets the version for the long version (`--version`) and help messages.
1840 ///
1841 /// If [`Command::version`] is not specified, this message will be displayed for `-V`.
1842 ///
1843 /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to
1844 /// automatically set your application's version to the same thing as your
1845 /// crate at compile time.
1846 ///
1847 /// # Examples
1848 ///
1849 /// ```rust
1850 /// # use clap_builder as clap;
1851 /// # use clap::Command;
1852 /// Command::new("myprog")
1853 /// .long_version(
1854 /// "v0.1.24
1855 /// commit: abcdef89726d
1856 /// revision: 123
1857 /// release: 2
1858 /// binary: myprog")
1859 /// # ;
1860 /// ```
1861 #[must_use]
1862 pub fn long_version(mut self, ver: impl IntoResettable<Str>) -> Self {
1863 self.long_version = ver.into_resettable().into_option();
1864 self
1865 }
1866
1867 /// Overrides the `clap` generated usage string for help and error messages.
1868 ///
1869 /// **NOTE:** Using this setting disables `clap`s "context-aware" usage
1870 /// strings. After this setting is set, this will be *the only* usage string
1871 /// displayed to the user!
1872 ///
1873 /// **NOTE:** Multiple usage lines may be present in the usage argument, but
1874 /// some rules need to be followed to ensure the usage lines are formatted
1875 /// correctly by the default help formatter:
1876 ///
1877 /// - Do not indent the first usage line.
1878 /// - Indent all subsequent usage lines with seven spaces.
1879 /// - The last line must not end with a newline.
1880 ///
1881 /// # Examples
1882 ///
1883 /// ```rust
1884 /// # use clap_builder as clap;
1885 /// # use clap::{Command, Arg};
1886 /// Command::new("myprog")
1887 /// .override_usage("myapp [-clDas] <some_file>")
1888 /// # ;
1889 /// ```
1890 ///
1891 /// Or for multiple usage lines:
1892 ///
1893 /// ```rust
1894 /// # use clap_builder as clap;
1895 /// # use clap::{Command, Arg};
1896 /// Command::new("myprog")
1897 /// .override_usage(
1898 /// "myapp -X [-a] [-b] <file>\n \
1899 /// myapp -Y [-c] <file1> <file2>\n \
1900 /// myapp -Z [-d|-e]"
1901 /// )
1902 /// # ;
1903 /// ```
1904 ///
1905 /// [`ArgMatches::usage`]: ArgMatches::usage()
1906 #[must_use]
1907 pub fn override_usage(mut self, usage: impl IntoResettable<StyledStr>) -> Self {
1908 self.usage_str = usage.into_resettable().into_option();
1909 self
1910 }
1911
1912 /// Overrides the `clap` generated help message (both `-h` and `--help`).
1913 ///
1914 /// This should only be used when the auto-generated message does not suffice.
1915 ///
1916 /// **NOTE:** This **only** replaces the help message for the current
1917 /// command, meaning if you are using subcommands, those help messages will
1918 /// still be auto-generated unless you specify a [`Command::override_help`] for
1919 /// them as well.
1920 ///
1921 /// # Examples
1922 ///
1923 /// ```rust
1924 /// # use clap_builder as clap;
1925 /// # use clap::{Command, Arg};
1926 /// Command::new("myapp")
1927 /// .override_help("myapp v1.0\n\
1928 /// Does awesome things\n\
1929 /// (C) me@mail.com\n\n\
1930 ///
1931 /// Usage: myapp <opts> <command>\n\n\
1932 ///
1933 /// Options:\n\
1934 /// -h, --help Display this message\n\
1935 /// -V, --version Display version info\n\
1936 /// -s <stuff> Do something with stuff\n\
1937 /// -v Be verbose\n\n\
1938 ///
1939 /// Commands:\n\
1940 /// help Print this message\n\
1941 /// work Do some work")
1942 /// # ;
1943 /// ```
1944 #[must_use]
1945 pub fn override_help(mut self, help: impl IntoResettable<StyledStr>) -> Self {
1946 self.help_str = help.into_resettable().into_option();
1947 self
1948 }
1949
1950 /// Sets the help template to be used, overriding the default format.
1951 ///
1952 /// **NOTE:** The template system is by design very simple. Therefore, the
1953 /// tags have to be written in the lowercase and without spacing.
1954 ///
1955 /// Tags are given inside curly brackets.
1956 ///
1957 /// Valid tags are:
1958 ///
1959 /// * `{name}` - Display name for the (sub-)command.
1960 /// * `{bin}` - Binary name.(deprecated)
1961 /// * `{version}` - Version number.
1962 /// * `{author}` - Author information.
1963 /// * `{author-with-newline}` - Author followed by `\n`.
1964 /// * `{author-section}` - Author preceded and followed by `\n`.
1965 /// * `{about}` - General description (from [`Command::about`] or
1966 /// [`Command::long_about`]).
1967 /// * `{about-with-newline}` - About followed by `\n`.
1968 /// * `{about-section}` - About preceded and followed by '\n'.
1969 /// * `{usage-heading}` - Automatically generated usage heading.
1970 /// * `{usage}` - Automatically generated or given usage string.
1971 /// * `{all-args}` - Help for all arguments (options, flags, positional
1972 /// arguments, and subcommands) including titles.
1973 /// * `{options}` - Help for options.
1974 /// * `{positionals}` - Help for positional arguments.
1975 /// * `{subcommands}` - Help for subcommands.
1976 /// * `{tab}` - Standard tab sized used within clap
1977 /// * `{after-help}` - Help from [`Command::after_help`] or [`Command::after_long_help`].
1978 /// * `{before-help}` - Help from [`Command::before_help`] or [`Command::before_long_help`].
1979 ///
1980 /// # Examples
1981 ///
1982 /// For a very brief help:
1983 ///
1984 /// ```rust
1985 /// # use clap_builder as clap;
1986 /// # use clap::Command;
1987 /// Command::new("myprog")
1988 /// .version("1.0")
1989 /// .help_template("{name} ({version}) - {usage}")
1990 /// # ;
1991 /// ```
1992 ///
1993 /// For showing more application context:
1994 ///
1995 /// ```rust
1996 /// # use clap_builder as clap;
1997 /// # use clap::Command;
1998 /// Command::new("myprog")
1999 /// .version("1.0")
2000 /// .help_template("\
2001 /// {before-help}{name} {version}
2002 /// {author-with-newline}{about-with-newline}
2003 /// {usage-heading} {usage}
2004 ///
2005 /// {all-args}{after-help}
2006 /// ")
2007 /// # ;
2008 /// ```
2009 /// [`Command::about`]: Command::about()
2010 /// [`Command::long_about`]: Command::long_about()
2011 /// [`Command::after_help`]: Command::after_help()
2012 /// [`Command::after_long_help`]: Command::after_long_help()
2013 /// [`Command::before_help`]: Command::before_help()
2014 /// [`Command::before_long_help`]: Command::before_long_help()
2015 #[must_use]
2016 #[cfg(feature = "help")]
2017 pub fn help_template(mut self, s: impl IntoResettable<StyledStr>) -> Self {
2018 self.template = s.into_resettable().into_option();
2019 self
2020 }
2021
2022 #[inline]
2023 #[must_use]
2024 pub(crate) fn setting(mut self, setting: AppSettings) -> Self {
2025 self.settings.set(setting);
2026 self
2027 }
2028
2029 #[inline]
2030 #[must_use]
2031 pub(crate) fn unset_setting(mut self, setting: AppSettings) -> Self {
2032 self.settings.unset(setting);
2033 self
2034 }
2035
2036 #[inline]
2037 #[must_use]
2038 pub(crate) fn global_setting(mut self, setting: AppSettings) -> Self {
2039 self.settings.set(setting);
2040 self.g_settings.set(setting);
2041 self
2042 }
2043
2044 #[inline]
2045 #[must_use]
2046 pub(crate) fn unset_global_setting(mut self, setting: AppSettings) -> Self {
2047 self.settings.unset(setting);
2048 self.g_settings.unset(setting);
2049 self
2050 }
2051
2052 /// Set the default section heading for future args.
2053 ///
2054 /// This will be used for any arg that hasn't had [`Arg::help_heading`] called.
2055 ///
2056 /// This is useful if the default `Options` or `Arguments` headings are
2057 /// not specific enough for one's use case.
2058 ///
2059 /// For subcommands, see [`Command::subcommand_help_heading`]
2060 ///
2061 /// [`Command::arg`]: Command::arg()
2062 /// [`Arg::help_heading`]: crate::Arg::help_heading()
2063 #[inline]
2064 #[must_use]
2065 pub fn next_help_heading(mut self, heading: impl IntoResettable<Str>) -> Self {
2066 self.current_help_heading = heading.into_resettable().into_option();
2067 self
2068 }
2069
2070 /// Change the starting value for assigning future display orders for args.
2071 ///
2072 /// This will be used for any arg that hasn't had [`Arg::display_order`] called.
2073 #[inline]
2074 #[must_use]
2075 pub fn next_display_order(mut self, disp_ord: impl IntoResettable<usize>) -> Self {
2076 self.current_disp_ord = disp_ord.into_resettable().into_option();
2077 self
2078 }
2079
2080 /// Exit gracefully if no arguments are present (e.g. `$ myprog`).
2081 ///
2082 /// **NOTE:** [`subcommands`] count as arguments
2083 ///
2084 /// # Examples
2085 ///
2086 /// ```rust
2087 /// # use clap_builder as clap;
2088 /// # use clap::{Command};
2089 /// Command::new("myprog")
2090 /// .arg_required_else_help(true);
2091 /// ```
2092 ///
2093 /// [`subcommands`]: crate::Command::subcommand()
2094 /// [`Arg::default_value`]: crate::Arg::default_value()
2095 #[inline]
2096 pub fn arg_required_else_help(self, yes: bool) -> Self {
2097 if yes {
2098 self.setting(AppSettings::ArgRequiredElseHelp)
2099 } else {
2100 self.unset_setting(AppSettings::ArgRequiredElseHelp)
2101 }
2102 }
2103
2104 #[doc(hidden)]
2105 #[cfg_attr(
2106 feature = "deprecated",
2107 deprecated(since = "4.0.0", note = "Replaced with `Arg::allow_hyphen_values`")
2108 )]
2109 pub fn allow_hyphen_values(self, yes: bool) -> Self {
2110 if yes {
2111 self.setting(AppSettings::AllowHyphenValues)
2112 } else {
2113 self.unset_setting(AppSettings::AllowHyphenValues)
2114 }
2115 }
2116
2117 #[doc(hidden)]
2118 #[cfg_attr(
2119 feature = "deprecated",
2120 deprecated(since = "4.0.0", note = "Replaced with `Arg::allow_negative_numbers`")
2121 )]
2122 pub fn allow_negative_numbers(self, yes: bool) -> Self {
2123 if yes {
2124 self.setting(AppSettings::AllowNegativeNumbers)
2125 } else {
2126 self.unset_setting(AppSettings::AllowNegativeNumbers)
2127 }
2128 }
2129
2130 #[doc(hidden)]
2131 #[cfg_attr(
2132 feature = "deprecated",
2133 deprecated(since = "4.0.0", note = "Replaced with `Arg::trailing_var_arg`")
2134 )]
2135 pub fn trailing_var_arg(self, yes: bool) -> Self {
2136 if yes {
2137 self.setting(AppSettings::TrailingVarArg)
2138 } else {
2139 self.unset_setting(AppSettings::TrailingVarArg)
2140 }
2141 }
2142
2143 /// Allows one to implement two styles of CLIs where positionals can be used out of order.
2144 ///
2145 /// The first example is a CLI where the second to last positional argument is optional, but
2146 /// the final positional argument is required. Such as `$ prog [optional] <required>` where one
2147 /// of the two following usages is allowed:
2148 ///
2149 /// * `$ prog [optional] <required>`
2150 /// * `$ prog <required>`
2151 ///
2152 /// This would otherwise not be allowed. This is useful when `[optional]` has a default value.
2153 ///
2154 /// **Note:** when using this style of "missing positionals" the final positional *must* be
2155 /// [required] if `--` will not be used to skip to the final positional argument.
2156 ///
2157 /// **Note:** This style also only allows a single positional argument to be "skipped" without
2158 /// the use of `--`. To skip more than one, see the second example.
2159 ///
2160 /// The second example is when one wants to skip multiple optional positional arguments, and use
2161 /// of the `--` operator is OK (but not required if all arguments will be specified anyways).
2162 ///
2163 /// For example, imagine a CLI which has three positional arguments `[foo] [bar] [baz]...` where
2164 /// `baz` accepts multiple values (similar to man `ARGS...` style training arguments).
2165 ///
2166 /// With this setting the following invocations are posisble:
2167 ///
2168 /// * `$ prog foo bar baz1 baz2 baz3`
2169 /// * `$ prog foo -- baz1 baz2 baz3`
2170 /// * `$ prog -- baz1 baz2 baz3`
2171 ///
2172 /// # Examples
2173 ///
2174 /// Style number one from above:
2175 ///
2176 /// ```rust
2177 /// # use clap_builder as clap;
2178 /// # use clap::{Command, Arg};
2179 /// // Assume there is an external subcommand named "subcmd"
2180 /// let m = Command::new("myprog")
2181 /// .allow_missing_positional(true)
2182 /// .arg(Arg::new("arg1"))
2183 /// .arg(Arg::new("arg2")
2184 /// .required(true))
2185 /// .get_matches_from(vec![
2186 /// "prog", "other"
2187 /// ]);
2188 ///
2189 /// assert_eq!(m.get_one::<String>("arg1"), None);
2190 /// assert_eq!(m.get_one::<String>("arg2").unwrap(), "other");
2191 /// ```
2192 ///
2193 /// Now the same example, but using a default value for the first optional positional argument
2194 ///
2195 /// ```rust
2196 /// # use clap_builder as clap;
2197 /// # use clap::{Command, Arg};
2198 /// // Assume there is an external subcommand named "subcmd"
2199 /// let m = Command::new("myprog")
2200 /// .allow_missing_positional(true)
2201 /// .arg(Arg::new("arg1")
2202 /// .default_value("something"))
2203 /// .arg(Arg::new("arg2")
2204 /// .required(true))
2205 /// .get_matches_from(vec![
2206 /// "prog", "other"
2207 /// ]);
2208 ///
2209 /// assert_eq!(m.get_one::<String>("arg1").unwrap(), "something");
2210 /// assert_eq!(m.get_one::<String>("arg2").unwrap(), "other");
2211 /// ```
2212 ///
2213 /// Style number two from above:
2214 ///
2215 /// ```rust
2216 /// # use clap_builder as clap;
2217 /// # use clap::{Command, Arg, ArgAction};
2218 /// // Assume there is an external subcommand named "subcmd"
2219 /// let m = Command::new("myprog")
2220 /// .allow_missing_positional(true)
2221 /// .arg(Arg::new("foo"))
2222 /// .arg(Arg::new("bar"))
2223 /// .arg(Arg::new("baz").action(ArgAction::Set).num_args(1..))
2224 /// .get_matches_from(vec![
2225 /// "prog", "foo", "bar", "baz1", "baz2", "baz3"
2226 /// ]);
2227 ///
2228 /// assert_eq!(m.get_one::<String>("foo").unwrap(), "foo");
2229 /// assert_eq!(m.get_one::<String>("bar").unwrap(), "bar");
2230 /// assert_eq!(m.get_many::<String>("baz").unwrap().collect::<Vec<_>>(), &["baz1", "baz2", "baz3"]);
2231 /// ```
2232 ///
2233 /// Now nofice if we don't specify `foo` or `baz` but use the `--` operator.
2234 ///
2235 /// ```rust
2236 /// # use clap_builder as clap;
2237 /// # use clap::{Command, Arg, ArgAction};
2238 /// // Assume there is an external subcommand named "subcmd"
2239 /// let m = Command::new("myprog")
2240 /// .allow_missing_positional(true)
2241 /// .arg(Arg::new("foo"))
2242 /// .arg(Arg::new("bar"))
2243 /// .arg(Arg::new("baz").action(ArgAction::Set).num_args(1..))
2244 /// .get_matches_from(vec![
2245 /// "prog", "--", "baz1", "baz2", "baz3"
2246 /// ]);
2247 ///
2248 /// assert_eq!(m.get_one::<String>("foo"), None);
2249 /// assert_eq!(m.get_one::<String>("bar"), None);
2250 /// assert_eq!(m.get_many::<String>("baz").unwrap().collect::<Vec<_>>(), &["baz1", "baz2", "baz3"]);
2251 /// ```
2252 ///
2253 /// [required]: crate::Arg::required()
2254 #[inline]
2255 pub fn allow_missing_positional(self, yes: bool) -> Self {
2256 if yes {
2257 self.setting(AppSettings::AllowMissingPositional)
2258 } else {
2259 self.unset_setting(AppSettings::AllowMissingPositional)
2260 }
2261 }
2262 }
2263
2264 /// # Subcommand-specific Settings
2265 impl Command {
2266 /// Sets the short version of the subcommand flag without the preceding `-`.
2267 ///
2268 /// Allows the subcommand to be used as if it were an [`Arg::short`].
2269 ///
2270 /// # Examples
2271 ///
2272 /// ```
2273 /// # use clap_builder as clap;
2274 /// # use clap::{Command, Arg, ArgAction};
2275 /// let matches = Command::new("pacman")
2276 /// .subcommand(
2277 /// Command::new("sync").short_flag('S').arg(
2278 /// Arg::new("search")
2279 /// .short('s')
2280 /// .long("search")
2281 /// .action(ArgAction::SetTrue)
2282 /// .help("search remote repositories for matching strings"),
2283 /// ),
2284 /// )
2285 /// .get_matches_from(vec!["pacman", "-Ss"]);
2286 ///
2287 /// assert_eq!(matches.subcommand_name().unwrap(), "sync");
2288 /// let sync_matches = matches.subcommand_matches("sync").unwrap();
2289 /// assert!(sync_matches.get_flag("search"));
2290 /// ```
2291 /// [`Arg::short`]: Arg::short()
2292 #[must_use]
2293 pub fn short_flag(mut self, short: impl IntoResettable<char>) -> Self {
2294 self.short_flag = short.into_resettable().into_option();
2295 self
2296 }
2297
2298 /// Sets the long version of the subcommand flag without the preceding `--`.
2299 ///
2300 /// Allows the subcommand to be used as if it were an [`Arg::long`].
2301 ///
2302 /// **NOTE:** Any leading `-` characters will be stripped.
2303 ///
2304 /// # Examples
2305 ///
2306 /// To set `long_flag` use a word containing valid UTF-8 codepoints. If you supply a double leading
2307 /// `--` such as `--sync` they will be stripped. Hyphens in the middle of the word; however,
2308 /// will *not* be stripped (i.e. `sync-file` is allowed).
2309 ///
2310 /// ```rust
2311 /// # use clap_builder as clap;
2312 /// # use clap::{Command, Arg, ArgAction};
2313 /// let matches = Command::new("pacman")
2314 /// .subcommand(
2315 /// Command::new("sync").long_flag("sync").arg(
2316 /// Arg::new("search")
2317 /// .short('s')
2318 /// .long("search")
2319 /// .action(ArgAction::SetTrue)
2320 /// .help("search remote repositories for matching strings"),
2321 /// ),
2322 /// )
2323 /// .get_matches_from(vec!["pacman", "--sync", "--search"]);
2324 ///
2325 /// assert_eq!(matches.subcommand_name().unwrap(), "sync");
2326 /// let sync_matches = matches.subcommand_matches("sync").unwrap();
2327 /// assert!(sync_matches.get_flag("search"));
2328 /// ```
2329 ///
2330 /// [`Arg::long`]: Arg::long()
2331 #[must_use]
2332 pub fn long_flag(mut self, long: impl Into<Str>) -> Self {
2333 self.long_flag = Some(long.into());
2334 self
2335 }
2336
2337 /// Sets a hidden alias to this subcommand.
2338 ///
2339 /// This allows the subcommand to be accessed via *either* the original name, or this given
2340 /// alias. This is more efficient and easier than creating multiple hidden subcommands as one
2341 /// only needs to check for the existence of this command, and not all aliased variants.
2342 ///
2343 /// **NOTE:** Aliases defined with this method are *hidden* from the help
2344 /// message. If you're looking for aliases that will be displayed in the help
2345 /// message, see [`Command::visible_alias`].
2346 ///
2347 /// **NOTE:** When using aliases and checking for the existence of a
2348 /// particular subcommand within an [`ArgMatches`] struct, one only needs to
2349 /// search for the original name and not all aliases.
2350 ///
2351 /// # Examples
2352 ///
2353 /// ```rust
2354 /// # use clap_builder as clap;
2355 /// # use clap::{Command, Arg, };
2356 /// let m = Command::new("myprog")
2357 /// .subcommand(Command::new("test")
2358 /// .alias("do-stuff"))
2359 /// .get_matches_from(vec!["myprog", "do-stuff"]);
2360 /// assert_eq!(m.subcommand_name(), Some("test"));
2361 /// ```
2362 /// [`Command::visible_alias`]: Command::visible_alias()
2363 #[must_use]
2364 pub fn alias(mut self, name: impl IntoResettable<Str>) -> Self {
2365 if let Some(name) = name.into_resettable().into_option() {
2366 self.aliases.push((name, false));
2367 } else {
2368 self.aliases.clear();
2369 }
2370 self
2371 }
2372
2373 /// Add an alias, which functions as "hidden" short flag subcommand
2374 ///
2375 /// This will automatically dispatch as if this subcommand was used. This is more efficient,
2376 /// and easier than creating multiple hidden subcommands as one only needs to check for the
2377 /// existence of this command, and not all variants.
2378 ///
2379 /// # Examples
2380 ///
2381 /// ```rust
2382 /// # use clap_builder as clap;
2383 /// # use clap::{Command, Arg, };
2384 /// let m = Command::new("myprog")
2385 /// .subcommand(Command::new("test").short_flag('t')
2386 /// .short_flag_alias('d'))
2387 /// .get_matches_from(vec!["myprog", "-d"]);
2388 /// assert_eq!(m.subcommand_name(), Some("test"));
2389 /// ```
2390 #[must_use]
2391 pub fn short_flag_alias(mut self, name: impl IntoResettable<char>) -> Self {
2392 if let Some(name) = name.into_resettable().into_option() {
2393 debug_assert!(name != '-', "short alias name cannot be `-`");
2394 self.short_flag_aliases.push((name, false));
2395 } else {
2396 self.short_flag_aliases.clear();
2397 }
2398 self
2399 }
2400
2401 /// Add an alias, which functions as a "hidden" long flag subcommand.
2402 ///
2403 /// This will automatically dispatch as if this subcommand was used. This is more efficient,
2404 /// and easier than creating multiple hidden subcommands as one only needs to check for the
2405 /// existence of this command, and not all variants.
2406 ///
2407 /// # Examples
2408 ///
2409 /// ```rust
2410 /// # use clap_builder as clap;
2411 /// # use clap::{Command, Arg, };
2412 /// let m = Command::new("myprog")
2413 /// .subcommand(Command::new("test").long_flag("test")
2414 /// .long_flag_alias("testing"))
2415 /// .get_matches_from(vec!["myprog", "--testing"]);
2416 /// assert_eq!(m.subcommand_name(), Some("test"));
2417 /// ```
2418 #[must_use]
2419 pub fn long_flag_alias(mut self, name: impl IntoResettable<Str>) -> Self {
2420 if let Some(name) = name.into_resettable().into_option() {
2421 self.long_flag_aliases.push((name, false));
2422 } else {
2423 self.long_flag_aliases.clear();
2424 }
2425 self
2426 }
2427
2428 /// Sets multiple hidden aliases to this subcommand.
2429 ///
2430 /// This allows the subcommand to be accessed via *either* the original name or any of the
2431 /// given aliases. This is more efficient, and easier than creating multiple hidden subcommands
2432 /// as one only needs to check for the existence of this command and not all aliased variants.
2433 ///
2434 /// **NOTE:** Aliases defined with this method are *hidden* from the help
2435 /// message. If looking for aliases that will be displayed in the help
2436 /// message, see [`Command::visible_aliases`].
2437 ///
2438 /// **NOTE:** When using aliases and checking for the existence of a
2439 /// particular subcommand within an [`ArgMatches`] struct, one only needs to
2440 /// search for the original name and not all aliases.
2441 ///
2442 /// # Examples
2443 ///
2444 /// ```rust
2445 /// # use clap_builder as clap;
2446 /// # use clap::{Command, Arg};
2447 /// let m = Command::new("myprog")
2448 /// .subcommand(Command::new("test")
2449 /// .aliases(["do-stuff", "do-tests", "tests"]))
2450 /// .arg(Arg::new("input")
2451 /// .help("the file to add")
2452 /// .required(false))
2453 /// .get_matches_from(vec!["myprog", "do-tests"]);
2454 /// assert_eq!(m.subcommand_name(), Some("test"));
2455 /// ```
2456 /// [`Command::visible_aliases`]: Command::visible_aliases()
2457 #[must_use]
2458 pub fn aliases(mut self, names: impl IntoIterator<Item = impl Into<Str>>) -> Self {
2459 self.aliases
2460 .extend(names.into_iter().map(|n| (n.into(), false)));
2461 self
2462 }
2463
2464 /// Add aliases, which function as "hidden" short flag subcommands.
2465 ///
2466 /// These will automatically dispatch as if this subcommand was used. This is more efficient,
2467 /// and easier than creating multiple hidden subcommands as one only needs to check for the
2468 /// existence of this command, and not all variants.
2469 ///
2470 /// # Examples
2471 ///
2472 /// ```rust
2473 /// # use clap_builder as clap;
2474 /// # use clap::{Command, Arg, };
2475 /// let m = Command::new("myprog")
2476 /// .subcommand(Command::new("test").short_flag('t')
2477 /// .short_flag_aliases(['a', 'b', 'c']))
2478 /// .arg(Arg::new("input")
2479 /// .help("the file to add")
2480 /// .required(false))
2481 /// .get_matches_from(vec!["myprog", "-a"]);
2482 /// assert_eq!(m.subcommand_name(), Some("test"));
2483 /// ```
2484 #[must_use]
2485 pub fn short_flag_aliases(mut self, names: impl IntoIterator<Item = char>) -> Self {
2486 for s in names {
2487 debug_assert!(s != '-', "short alias name cannot be `-`");
2488 self.short_flag_aliases.push((s, false));
2489 }
2490 self
2491 }
2492
2493 /// Add aliases, which function as "hidden" long flag subcommands.
2494 ///
2495 /// These will automatically dispatch as if this subcommand was used. This is more efficient,
2496 /// and easier than creating multiple hidden subcommands as one only needs to check for the
2497 /// existence of this command, and not all variants.
2498 ///
2499 /// # Examples
2500 ///
2501 /// ```rust
2502 /// # use clap_builder as clap;
2503 /// # use clap::{Command, Arg, };
2504 /// let m = Command::new("myprog")
2505 /// .subcommand(Command::new("test").long_flag("test")
2506 /// .long_flag_aliases(["testing", "testall", "test_all"]))
2507 /// .arg(Arg::new("input")
2508 /// .help("the file to add")
2509 /// .required(false))
2510 /// .get_matches_from(vec!["myprog", "--testing"]);
2511 /// assert_eq!(m.subcommand_name(), Some("test"));
2512 /// ```
2513 #[must_use]
2514 pub fn long_flag_aliases(mut self, names: impl IntoIterator<Item = impl Into<Str>>) -> Self {
2515 for s in names {
2516 self = self.long_flag_alias(s)
2517 }
2518 self
2519 }
2520
2521 /// Sets a visible alias to this subcommand.
2522 ///
2523 /// This allows the subcommand to be accessed via *either* the
2524 /// original name or the given alias. This is more efficient and easier
2525 /// than creating hidden subcommands as one only needs to check for
2526 /// the existence of this command and not all aliased variants.
2527 ///
2528 /// **NOTE:** The alias defined with this method is *visible* from the help
2529 /// message and displayed as if it were just another regular subcommand. If
2530 /// looking for an alias that will not be displayed in the help message, see
2531 /// [`Command::alias`].
2532 ///
2533 /// **NOTE:** When using aliases and checking for the existence of a
2534 /// particular subcommand within an [`ArgMatches`] struct, one only needs to
2535 /// search for the original name and not all aliases.
2536 ///
2537 /// # Examples
2538 ///
2539 /// ```rust
2540 /// # use clap_builder as clap;
2541 /// # use clap::{Command, Arg};
2542 /// let m = Command::new("myprog")
2543 /// .subcommand(Command::new("test")
2544 /// .visible_alias("do-stuff"))
2545 /// .get_matches_from(vec!["myprog", "do-stuff"]);
2546 /// assert_eq!(m.subcommand_name(), Some("test"));
2547 /// ```
2548 /// [`Command::alias`]: Command::alias()
2549 #[must_use]
2550 pub fn visible_alias(mut self, name: impl IntoResettable<Str>) -> Self {
2551 if let Some(name) = name.into_resettable().into_option() {
2552 self.aliases.push((name, true));
2553 } else {
2554 self.aliases.clear();
2555 }
2556 self
2557 }
2558
2559 /// Add an alias, which functions as "visible" short flag subcommand
2560 ///
2561 /// This will automatically dispatch as if this subcommand was used. This is more efficient,
2562 /// and easier than creating multiple hidden subcommands as one only needs to check for the
2563 /// existence of this command, and not all variants.
2564 ///
2565 /// See also [`Command::short_flag_alias`].
2566 ///
2567 /// # Examples
2568 ///
2569 /// ```rust
2570 /// # use clap_builder as clap;
2571 /// # use clap::{Command, Arg, };
2572 /// let m = Command::new("myprog")
2573 /// .subcommand(Command::new("test").short_flag('t')
2574 /// .visible_short_flag_alias('d'))
2575 /// .get_matches_from(vec!["myprog", "-d"]);
2576 /// assert_eq!(m.subcommand_name(), Some("test"));
2577 /// ```
2578 /// [`Command::short_flag_alias`]: Command::short_flag_alias()
2579 #[must_use]
2580 pub fn visible_short_flag_alias(mut self, name: impl IntoResettable<char>) -> Self {
2581 if let Some(name) = name.into_resettable().into_option() {
2582 debug_assert!(name != '-', "short alias name cannot be `-`");
2583 self.short_flag_aliases.push((name, true));
2584 } else {
2585 self.short_flag_aliases.clear();
2586 }
2587 self
2588 }
2589
2590 /// Add an alias, which functions as a "visible" long flag subcommand.
2591 ///
2592 /// This will automatically dispatch as if this subcommand was used. This is more efficient,
2593 /// and easier than creating multiple hidden subcommands as one only needs to check for the
2594 /// existence of this command, and not all variants.
2595 ///
2596 /// See also [`Command::long_flag_alias`].
2597 ///
2598 /// # Examples
2599 ///
2600 /// ```rust
2601 /// # use clap_builder as clap;
2602 /// # use clap::{Command, Arg, };
2603 /// let m = Command::new("myprog")
2604 /// .subcommand(Command::new("test").long_flag("test")
2605 /// .visible_long_flag_alias("testing"))
2606 /// .get_matches_from(vec!["myprog", "--testing"]);
2607 /// assert_eq!(m.subcommand_name(), Some("test"));
2608 /// ```
2609 /// [`Command::long_flag_alias`]: Command::long_flag_alias()
2610 #[must_use]
2611 pub fn visible_long_flag_alias(mut self, name: impl IntoResettable<Str>) -> Self {
2612 if let Some(name) = name.into_resettable().into_option() {
2613 self.long_flag_aliases.push((name, true));
2614 } else {
2615 self.long_flag_aliases.clear();
2616 }
2617 self
2618 }
2619
2620 /// Sets multiple visible aliases to this subcommand.
2621 ///
2622 /// This allows the subcommand to be accessed via *either* the
2623 /// original name or any of the given aliases. This is more efficient and easier
2624 /// than creating multiple hidden subcommands as one only needs to check for
2625 /// the existence of this command and not all aliased variants.
2626 ///
2627 /// **NOTE:** The alias defined with this method is *visible* from the help
2628 /// message and displayed as if it were just another regular subcommand. If
2629 /// looking for an alias that will not be displayed in the help message, see
2630 /// [`Command::alias`].
2631 ///
2632 /// **NOTE:** When using aliases, and checking for the existence of a
2633 /// particular subcommand within an [`ArgMatches`] struct, one only needs to
2634 /// search for the original name and not all aliases.
2635 ///
2636 /// # Examples
2637 ///
2638 /// ```rust
2639 /// # use clap_builder as clap;
2640 /// # use clap::{Command, Arg, };
2641 /// let m = Command::new("myprog")
2642 /// .subcommand(Command::new("test")
2643 /// .visible_aliases(["do-stuff", "tests"]))
2644 /// .get_matches_from(vec!["myprog", "do-stuff"]);
2645 /// assert_eq!(m.subcommand_name(), Some("test"));
2646 /// ```
2647 /// [`Command::alias`]: Command::alias()
2648 #[must_use]
2649 pub fn visible_aliases(mut self, names: impl IntoIterator<Item = impl Into<Str>>) -> Self {
2650 self.aliases
2651 .extend(names.into_iter().map(|n| (n.into(), true)));
2652 self
2653 }
2654
2655 /// Add aliases, which function as *visible* short flag subcommands.
2656 ///
2657 /// See [`Command::short_flag_aliases`].
2658 ///
2659 /// # Examples
2660 ///
2661 /// ```rust
2662 /// # use clap_builder as clap;
2663 /// # use clap::{Command, Arg, };
2664 /// let m = Command::new("myprog")
2665 /// .subcommand(Command::new("test").short_flag('b')
2666 /// .visible_short_flag_aliases(['t']))
2667 /// .get_matches_from(vec!["myprog", "-t"]);
2668 /// assert_eq!(m.subcommand_name(), Some("test"));
2669 /// ```
2670 /// [`Command::short_flag_aliases`]: Command::short_flag_aliases()
2671 #[must_use]
2672 pub fn visible_short_flag_aliases(mut self, names: impl IntoIterator<Item = char>) -> Self {
2673 for s in names {
2674 debug_assert!(s != '-', "short alias name cannot be `-`");
2675 self.short_flag_aliases.push((s, true));
2676 }
2677 self
2678 }
2679
2680 /// Add aliases, which function as *visible* long flag subcommands.
2681 ///
2682 /// See [`Command::long_flag_aliases`].
2683 ///
2684 /// # Examples
2685 ///
2686 /// ```rust
2687 /// # use clap_builder as clap;
2688 /// # use clap::{Command, Arg, };
2689 /// let m = Command::new("myprog")
2690 /// .subcommand(Command::new("test").long_flag("test")
2691 /// .visible_long_flag_aliases(["testing", "testall", "test_all"]))
2692 /// .get_matches_from(vec!["myprog", "--testing"]);
2693 /// assert_eq!(m.subcommand_name(), Some("test"));
2694 /// ```
2695 /// [`Command::long_flag_aliases`]: Command::long_flag_aliases()
2696 #[must_use]
2697 pub fn visible_long_flag_aliases(
2698 mut self,
2699 names: impl IntoIterator<Item = impl Into<Str>>,
2700 ) -> Self {
2701 for s in names {
2702 self = self.visible_long_flag_alias(s);
2703 }
2704 self
2705 }
2706
2707 /// Set the placement of this subcommand within the help.
2708 ///
2709 /// Subcommands with a lower value will be displayed first in the help message.
2710 /// Those with the same display order will be sorted.
2711 ///
2712 /// `Command`s are automatically assigned a display order based on the order they are added to
2713 /// their parent [`Command`].
2714 /// Overriding this is helpful when the order commands are added in isn't the same as the
2715 /// display order, whether in one-off cases or to automatically sort commands.
2716 ///
2717 /// # Examples
2718 ///
2719 /// ```rust
2720 /// # #[cfg(feature = "help")] {
2721 /// # use clap_builder as clap;
2722 /// # use clap::{Command, };
2723 /// let m = Command::new("cust-ord")
2724 /// .subcommand(Command::new("beta")
2725 /// .display_order(0) // Sort
2726 /// .about("Some help and text"))
2727 /// .subcommand(Command::new("alpha")
2728 /// .display_order(0) // Sort
2729 /// .about("I should be first!"))
2730 /// .get_matches_from(vec![
2731 /// "cust-ord", "--help"
2732 /// ]);
2733 /// # }
2734 /// ```
2735 ///
2736 /// The above example displays the following help message
2737 ///
2738 /// ```text
2739 /// cust-ord
2740 ///
2741 /// Usage: cust-ord [OPTIONS]
2742 ///
2743 /// Commands:
2744 /// alpha I should be first!
2745 /// beta Some help and text
2746 /// help Print help for the subcommand(s)
2747 ///
2748 /// Options:
2749 /// -h, --help Print help
2750 /// -V, --version Print version
2751 /// ```
2752 #[inline]
2753 #[must_use]
2754 pub fn display_order(mut self, ord: impl IntoResettable<usize>) -> Self {
2755 self.disp_ord = ord.into_resettable().into_option();
2756 self
2757 }
2758
2759 /// Specifies that this [`subcommand`] should be hidden from help messages
2760 ///
2761 /// # Examples
2762 ///
2763 /// ```rust
2764 /// # use clap_builder as clap;
2765 /// # use clap::{Command, Arg};
2766 /// Command::new("myprog")
2767 /// .subcommand(
2768 /// Command::new("test").hide(true)
2769 /// )
2770 /// # ;
2771 /// ```
2772 ///
2773 /// [`subcommand`]: crate::Command::subcommand()
2774 #[inline]
2775 pub fn hide(self, yes: bool) -> Self {
2776 if yes {
2777 self.setting(AppSettings::Hidden)
2778 } else {
2779 self.unset_setting(AppSettings::Hidden)
2780 }
2781 }
2782
2783 /// If no [`subcommand`] is present at runtime, error and exit gracefully.
2784 ///
2785 /// # Examples
2786 ///
2787 /// ```rust
2788 /// # use clap_builder as clap;
2789 /// # use clap::{Command, error::ErrorKind};
2790 /// let err = Command::new("myprog")
2791 /// .subcommand_required(true)
2792 /// .subcommand(Command::new("test"))
2793 /// .try_get_matches_from(vec![
2794 /// "myprog",
2795 /// ]);
2796 /// assert!(err.is_err());
2797 /// assert_eq!(err.unwrap_err().kind(), ErrorKind::MissingSubcommand);
2798 /// # ;
2799 /// ```
2800 ///
2801 /// [`subcommand`]: crate::Command::subcommand()
2802 pub fn subcommand_required(self, yes: bool) -> Self {
2803 if yes {
2804 self.setting(AppSettings::SubcommandRequired)
2805 } else {
2806 self.unset_setting(AppSettings::SubcommandRequired)
2807 }
2808 }
2809
2810 /// Assume unexpected positional arguments are a [`subcommand`].
2811 ///
2812 /// Arguments will be stored in the `""` argument in the [`ArgMatches`]
2813 ///
2814 /// **NOTE:** Use this setting with caution,
2815 /// as a truly unexpected argument (i.e. one that is *NOT* an external subcommand)
2816 /// will **not** cause an error and instead be treated as a potential subcommand.
2817 /// One should check for such cases manually and inform the user appropriately.
2818 ///
2819 /// **NOTE:** A built-in subcommand will be parsed as an external subcommand when escaped with
2820 /// `--`.
2821 ///
2822 /// # Examples
2823 ///
2824 /// ```rust
2825 /// # use clap_builder as clap;
2826 /// # use std::ffi::OsString;
2827 /// # use clap::Command;
2828 /// // Assume there is an external subcommand named "subcmd"
2829 /// let m = Command::new("myprog")
2830 /// .allow_external_subcommands(true)
2831 /// .get_matches_from(vec![
2832 /// "myprog", "subcmd", "--option", "value", "-fff", "--flag"
2833 /// ]);
2834 ///
2835 /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty
2836 /// // string argument name
2837 /// match m.subcommand() {
2838 /// Some((external, ext_m)) => {
2839 /// let ext_args: Vec<_> = ext_m.get_many::<OsString>("").unwrap().collect();
2840 /// assert_eq!(external, "subcmd");
2841 /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
2842 /// },
2843 /// _ => {},
2844 /// }
2845 /// ```
2846 ///
2847 /// [`subcommand`]: crate::Command::subcommand()
2848 /// [`ArgMatches`]: crate::ArgMatches
2849 /// [`ErrorKind::UnknownArgument`]: crate::error::ErrorKind::UnknownArgument
2850 pub fn allow_external_subcommands(self, yes: bool) -> Self {
2851 if yes {
2852 self.setting(AppSettings::AllowExternalSubcommands)
2853 } else {
2854 self.unset_setting(AppSettings::AllowExternalSubcommands)
2855 }
2856 }
2857
2858 /// Specifies how to parse external subcommand arguments.
2859 ///
2860 /// The default parser is for `OsString`. This can be used to switch it to `String` or another
2861 /// type.
2862 ///
2863 /// **NOTE:** Setting this requires [`Command::allow_external_subcommands`]
2864 ///
2865 /// # Examples
2866 ///
2867 /// ```rust
2868 /// # #[cfg(unix)] {
2869 /// # use clap_builder as clap;
2870 /// # use std::ffi::OsString;
2871 /// # use clap::Command;
2872 /// # use clap::value_parser;
2873 /// // Assume there is an external subcommand named "subcmd"
2874 /// let m = Command::new("myprog")
2875 /// .allow_external_subcommands(true)
2876 /// .get_matches_from(vec![
2877 /// "myprog", "subcmd", "--option", "value", "-fff", "--flag"
2878 /// ]);
2879 ///
2880 /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty
2881 /// // string argument name
2882 /// match m.subcommand() {
2883 /// Some((external, ext_m)) => {
2884 /// let ext_args: Vec<_> = ext_m.get_many::<OsString>("").unwrap().collect();
2885 /// assert_eq!(external, "subcmd");
2886 /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
2887 /// },
2888 /// _ => {},
2889 /// }
2890 /// # }
2891 /// ```
2892 ///
2893 /// ```rust
2894 /// # use clap_builder as clap;
2895 /// # use clap::Command;
2896 /// # use clap::value_parser;
2897 /// // Assume there is an external subcommand named "subcmd"
2898 /// let m = Command::new("myprog")
2899 /// .external_subcommand_value_parser(value_parser!(String))
2900 /// .get_matches_from(vec![
2901 /// "myprog", "subcmd", "--option", "value", "-fff", "--flag"
2902 /// ]);
2903 ///
2904 /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty
2905 /// // string argument name
2906 /// match m.subcommand() {
2907 /// Some((external, ext_m)) => {
2908 /// let ext_args: Vec<_> = ext_m.get_many::<String>("").unwrap().collect();
2909 /// assert_eq!(external, "subcmd");
2910 /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
2911 /// },
2912 /// _ => {},
2913 /// }
2914 /// ```
2915 ///
2916 /// [`subcommands`]: crate::Command::subcommand()
2917 pub fn external_subcommand_value_parser(
2918 mut self,
2919 parser: impl IntoResettable<super::ValueParser>,
2920 ) -> Self {
2921 self.external_value_parser = parser.into_resettable().into_option();
2922 self
2923 }
2924
2925 /// Specifies that use of an argument prevents the use of [`subcommands`].
2926 ///
2927 /// By default `clap` allows arguments between subcommands such
2928 /// as `<cmd> [cmd_args] <subcmd> [subcmd_args] <subsubcmd> [subsubcmd_args]`.
2929 ///
2930 /// This setting disables that functionality and says that arguments can
2931 /// only follow the *final* subcommand. For instance using this setting
2932 /// makes only the following invocations possible:
2933 ///
2934 /// * `<cmd> <subcmd> <subsubcmd> [subsubcmd_args]`
2935 /// * `<cmd> <subcmd> [subcmd_args]`
2936 /// * `<cmd> [cmd_args]`
2937 ///
2938 /// # Examples
2939 ///
2940 /// ```rust
2941 /// # use clap_builder as clap;
2942 /// # use clap::Command;
2943 /// Command::new("myprog")
2944 /// .args_conflicts_with_subcommands(true);
2945 /// ```
2946 ///
2947 /// [`subcommands`]: crate::Command::subcommand()
2948 pub fn args_conflicts_with_subcommands(self, yes: bool) -> Self {
2949 if yes {
2950 self.setting(AppSettings::ArgsNegateSubcommands)
2951 } else {
2952 self.unset_setting(AppSettings::ArgsNegateSubcommands)
2953 }
2954 }
2955
2956 /// Prevent subcommands from being consumed as an arguments value.
2957 ///
2958 /// By default, if an option taking multiple values is followed by a subcommand, the
2959 /// subcommand will be parsed as another value.
2960 ///
2961 /// ```text
2962 /// cmd --foo val1 val2 subcommand
2963 /// --------- ----------
2964 /// values another value
2965 /// ```
2966 ///
2967 /// This setting instructs the parser to stop when encountering a subcommand instead of
2968 /// greedily consuming arguments.
2969 ///
2970 /// ```text
2971 /// cmd --foo val1 val2 subcommand
2972 /// --------- ----------
2973 /// values subcommand
2974 /// ```
2975 ///
2976 /// # Examples
2977 ///
2978 /// ```rust
2979 /// # use clap_builder as clap;
2980 /// # use clap::{Command, Arg, ArgAction};
2981 /// let cmd = Command::new("cmd").subcommand(Command::new("sub")).arg(
2982 /// Arg::new("arg")
2983 /// .long("arg")
2984 /// .num_args(1..)
2985 /// .action(ArgAction::Set),
2986 /// );
2987 ///
2988 /// let matches = cmd
2989 /// .clone()
2990 /// .try_get_matches_from(&["cmd", "--arg", "1", "2", "3", "sub"])
2991 /// .unwrap();
2992 /// assert_eq!(
2993 /// matches.get_many::<String>("arg").unwrap().collect::<Vec<_>>(),
2994 /// &["1", "2", "3", "sub"]
2995 /// );
2996 /// assert!(matches.subcommand_matches("sub").is_none());
2997 ///
2998 /// let matches = cmd
2999 /// .subcommand_precedence_over_arg(true)
3000 /// .try_get_matches_from(&["cmd", "--arg", "1", "2", "3", "sub"])
3001 /// .unwrap();
3002 /// assert_eq!(
3003 /// matches.get_many::<String>("arg").unwrap().collect::<Vec<_>>(),
3004 /// &["1", "2", "3"]
3005 /// );
3006 /// assert!(matches.subcommand_matches("sub").is_some());
3007 /// ```
3008 pub fn subcommand_precedence_over_arg(self, yes: bool) -> Self {
3009 if yes {
3010 self.setting(AppSettings::SubcommandPrecedenceOverArg)
3011 } else {
3012 self.unset_setting(AppSettings::SubcommandPrecedenceOverArg)
3013 }
3014 }
3015
3016 /// Allows [`subcommands`] to override all requirements of the parent command.
3017 ///
3018 /// For example, if you had a subcommand or top level application with a required argument
3019 /// that is only required as long as there is no subcommand present,
3020 /// using this setting would allow you to set those arguments to [`Arg::required(true)`]
3021 /// and yet receive no error so long as the user uses a valid subcommand instead.
3022 ///
3023 /// **NOTE:** This defaults to false (using subcommand does *not* negate requirements)
3024 ///
3025 /// # Examples
3026 ///
3027 /// This first example shows that it is an error to not use a required argument
3028 ///
3029 /// ```rust
3030 /// # use clap_builder as clap;
3031 /// # use clap::{Command, Arg, error::ErrorKind};
3032 /// let err = Command::new("myprog")
3033 /// .subcommand_negates_reqs(true)
3034 /// .arg(Arg::new("opt").required(true))
3035 /// .subcommand(Command::new("test"))
3036 /// .try_get_matches_from(vec![
3037 /// "myprog"
3038 /// ]);
3039 /// assert!(err.is_err());
3040 /// assert_eq!(err.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3041 /// # ;
3042 /// ```
3043 ///
3044 /// This next example shows that it is no longer error to not use a required argument if a
3045 /// valid subcommand is used.
3046 ///
3047 /// ```rust
3048 /// # use clap_builder as clap;
3049 /// # use clap::{Command, Arg, error::ErrorKind};
3050 /// let noerr = Command::new("myprog")
3051 /// .subcommand_negates_reqs(true)
3052 /// .arg(Arg::new("opt").required(true))
3053 /// .subcommand(Command::new("test"))
3054 /// .try_get_matches_from(vec![
3055 /// "myprog", "test"
3056 /// ]);
3057 /// assert!(noerr.is_ok());
3058 /// # ;
3059 /// ```
3060 ///
3061 /// [`Arg::required(true)`]: crate::Arg::required()
3062 /// [`subcommands`]: crate::Command::subcommand()
3063 pub fn subcommand_negates_reqs(self, yes: bool) -> Self {
3064 if yes {
3065 self.setting(AppSettings::SubcommandsNegateReqs)
3066 } else {
3067 self.unset_setting(AppSettings::SubcommandsNegateReqs)
3068 }
3069 }
3070
3071 /// Multiple-personality program dispatched on the binary name (`argv[0]`)
3072 ///
3073 /// A "multicall" executable is a single executable
3074 /// that contains a variety of applets,
3075 /// and decides which applet to run based on the name of the file.
3076 /// The executable can be called from different names by creating hard links
3077 /// or symbolic links to it.
3078 ///
3079 /// This is desirable for:
3080 /// - Easy distribution, a single binary that can install hardlinks to access the different
3081 /// personalities.
3082 /// - Minimal binary size by sharing common code (e.g. standard library, clap)
3083 /// - Custom shells or REPLs where there isn't a single top-level command
3084 ///
3085 /// Setting `multicall` will cause
3086 /// - `argv[0]` to be stripped to the base name and parsed as the first argument, as if
3087 /// [`Command::no_binary_name`][Command::no_binary_name] was set.
3088 /// - Help and errors to report subcommands as if they were the top-level command
3089 ///
3090 /// When the subcommand is not present, there are several strategies you may employ, depending
3091 /// on your needs:
3092 /// - Let the error percolate up normally
3093 /// - Print a specialized error message using the
3094 /// [`Error::context`][crate::Error::context]
3095 /// - Print the [help][Command::write_help] but this might be ambiguous
3096 /// - Disable `multicall` and re-parse it
3097 /// - Disable `multicall` and re-parse it with a specific subcommand
3098 ///
3099 /// When detecting the error condition, the [`ErrorKind`] isn't sufficient as a sub-subcommand
3100 /// might report the same error. Enable
3101 /// [`allow_external_subcommands`][Command::allow_external_subcommands] if you want to specifically
3102 /// get the unrecognized binary name.
3103 ///
3104 /// **NOTE:** Multicall can't be used with [`no_binary_name`] since they interpret
3105 /// the command name in incompatible ways.
3106 ///
3107 /// **NOTE:** The multicall command cannot have arguments.
3108 ///
3109 /// **NOTE:** Applets are slightly semantically different from subcommands,
3110 /// so it's recommended to use [`Command::subcommand_help_heading`] and
3111 /// [`Command::subcommand_value_name`] to change the descriptive text as above.
3112 ///
3113 /// # Examples
3114 ///
3115 /// `hostname` is an example of a multicall executable.
3116 /// Both `hostname` and `dnsdomainname` are provided by the same executable
3117 /// and which behaviour to use is based on the executable file name.
3118 ///
3119 /// This is desirable when the executable has a primary purpose
3120 /// but there is related functionality that would be convenient to provide
3121 /// and implement it to be in the same executable.
3122 ///
3123 /// The name of the cmd is essentially unused
3124 /// and may be the same as the name of a subcommand.
3125 ///
3126 /// The names of the immediate subcommands of the Command
3127 /// are matched against the basename of the first argument,
3128 /// which is conventionally the path of the executable.
3129 ///
3130 /// This does not allow the subcommand to be passed as the first non-path argument.
3131 ///
3132 /// ```rust
3133 /// # use clap_builder as clap;
3134 /// # use clap::{Command, error::ErrorKind};
3135 /// let mut cmd = Command::new("hostname")
3136 /// .multicall(true)
3137 /// .subcommand(Command::new("hostname"))
3138 /// .subcommand(Command::new("dnsdomainname"));
3139 /// let m = cmd.try_get_matches_from_mut(&["/usr/bin/hostname", "dnsdomainname"]);
3140 /// assert!(m.is_err());
3141 /// assert_eq!(m.unwrap_err().kind(), ErrorKind::UnknownArgument);
3142 /// let m = cmd.get_matches_from(&["/usr/bin/dnsdomainname"]);
3143 /// assert_eq!(m.subcommand_name(), Some("dnsdomainname"));
3144 /// ```
3145 ///
3146 /// Busybox is another common example of a multicall executable
3147 /// with a subcommmand for each applet that can be run directly,
3148 /// e.g. with the `cat` applet being run by running `busybox cat`,
3149 /// or with `cat` as a link to the `busybox` binary.
3150 ///
3151 /// This is desirable when the launcher program has additional options
3152 /// or it is useful to run the applet without installing a symlink
3153 /// e.g. to test the applet without installing it
3154 /// or there may already be a command of that name installed.
3155 ///
3156 /// To make an applet usable as both a multicall link and a subcommand
3157 /// the subcommands must be defined both in the top-level Command
3158 /// and as subcommands of the "main" applet.
3159 ///
3160 /// ```rust
3161 /// # use clap_builder as clap;
3162 /// # use clap::Command;
3163 /// fn applet_commands() -> [Command; 2] {
3164 /// [Command::new("true"), Command::new("false")]
3165 /// }
3166 /// let mut cmd = Command::new("busybox")
3167 /// .multicall(true)
3168 /// .subcommand(
3169 /// Command::new("busybox")
3170 /// .subcommand_value_name("APPLET")
3171 /// .subcommand_help_heading("APPLETS")
3172 /// .subcommands(applet_commands()),
3173 /// )
3174 /// .subcommands(applet_commands());
3175 /// // When called from the executable's canonical name
3176 /// // its applets can be matched as subcommands.
3177 /// let m = cmd.try_get_matches_from_mut(&["/usr/bin/busybox", "true"]).unwrap();
3178 /// assert_eq!(m.subcommand_name(), Some("busybox"));
3179 /// assert_eq!(m.subcommand().unwrap().1.subcommand_name(), Some("true"));
3180 /// // When called from a link named after an applet that applet is matched.
3181 /// let m = cmd.get_matches_from(&["/usr/bin/true"]);
3182 /// assert_eq!(m.subcommand_name(), Some("true"));
3183 /// ```
3184 ///
3185 /// [`no_binary_name`]: crate::Command::no_binary_name
3186 /// [`Command::subcommand_value_name`]: crate::Command::subcommand_value_name
3187 /// [`Command::subcommand_help_heading`]: crate::Command::subcommand_help_heading
3188 #[inline]
3189 pub fn multicall(self, yes: bool) -> Self {
3190 if yes {
3191 self.setting(AppSettings::Multicall)
3192 } else {
3193 self.unset_setting(AppSettings::Multicall)
3194 }
3195 }
3196
3197 /// Sets the value name used for subcommands when printing usage and help.
3198 ///
3199 /// By default, this is "COMMAND".
3200 ///
3201 /// See also [`Command::subcommand_help_heading`]
3202 ///
3203 /// # Examples
3204 ///
3205 /// ```rust
3206 /// # use clap_builder as clap;
3207 /// # use clap::{Command, Arg};
3208 /// Command::new("myprog")
3209 /// .subcommand(Command::new("sub1"))
3210 /// .print_help()
3211 /// # ;
3212 /// ```
3213 ///
3214 /// will produce
3215 ///
3216 /// ```text
3217 /// myprog
3218 ///
3219 /// Usage: myprog [COMMAND]
3220 ///
3221 /// Commands:
3222 /// help Print this message or the help of the given subcommand(s)
3223 /// sub1
3224 ///
3225 /// Options:
3226 /// -h, --help Print help
3227 /// -V, --version Print version
3228 /// ```
3229 ///
3230 /// but usage of `subcommand_value_name`
3231 ///
3232 /// ```rust
3233 /// # use clap_builder as clap;
3234 /// # use clap::{Command, Arg};
3235 /// Command::new("myprog")
3236 /// .subcommand(Command::new("sub1"))
3237 /// .subcommand_value_name("THING")
3238 /// .print_help()
3239 /// # ;
3240 /// ```
3241 ///
3242 /// will produce
3243 ///
3244 /// ```text
3245 /// myprog
3246 ///
3247 /// Usage: myprog [THING]
3248 ///
3249 /// Commands:
3250 /// help Print this message or the help of the given subcommand(s)
3251 /// sub1
3252 ///
3253 /// Options:
3254 /// -h, --help Print help
3255 /// -V, --version Print version
3256 /// ```
3257 #[must_use]
3258 pub fn subcommand_value_name(mut self, value_name: impl IntoResettable<Str>) -> Self {
3259 self.subcommand_value_name = value_name.into_resettable().into_option();
3260 self
3261 }
3262
3263 /// Sets the help heading used for subcommands when printing usage and help.
3264 ///
3265 /// By default, this is "Commands".
3266 ///
3267 /// See also [`Command::subcommand_value_name`]
3268 ///
3269 /// # Examples
3270 ///
3271 /// ```rust
3272 /// # use clap_builder as clap;
3273 /// # use clap::{Command, Arg};
3274 /// Command::new("myprog")
3275 /// .subcommand(Command::new("sub1"))
3276 /// .print_help()
3277 /// # ;
3278 /// ```
3279 ///
3280 /// will produce
3281 ///
3282 /// ```text
3283 /// myprog
3284 ///
3285 /// Usage: myprog [COMMAND]
3286 ///
3287 /// Commands:
3288 /// help Print this message or the help of the given subcommand(s)
3289 /// sub1
3290 ///
3291 /// Options:
3292 /// -h, --help Print help
3293 /// -V, --version Print version
3294 /// ```
3295 ///
3296 /// but usage of `subcommand_help_heading`
3297 ///
3298 /// ```rust
3299 /// # use clap_builder as clap;
3300 /// # use clap::{Command, Arg};
3301 /// Command::new("myprog")
3302 /// .subcommand(Command::new("sub1"))
3303 /// .subcommand_help_heading("Things")
3304 /// .print_help()
3305 /// # ;
3306 /// ```
3307 ///
3308 /// will produce
3309 ///
3310 /// ```text
3311 /// myprog
3312 ///
3313 /// Usage: myprog [COMMAND]
3314 ///
3315 /// Things:
3316 /// help Print this message or the help of the given subcommand(s)
3317 /// sub1
3318 ///
3319 /// Options:
3320 /// -h, --help Print help
3321 /// -V, --version Print version
3322 /// ```
3323 #[must_use]
3324 pub fn subcommand_help_heading(mut self, heading: impl IntoResettable<Str>) -> Self {
3325 self.subcommand_heading = heading.into_resettable().into_option();
3326 self
3327 }
3328 }
3329
3330 /// # Reflection
3331 impl Command {
3332 #[inline]
3333 #[cfg(feature = "usage")]
3334 pub(crate) fn get_usage_name(&self) -> Option<&str> {
3335 self.usage_name.as_deref()
3336 }
3337
3338 /// Get the name of the binary.
3339 #[inline]
3340 pub fn get_display_name(&self) -> Option<&str> {
3341 self.display_name.as_deref()
3342 }
3343
3344 /// Get the name of the binary.
3345 #[inline]
3346 pub fn get_bin_name(&self) -> Option<&str> {
3347 self.bin_name.as_deref()
3348 }
3349
3350 /// Set binary name. Uses `&mut self` instead of `self`.
3351 pub fn set_bin_name(&mut self, name: impl Into<String>) {
3352 self.bin_name = Some(name.into());
3353 }
3354
3355 /// Get the name of the cmd.
3356 #[inline]
3357 pub fn get_name(&self) -> &str {
3358 self.name.as_str()
3359 }
3360
3361 #[inline]
3362 #[cfg(debug_assertions)]
3363 pub(crate) fn get_name_str(&self) -> &Str {
3364 &self.name
3365 }
3366
3367 /// Get the version of the cmd.
3368 #[inline]
3369 pub fn get_version(&self) -> Option<&str> {
3370 self.version.as_deref()
3371 }
3372
3373 /// Get the long version of the cmd.
3374 #[inline]
3375 pub fn get_long_version(&self) -> Option<&str> {
3376 self.long_version.as_deref()
3377 }
3378
3379 /// Get the authors of the cmd.
3380 #[inline]
3381 pub fn get_author(&self) -> Option<&str> {
3382 self.author.as_deref()
3383 }
3384
3385 /// Get the short flag of the subcommand.
3386 #[inline]
3387 pub fn get_short_flag(&self) -> Option<char> {
3388 self.short_flag
3389 }
3390
3391 /// Get the long flag of the subcommand.
3392 #[inline]
3393 pub fn get_long_flag(&self) -> Option<&str> {
3394 self.long_flag.as_deref()
3395 }
3396
3397 /// Get the help message specified via [`Command::about`].
3398 ///
3399 /// [`Command::about`]: Command::about()
3400 #[inline]
3401 pub fn get_about(&self) -> Option<&StyledStr> {
3402 self.about.as_ref()
3403 }
3404
3405 /// Get the help message specified via [`Command::long_about`].
3406 ///
3407 /// [`Command::long_about`]: Command::long_about()
3408 #[inline]
3409 pub fn get_long_about(&self) -> Option<&StyledStr> {
3410 self.long_about.as_ref()
3411 }
3412
3413 /// Get the custom section heading specified via [`Command::next_help_heading`].
3414 ///
3415 /// [`Command::help_heading`]: Command::help_heading()
3416 #[inline]
3417 pub fn get_next_help_heading(&self) -> Option<&str> {
3418 self.current_help_heading.as_deref()
3419 }
3420
3421 /// Iterate through the *visible* aliases for this subcommand.
3422 #[inline]
3423 pub fn get_visible_aliases(&self) -> impl Iterator<Item = &str> + '_ {
3424 self.aliases
3425 .iter()
3426 .filter(|(_, vis)| *vis)
3427 .map(|a| a.0.as_str())
3428 }
3429
3430 /// Iterate through the *visible* short aliases for this subcommand.
3431 #[inline]
3432 pub fn get_visible_short_flag_aliases(&self) -> impl Iterator<Item = char> + '_ {
3433 self.short_flag_aliases
3434 .iter()
3435 .filter(|(_, vis)| *vis)
3436 .map(|a| a.0)
3437 }
3438
3439 /// Iterate through the *visible* long aliases for this subcommand.
3440 #[inline]
3441 pub fn get_visible_long_flag_aliases(&self) -> impl Iterator<Item = &str> + '_ {
3442 self.long_flag_aliases
3443 .iter()
3444 .filter(|(_, vis)| *vis)
3445 .map(|a| a.0.as_str())
3446 }
3447
3448 /// Iterate through the set of *all* the aliases for this subcommand, both visible and hidden.
3449 #[inline]
3450 pub fn get_all_aliases(&self) -> impl Iterator<Item = &str> + '_ {
3451 self.aliases.iter().map(|a| a.0.as_str())
3452 }
3453
3454 /// Iterate through the set of *all* the short aliases for this subcommand, both visible and hidden.
3455 #[inline]
3456 pub fn get_all_short_flag_aliases(&self) -> impl Iterator<Item = char> + '_ {
3457 self.short_flag_aliases.iter().map(|a| a.0)
3458 }
3459
3460 /// Iterate through the set of *all* the long aliases for this subcommand, both visible and hidden.
3461 #[inline]
3462 pub fn get_all_long_flag_aliases(&self) -> impl Iterator<Item = &str> + '_ {
3463 self.long_flag_aliases.iter().map(|a| a.0.as_str())
3464 }
3465
3466 #[inline]
3467 pub(crate) fn is_set(&self, s: AppSettings) -> bool {
3468 self.settings.is_set(s) || self.g_settings.is_set(s)
3469 }
3470
3471 /// Should we color the output?
3472 pub fn get_color(&self) -> ColorChoice {
3473 debug!("Command::color: Color setting...");
3474
3475 if cfg!(feature = "color") {
3476 if self.is_set(AppSettings::ColorNever) {
3477 debug!("Never");
3478 ColorChoice::Never
3479 } else if self.is_set(AppSettings::ColorAlways) {
3480 debug!("Always");
3481 ColorChoice::Always
3482 } else {
3483 debug!("Auto");
3484 ColorChoice::Auto
3485 }
3486 } else {
3487 ColorChoice::Never
3488 }
3489 }
3490
3491 /// Return the current `Styles` for the `Command`
3492 #[inline]
3493 pub fn get_styles(&self) -> &Styles {
3494 self.app_ext.get().unwrap_or_default()
3495 }
3496
3497 /// Iterate through the set of subcommands, getting a reference to each.
3498 #[inline]
3499 pub fn get_subcommands(&self) -> impl Iterator<Item = &Command> {
3500 self.subcommands.iter()
3501 }
3502
3503 /// Iterate through the set of subcommands, getting a mutable reference to each.
3504 #[inline]
3505 pub fn get_subcommands_mut(&mut self) -> impl Iterator<Item = &mut Command> {
3506 self.subcommands.iter_mut()
3507 }
3508
3509 /// Returns `true` if this `Command` has subcommands.
3510 #[inline]
3511 pub fn has_subcommands(&self) -> bool {
3512 !self.subcommands.is_empty()
3513 }
3514
3515 /// Returns the help heading for listing subcommands.
3516 #[inline]
3517 pub fn get_subcommand_help_heading(&self) -> Option<&str> {
3518 self.subcommand_heading.as_deref()
3519 }
3520
3521 /// Returns the subcommand value name.
3522 #[inline]
3523 pub fn get_subcommand_value_name(&self) -> Option<&str> {
3524 self.subcommand_value_name.as_deref()
3525 }
3526
3527 /// Returns the help heading for listing subcommands.
3528 #[inline]
3529 pub fn get_before_help(&self) -> Option<&StyledStr> {
3530 self.before_help.as_ref()
3531 }
3532
3533 /// Returns the help heading for listing subcommands.
3534 #[inline]
3535 pub fn get_before_long_help(&self) -> Option<&StyledStr> {
3536 self.before_long_help.as_ref()
3537 }
3538
3539 /// Returns the help heading for listing subcommands.
3540 #[inline]
3541 pub fn get_after_help(&self) -> Option<&StyledStr> {
3542 self.after_help.as_ref()
3543 }
3544
3545 /// Returns the help heading for listing subcommands.
3546 #[inline]
3547 pub fn get_after_long_help(&self) -> Option<&StyledStr> {
3548 self.after_long_help.as_ref()
3549 }
3550
3551 /// Find subcommand such that its name or one of aliases equals `name`.
3552 ///
3553 /// This does not recurse through subcommands of subcommands.
3554 #[inline]
3555 pub fn find_subcommand(&self, name: impl AsRef<std::ffi::OsStr>) -> Option<&Command> {
3556 let name = name.as_ref();
3557 self.get_subcommands().find(|s| s.aliases_to(name))
3558 }
3559
3560 /// Find subcommand such that its name or one of aliases equals `name`, returning
3561 /// a mutable reference to the subcommand.
3562 ///
3563 /// This does not recurse through subcommands of subcommands.
3564 #[inline]
3565 pub fn find_subcommand_mut(
3566 &mut self,
3567 name: impl AsRef<std::ffi::OsStr>,
3568 ) -> Option<&mut Command> {
3569 let name = name.as_ref();
3570 self.get_subcommands_mut().find(|s| s.aliases_to(name))
3571 }
3572
3573 /// Iterate through the set of groups.
3574 #[inline]
3575 pub fn get_groups(&self) -> impl Iterator<Item = &ArgGroup> {
3576 self.groups.iter()
3577 }
3578
3579 /// Iterate through the set of arguments.
3580 #[inline]
3581 pub fn get_arguments(&self) -> impl Iterator<Item = &Arg> {
3582 self.args.args()
3583 }
3584
3585 /// Iterate through the *positionals* arguments.
3586 #[inline]
3587 pub fn get_positionals(&self) -> impl Iterator<Item = &Arg> {
3588 self.get_arguments().filter(|a| a.is_positional())
3589 }
3590
3591 /// Iterate through the *options*.
3592 pub fn get_opts(&self) -> impl Iterator<Item = &Arg> {
3593 self.get_arguments()
3594 .filter(|a| a.is_takes_value_set() && !a.is_positional())
3595 }
3596
3597 /// Get a list of all arguments the given argument conflicts with.
3598 ///
3599 /// If the provided argument is declared as global, the conflicts will be determined
3600 /// based on the propagation rules of global arguments.
3601 ///
3602 /// ### Panics
3603 ///
3604 /// If the given arg contains a conflict with an argument that is unknown to
3605 /// this `Command`.
3606 pub fn get_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg> // FIXME: This could probably have been an iterator
3607 {
3608 if arg.is_global_set() {
3609 self.get_global_arg_conflicts_with(arg)
3610 } else {
3611 let mut result = Vec::new();
3612 for id in arg.blacklist.iter() {
3613 if let Some(arg) = self.find(id) {
3614 result.push(arg);
3615 } else if let Some(group) = self.find_group(id) {
3616 result.extend(
3617 self.unroll_args_in_group(&group.id)
3618 .iter()
3619 .map(|id| self.find(id).expect(INTERNAL_ERROR_MSG)),
3620 );
3621 } else {
3622 panic!("Command::get_arg_conflicts_with: The passed arg conflicts with an arg unknown to the cmd");
3623 }
3624 }
3625 result
3626 }
3627 }
3628
3629 // Get a unique list of all arguments of all commands and continuous subcommands the given argument conflicts with.
3630 //
3631 // This behavior follows the propagation rules of global arguments.
3632 // It is useful for finding conflicts for arguments declared as global.
3633 //
3634 // ### Panics
3635 //
3636 // If the given arg contains a conflict with an argument that is unknown to
3637 // this `Command`.
3638 fn get_global_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg> // FIXME: This could probably have been an iterator
3639 {
3640 arg.blacklist
3641 .iter()
3642 .map(|id| {
3643 self.args
3644 .args()
3645 .chain(
3646 self.get_subcommands_containing(arg)
3647 .iter()
3648 .flat_map(|x| x.args.args()),
3649 )
3650 .find(|arg| arg.get_id() == id)
3651 .expect(
3652 "Command::get_arg_conflicts_with: \
3653 The passed arg conflicts with an arg unknown to the cmd",
3654 )
3655 })
3656 .collect()
3657 }
3658
3659 // Get a list of subcommands which contain the provided Argument
3660 //
3661 // This command will only include subcommands in its list for which the subcommands
3662 // parent also contains the Argument.
3663 //
3664 // This search follows the propagation rules of global arguments.
3665 // It is useful to finding subcommands, that have inherited a global argument.
3666 //
3667 // **NOTE:** In this case only Sucommand_1 will be included
3668 // Subcommand_1 (contains Arg)
3669 // Subcommand_1.1 (doesn't contain Arg)
3670 // Subcommand_1.1.1 (contains Arg)
3671 //
3672 fn get_subcommands_containing(&self, arg: &Arg) -> Vec<&Self> {
3673 let mut vec = std::vec::Vec::new();
3674 for idx in 0..self.subcommands.len() {
3675 if self.subcommands[idx]
3676 .args
3677 .args()
3678 .any(|ar| ar.get_id() == arg.get_id())
3679 {
3680 vec.push(&self.subcommands[idx]);
3681 vec.append(&mut self.subcommands[idx].get_subcommands_containing(arg));
3682 }
3683 }
3684 vec
3685 }
3686
3687 /// Report whether [`Command::no_binary_name`] is set
3688 pub fn is_no_binary_name_set(&self) -> bool {
3689 self.is_set(AppSettings::NoBinaryName)
3690 }
3691
3692 /// Report whether [`Command::ignore_errors`] is set
3693 pub(crate) fn is_ignore_errors_set(&self) -> bool {
3694 self.is_set(AppSettings::IgnoreErrors)
3695 }
3696
3697 /// Report whether [`Command::dont_delimit_trailing_values`] is set
3698 pub fn is_dont_delimit_trailing_values_set(&self) -> bool {
3699 self.is_set(AppSettings::DontDelimitTrailingValues)
3700 }
3701
3702 /// Report whether [`Command::disable_version_flag`] is set
3703 pub fn is_disable_version_flag_set(&self) -> bool {
3704 self.is_set(AppSettings::DisableVersionFlag)
3705 || (self.version.is_none() && self.long_version.is_none())
3706 }
3707
3708 /// Report whether [`Command::propagate_version`] is set
3709 pub fn is_propagate_version_set(&self) -> bool {
3710 self.is_set(AppSettings::PropagateVersion)
3711 }
3712
3713 /// Report whether [`Command::next_line_help`] is set
3714 pub fn is_next_line_help_set(&self) -> bool {
3715 self.is_set(AppSettings::NextLineHelp)
3716 }
3717
3718 /// Report whether [`Command::disable_help_flag`] is set
3719 pub fn is_disable_help_flag_set(&self) -> bool {
3720 self.is_set(AppSettings::DisableHelpFlag)
3721 }
3722
3723 /// Report whether [`Command::disable_help_subcommand`] is set
3724 pub fn is_disable_help_subcommand_set(&self) -> bool {
3725 self.is_set(AppSettings::DisableHelpSubcommand)
3726 }
3727
3728 /// Report whether [`Command::disable_colored_help`] is set
3729 pub fn is_disable_colored_help_set(&self) -> bool {
3730 self.is_set(AppSettings::DisableColoredHelp)
3731 }
3732
3733 /// Report whether [`Command::help_expected`] is set
3734 #[cfg(debug_assertions)]
3735 pub(crate) fn is_help_expected_set(&self) -> bool {
3736 self.is_set(AppSettings::HelpExpected)
3737 }
3738
3739 #[doc(hidden)]
3740 #[cfg_attr(
3741 feature = "deprecated",
3742 deprecated(since = "4.0.0", note = "This is now the default")
3743 )]
3744 pub fn is_dont_collapse_args_in_usage_set(&self) -> bool {
3745 true
3746 }
3747
3748 /// Report whether [`Command::infer_long_args`] is set
3749 pub(crate) fn is_infer_long_args_set(&self) -> bool {
3750 self.is_set(AppSettings::InferLongArgs)
3751 }
3752
3753 /// Report whether [`Command::infer_subcommands`] is set
3754 pub(crate) fn is_infer_subcommands_set(&self) -> bool {
3755 self.is_set(AppSettings::InferSubcommands)
3756 }
3757
3758 /// Report whether [`Command::arg_required_else_help`] is set
3759 pub fn is_arg_required_else_help_set(&self) -> bool {
3760 self.is_set(AppSettings::ArgRequiredElseHelp)
3761 }
3762
3763 #[doc(hidden)]
3764 #[cfg_attr(
3765 feature = "deprecated",
3766 deprecated(
3767 since = "4.0.0",
3768 note = "Replaced with `Arg::is_allow_hyphen_values_set`"
3769 )
3770 )]
3771 pub(crate) fn is_allow_hyphen_values_set(&self) -> bool {
3772 self.is_set(AppSettings::AllowHyphenValues)
3773 }
3774
3775 #[doc(hidden)]
3776 #[cfg_attr(
3777 feature = "deprecated",
3778 deprecated(
3779 since = "4.0.0",
3780 note = "Replaced with `Arg::is_allow_negative_numbers_set`"
3781 )
3782 )]
3783 pub fn is_allow_negative_numbers_set(&self) -> bool {
3784 self.is_set(AppSettings::AllowNegativeNumbers)
3785 }
3786
3787 #[doc(hidden)]
3788 #[cfg_attr(
3789 feature = "deprecated",
3790 deprecated(since = "4.0.0", note = "Replaced with `Arg::is_trailing_var_arg_set`")
3791 )]
3792 pub fn is_trailing_var_arg_set(&self) -> bool {
3793 self.is_set(AppSettings::TrailingVarArg)
3794 }
3795
3796 /// Report whether [`Command::allow_missing_positional`] is set
3797 pub fn is_allow_missing_positional_set(&self) -> bool {
3798 self.is_set(AppSettings::AllowMissingPositional)
3799 }
3800
3801 /// Report whether [`Command::hide`] is set
3802 pub fn is_hide_set(&self) -> bool {
3803 self.is_set(AppSettings::Hidden)
3804 }
3805
3806 /// Report whether [`Command::subcommand_required`] is set
3807 pub fn is_subcommand_required_set(&self) -> bool {
3808 self.is_set(AppSettings::SubcommandRequired)
3809 }
3810
3811 /// Report whether [`Command::allow_external_subcommands`] is set
3812 pub fn is_allow_external_subcommands_set(&self) -> bool {
3813 self.is_set(AppSettings::AllowExternalSubcommands)
3814 }
3815
3816 /// Configured parser for values passed to an external subcommand
3817 ///
3818 /// # Example
3819 ///
3820 /// ```rust
3821 /// # use clap_builder as clap;
3822 /// let cmd = clap::Command::new("raw")
3823 /// .external_subcommand_value_parser(clap::value_parser!(String));
3824 /// let value_parser = cmd.get_external_subcommand_value_parser();
3825 /// println!("{value_parser:?}");
3826 /// ```
3827 pub fn get_external_subcommand_value_parser(&self) -> Option<&super::ValueParser> {
3828 if !self.is_allow_external_subcommands_set() {
3829 None
3830 } else {
3831 static DEFAULT: super::ValueParser = super::ValueParser::os_string();
3832 Some(self.external_value_parser.as_ref().unwrap_or(&DEFAULT))
3833 }
3834 }
3835
3836 /// Report whether [`Command::args_conflicts_with_subcommands`] is set
3837 pub fn is_args_conflicts_with_subcommands_set(&self) -> bool {
3838 self.is_set(AppSettings::ArgsNegateSubcommands)
3839 }
3840
3841 #[doc(hidden)]
3842 pub fn is_args_override_self(&self) -> bool {
3843 self.is_set(AppSettings::AllArgsOverrideSelf)
3844 }
3845
3846 /// Report whether [`Command::subcommand_precedence_over_arg`] is set
3847 pub fn is_subcommand_precedence_over_arg_set(&self) -> bool {
3848 self.is_set(AppSettings::SubcommandPrecedenceOverArg)
3849 }
3850
3851 /// Report whether [`Command::subcommand_negates_reqs`] is set
3852 pub fn is_subcommand_negates_reqs_set(&self) -> bool {
3853 self.is_set(AppSettings::SubcommandsNegateReqs)
3854 }
3855
3856 /// Report whether [`Command::multicall`] is set
3857 pub fn is_multicall_set(&self) -> bool {
3858 self.is_set(AppSettings::Multicall)
3859 }
3860 }
3861
3862 // Internally used only
3863 impl Command {
3864 pub(crate) fn get_override_usage(&self) -> Option<&StyledStr> {
3865 self.usage_str.as_ref()
3866 }
3867
3868 pub(crate) fn get_override_help(&self) -> Option<&StyledStr> {
3869 self.help_str.as_ref()
3870 }
3871
3872 #[cfg(feature = "help")]
3873 pub(crate) fn get_help_template(&self) -> Option<&StyledStr> {
3874 self.template.as_ref()
3875 }
3876
3877 #[cfg(feature = "help")]
3878 pub(crate) fn get_term_width(&self) -> Option<usize> {
3879 self.app_ext.get::<TermWidth>().map(|e| e.0)
3880 }
3881
3882 #[cfg(feature = "help")]
3883 pub(crate) fn get_max_term_width(&self) -> Option<usize> {
3884 self.app_ext.get::<MaxTermWidth>().map(|e| e.0)
3885 }
3886
3887 pub(crate) fn get_keymap(&self) -> &MKeyMap {
3888 &self.args
3889 }
3890
3891 fn get_used_global_args(&self, matches: &ArgMatches, global_arg_vec: &mut Vec<Id>) {
3892 global_arg_vec.extend(
3893 self.args
3894 .args()
3895 .filter(|a| a.is_global_set())
3896 .map(|ga| ga.id.clone()),
3897 );
3898 if let Some((id, matches)) = matches.subcommand() {
3899 if let Some(used_sub) = self.find_subcommand(id) {
3900 used_sub.get_used_global_args(matches, global_arg_vec);
3901 }
3902 }
3903 }
3904
3905 fn _do_parse(
3906 &mut self,
3907 raw_args: &mut clap_lex::RawArgs,
3908 args_cursor: clap_lex::ArgCursor,
3909 ) -> ClapResult<ArgMatches> {
3910 debug!("Command::_do_parse");
3911
3912 // If there are global arguments, or settings we need to propagate them down to subcommands
3913 // before parsing in case we run into a subcommand
3914 self._build_self(false);
3915
3916 let mut matcher = ArgMatcher::new(self);
3917
3918 // do the real parsing
3919 let mut parser = Parser::new(self);
3920 if let Err(error) = parser.get_matches_with(&mut matcher, raw_args, args_cursor) {
3921 if self.is_set(AppSettings::IgnoreErrors) && error.use_stderr() {
3922 debug!("Command::_do_parse: ignoring error: {error}");
3923 } else {
3924 return Err(error);
3925 }
3926 }
3927
3928 let mut global_arg_vec = Default::default();
3929 self.get_used_global_args(&matcher, &mut global_arg_vec);
3930
3931 matcher.propagate_globals(&global_arg_vec);
3932
3933 Ok(matcher.into_inner())
3934 }
3935
3936 /// Prepare for introspecting on all included [`Command`]s
3937 ///
3938 /// Call this on the top-level [`Command`] when done building and before reading state for
3939 /// cases like completions, custom help output, etc.
3940 pub fn build(&mut self) {
3941 self._build_recursive(true);
3942 self._build_bin_names_internal();
3943 }
3944
3945 pub(crate) fn _build_recursive(&mut self, expand_help_tree: bool) {
3946 self._build_self(expand_help_tree);
3947 for subcmd in self.get_subcommands_mut() {
3948 subcmd._build_recursive(expand_help_tree);
3949 }
3950 }
3951
3952 pub(crate) fn _build_self(&mut self, expand_help_tree: bool) {
3953 debug!("Command::_build: name={:?}", self.get_name());
3954 if !self.settings.is_set(AppSettings::Built) {
3955 if let Some(deferred) = self.deferred.take() {
3956 *self = (deferred)(std::mem::take(self));
3957 }
3958
3959 // Make sure all the globally set flags apply to us as well
3960 self.settings = self.settings | self.g_settings;
3961
3962 if self.is_multicall_set() {
3963 self.settings.set(AppSettings::SubcommandRequired);
3964 self.settings.set(AppSettings::DisableHelpFlag);
3965 self.settings.set(AppSettings::DisableVersionFlag);
3966 }
3967 if !cfg!(feature = "help") && self.get_override_help().is_none() {
3968 self.settings.set(AppSettings::DisableHelpFlag);
3969 self.settings.set(AppSettings::DisableHelpSubcommand);
3970 }
3971 if self.is_set(AppSettings::ArgsNegateSubcommands) {
3972 self.settings.set(AppSettings::SubcommandsNegateReqs);
3973 }
3974 if self.external_value_parser.is_some() {
3975 self.settings.set(AppSettings::AllowExternalSubcommands);
3976 }
3977 if !self.has_subcommands() {
3978 self.settings.set(AppSettings::DisableHelpSubcommand);
3979 }
3980
3981 self._propagate();
3982 self._check_help_and_version(expand_help_tree);
3983 self._propagate_global_args();
3984
3985 let mut pos_counter = 1;
3986 let hide_pv = self.is_set(AppSettings::HidePossibleValues);
3987 for a in self.args.args_mut() {
3988 // Fill in the groups
3989 for g in &a.groups {
3990 if let Some(ag) = self.groups.iter_mut().find(|grp| grp.id == *g) {
3991 ag.args.push(a.get_id().clone());
3992 } else {
3993 let mut ag = ArgGroup::new(g);
3994 ag.args.push(a.get_id().clone());
3995 self.groups.push(ag);
3996 }
3997 }
3998
3999 // Figure out implied settings
4000 a._build();
4001 if hide_pv && a.is_takes_value_set() {
4002 a.settings.set(ArgSettings::HidePossibleValues);
4003 }
4004 if a.is_positional() && a.index.is_none() {
4005 a.index = Some(pos_counter);
4006 pos_counter += 1;
4007 }
4008 }
4009
4010 self.args._build();
4011
4012 #[allow(deprecated)]
4013 {
4014 let highest_idx = self
4015 .get_keymap()
4016 .keys()
4017 .filter_map(|x| {
4018 if let crate::mkeymap::KeyType::Position(n) = x {
4019 Some(*n)
4020 } else {
4021 None
4022 }
4023 })
4024 .max()
4025 .unwrap_or(0);
4026 let is_trailing_var_arg_set = self.is_trailing_var_arg_set();
4027 let is_allow_hyphen_values_set = self.is_allow_hyphen_values_set();
4028 let is_allow_negative_numbers_set = self.is_allow_negative_numbers_set();
4029 for arg in self.args.args_mut() {
4030 if is_allow_hyphen_values_set && arg.is_takes_value_set() {
4031 arg.settings.set(ArgSettings::AllowHyphenValues);
4032 }
4033 if is_allow_negative_numbers_set && arg.is_takes_value_set() {
4034 arg.settings.set(ArgSettings::AllowNegativeNumbers);
4035 }
4036 if is_trailing_var_arg_set && arg.get_index() == Some(highest_idx) {
4037 arg.settings.set(ArgSettings::TrailingVarArg);
4038 }
4039 }
4040 }
4041
4042 #[cfg(debug_assertions)]
4043 assert_app(self);
4044 self.settings.set(AppSettings::Built);
4045 } else {
4046 debug!("Command::_build: already built");
4047 }
4048 }
4049
4050 pub(crate) fn _build_subcommand(&mut self, name: &str) -> Option<&mut Self> {
4051 use std::fmt::Write;
4052
4053 let mut mid_string = String::from(" ");
4054 #[cfg(feature = "usage")]
4055 if !self.is_subcommand_negates_reqs_set() && !self.is_args_conflicts_with_subcommands_set()
4056 {
4057 let reqs = Usage::new(self).get_required_usage_from(&[], None, true); // maybe Some(m)
4058
4059 for s in &reqs {
4060 mid_string.push_str(&s.to_string());
4061 mid_string.push(' ');
4062 }
4063 }
4064 let is_multicall_set = self.is_multicall_set();
4065
4066 let sc = some!(self.subcommands.iter_mut().find(|s| s.name == name));
4067
4068 // Display subcommand name, short and long in usage
4069 let mut sc_names = String::new();
4070 sc_names.push_str(sc.name.as_str());
4071 let mut flag_subcmd = false;
4072 if let Some(l) = sc.get_long_flag() {
4073 write!(sc_names, "|--{l}").unwrap();
4074 flag_subcmd = true;
4075 }
4076 if let Some(s) = sc.get_short_flag() {
4077 write!(sc_names, "|-{s}").unwrap();
4078 flag_subcmd = true;
4079 }
4080
4081 if flag_subcmd {
4082 sc_names = format!("{{{sc_names}}}");
4083 }
4084
4085 let usage_name = self
4086 .bin_name
4087 .as_ref()
4088 .map(|bin_name| format!("{bin_name}{mid_string}{sc_names}"))
4089 .unwrap_or(sc_names);
4090 sc.usage_name = Some(usage_name);
4091
4092 // bin_name should be parent's bin_name + [<reqs>] + the sc's name separated by
4093 // a space
4094 let bin_name = format!(
4095 "{}{}{}",
4096 self.bin_name.as_deref().unwrap_or_default(),
4097 if self.bin_name.is_some() { " " } else { "" },
4098 &*sc.name
4099 );
4100 debug!(
4101 "Command::_build_subcommand Setting bin_name of {} to {:?}",
4102 sc.name, bin_name
4103 );
4104 sc.bin_name = Some(bin_name);
4105
4106 if sc.display_name.is_none() {
4107 let self_display_name = if is_multicall_set {
4108 self.display_name.as_deref().unwrap_or("")
4109 } else {
4110 self.display_name.as_deref().unwrap_or(&self.name)
4111 };
4112 let display_name = format!(
4113 "{}{}{}",
4114 self_display_name,
4115 if !self_display_name.is_empty() {
4116 "-"
4117 } else {
4118 ""
4119 },
4120 &*sc.name
4121 );
4122 debug!(
4123 "Command::_build_subcommand Setting display_name of {} to {:?}",
4124 sc.name, display_name
4125 );
4126 sc.display_name = Some(display_name);
4127 }
4128
4129 // Ensure all args are built and ready to parse
4130 sc._build_self(false);
4131
4132 Some(sc)
4133 }
4134
4135 fn _build_bin_names_internal(&mut self) {
4136 debug!("Command::_build_bin_names");
4137
4138 if !self.is_set(AppSettings::BinNameBuilt) {
4139 let mut mid_string = String::from(" ");
4140 #[cfg(feature = "usage")]
4141 if !self.is_subcommand_negates_reqs_set()
4142 && !self.is_args_conflicts_with_subcommands_set()
4143 {
4144 let reqs = Usage::new(self).get_required_usage_from(&[], None, true); // maybe Some(m)
4145
4146 for s in &reqs {
4147 mid_string.push_str(&s.to_string());
4148 mid_string.push(' ');
4149 }
4150 }
4151 let is_multicall_set = self.is_multicall_set();
4152
4153 let self_bin_name = if is_multicall_set {
4154 self.bin_name.as_deref().unwrap_or("")
4155 } else {
4156 self.bin_name.as_deref().unwrap_or(&self.name)
4157 }
4158 .to_owned();
4159
4160 for sc in &mut self.subcommands {
4161 debug!("Command::_build_bin_names:iter: bin_name set...");
4162
4163 if sc.usage_name.is_none() {
4164 use std::fmt::Write;
4165 // Display subcommand name, short and long in usage
4166 let mut sc_names = String::new();
4167 sc_names.push_str(sc.name.as_str());
4168 let mut flag_subcmd = false;
4169 if let Some(l) = sc.get_long_flag() {
4170 write!(sc_names, "|--{l}").unwrap();
4171 flag_subcmd = true;
4172 }
4173 if let Some(s) = sc.get_short_flag() {
4174 write!(sc_names, "|-{s}").unwrap();
4175 flag_subcmd = true;
4176 }
4177
4178 if flag_subcmd {
4179 sc_names = format!("{{{sc_names}}}");
4180 }
4181
4182 let usage_name = format!("{self_bin_name}{mid_string}{sc_names}");
4183 debug!(
4184 "Command::_build_bin_names:iter: Setting usage_name of {} to {:?}",
4185 sc.name, usage_name
4186 );
4187 sc.usage_name = Some(usage_name);
4188 } else {
4189 debug!(
4190 "Command::_build_bin_names::iter: Using existing usage_name of {} ({:?})",
4191 sc.name, sc.usage_name
4192 );
4193 }
4194
4195 if sc.bin_name.is_none() {
4196 let bin_name = format!(
4197 "{}{}{}",
4198 self_bin_name,
4199 if !self_bin_name.is_empty() { " " } else { "" },
4200 &*sc.name
4201 );
4202 debug!(
4203 "Command::_build_bin_names:iter: Setting bin_name of {} to {:?}",
4204 sc.name, bin_name
4205 );
4206 sc.bin_name = Some(bin_name);
4207 } else {
4208 debug!(
4209 "Command::_build_bin_names::iter: Using existing bin_name of {} ({:?})",
4210 sc.name, sc.bin_name
4211 );
4212 }
4213
4214 if sc.display_name.is_none() {
4215 let self_display_name = if is_multicall_set {
4216 self.display_name.as_deref().unwrap_or("")
4217 } else {
4218 self.display_name.as_deref().unwrap_or(&self.name)
4219 };
4220 let display_name = format!(
4221 "{}{}{}",
4222 self_display_name,
4223 if !self_display_name.is_empty() {
4224 "-"
4225 } else {
4226 ""
4227 },
4228 &*sc.name
4229 );
4230 debug!(
4231 "Command::_build_bin_names:iter: Setting display_name of {} to {:?}",
4232 sc.name, display_name
4233 );
4234 sc.display_name = Some(display_name);
4235 } else {
4236 debug!(
4237 "Command::_build_bin_names::iter: Using existing display_name of {} ({:?})",
4238 sc.name, sc.display_name
4239 );
4240 }
4241
4242 sc._build_bin_names_internal();
4243 }
4244 self.set(AppSettings::BinNameBuilt);
4245 } else {
4246 debug!("Command::_build_bin_names: already built");
4247 }
4248 }
4249
4250 pub(crate) fn _panic_on_missing_help(&self, help_required_globally: bool) {
4251 if self.is_set(AppSettings::HelpExpected) || help_required_globally {
4252 let args_missing_help: Vec<Id> = self
4253 .args
4254 .args()
4255 .filter(|arg| arg.get_help().is_none() && arg.get_long_help().is_none())
4256 .map(|arg| arg.get_id().clone())
4257 .collect();
4258
4259 debug_assert!(args_missing_help.is_empty(),
4260 "Command::help_expected is enabled for the Command {}, but at least one of its arguments does not have either `help` or `long_help` set. List of such arguments: {}",
4261 self.name,
4262 args_missing_help.join(", ")
4263 );
4264 }
4265
4266 for sub_app in &self.subcommands {
4267 sub_app._panic_on_missing_help(help_required_globally);
4268 }
4269 }
4270
4271 #[cfg(debug_assertions)]
4272 pub(crate) fn two_args_of<F>(&self, condition: F) -> Option<(&Arg, &Arg)>
4273 where
4274 F: Fn(&Arg) -> bool,
4275 {
4276 two_elements_of(self.args.args().filter(|a: &&Arg| condition(a)))
4277 }
4278
4279 // just in case
4280 #[allow(unused)]
4281 fn two_groups_of<F>(&self, condition: F) -> Option<(&ArgGroup, &ArgGroup)>
4282 where
4283 F: Fn(&ArgGroup) -> bool,
4284 {
4285 two_elements_of(self.groups.iter().filter(|a| condition(a)))
4286 }
4287
4288 /// Propagate global args
4289 pub(crate) fn _propagate_global_args(&mut self) {
4290 debug!("Command::_propagate_global_args:{}", self.name);
4291
4292 let autogenerated_help_subcommand = !self.is_disable_help_subcommand_set();
4293
4294 for sc in &mut self.subcommands {
4295 if sc.get_name() == "help" && autogenerated_help_subcommand {
4296 // Avoid propagating args to the autogenerated help subtrees used in completion.
4297 // This prevents args from showing up during help completions like
4298 // `myapp help subcmd <TAB>`, which should only suggest subcommands and not args,
4299 // while still allowing args to show up properly on the generated help message.
4300 continue;
4301 }
4302
4303 for a in self.args.args().filter(|a| a.is_global_set()) {
4304 if sc.find(&a.id).is_some() {
4305 debug!(
4306 "Command::_propagate skipping {:?} to {}, already exists",
4307 a.id,
4308 sc.get_name(),
4309 );
4310 continue;
4311 }
4312
4313 debug!(
4314 "Command::_propagate pushing {:?} to {}",
4315 a.id,
4316 sc.get_name(),
4317 );
4318 sc.args.push(a.clone());
4319 }
4320 }
4321 }
4322
4323 /// Propagate settings
4324 pub(crate) fn _propagate(&mut self) {
4325 debug!("Command::_propagate:{}", self.name);
4326 let mut subcommands = std::mem::take(&mut self.subcommands);
4327 for sc in &mut subcommands {
4328 self._propagate_subcommand(sc);
4329 }
4330 self.subcommands = subcommands;
4331 }
4332
4333 fn _propagate_subcommand(&self, sc: &mut Self) {
4334 // We have to create a new scope in order to tell rustc the borrow of `sc` is
4335 // done and to recursively call this method
4336 {
4337 if self.settings.is_set(AppSettings::PropagateVersion) {
4338 if let Some(version) = self.version.as_ref() {
4339 sc.version.get_or_insert_with(|| version.clone());
4340 }
4341 if let Some(long_version) = self.long_version.as_ref() {
4342 sc.long_version.get_or_insert_with(|| long_version.clone());
4343 }
4344 }
4345
4346 sc.settings = sc.settings | self.g_settings;
4347 sc.g_settings = sc.g_settings | self.g_settings;
4348 sc.app_ext.update(&self.app_ext);
4349 }
4350 }
4351
4352 pub(crate) fn _check_help_and_version(&mut self, expand_help_tree: bool) {
4353 debug!(
4354 "Command::_check_help_and_version:{} expand_help_tree={}",
4355 self.name, expand_help_tree
4356 );
4357
4358 self.long_help_exists = self.long_help_exists_();
4359
4360 if !self.is_disable_help_flag_set() {
4361 debug!("Command::_check_help_and_version: Building default --help");
4362 let mut arg = Arg::new(Id::HELP)
4363 .short('h')
4364 .long("help")
4365 .action(ArgAction::Help);
4366 if self.long_help_exists {
4367 arg = arg
4368 .help("Print help (see more with '--help')")
4369 .long_help("Print help (see a summary with '-h')");
4370 } else {
4371 arg = arg.help("Print help");
4372 }
4373 // Avoiding `arg_internal` to not be sensitive to `next_help_heading` /
4374 // `next_display_order`
4375 self.args.push(arg);
4376 }
4377 if !self.is_disable_version_flag_set() {
4378 debug!("Command::_check_help_and_version: Building default --version");
4379 let arg = Arg::new(Id::VERSION)
4380 .short('V')
4381 .long("version")
4382 .action(ArgAction::Version)
4383 .help("Print version");
4384 // Avoiding `arg_internal` to not be sensitive to `next_help_heading` /
4385 // `next_display_order`
4386 self.args.push(arg);
4387 }
4388
4389 if !self.is_set(AppSettings::DisableHelpSubcommand) {
4390 debug!("Command::_check_help_and_version: Building help subcommand");
4391 let help_about = "Print this message or the help of the given subcommand(s)";
4392
4393 let mut help_subcmd = if expand_help_tree {
4394 // Slow code path to recursively clone all other subcommand subtrees under help
4395 let help_subcmd = Command::new("help")
4396 .about(help_about)
4397 .global_setting(AppSettings::DisableHelpSubcommand)
4398 .subcommands(self.get_subcommands().map(Command::_copy_subtree_for_help));
4399
4400 let mut help_help_subcmd = Command::new("help").about(help_about);
4401 help_help_subcmd.version = None;
4402 help_help_subcmd.long_version = None;
4403 help_help_subcmd = help_help_subcmd
4404 .setting(AppSettings::DisableHelpFlag)
4405 .setting(AppSettings::DisableVersionFlag);
4406
4407 help_subcmd.subcommand(help_help_subcmd)
4408 } else {
4409 Command::new("help").about(help_about).arg(
4410 Arg::new("subcommand")
4411 .action(ArgAction::Append)
4412 .num_args(..)
4413 .value_name("COMMAND")
4414 .help("Print help for the subcommand(s)"),
4415 )
4416 };
4417 self._propagate_subcommand(&mut help_subcmd);
4418
4419 // The parser acts like this is set, so let's set it so we don't falsely
4420 // advertise it to the user
4421 help_subcmd.version = None;
4422 help_subcmd.long_version = None;
4423 help_subcmd = help_subcmd
4424 .setting(AppSettings::DisableHelpFlag)
4425 .setting(AppSettings::DisableVersionFlag)
4426 .unset_global_setting(AppSettings::PropagateVersion);
4427
4428 self.subcommands.push(help_subcmd);
4429 }
4430 }
4431
4432 fn _copy_subtree_for_help(&self) -> Command {
4433 let mut cmd = Command::new(self.name.clone())
4434 .hide(self.is_hide_set())
4435 .global_setting(AppSettings::DisableHelpFlag)
4436 .global_setting(AppSettings::DisableVersionFlag)
4437 .subcommands(self.get_subcommands().map(Command::_copy_subtree_for_help));
4438 if self.get_about().is_some() {
4439 cmd = cmd.about(self.get_about().unwrap().clone());
4440 }
4441 cmd
4442 }
4443
4444 pub(crate) fn _render_version(&self, use_long: bool) -> String {
4445 debug!("Command::_render_version");
4446
4447 let ver = if use_long {
4448 self.long_version
4449 .as_deref()
4450 .or(self.version.as_deref())
4451 .unwrap_or_default()
4452 } else {
4453 self.version
4454 .as_deref()
4455 .or(self.long_version.as_deref())
4456 .unwrap_or_default()
4457 };
4458 let display_name = self.get_display_name().unwrap_or_else(|| self.get_name());
4459 format!("{display_name} {ver}\n")
4460 }
4461
4462 pub(crate) fn format_group(&self, g: &Id) -> StyledStr {
4463 let g_string = self
4464 .unroll_args_in_group(g)
4465 .iter()
4466 .filter_map(|x| self.find(x))
4467 .map(|x| {
4468 if x.is_positional() {
4469 // Print val_name for positional arguments. e.g. <file_name>
4470 x.name_no_brackets()
4471 } else {
4472 // Print usage string for flags arguments, e.g. <--help>
4473 x.to_string()
4474 }
4475 })
4476 .collect::<Vec<_>>()
4477 .join("|");
4478 let mut styled = StyledStr::new();
4479 styled.push_str("<");
4480 styled.push_string(g_string);
4481 styled.push_str(">");
4482 styled
4483 }
4484 }
4485
4486 /// A workaround:
4487 /// <https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999>
4488 pub(crate) trait Captures<'a> {}
4489 impl<'a, T> Captures<'a> for T {}
4490
4491 // Internal Query Methods
4492 impl Command {
4493 /// Iterate through the *flags* & *options* arguments.
4494 #[cfg(any(feature = "usage", feature = "help"))]
4495 pub(crate) fn get_non_positionals(&self) -> impl Iterator<Item = &Arg> {
4496 self.get_arguments().filter(|a| !a.is_positional())
4497 }
4498
4499 pub(crate) fn find(&self, arg_id: &Id) -> Option<&Arg> {
4500 self.args.args().find(|a| a.get_id() == arg_id)
4501 }
4502
4503 #[inline]
4504 pub(crate) fn contains_short(&self, s: char) -> bool {
4505 debug_assert!(
4506 self.is_set(AppSettings::Built),
4507 "If Command::_build hasn't been called, manually search through Arg shorts"
4508 );
4509
4510 self.args.contains(s)
4511 }
4512
4513 #[inline]
4514 pub(crate) fn set(&mut self, s: AppSettings) {
4515 self.settings.set(s)
4516 }
4517
4518 #[inline]
4519 pub(crate) fn has_positionals(&self) -> bool {
4520 self.get_positionals().next().is_some()
4521 }
4522
4523 #[cfg(any(feature = "usage", feature = "help"))]
4524 pub(crate) fn has_visible_subcommands(&self) -> bool {
4525 self.subcommands
4526 .iter()
4527 .any(|sc| sc.name != "help" && !sc.is_set(AppSettings::Hidden))
4528 }
4529
4530 /// Check if this subcommand can be referred to as `name`. In other words,
4531 /// check if `name` is the name of this subcommand or is one of its aliases.
4532 #[inline]
4533 pub(crate) fn aliases_to(&self, name: impl AsRef<std::ffi::OsStr>) -> bool {
4534 let name = name.as_ref();
4535 self.get_name() == name || self.get_all_aliases().any(|alias| alias == name)
4536 }
4537
4538 /// Check if this subcommand can be referred to as `name`. In other words,
4539 /// check if `name` is the name of this short flag subcommand or is one of its short flag aliases.
4540 #[inline]
4541 pub(crate) fn short_flag_aliases_to(&self, flag: char) -> bool {
4542 Some(flag) == self.short_flag
4543 || self.get_all_short_flag_aliases().any(|alias| flag == alias)
4544 }
4545
4546 /// Check if this subcommand can be referred to as `name`. In other words,
4547 /// check if `name` is the name of this long flag subcommand or is one of its long flag aliases.
4548 #[inline]
4549 pub(crate) fn long_flag_aliases_to(&self, flag: &str) -> bool {
4550 match self.long_flag.as_ref() {
4551 Some(long_flag) => {
4552 long_flag == flag || self.get_all_long_flag_aliases().any(|alias| alias == flag)
4553 }
4554 None => self.get_all_long_flag_aliases().any(|alias| alias == flag),
4555 }
4556 }
4557
4558 #[cfg(debug_assertions)]
4559 pub(crate) fn id_exists(&self, id: &Id) -> bool {
4560 self.args.args().any(|x| x.get_id() == id) || self.groups.iter().any(|x| x.id == *id)
4561 }
4562
4563 /// Iterate through the groups this arg is member of.
4564 pub(crate) fn groups_for_arg<'a>(&'a self, arg: &Id) -> impl Iterator<Item = Id> + 'a {
4565 debug!("Command::groups_for_arg: id={arg:?}");
4566 let arg = arg.clone();
4567 self.groups
4568 .iter()
4569 .filter(move |grp| grp.args.iter().any(|a| a == &arg))
4570 .map(|grp| grp.id.clone())
4571 }
4572
4573 pub(crate) fn find_group(&self, group_id: &Id) -> Option<&ArgGroup> {
4574 self.groups.iter().find(|g| g.id == *group_id)
4575 }
4576
4577 /// Iterate through all the names of all subcommands (not recursively), including aliases.
4578 /// Used for suggestions.
4579 pub(crate) fn all_subcommand_names(&self) -> impl Iterator<Item = &str> + Captures {
4580 self.get_subcommands().flat_map(|sc| {
4581 let name = sc.get_name();
4582 let aliases = sc.get_all_aliases();
4583 std::iter::once(name).chain(aliases)
4584 })
4585 }
4586
4587 pub(crate) fn required_graph(&self) -> ChildGraph<Id> {
4588 let mut reqs = ChildGraph::with_capacity(5);
4589 for a in self.args.args().filter(|a| a.is_required_set()) {
4590 reqs.insert(a.get_id().clone());
4591 }
4592 for group in &self.groups {
4593 if group.required {
4594 let idx = reqs.insert(group.id.clone());
4595 for a in &group.requires {
4596 reqs.insert_child(idx, a.clone());
4597 }
4598 }
4599 }
4600
4601 reqs
4602 }
4603
4604 pub(crate) fn unroll_args_in_group(&self, group: &Id) -> Vec<Id> {
4605 debug!("Command::unroll_args_in_group: group={group:?}");
4606 let mut g_vec = vec![group];
4607 let mut args = vec![];
4608
4609 while let Some(g) = g_vec.pop() {
4610 for n in self
4611 .groups
4612 .iter()
4613 .find(|grp| grp.id == *g)
4614 .expect(INTERNAL_ERROR_MSG)
4615 .args
4616 .iter()
4617 {
4618 debug!("Command::unroll_args_in_group:iter: entity={n:?}");
4619 if !args.contains(n) {
4620 if self.find(n).is_some() {
4621 debug!("Command::unroll_args_in_group:iter: this is an arg");
4622 args.push(n.clone())
4623 } else {
4624 debug!("Command::unroll_args_in_group:iter: this is a group");
4625 g_vec.push(n);
4626 }
4627 }
4628 }
4629 }
4630
4631 args
4632 }
4633
4634 pub(crate) fn unroll_arg_requires<F>(&self, func: F, arg: &Id) -> Vec<Id>
4635 where
4636 F: Fn(&(ArgPredicate, Id)) -> Option<Id>,
4637 {
4638 let mut processed = vec![];
4639 let mut r_vec = vec![arg];
4640 let mut args = vec![];
4641
4642 while let Some(a) = r_vec.pop() {
4643 if processed.contains(&a) {
4644 continue;
4645 }
4646
4647 processed.push(a);
4648
4649 if let Some(arg) = self.find(a) {
4650 for r in arg.requires.iter().filter_map(&func) {
4651 if let Some(req) = self.find(&r) {
4652 if !req.requires.is_empty() {
4653 r_vec.push(req.get_id())
4654 }
4655 }
4656 args.push(r);
4657 }
4658 }
4659 }
4660
4661 args
4662 }
4663
4664 /// Find a flag subcommand name by short flag or an alias
4665 pub(crate) fn find_short_subcmd(&self, c: char) -> Option<&str> {
4666 self.get_subcommands()
4667 .find(|sc| sc.short_flag_aliases_to(c))
4668 .map(|sc| sc.get_name())
4669 }
4670
4671 /// Find a flag subcommand name by long flag or an alias
4672 pub(crate) fn find_long_subcmd(&self, long: &str) -> Option<&str> {
4673 self.get_subcommands()
4674 .find(|sc| sc.long_flag_aliases_to(long))
4675 .map(|sc| sc.get_name())
4676 }
4677
4678 #[cfg(feature = "help")]
4679 pub(crate) fn get_display_order(&self) -> usize {
4680 self.disp_ord.unwrap_or(999)
4681 }
4682
4683 pub(crate) fn write_help_err(&self, mut use_long: bool) -> StyledStr {
4684 debug!(
4685 "Command::write_help_err: {}, use_long={:?}",
4686 self.get_display_name().unwrap_or_else(|| self.get_name()),
4687 use_long && self.long_help_exists(),
4688 );
4689
4690 use_long = use_long && self.long_help_exists();
4691 let usage = Usage::new(self);
4692
4693 let mut styled = StyledStr::new();
4694 write_help(&mut styled, self, &usage, use_long);
4695
4696 styled
4697 }
4698
4699 pub(crate) fn write_version_err(&self, use_long: bool) -> StyledStr {
4700 let msg = self._render_version(use_long);
4701 StyledStr::from(msg)
4702 }
4703
4704 pub(crate) fn long_help_exists(&self) -> bool {
4705 debug!("Command::long_help_exists: {}", self.long_help_exists);
4706 self.long_help_exists
4707 }
4708
4709 fn long_help_exists_(&self) -> bool {
4710 debug!("Command::long_help_exists");
4711 // In this case, both must be checked. This allows the retention of
4712 // original formatting, but also ensures that the actual -h or --help
4713 // specified by the user is sent through. If hide_short_help is not included,
4714 // then items specified with hidden_short_help will also be hidden.
4715 let should_long = |v: &Arg| {
4716 !v.is_hide_set()
4717 && (v.get_long_help().is_some()
4718 || v.is_hide_long_help_set()
4719 || v.is_hide_short_help_set()
4720 || (!v.is_hide_possible_values_set()
4721 && v.get_possible_values()
4722 .iter()
4723 .any(PossibleValue::should_show_help)))
4724 };
4725
4726 // Subcommands aren't checked because we prefer short help for them, deferring to
4727 // `cmd subcmd --help` for more.
4728 self.get_long_about().is_some()
4729 || self.get_before_long_help().is_some()
4730 || self.get_after_long_help().is_some()
4731 || self.get_arguments().any(should_long)
4732 }
4733
4734 // Should we color the help?
4735 pub(crate) fn color_help(&self) -> ColorChoice {
4736 #[cfg(feature = "color")]
4737 if self.is_disable_colored_help_set() {
4738 return ColorChoice::Never;
4739 }
4740
4741 self.get_color()
4742 }
4743 }
4744
4745 impl Default for Command {
4746 fn default() -> Self {
4747 Self {
4748 name: Default::default(),
4749 long_flag: Default::default(),
4750 short_flag: Default::default(),
4751 display_name: Default::default(),
4752 bin_name: Default::default(),
4753 author: Default::default(),
4754 version: Default::default(),
4755 long_version: Default::default(),
4756 about: Default::default(),
4757 long_about: Default::default(),
4758 before_help: Default::default(),
4759 before_long_help: Default::default(),
4760 after_help: Default::default(),
4761 after_long_help: Default::default(),
4762 aliases: Default::default(),
4763 short_flag_aliases: Default::default(),
4764 long_flag_aliases: Default::default(),
4765 usage_str: Default::default(),
4766 usage_name: Default::default(),
4767 help_str: Default::default(),
4768 disp_ord: Default::default(),
4769 #[cfg(feature = "help")]
4770 template: Default::default(),
4771 settings: Default::default(),
4772 g_settings: Default::default(),
4773 args: Default::default(),
4774 subcommands: Default::default(),
4775 groups: Default::default(),
4776 current_help_heading: Default::default(),
4777 current_disp_ord: Some(0),
4778 subcommand_value_name: Default::default(),
4779 subcommand_heading: Default::default(),
4780 external_value_parser: Default::default(),
4781 long_help_exists: false,
4782 deferred: None,
4783 app_ext: Default::default(),
4784 }
4785 }
4786 }
4787
4788 impl Index<&'_ Id> for Command {
4789 type Output = Arg;
4790
4791 fn index(&self, key: &Id) -> &Self::Output {
4792 self.find(key).expect(INTERNAL_ERROR_MSG)
4793 }
4794 }
4795
4796 impl From<&'_ Command> for Command {
4797 fn from(cmd: &'_ Command) -> Self {
4798 cmd.clone()
4799 }
4800 }
4801
4802 impl fmt::Display for Command {
4803 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4804 write!(f, "{}", self.name)
4805 }
4806 }
4807
4808 pub(crate) trait AppTag: crate::builder::ext::Extension {}
4809
4810 #[derive(Default, Copy, Clone, Debug)]
4811 struct TermWidth(usize);
4812
4813 impl AppTag for TermWidth {}
4814
4815 #[derive(Default, Copy, Clone, Debug)]
4816 struct MaxTermWidth(usize);
4817
4818 impl AppTag for MaxTermWidth {}
4819
4820 fn two_elements_of<I, T>(mut iter: I) -> Option<(T, T)>
4821 where
4822 I: Iterator<Item = T>,
4823 {
4824 let first = iter.next();
4825 let second = iter.next();
4826
4827 match (first, second) {
4828 (Some(first), Some(second)) => Some((first, second)),
4829 _ => None,
4830 }
4831 }
4832
4833 #[test]
4834 fn check_auto_traits() {
4835 static_assertions::assert_impl_all!(Command: Send, Sync, Unpin);
4836 }