Skip to content

Commit

Permalink
feat: allows defining hidden args and subcmds
Browse files Browse the repository at this point in the history
Closes #231
  • Loading branch information
kbknapp committed Sep 9, 2015
1 parent ebdd73f commit 2cab4d0
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 7 deletions.
51 changes: 44 additions & 7 deletions src/app/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ pub struct App<'a, 'v, 'ab, 'u, 'h, 'ar> {
versionless_scs: Option<bool>,
unified_help: bool,
overrides: Vec<&'ar str>,
hidden: bool
}

impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
Expand Down Expand Up @@ -146,7 +147,8 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
global_ver: false,
versionless_scs: None,
unified_help: false,
overrides: vec![],
hidden: false,
overrides: vec![]
}
}

Expand Down Expand Up @@ -521,6 +523,26 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
self
}

/// Hides a subcommand from help message output.
///
/// **NOTE:** This does **not** hide the subcommand from usage strings on error
///
/// # Example
///
/// ```no_run
/// # use clap::{App, SubCommand};
/// # let matches = App::new("myprog")
/// # .subcommand(
/// # SubCommand::with_name("debug")
/// .hidden(true)
/// # ).get_matches();
pub fn hidden(mut self,
h: bool)
-> Self {
self.hidden = h;
self
}

/// Uses version of the current command for all subcommands. (Defaults to false; subcommands
/// have independant version strings)
///
Expand Down Expand Up @@ -827,6 +849,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
empty_vals: a.empty_vals,
validator: None,
overrides: None,
hidden: a.hidden
};
if pb.min_vals.is_some() && !pb.multiple {
panic!("Argument \"{}\" does not allow multiple values, yet it is expecting {} \
Expand Down Expand Up @@ -906,6 +929,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
empty_vals: a.empty_vals,
validator: None,
overrides: None,
hidden: a.hidden
};
if let Some(ref vec) = ob.val_names {
ob.num_vals = Some(vec.len() as u8);
Expand Down Expand Up @@ -994,6 +1018,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
multiple: a.multiple,
requires: None,
overrides: None,
hidden: a.hidden
};
// Check if there is anything in the blacklist (mutually excludes list) and add any
// values
Expand Down Expand Up @@ -1570,7 +1595,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
let mut longest_flag = 0;
for fl in self.flags
.values()
.filter(|f| f.long.is_some())
.filter(|f| f.long.is_some() && !f.hidden)
// 2='--'
.map(|a| a.to_string().len() ) {
if fl > longest_flag {
Expand All @@ -1580,7 +1605,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
let mut longest_opt = 0;
for ol in self.opts
.values()
// .filter(|ref o| o.long.is_some())
.filter(|o| !o.hidden)
.map(|a|
a.to_string().len() // + if a.short.is_some() { 4 } else { 0 }
) {
Expand All @@ -1591,6 +1616,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
let mut longest_pos = 0;
for pl in self.positionals_idx
.values()
.filter(|p| !p.hidden)
.map(|f| f.to_string().len() ) {
if pl > longest_pos {
longest_pos = pl;
Expand All @@ -1599,6 +1625,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
let mut longest_sc = 0;
for scl in self.subcommands
.values()
.filter(|s| !s.hidden)
.map(|f| f.name.len() ) {
if scl > longest_sc {
longest_sc = scl;
Expand All @@ -1625,7 +1652,9 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
} else {
print!("\nOPTIONS:\n")
}
for v in self.flags.values() {
for v in self.flags
.values()
.filter(|f| !f.hidden) {
print!("{}", tab);
if let Some(s) = v.short {
print!("-{}",s);
Expand Down Expand Up @@ -1680,7 +1709,9 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
} else {
// maybe erase
}
for v in self.opts.values() {
for v in self.opts
.values()
.filter(|o| !o.hidden) {
// if it supports multiple we add '...' i.e. 3 to the name length
print!("{}", tab);
if let Some(s) = v.short {
Expand Down Expand Up @@ -1716,7 +1747,9 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
}
if pos {
print!("\nARGS:\n");
for v in self.positionals_idx.values() {
for v in self.positionals_idx
.values()
.filter(|p| !p.hidden) {
// let mult = if v.multiple { 3 } else { 0 };
print!("{}", tab);
print!("{}", v.name);
Expand All @@ -1741,7 +1774,9 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
}
if subcmds {
print!("\nSUBCOMMANDS:\n");
for sc in self.subcommands.values() {
for sc in self.subcommands
.values()
.filter(|s| !s.hidden) {
print!("{}{}", tab, sc.name);
self.print_spaces((longest_sc + 4) - (sc.name.len()));
if let Some(a) = sc.about {
Expand Down Expand Up @@ -2655,6 +2690,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
global: false,
requires: None,
overrides: None,
hidden: false,
};
self.long_list.push("help");
self.flags.insert("hclap_help", arg);
Expand All @@ -2675,6 +2711,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
global: false,
requires: None,
overrides: None,
hidden: false,
};
self.long_list.push("version");
self.flags.insert("vclap_version", arg);
Expand Down
25 changes: 25 additions & 0 deletions src/args/arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ pub struct Arg<'n, 'l, 'h, 'g, 'p, 'r> {
/// A list of names for other arguments that *mutually override* this flag
#[doc(hidden)]
pub overrides: Option<Vec<&'r str>>,
#[doc(hidden)]
pub hidden: bool
}

impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
Expand Down Expand Up @@ -145,6 +147,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
empty_vals: true,
validator: None,
overrides: None,
hidden: false,
}
}

Expand Down Expand Up @@ -395,6 +398,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
empty_vals: true,
validator: None,
overrides: None,
hidden: false,
}
}

Expand Down Expand Up @@ -772,6 +776,26 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
self
}

/// Hides an argument from help message output.
///
/// **NOTE:** This does **not** hide the argument from usage strings on error
///
/// # Example
///
/// ```no_run
/// # use clap::{App, Arg};
/// # let matches = App::new("myprog")
/// # .arg(
/// # Arg::with_name("debug")
/// .hidden(true)
/// # ).get_matches();
pub fn hidden(mut self,
h: bool)
-> Self {
self.hidden = h;
self
}

/// Specifies a list of possible values for this argument. At runtime, clap verifies that only
/// one of the specified values was used, or fails with a usage string.
///
Expand Down Expand Up @@ -1061,6 +1085,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r, 'z> From<&'z Arg<'n, 'l, 'h, 'g, 'p, 'r>>
empty_vals: a.empty_vals,
validator: a.validator.clone(),
overrides: a.overrides.clone(),
hidden: a.hidden
}
}
}
1 change: 1 addition & 0 deletions src/args/argbuilder/flag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub struct FlagBuilder<'n> {
pub global: bool,
/// A list of names for other arguments that *mutually override* this flag
pub overrides: Option<Vec<&'n str>>,
pub hidden: bool
}

impl<'n> Display for FlagBuilder<'n> {
Expand Down
1 change: 1 addition & 0 deletions src/args/argbuilder/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub struct OptBuilder<'n> {
pub validator: Option<Rc<Fn(String) -> StdResult<(), String>>>,
/// A list of names for other arguments that *mutually override* this flag
pub overrides: Option<Vec<&'n str>>,
pub hidden: bool
}

impl<'n> Display for OptBuilder<'n> {
Expand Down
1 change: 1 addition & 0 deletions src/args/argbuilder/positional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub struct PosBuilder<'n> {
pub validator: Option<Rc<Fn(String) -> StdResult<(), String>>>,
/// A list of names for other arguments that *mutually override* this flag
pub overrides: Option<Vec<&'n str>>,
pub hidden: bool
}

impl<'n> Display for PosBuilder<'n> {
Expand Down

0 comments on commit 2cab4d0

Please sign in to comment.