Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add mut_subcommand method to modify existing subcommands #3882

Merged
merged 1 commit into from Jun 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 44 additions & 0 deletions src/builder/command.rs
Expand Up @@ -274,6 +274,50 @@ impl<'help> App<'help> {
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`].
///
/// # Examples
///
/// ```rust
/// # 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<T, F>(mut self, subcmd_id: T, f: F) -> Self
where
F: FnOnce(App<'help>) -> App<'help>,
T: Into<&'help str>,
{
let subcmd_id: &str = subcmd_id.into();
let id = Id::from(subcmd_id);

let pos = self.subcommands.iter().position(|s| s.id == id);

let subcmd = if let Some(idx) = pos {
self.subcommands.remove(idx)
} else {
App::new(subcmd_id)
};

self.subcommands.push(f(subcmd));
self
}

/// Adds an [`ArgGroup`] to the application.
///
/// [`ArgGroup`]s are a family of related arguments.
Expand Down
19 changes: 19 additions & 0 deletions tests/builder/tests.rs
Expand Up @@ -426,6 +426,25 @@ fn mut_arg_all() {
}
}

#[test]
fn mut_subcommand_all() {
let cmd = utils::complex_app();

assert_eq!(
cmd.find_subcommand("subcmd")
.unwrap()
.is_disable_version_flag_set(),
false
);
let cmd = cmd.mut_subcommand("subcmd", |subcmd| subcmd.disable_version_flag(true));
assert_eq!(
cmd.find_subcommand("subcmd")
.unwrap()
.is_disable_version_flag_set(),
true
);
}

#[test]
fn issue_3669_command_build_recurses() {
let mut cmd = Command::new("ctest").subcommand(
Expand Down