#![cfg_attr(not(feature = "usage"), allow(unused_mut))]
// Std
use std::env;
use std::ffi::OsString;
use std::fmt;
use std::io;
use std::ops::Index;
use std::path::Path;
// Internal
use crate::builder::app_settings::{AppFlags, AppSettings};
use crate::builder::arg_settings::ArgSettings;
use crate::builder::ext::Extensions;
use crate::builder::ArgAction;
use crate::builder::IntoResettable;
use crate::builder::PossibleValue;
use crate::builder::Str;
use crate::builder::StyledStr;
use crate::builder::Styles;
use crate::builder::{Arg, ArgGroup, ArgPredicate};
use crate::error::ErrorKind;
use crate::error::Result as ClapResult;
use crate::mkeymap::MKeyMap;
use crate::output::fmt::Stream;
use crate::output::{fmt::Colorizer, write_help, Usage};
use crate::parser::{ArgMatcher, ArgMatches, Parser};
use crate::util::ChildGraph;
use crate::util::{color::ColorChoice, Id};
use crate::{Error, INTERNAL_ERROR_MSG};
#[cfg(debug_assertions)]
use crate::builder::debug_asserts::assert_app;
/// Build a command-line interface.
///
/// This includes defining arguments, subcommands, parser behavior, and help output.
/// Once all configuration is complete,
/// the [`Command::get_matches`] family of methods starts the runtime-parsing
/// process. These methods then return information about the user supplied
/// arguments (or lack thereof).
///
/// When deriving a [`Parser`][crate::Parser], you can use
/// [`CommandFactory::command`][crate::CommandFactory::command] to access the
/// `Command`.
///
/// - [Basic API][crate::Command#basic-api]
/// - [Application-wide Settings][crate::Command#application-wide-settings]
/// - [Command-specific Settings][crate::Command#command-specific-settings]
/// - [Subcommand-specific Settings][crate::Command#subcommand-specific-settings]
/// - [Reflection][crate::Command#reflection]
///
/// # Examples
///
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// let m = Command::new("My Program")
/// .author("Me, me@mail.com")
/// .version("1.0.2")
/// .about("Explains in brief what the program does")
/// .arg(
/// Arg::new("in_file")
/// )
/// .after_help("Longer explanation to appear after the options when \
/// displaying the help information from --help or -h")
/// .get_matches();
///
/// // Your program logic starts here...
/// ```
/// [`Command::get_matches`]: Command::get_matches()
#[derive(Debug, Clone)]
pub struct Command {
name: Str,
long_flag: Option<Str>,
short_flag: Option<char>,
display_name: Option<String>,
bin_name: Option<String>,
author: Option<Str>,
version: Option<Str>,
long_version: Option<Str>,
about: Option<StyledStr>,
long_about: Option<StyledStr>,
before_help: Option<StyledStr>,
before_long_help: Option<StyledStr>,
after_help: Option<StyledStr>,
after_long_help: Option<StyledStr>,
aliases: Vec<(Str, bool)>, // (name, visible)
short_flag_aliases: Vec<(char, bool)>, // (name, visible)
long_flag_aliases: Vec<(Str, bool)>, // (name, visible)
usage_str: Option<StyledStr>,
usage_name: Option<String>,
help_str: Option<StyledStr>,
disp_ord: Option<usize>,
#[cfg(feature = "help")]
template: Option<StyledStr>,
settings: AppFlags,
g_settings: AppFlags,
args: MKeyMap,
subcommands: Vec<Command>,
groups: Vec<ArgGroup>,
current_help_heading: Option<Str>,
current_disp_ord: Option<usize>,
subcommand_value_name: Option<Str>,
subcommand_heading: Option<Str>,
external_value_parser: Option<super::ValueParser>,
long_help_exists: bool,
deferred: Option<fn(Command) -> Command>,
app_ext: Extensions,
}
/// # Basic API
impl Command {
/// Creates a new instance of an `Command`.
///
/// It is common, but not required, to use binary name as the `name`. This
/// name will only be displayed to the user when they request to print
/// version or help and usage information.
///
/// See also [`command!`](crate::command!) and [`crate_name!`](crate::crate_name!).
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("My Program")
/// # ;
/// ```
pub fn new(name: impl Into<Str>) -> Self {
/// The actual implementation of `new`, non-generic to save code size.
///
/// If we don't do this rustc will unnecessarily generate multiple versions
/// of this code.
fn new_inner(name: Str) -> Command {
Command {
name,
..Default::default()
}
}
new_inner(name.into())
}
/// Adds an [argument] to the list of valid possibilities.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, arg, Arg};
/// Command::new("myprog")
/// // Adding a single "flag" argument with a short and help text, using Arg::new()
/// .arg(
/// Arg::new("debug")
/// .short('d')
/// .help("turns on debugging mode")
/// )
/// // Adding a single "option" argument with a short, a long, and help text using the less
/// // verbose Arg::from()
/// .arg(
/// arg!(-c --config <CONFIG> "Optionally sets a config file to use")
/// )
/// # ;
/// ```
/// [argument]: Arg
#[must_use]
pub fn arg(mut self, a: impl Into<Arg>) -> Self {
let arg = a.into();
self.arg_internal(arg);
self
}
fn arg_internal(&mut self, mut arg: Arg) {
if let Some(current_disp_ord) = self.current_disp_ord.as_mut() {
if !arg.is_positional() {
let current = *current_disp_ord;
arg.disp_ord.get_or_insert(current);
*current_disp_ord = current + 1;
}
}
arg.help_heading
.get_or_insert_with(|| self.current_help_heading.clone());
self.args.push(arg);
}
/// Adds multiple [arguments] to the list of valid possibilities.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, arg, Arg};
/// Command::new("myprog")
/// .args([
/// arg!(-d --debug "turns on debugging info"),
/// Arg::new("input").help("the input file to use")
/// ])
/// # ;
/// ```
/// [arguments]: Arg
#[must_use]
pub fn args(mut self, args: impl IntoIterator<Item = impl Into<Arg>>) -> Self {
for arg in args {
self = self.arg(arg);
}
self
}
/// Allows one to mutate an [`Arg`] after it's been added to a [`Command`].
///
/// # Panics
///
/// If the argument is undefined
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, Arg, ArgAction};
///
/// let mut cmd = Command::new("foo")
/// .arg(Arg::new("bar")
/// .short('b')
/// .action(ArgAction::SetTrue))
/// .mut_arg("bar", |a| a.short('B'));
///
/// let res = cmd.try_get_matches_from_mut(vec!["foo", "-b"]);
///
/// // Since we changed `bar`'s short to "B" this should err as there
/// // is no `-b` anymore, only `-B`
///
/// assert!(res.is_err());
///
/// let res = cmd.try_get_matches_from_mut(vec!["foo", "-B"]);
/// assert!(res.is_ok());
/// ```
#[must_use]
#[cfg_attr(debug_assertions, track_caller)]
pub fn mut_arg<F>(mut self, arg_id: impl AsRef<str>, f: F) -> Self
where
F: FnOnce(Arg) -> Arg,
{
let id = arg_id.as_ref();
let a = self
.args
.remove_by_name(id)
.unwrap_or_else(|| panic!("Argument `{id}` is undefined"));
self.args.push(f(a));
self
}
/// Allows one to mutate all [`Arg`]s after they've been added to a [`Command`].
///
/// This does not affect the built-in `--help` or `--version` arguments.
///
/// # Examples
///
#[cfg_attr(feature = "string", doc = "```")]
#[cfg_attr(not(feature = "string"), doc = "```ignore")]
/// # use clap_builder as clap;
/// # use clap::{Command, Arg, ArgAction};
///
/// let mut cmd = Command::new("foo")
/// .arg(Arg::new("bar")
/// .long("bar")
/// .action(ArgAction::SetTrue))
/// .arg(Arg::new("baz")
/// .long("baz")
/// .action(ArgAction::SetTrue))
/// .mut_args(|a| {
/// if let Some(l) = a.get_long().map(|l| format!("prefix-{l}")) {
/// a.long(l)
/// } else {
/// a
/// }
/// });
///
/// let res = cmd.try_get_matches_from_mut(vec!["foo", "--bar"]);
///
/// // Since we changed `bar`'s long to "prefix-bar" this should err as there
/// // is no `--bar` anymore, only `--prefix-bar`.
///
/// assert!(res.is_err());
///
/// let res = cmd.try_get_matches_from_mut(vec!["foo", "--prefix-bar"]);
/// assert!(res.is_ok());
/// ```
#[must_use]
#[cfg_attr(debug_assertions, track_caller)]
pub fn mut_args<F>(mut self, f: F) -> Self
where
F: FnMut(Arg) -> Arg,
{
self.args.mut_args(f);
self
}
/// Allows one to mutate an [`ArgGroup`] after it's been added to a [`Command`].
///
/// # Panics
///
/// If the argument is undefined
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, arg, ArgGroup};
///
/// Command::new("foo")
/// .arg(arg!(--"set-ver" <ver> "set the version manually").required(false))
/// .arg(arg!(--major "auto increase major"))
/// .arg(arg!(--minor "auto increase minor"))
/// .arg(arg!(--patch "auto increase patch"))
/// .group(ArgGroup::new("vers")
/// .args(["set-ver", "major", "minor","patch"])
/// .required(true))
/// .mut_group("vers", |a| a.required(false));
/// ```
#[must_use]
#[cfg_attr(debug_assertions, track_caller)]
pub fn mut_group<F>(mut self, arg_id: impl AsRef<str>, f: F) -> Self
where
F: FnOnce(ArgGroup) -> ArgGroup,
{
let id = arg_id.as_ref();
let index = self
.groups
.iter()
.position(|g| g.get_id() == id)
.unwrap_or_else(|| panic!("Group `{id}` is undefined"));
let a = self.groups.remove(index);
self.groups.push(f(a));
self
}
/// Allows one to mutate a [`Command`] after it's been added as a subcommand.
///
/// This can be useful for modifying auto-generated arguments of nested subcommands with
/// [`Command::mut_arg`].
///
/// # Panics
///
/// If the subcommand is undefined
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
///
/// let mut cmd = Command::new("foo")
/// .subcommand(Command::new("bar"))
/// .mut_subcommand("bar", |subcmd| subcmd.disable_help_flag(true));
///
/// let res = cmd.try_get_matches_from_mut(vec!["foo", "bar", "--help"]);
///
/// // Since we disabled the help flag on the "bar" subcommand, this should err.
///
/// assert!(res.is_err());
///
/// let res = cmd.try_get_matches_from_mut(vec!["foo", "bar"]);
/// assert!(res.is_ok());
/// ```
#[must_use]
pub fn mut_subcommand<F>(mut self, name: impl AsRef<str>, f: F) -> Self
where
F: FnOnce(Self) -> Self,
{
let name = name.as_ref();
let pos = self.subcommands.iter().position(|s| s.name == name);
let subcmd = if let Some(idx) = pos {
self.subcommands.remove(idx)
} else {
panic!("Command `{name}` is undefined")
};
self.subcommands.push(f(subcmd));
self
}
/// Adds an [`ArgGroup`] to the application.
///
/// [`ArgGroup`]s are a family of related arguments.
/// By placing them in a logical group, you can build easier requirement and exclusion rules.
///
/// Example use cases:
/// - Make an entire [`ArgGroup`] required, meaning that one (and *only*
/// one) argument from that group must be present at runtime.
/// - Name an [`ArgGroup`] as a conflict to another argument.
/// Meaning any of the arguments that belong to that group will cause a failure if present with
/// the conflicting argument.
/// - Ensure exclusion between arguments.
/// - Extract a value from a group instead of determining exactly which argument was used.
///
/// # Examples
///
/// The following example demonstrates using an [`ArgGroup`] to ensure that one, and only one,
/// of the arguments from the specified group is present at runtime.
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, arg, ArgGroup};
/// Command::new("cmd")
/// .arg(arg!(--"set-ver" <ver> "set the version manually").required(false))
/// .arg(arg!(--major "auto increase major"))
/// .arg(arg!(--minor "auto increase minor"))
/// .arg(arg!(--patch "auto increase patch"))
/// .group(ArgGroup::new("vers")
/// .args(["set-ver", "major", "minor","patch"])
/// .required(true))
/// # ;
/// ```
#[inline]
#[must_use]
pub fn group(mut self, group: impl Into<ArgGroup>) -> Self {
self.groups.push(group.into());
self
}
/// Adds multiple [`ArgGroup`]s to the [`Command`] at once.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, arg, ArgGroup};
/// Command::new("cmd")
/// .arg(arg!(--"set-ver" <ver> "set the version manually").required(false))
/// .arg(arg!(--major "auto increase major"))
/// .arg(arg!(--minor "auto increase minor"))
/// .arg(arg!(--patch "auto increase patch"))
/// .arg(arg!(-c <FILE> "a config file").required(false))
/// .arg(arg!(-i <IFACE> "an interface").required(false))
/// .groups([
/// ArgGroup::new("vers")
/// .args(["set-ver", "major", "minor","patch"])
/// .required(true),
/// ArgGroup::new("input")
/// .args(["c", "i"])
/// ])
/// # ;
/// ```
#[must_use]
pub fn groups(mut self, groups: impl IntoIterator<Item = impl Into<ArgGroup>>) -> Self {
for g in groups {
self = self.group(g.into());
}
self
}
/// Adds a subcommand to the list of valid possibilities.
///
/// Subcommands are effectively sub-[`Command`]s, because they can contain their own argume
nts,
/// subcommands, version, usage, etc. They also function just like [`Command`]s, in that they get
/// their own auto generated help, version, and usage.
///
/// A subcommand's [`Command::name`] will be used for:
/// - The argument the user passes in
/// - Programmatically looking up the subcommand
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, arg};
/// Command::new("myprog")
/// .subcommand(Command::new("config")
/// .about("Controls configuration features")
/// .arg(arg!(<config> "Required configuration file to use")))
/// # ;
/// ```
#[inline]
#[must_use]
pub fn subcommand(self, subcmd: impl Into<Command>) -> Self {
let subcmd = subcmd.into();
self.subcommand_internal(subcmd)
}
fn subcommand_internal(mut self, mut subcmd: Self) -> Self {
if let Some(current_disp_ord) = self.current_disp_ord.as_mut() {
let current = *current_disp_ord;
subcmd.disp_ord.get_or_insert(current);
*current_disp_ord = current + 1;
}
self.subcommands.push(subcmd);
self
}
/// Adds multiple subcommands to the list of valid possibilities.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, Arg, };
/// # Command::new("myprog")
/// .subcommands( [
/// Command::new("config").about("Controls configuration functionality")
/// .arg(Arg::new("config_file")),
/// Command::new("debug").about("Controls debug functionality")])
/// # ;
/// ```
/// [`IntoIterator`]: std::iter::IntoIterator
#[must_use]
pub fn subcommands(mut self, subcmds: impl IntoIterator<Item = impl Into<Self>>) -> Self {
for subcmd in subcmds {
self = self.subcommand(subcmd);
}
self
}
/// Delay initialization for parts of the `Command`
///
/// This is useful for large applications to delay definitions of subcommands until they are
/// being invoked.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, arg};
/// Command::new("myprog")
/// .subcommand(Command::new("config")
/// .about("Controls configuration features")
/// .defer(|cmd| {
/// cmd.arg(arg!(<config> "Required configuration file to use"))
/// })
/// )
/// # ;
/// ```
pub fn defer(mut self, deferred: fn(Command) -> Command) -> Self {
self.deferred = Some(deferred);
self
}
/// Catch problems earlier in the development cycle.
///
/// Most error states are handled as asserts under the assumption they are programming mistake
/// and not something to handle at runtime. Rather than relying on tests (manual or automated)
/// that exhaustively test your CLI to ensure the asserts are evaluated, this will run those
/// asserts in a way convenient for running as a test.
///
/// **Note:** This will not help with asserts in [`ArgMatches`], those will need exhaustive
/// testing of your CLI.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, Arg, ArgAction};
/// fn cmd() -> Command {
/// Command::new("foo")
/// .arg(
/// Arg::new("bar").short('b').action(ArgAction::SetTrue)
/// )
/// }
///
/// #[test]
/// fn verify_app() {
/// cmd().debug_assert();
/// }
///
/// fn main() {
/// let m = cmd().get_matches_from(vec!["foo", "-b"]);
/// println!("{}", m.get_flag("bar"));
/// }
/// ```
pub fn debug_assert(mut self) {
self.build();
}
/// Custom error message for post-parsing validation
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, error::ErrorKind};
/// let mut cmd = Command::new("myprog");
/// let err = cmd.error(ErrorKind::InvalidValue, "Some failure case");
/// ```
pub fn error(&mut self, kind: ErrorKind, message: impl fmt::Display) -> Error {
Error::raw(kind, message).format(self)
}
/// Parse [`env::args_os`], [exiting][Error::exit] on failure.
///
/// # Panics
///
/// If contradictory arguments or settings exist (debug builds).
///
/// # Examples
///
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// let matches = Command::new("myprog")
/// // Args and options go here...
/// .get_matches();
/// ```
/// [`env::args_os`]: std::env::args_os()
/// [`Command::try_get_matches_from_mut`]: Command::try_get_matches_from_mut()
#[inline]
pub fn get_matches(self) -> ArgMatches {
self.get_matches_from(env::args_os())
}
/// Parse [`env::args_os`], [exiting][Error::exit] on failure.
///
/// Like [`Command::get_matches`] but doesn't consume the `Command`.
///
/// # Panics
///
/// If contradictory arguments or settings exist (debug builds).
///
/// # Examples
///
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// let mut cmd = Command::new("myprog")
/// // Args and options go here...
/// ;
/// let matches = cmd.get_matches_mut();
/// ```
/// [`env::args_os`]: std::env::args_os()
/// [`Command::get_matches`]: Command::get_matches()
pub fn get_matches_mut(&mut self) -> ArgMatches {
self.try_get_matches_from_mut(env::args_os())
.unwrap_or_else(|e| e.exit())
}
/// Parse [`env::args_os`], returning a [`clap::Result`] on failure.
///
/// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are
/// used. It will return a [`clap::Error`], where the [`kind`] is a
/// [`ErrorKind::DisplayHelp`] or [`ErrorKind::DisplayVersion`] respectively. You must call
/// [`Error::exit`] or perform a [`std::process::exit`].
///
/// # Panics
///
/// If contradictory arguments or settings exist (debug builds).
///
/// # Examples
///
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// let matches = Command::new("myprog")
/// // Args and options go here...
/// .try_get_matches()
/// .unwrap_or_else(|e| e.exit());
/// ```
/// [`env::args_os`]: std::env::args_os()
/// [`Error::exit`]: crate::Error::exit()
/// [`std::process::exit`]: std::process::exit()
/// [`clap::Result`]: Result
/// [`clap::Error`]: crate::Error
/// [`kind`]: crate::Error
/// [`ErrorKind::DisplayHelp`]: crate::error::ErrorKind::DisplayHelp
/// [`ErrorKind::DisplayVersion`]: crate::error::ErrorKind::DisplayVersion
#[inline]
pub fn try_get_matches(self) -> ClapResult<ArgMatches> {
// Start the parsing
self.try_get_matches_from(env::args_os())
}
/// Parse the specified arguments, [exiting][Error::exit] on failure.
///
/// **NOTE:** The first argument will be parsed as the binary name unless
/// [`Command::no_binary_name`] is used.
///
/// # Panics
///
/// If contradictory arguments or settings exist (debug builds).
///
/// # Examples
///
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"];
///
/// let matches = Command::new("myprog")
/// // Args and options go here...
/// .get_matches_from(arg_vec);
/// ```
/// [`Command::get_matches`]: Command::get_matches()
/// [`clap::Result`]: Result
/// [`Vec`]: std::vec::Vec
pub fn get_matches_from<I, T>(mut self, itr: I) -> ArgMatches
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
self.try_get_matches_from_mut(itr).unwrap_or_else(|e| {
drop(self);
e.exit()
})
}
/// Parse the specified arguments, returning a [`clap::Result`] on failure.
///
/// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are
/// used. It will return a [`clap::Error`], where the [`kind`] is a [`ErrorKind::DisplayHelp`]
/// or [`ErrorKind::DisplayVersion`] respectively. You must call [`Error::exit`] or
/// perform a [`std::process::exit`] yourself.
///
/// **NOTE:** The first argument will be parsed as the binary name unless
/// [`Command::no_binary_name`] is used.
///
/// # Panics
///
/// If contradictory arguments or settings exist (debug builds).
///
/// # Examples
///
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"];
///
/// let matches = Command::new("myprog")
/// // Args and options go here...
/// .try_get_matches_from(arg_vec)
/// .unwrap_or_else(|e| e.exit());
/// ```
/// [`Command::get_matches_from`]: Command::get_matches_from()
/// [`Command::try_get_matches`]: Command::try_get_matches()
/// [`Error::exit`]: crate::Error::exit()
/// [`std::process::exit`]: std::process::exit()
/// [`clap::Error`]: crate::Error
/// [`Error::exit`]: crate::Error::exit()
/// [`kind`]: crate::Error
/// [`ErrorKind::DisplayHelp`]: crate::error::ErrorKind::DisplayHelp
/// [`ErrorKind::DisplayVersion`]: crate::error::ErrorKind::DisplayVersion
/// [`clap::Result`]: Result
pub fn try_get_matches_from<I, T>(mut self, itr: I) -> ClapResult<ArgMatches>
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
self.try_get_matches_from_mut(itr)
}
/// Parse the specified arguments, returning a [`clap::Result`] on failure.
///
/// Like [`Command::try_get_matches_from`] but doesn't consume the `Command`.
///
/// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are
/// used. It will return a [`clap::Error`], where the [`kind`] is a [`ErrorKind::DisplayHelp`]
/// or [`ErrorKind::DisplayVersion`] respectively. You must call [`Error::exit`] or
/// perform a [`std::process::exit`] yourself.
///
/// **NOTE:** The first argument will be parsed as the binary name unless
/// [`Command::no_binary_name`] is used.
///
/// # Panics
///
/// If contradictory arguments or settings exist (debug builds).
///
/// # Examples
///
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"];
///
/// let mut cmd = Command::new("myprog");
/// // Args and options go here...
/// let matches = cmd.try_get_matches_from_mut(arg_vec)
/// .unwrap_or_else(|e| e.exit());
/// ```
/// [`Command::try_get_matches_from`]: Command::try_get_matches_from()
/// [`clap::Result`]: Result
/// [`clap::Error`]: crate::Error
/// [`kind`]: crate::Error
pub fn try_get_matches_from_mut<I, T>(&mut self, itr: I) -> ClapResult<ArgMatches>
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let mut raw_args = clap_lex::RawArgs::new(itr);
let mut cursor = raw_args.cursor();
if self.settings.is_set(AppSettings::Multicall) {
if let Some(argv0) = raw_args.next_os(&mut cursor) {
let argv0 = Path::new(&argv0);
if let Some(command) = argv0.file_stem().and_then(|f| f.to_str()) {
// Stop borrowing command so we can get another mut ref to it.
let command = command.to_owned();
debug!("Command::try_get_matches_from_mut: Parsed command {command} from argv");
debug!("Command::try_get_matches_from_mut: Reinserting command into arguments so subcommand parser matches it");
raw_args.insert(&cursor, [&command]);
debug!("Command::try_get_matches_from_mut: Clearing name and bin_name so that displayed command name starts with applet name");
self.name = "".into();
self.bin_name = None;
return self._do_parse(&mut raw_args, cursor);
}
}
};
// Get the name of the program (argument 1 of env::args()) and determine the
// actual file
// that was used to execute the program. This is because a program called
// ./target/release/my_prog -a
// will have two arguments, './target/release/my_prog', '-a' but we don't want
// to display
// the full path when displaying help messages and such
if !self.settings.is_set(AppSettings::NoBinaryName) {
if let Some(name) = raw_args.next_os(&mut cursor) {
let p = Path::new(name);
if let Some(f) = p.file_name() {
if let Some(s) = f.to_str() {
if self.bin_name.is_none() {
self.bin_name = Some(s.to_owned());
}
}
}
}
}
self._do_parse(&mut raw_args, cursor)
}
/// Prints the short help message (`-h`) to [`io::stdout()`].
///
/// See also [`Command::print_long_help`].
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// let mut cmd = Command::new("myprog");
/// cmd.print_help();
/// ```
/// [`io::stdout()`]: std::io::stdout()
pub fn print_help(&mut self) -> io::Result<()> {
self._build_self(false);
let color = self.color_help();
let mut styled = StyledStr::new();
let usage = Usage::new(self);
write_help(&mut styled, self, &usage, false);
let c = Colorizer::new(Stream::Stdout, color).with_content(styled);
c.print()
}
/// Prints the long help message (`--help`) to [`io::stdout()`].
///
/// See also [`Command::print_help`].
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// let mut cmd = Command::new("myprog");
/// cmd.print_long_help();
/// ```
/// [`io::stdout()`]: std::io::stdout()
/// [`BufWriter`]: std::io::BufWriter
/// [`-h` (short)]: Arg::help()
/// [`--help` (long)]: Arg::long_help()
pub fn print_long_help(&mut self) -> io::Result<()> {
self._build_self(false);
let color = self.color_help();
let mut styled = StyledStr::new();
let usage = Usage::new(self);
write_help(&mut styled, self, &usage, true);
let c = Colorizer::new(Stream::Stdout, color).with_content(styled);
c.print()
}
/// Render the short help message (`-h`) to a [`StyledStr`]
///
/// See also [`Command::render_long_help`].
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// use std::io;
/// let mut cmd = Command::new("myprog");
/// let mut out = io::stdout();
/// let help = cmd.render_help();
/// println!("{help}");
/// ```
/// [`io::Write`]: std::io::Write
/// [`-h` (short)]: Arg::help()
/// [`--help` (long)]: Arg::long_help()
pub fn render_help(&mut self) -> StyledStr {
self._build_self(false);
let mut styled = StyledStr::new();
let usage = Usage::new(self);
write_help(&mut styled, self, &usage, false);
styled
}
/// Render the long help message (`--help`) to a [`StyledStr`].
///
/// See also [`Command::render_help`].
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// use std::io;
/// let mut cmd = Command::new("myprog");
/// let mut out = io::stdout();
/// let help = cmd.render_long_help();
/// println!("{help}");
/// ```
/// [`io::Write`]: std::io::Write
/// [`-h` (short)]: Arg::help()
/// [`--help` (long)]: Arg::long_help()
pub fn render_long_help(&mut self) -> StyledStr {
self._build_self(false);
let mut styled = StyledStr::new();
let usage = Usage::new(self);
write_help(&mut styled, self, &usage, true);
styled
}
#[doc(hidden)]
#[cfg_attr(
feature = "deprecated",
deprecated(since = "4.0.0", note = "Replaced with `Command::render_help`")
)]
pub fn write_help<W: io::Write>(&mut self, w: &mut W) -> io::Result<()> {
self._build_self(false);
let mut styled = StyledStr::new();
let usage = Usage::new(self);
write_help(&mut styled, self, &usage, false);
ok!(write!(w, "{styled}"));
w.flush()
}
#[doc(hidden)]
#[cfg_attr(
feature = "deprecated",
deprecated(since = "4.0.0", note = "Replaced with `Command::render_long_help`")
)]
pub fn write_long_help<W: io::Write>(&mut self, w: &mut W) -> io::Result<()> {
self._build_self(false);
let mut styled = StyledStr::new();
let usage = Usage::new(self);
write_help(&mut styled, self, &usage, true);
ok!(write!(w, "{styled}"));
w.flush()
}
/// Version message rendered as if the user ran `-V`.
///
/// See also [`Command::render_long_version`].
///
/// ### Coloring
///
/// This function does not try to color the message nor it inserts any [ANSI escape codes].
///
/// ### Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// use std::io;
/// let cmd = Command::new("myprog");
/// println!("{}", cmd.render_version());
/// ```
/// [`io::Write`]: std::io::Write
/// [`-V` (short)]: Command::version()
/// [`--version` (long)]: Command::long_version()
/// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code
pub fn render_version(&self) -> String {
self._render_version(false)
}
/// Version message rendered as if the user ran `--version`.
///
/// See also [`Command::render_version`].
///
/// ### Coloring
///
/// This function does not try to color the message nor it inserts any [ANSI escape codes].
///
/// ### Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// use std::io;
/// let cmd = Command::new("myprog");
/// println!("{}", cmd.render_long_version());
/// ```
/// [`io::Write`]: std::io::Write
/// [`-V` (short)]: Command::version()
/// [`--version` (long)]: Command::long_version()
/// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code
pub fn render_long_version(&self) -> String {
self._render_version(true)
}
/// Usage statement
///
/// ### Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// use std::io;
/// let mut cmd = Command::new("myprog");
/// println!("{}", cmd.render_usage());
/// ```
pub fn render_usage(&mut self) -> StyledStr {
self.render_usage_().unwrap_or_default()
}
pub(crate) fn render_usage_(&mut self) -> Option<StyledStr> {
// If there are global arguments, or settings we need to propagate them down to subcommands
// before parsing incase we run into a subcommand
self._build_self(false);
Usage::new(self).create_usage_with_title(&[])
}
}
/// # Application-wide Settings
///
/// These settings will apply to the top-level command and all subcommands, by default. Some
/// settings can be overridden in subcommands.
impl Command {
/// Specifies that the parser should not assume the first argument passed is the binary name.
///
/// This is normally the case when using a "daemon" style mode. For shells / REPLs, see
/// [`Command::multicall`][Command::multicall].
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, arg};
/// let m = Command::new("myprog")
/// .no_binary_name(true)
/// .arg(arg!(<cmd> ... "commands to run"))
/// .get_matches_from(vec!["command", "set"]);
///
/// let cmds: Vec<_> = m.get_many::<String>("cmd").unwrap().collect();
/// assert_eq!(cmds, ["command", "set"]);
/// ```
/// [`try_get_matches_from_mut`]: crate::Command::try_get_matches_from_mut()
#[inline]
pub fn no_binary_name(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::NoBinaryName)
} else {
self.unset_global_setting(AppSettings::NoBinaryName)
}
}
/// Try not to fail on parse errors, like missing option values.
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, arg};
/// let cmd = Command::new("cmd")
/// .ignore_errors(true)
/// .arg(arg!(-c --config <FILE> "Sets a custom config file"))
/// .arg(arg!(-x --stuff <FILE> "Sets a custom stuff file"))
/// .arg(arg!(f: -f "Flag"));
///
/// let r = cmd.try_get_matches_from(vec!["cmd", "-c", "file", "-f", "-x"]);
///
/// assert!(r.is_ok(), "unexpected error: {r:?}");
/// let m = r.unwrap();
/// assert_eq!(m.get_one::<String>("config").unwrap(), "file");
/// assert!(m.get_flag("f"));
/// assert_eq!(m.get_one::<String>("stuff"), None);
/// ```
#[inline]
pub fn ignore_errors(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::IgnoreErrors)
} else {
self.unset_global_setting(AppSettings::IgnoreErrors)
}
}
/// Replace prior occurrences of arguments rather than error
///
/// For any argument that would conflict with itself by default (e.g.
/// [`ArgAction::Set`], it will now override itself.
///
/// This is the equivalent to saying the `foo` arg using [`Arg::overrides_with("foo")`] for all
/// defined arguments.
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// [`Arg::overrides_with("foo")`]: crate::Arg::overrides_with()
#[inline]
pub fn args_override_self(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::AllArgsOverrideSelf)
} else {
self.unset_global_setting(AppSettings::AllArgsOverrideSelf)
}
}
/// Disables the automatic delimiting of values after `--` or when [`Arg::trailing_var_arg`]
/// was used.
///
/// **NOTE:** The same thing can be done manually by setting the final positional argument to
/// [`Arg::value_delimiter(None)`]. Using this setting is safer, because it's easier to locate
/// when making changes.
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// # Examples
///
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// Command::new("myprog")
/// .dont_delimit_trailing_values(true)
/// .get_matches();
/// ```
///
/// [`Arg::value_delimiter(None)`]: crate::Arg::value_delimiter()
#[inline]
pub fn dont_delimit_trailing_values(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::DontDelimitTrailingValues)
} else {
self.unset_global_setting(AppSettings::DontDelimitTrailingValues)
}
}
/// Sets when to color output.
///
/// To customize how the output is styled, see [`Command::styles`].
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// **NOTE:** Default behaviour is [`ColorChoice::Auto`].
///
/// # Examples
///
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::{Command, ColorChoice};
/// Command::new("myprog")
/// .color(ColorChoice::Never)
/// .get_matches();
/// ```
/// [`ColorChoice::Auto`]: crate::ColorChoice::Auto
#[cfg(feature = "color")]
#[inline]
#[must_use]
pub fn color(self, color: ColorChoice) -> Self {
let cmd = self
.unset_global_setting(AppSettings::ColorAuto)
.unset_global_setting(AppSettings::ColorAlways)
.unset_global_setting(AppSettings::ColorNever);
match color {
ColorChoice::Auto => cmd.global_setting(AppSettings::ColorAuto),
ColorChoice::Always => cmd.global_setting(AppSettings::ColorAlways),
ColorChoice::Never => cmd.global_setting(AppSettings::ColorNever),
}
}
/// Sets the [`Styles`] for terminal output
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// **NOTE:** Default behaviour is [`Styles::default`].
///
/// # Examples
///
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::{Command, ColorChoice, builder::styling};
/// const STYLES: styling::Styles = styling::Styles::styled()
/// .header(styling::AnsiColor::Green.on_default().bold())
/// .usage(styling::AnsiColor::Green.on_default().bold())
/// .literal(styling::AnsiColor::Blue.on_default().bold())
/// .placeholder(styling::AnsiColor::Cyan.on_default());
/// Command::new("myprog")
/// .styles(STYLES)
/// .get_matches();
/// ```
#[cfg(feature = "color")]
#[inline]
#[must_use]
pub fn styles(mut self, styles: Styles) -> Self {
self.app_ext.set(styles);
self
}
/// Sets the terminal width at which to wrap help messages.
///
/// Using `0` will ignore terminal widths and use source formatting.
///
/// Defaults to current terminal width when `wrap_help` feature flag is enabled. If current
/// width cannot be determined, the default is 100.
///
/// **`unstable-v5` feature**: Defaults to unbound, being subject to
/// [`Command::max_term_width`].
///
/// **NOTE:** This setting applies globally and *not* on a per-command basis.
///
/// **NOTE:** This requires the `wrap_help` feature
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("myprog")
/// .term_width(80)
/// # ;
/// ```
#[inline]
#[must_use]
#[cfg(any(not(feature = "unstable-v5"), feature = "wrap_help"))]
pub fn term_width(mut self, width: usize) -> Self {
self.app_ext.set(TermWidth(width));
self
}
/// Limit the line length for wrapping help when using the current terminal's width.
///
/// This only applies when [`term_width`][Command::term_width] is unset so that the current
/// terminal's width will be used. See [`Command::term_width`] for more details.
///
/// Using `0` will ignore this, always respecting [`Command::term_width`] (default).
///
/// **`unstable-v5` feature**: Defaults to 100.
///
/// **NOTE:** This setting applies globally and *not* on a per-command basis.
///
/// **NOTE:** This requires the `wrap_help` feature
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("myprog")
/// .max_term_width(100)
/// # ;
/// ```
#[inline]
#[must_use]
#[cfg(any(not(feature = "unstable-v5"), feature = "wrap_help"))]
pub fn max_term_width(mut self, width: usize) -> Self {
self.app_ext.set(MaxTermWidth(width));
self
}
/// Disables `-V` and `--version` flag.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, error::ErrorKind};
/// let res = Command::new("myprog")
/// .version("1.0.0")
/// .disable_version_flag(true)
/// .try_get_matches_from(vec![
/// "myprog", "--version"
/// ]);
/// assert!(res.is_err());
/// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
/// ```
///
/// You can create a custom version flag with [`ArgAction::Version`]
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, Arg, ArgAction, error::ErrorKind};
/// let mut cmd = Command::new("myprog")
/// .version("1.0.0")
/// // Remove the `-V` short flag
/// .disable_version_flag(true)
/// .arg(
/// Arg::new("version")
/// .long("version")
/// .action(ArgAction::Version)
/// .help("Print version")
/// );
///
/// let res = cmd.try_get_matches_from_mut(vec![
/// "myprog", "-V"
/// ]);
/// assert!(res.is_err());
/// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
///
/// let res = cmd.try_get_matches_from_mut(vec![
/// "myprog", "--version"
/// ]);
/// assert!(res.is_err());
/// assert_eq!(res.unwrap_err().kind(), ErrorKind::DisplayVersion);
/// ```
#[inline]
pub fn disable_version_flag(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::DisableVersionFlag)
} else {
self.unset_global_setting(AppSettings::DisableVersionFlag)
}
}
/// Specifies to use the version of the current command for all [`subcommands`].
///
/// Defaults to `false`; subcommands have independent version strings from their parents.
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// # Examples
///
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// Command::new("myprog")
/// .version("v1.1")
/// .propagate_version(true)
/// .subcommand(Command::new("test"))
/// .get_matches();
/// // running `$ myprog test --version` will display
/// // "myprog-test v1.1"
/// ```
///
/// [`subcommands`]: crate::Command::subcommand()
#[inline]
pub fn propagate_version(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::PropagateVersion)
} else {
self.unset_global_setting(AppSettings::PropagateVersion)
}
}
/// Places the help string for all arguments and subcommands on the line after them.
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// # Examples
///
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// Command::new("myprog")
/// .next_line_help(true)
/// .get_matches();
/// ```
#[inline]
pub fn next_line_help(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::NextLineHelp)
} else {
self.unset_global_setting(AppSettings::NextLineHelp)
}
}
/// Disables `-h` and `--help` flag.
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, error::ErrorKind};
/// let res = Command::new("myprog")
/// .disable_help_flag(true)
/// .try_get_matches_from(vec![
/// "myprog", "-h"
/// ]);
/// assert!(res.is_err());
/// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
/// ```
///
/// You can create a custom help flag with [`ArgAction::Help`], [`ArgAction::HelpShort`], or
/// [`ArgAction::HelpLong`]
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, Arg, ArgAction, error::ErrorKind};
/// let mut cmd = Command::new("myprog")
/// // Change help short flag to `?`
/// .disable_help_flag(true)
/// .arg(
/// Arg::new("help")
/// .short('?')
/// .long("help")
/// .action(ArgAction::Help)
/// .help("Print help")
/// );
///
/// let res = cmd.try_get_matches_from_mut(vec![
/// "myprog", "-h"
/// ]);
/// assert!(res.is_err());
/// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
///
/// let res = cmd.try_get_matches_from_mut(vec![
/// "myprog", "-?"
/// ]);
/// assert!(res.is_err());
/// assert_eq!(res.unwrap_err().kind(), ErrorKind::DisplayHelp);
/// ```
#[inline]
pub fn disable_help_flag(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::DisableHelpFlag)
} else {
self.unset_global_setting(AppSettings::DisableHelpFlag)
}
}
/// Disables the `help` [`subcommand`].
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, error::ErrorKind};
/// let res = Command::new("myprog")
/// .disable_help_subcommand(true)
/// // Normally, creating a subcommand causes a `help` subcommand to automatically
/// // be generated as well
/// .subcommand(Command::new("test"))
/// .try_get_matches_from(vec![
/// "myprog", "help"
/// ]);
/// assert!(res.is_err());
/// assert_eq!(res.unwrap_err().kind(), ErrorKind::InvalidSubcommand);
/// ```
///
/// [`subcommand`]: crate::Command::subcommand()
#[inline]
pub fn disable_help_subcommand(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::DisableHelpSubcommand)
} else {
self.unset_global_setting(AppSettings::DisableHelpSubcommand)
}
}
/// Disables colorized help messages.
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// # Examples
///
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("myprog")
/// .disable_colored_help(true)
/// .get_matches();
/// ```
#[inline]
pub fn disable_colored_help(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::DisableColoredHelp)
} else {
self.unset_global_setting(AppSettings::DisableColoredHelp)
}
}
/// Panic if help descriptions are omitted.
///
/// **NOTE:** When deriving [`Parser`][crate::Parser], you could instead check this at
/// compile-time with `#![deny(missing_docs)]`
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// Command::new("myprog")
/// .help_expected(true)
/// .arg(
/// Arg::new("foo").help("It does foo stuff")
/// // As required via `help_expected`, a help message was supplied
/// )
/// # .get_matches();
/// ```
///
/// # Panics
///
/// On debug builds:
/// ```rust,no_run
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// Command::new("myapp")
/// .help_expected(true)
/// .arg(
/// Arg::new("foo")
/// // Someone forgot to put .about("...") here
/// // Since the setting `help_expected` is activated, this will lead to
/// // a panic (if you are in debug mode)
/// )
/// # .get_matches();
///```
#[inline]
pub fn help_expected(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::HelpExpected)
} else {
self.unset_global_setting(AppSettings::HelpExpected)
}
}
#[doc(hidden)]
#[cfg_attr(
feature = "deprecated",
deprecated(since = "4.0.0", note = "This is now the default")
)]
pub fn dont_collapse_args_in_usage(self, _yes: bool) -> Self {
self
}
/// Tells `clap` *not* to print possible values when displaying help information.
///
/// This can be useful if there are many values, or they are explained elsewhere.
///
/// To set this per argument, see
/// [`Arg::hide_possible_values`][crate::Arg::hide_possible_values].
///
/// **NOTE:** This choice is propagated to all child subcommands.
#[inline]
pub fn hide_possible_values(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::HidePossibleValues)
} else {
self.unset_global_setting(AppSettings::HidePossibleValues)
}
}
/// Allow partial matches of long arguments or their [aliases].
///
/// For example, to match an argument named `--test`, one could use `--t`, `--te`, `--tes`, and
/// `--test`.
///
/// **NOTE:** The match *must not* be ambiguous at all in order to succeed. i.e. to match
/// `--te` to `--test` there could not also be another argument or alias `--temp` because both
/// start with `--te`
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// [aliases]: crate::Command::aliases()
#[inline]
pub fn infer_long_args(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::InferLongArgs)
} else {
self.unset_global_setting(AppSettings::InferLongArgs)
}
}
/// Allow partial matches of [subcommand] names and their [aliases].
///
/// For example, to match a subcommand named `test`, one could use `t`, `te`, `tes`, and
/// `test`.
///
/// **NOTE:** The match *must not* be ambiguous at all in order to succeed. i.e. to match `te`
/// to `test` there could not also be a subcommand or alias `temp` because both start with `te`
///
/// **CAUTION:** This setting can interfere with [positional/free arguments], take care when
/// designing CLIs which allow inferred subcommands and have potential positional/free
/// arguments whose values could start with the same characters as subcommands. If this is the
/// case, it's recommended to use settings such as [`Command::args_conflicts_with_subcommands`] in
/// conjunction with this setting.
///
/// **NOTE:** This choice is propagated to all child subcommands.
///
/// # Examples
///
/// ```no_run
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// let m = Command::new("prog")
/// .infer_subcommands(true)
/// .subcommand(Command::new("test"))
/// .get_matches_from(vec![
/// "prog", "te"
/// ]);
/// assert_eq!(m.subcommand_name(), Some("test"));
/// ```
///
/// [subcommand]: crate::Command::subcommand()
/// [positional/free arguments]: crate::Arg::index()
/// [aliases]: crate::Command::aliases()
#[inline]
pub fn infer_subcommands(self, yes: bool) -> Self {
if yes {
self.global_setting(AppSettings::InferSubcommands)
} else {
self.unset_global_setting(AppSettings::InferSubcommands)
}
}
}
/// # Command-specific Settings
///
/// These apply only to the current command and are not inherited by subcommands.
impl Command {
/// (Re)Sets the program's name.
///
/// See [`Command::new`] for more details.
///
/// # Examples
///
/// ```ignore
/// let cmd = clap::command!()
/// .name("foo");
///
/// // continued logic goes here, such as `cmd.get_matches()` etc.
/// ```
#[must_use]
pub fn name(mut self, name: impl Into<Str>) -> Self {
self.name = name.into();
self
}
/// Overrides the runtime-determined name of the binary for help and error messages.
///
/// This should only be used when absolutely necessary, such as when the binary name for your
/// application is misleading, or perhaps *not* how the user should invoke your program.
///
/// **Pro-tip:** When building things such as third party `cargo`
/// subcommands, this setting **should** be used!
///
/// **NOTE:** This *does not* change or set the name of the binary file on
/// disk. It only changes what clap thinks the name is for the purposes of
/// error or help messages.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("My Program")
/// .bin_name("my_binary")
/// # ;
/// ```
#[must_use]
pub fn bin_name(mut self, name: impl IntoResettable<String>) -> Self {
self.bin_name = name.into_resettable().into_option();
self
}
/// Overrides the runtime-determined display name of the program for help and error messages.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("My Program")
/// .display_name("my_program")
/// # ;
/// ```
#[must_use]
pub fn display_name(mut self, name: impl IntoResettable<String>) -> Self {
self.display_name = name.into_resettable().into_option();
self
}
/// Sets the author(s) for the help message.
///
/// **Pro-tip:** Use `clap`s convenience macro [`crate_authors!`] to
/// automatically set your application's author(s) to the same thing as your
/// crate at compile time.
///
/// **NOTE:** A custom [`help_template`][Command::help_template] is needed for author to show
/// up.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("myprog")
/// .author("Me, me@mymain.com")
/// # ;
/// ```
#[must_use]
pub fn author(mut self, author: impl IntoResettable<Str>) -> Self {
self.author = author.into_resettable().into_option();
self
}
/// Sets the program's description for the short help (`-h`).
///
/// If [`Command::long_about`] is not specified, this message will be displayed for `--help`.
///
/// **NOTE:** Only `Command::about` (short format) is used in completion
/// script generation in order to be concise.
///
/// See also [`crate_description!`](crate::crate_description!).
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("myprog")
/// .about("Does really amazing things for great people")
/// # ;
/// ```
#[must_use]
pub fn about(mut self, about: impl IntoResettable<StyledStr>) -> Self {
self.about = about.into_resettable().into_option();
self
}
/// Sets the program's description for the long help (`--help`).
///
/// If not set, [`Command::about`] will be used for long help in addition to short help
/// (`-h`).
///
/// **NOTE:** Only [`Command::about`] (short format) is used in completion
/// script generation in order to be concise.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("myprog")
/// .long_about(
/// "Does really amazing things to great people. Now let's talk a little
/// more in depth about how this subcommand really works. It may take about
/// a few lines of text, but that's ok!")
/// # ;
/// ```
/// [`Command::about`]: Command::about()
#[must_use]
pub fn long_about(mut self, long_about: impl IntoResettable<StyledStr>) -> Self {
self.long_about = long_about.into_resettable().into_option();
self
}
/// Free-form help text for after auto-generated short help (`-h`).
///
/// This is often used to describe how to use the arguments, caveats to be noted, or license
/// and contact information.
///
/// If [`Command::after_long_help`] is not specified, this message will be displayed for `--help`.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("myprog")
/// .after_help("Does really amazing things for great people... but be careful with -R!")
/// # ;
/// ```
///
#[must_use]
pub fn after_help(mut self, help: impl IntoResettable<StyledStr>) -> Self {
self.after_help = help.into_resettable().into_option();
self
}
/// Free-form help text for after auto-generated long help (`--help`).
///
/// This is often used to describe how to use the arguments, caveats to be noted, or license
/// and contact information.
///
/// If not set, [`Command::after_help`] will be used for long help in addition to short help
/// (`-h`).
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("myprog")
/// .after_long_help("Does really amazing things to great people... but be careful with -R, \
/// like, for real, be careful with this!")
/// # ;
/// ```
#[must_use]
pub fn after_long_help(mut self, help: impl IntoResettable<StyledStr>) -> Self {
self.after_long_help = help.into_resettable().into_option();
self
}
/// Free-form help text for before auto-generated short help (`-h`).
///
/// This is often used for header, copyright, or license information.
///
/// If [`Command::before_long_help`] is not specified, this message will be displayed for `--help`.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("myprog")
/// .before_help("Some info I'd like to appear before the help info")
/// # ;
/// ```
#[must_use]
pub fn before_help(mut self, help: impl IntoResettable<StyledStr>) -> Self {
self.before_help = help.into_resettable().into_option();
self
}
/// Free-form help text for before auto-generated long help (`--help`).
///
/// This is often used for header, copyright, or license information.
///
/// If not set, [`Command::before_help`] will be used for long help in addition to short help
/// (`-h`).
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("myprog")
/// .before_long_help("Some verbose and long info I'd like to appear before the help info")
/// # ;
/// ```
#[must_use]
pub fn before_long_help(mut self, help: impl IntoResettable<StyledStr>) -> Self {
self.before_long_help = help.into_resettable().into_option();
self
}
/// Sets the version for the short version (`-V`) and help messages.
///
/// If [`Command::long_version`] is not specified, this message will be displayed for `--version`.
///
/// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to
/// automatically set your application's version to the same thing as your
/// crate at compile time.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("myprog")
/// .version("v0.1.24")
/// # ;
/// ```
#[must_use]
pub fn version(mut self, ver: impl IntoResettable<Str>) -> Self {
self.version = ver.into_resettable().into_option();
self
}
/// Sets the version for the long version (`--version`) and help messages.
///
/// If [`Command::version`] is not specified, this message will be displayed for `-V`.
///
/// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to
/// automatically set your application's version to the same thing as your
/// crate at compile time.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::Command;
/// Command::new("myprog")
/// .long_version(
/// "v0.1.24
/// commit: abcdef89726d
/// revision: 123
/// release: 2
/// binary: myprog")
/// # ;
/// ```
#[must_use]
pub fn long_version(mut self, ver: impl IntoResettable<Str>) -> Self {
self.long_version = ver.into_resettable().into_option();
self
}
/// Overrides the `clap` generated usage string for help and error messages.
///
/// **NOTE:** Using this setting disables `clap`s "context-aware" usage
/// strings. After this setting is set, this will be *the only* usage string
/// displayed to the user!
///
/// **NOTE:** Multiple usage lines may be present in the usage argument, but
/// some rules need to be followed to ensure the usage lines are formatted
/// correctly by the default help formatter:
///
/// - Do not indent the first usage line.
/// - Indent all subsequent usage lines with seven spaces.
/// - The last line must not end with a newline.
///
/// # Examples
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// Command::new("myprog")
/// .override_usage("myapp [-clDas] <some_file>")
/// # ;
/// ```
///
/// Or for multiple usage lines:
///
/// ```rust
/// # use clap_builder as clap;
/// # use clap::{Command, Arg};
/// Command::new("myprog")
/// .override_usage(
/// "myapp -X [-a] [-b] <file>\n \
/// myapp -Y [-c] <file1> <file2>\n \
/// myapp -Z [-d|-e]"
/// )
/// # ;
/// ```
///
/// [`ArgMatches::usage`]: ArgMatches::usage()
#[must_use]
--> --------------------
--> maximum size reached
--> --------------------