Skip to content

Commit

Permalink
feat: allows parsing without a binary name for daemons and interactiv…
Browse files Browse the repository at this point in the history
…e CLIs

Closes #318
  • Loading branch information
kbknapp committed Oct 28, 2015
1 parent c47025d commit aff89d5
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 20 deletions.
14 changes: 8 additions & 6 deletions src/app/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1980,12 +1980,14 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
// ./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 let Some(name) = it.next() {
let p = Path::new(name.as_ref());
if let Some(f) = p.file_name() {
if let Ok(s) = f.to_os_string().into_string() {
if let None = self.bin_name {
self.bin_name = Some(s);
if !self.settings.is_set(&AppSettings::NoBinaryName) {
if let Some(name) = it.next() {
let p = Path::new(name.as_ref());
if let Some(f) = p.file_name() {
if let Ok(s) = f.to_os_string().into_string() {
if let None = self.bin_name {
self.bin_name = Some(s);
}
}
}
}
Expand Down
51 changes: 37 additions & 14 deletions src/app/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@ use std::ascii::AsciiExt;

bitflags! {
flags Flags: u32 {
const SC_NEGATE_REQS = 0b00000000000001,
const SC_REQUIRED = 0b00000000000010,
const A_REQUIRED_ELSE_HELP = 0b00000000000100,
const GLOBAL_VERSION = 0b00000000001000,
const VERSIONLESS_SC = 0b00000000010000,
const UNIFIED_HELP = 0b00000000100000,
const WAIT_ON_ERROR = 0b00000001000000,
const SC_REQUIRED_ELSE_HELP= 0b00000010000000,
const NEEDS_LONG_HELP = 0b00000100000000,
const NEEDS_LONG_VERSION = 0b00001000000000,
const NEEDS_SC_HELP = 0b00010000000000,
const DISABLE_VERSION = 0b00100000000000,
const HIDDEN = 0b01000000000000,
const TRAILING_VARARG = 0b10000000000000,
const SC_NEGATE_REQS = 0b000000000000001,
const SC_REQUIRED = 0b000000000000010,
const A_REQUIRED_ELSE_HELP = 0b000000000000100,
const GLOBAL_VERSION = 0b000000000001000,
const VERSIONLESS_SC = 0b000000000010000,
const UNIFIED_HELP = 0b000000000100000,
const WAIT_ON_ERROR = 0b000000001000000,
const SC_REQUIRED_ELSE_HELP= 0b000000010000000,
const NEEDS_LONG_HELP = 0b000000100000000,
const NEEDS_LONG_VERSION = 0b000001000000000,
const NEEDS_SC_HELP = 0b000010000000000,
const DISABLE_VERSION = 0b000100000000000,
const HIDDEN = 0b001000000000000,
const TRAILING_VARARG = 0b010000000000000,
const NO_BIN_NAME = 0b100000000000000,
}
}

Expand All @@ -43,6 +44,7 @@ impl AppFlags {
AppSettings::DisableVersion => self.0.insert(DISABLE_VERSION),
AppSettings::Hidden => self.0.insert(HIDDEN),
AppSettings::TrailingVarArg => self.0.insert(TRAILING_VARARG),
AppSettings::NoBinaryName => self.0.insert(NO_BIN_NAME),
}
}

Expand All @@ -62,6 +64,7 @@ impl AppFlags {
AppSettings::DisableVersion => self.0.remove(DISABLE_VERSION),
AppSettings::Hidden => self.0.remove(HIDDEN),
AppSettings::TrailingVarArg => self.0.remove(TRAILING_VARARG),
AppSettings::NoBinaryName => self.0.remove(NO_BIN_NAME),
}
}

Expand All @@ -81,6 +84,7 @@ impl AppFlags {
AppSettings::DisableVersion => self.0.contains(DISABLE_VERSION),
AppSettings::Hidden => self.0.contains(HIDDEN),
AppSettings::TrailingVarArg => self.0.contains(TRAILING_VARARG),
AppSettings::NoBinaryName => self.0.contains(NO_BIN_NAME),
}
}
}
Expand Down Expand Up @@ -256,6 +260,25 @@ pub enum AppSettings {
/// assert_eq!(m.values_of("cmd").unwrap(), &["some_command", "-r", "set"]);
/// ```
TrailingVarArg,
/// 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, or an interactive CLI where one
/// one would not normally type the binary or program name for each command.
///
/// **NOTE:** This should only be used when you absolutely know it's what you need. 99% of the
/// cases out there don't need this setting.
///
/// # Examples
///
/// ```no_run
/// # use clap::{App, Arg, AppSettings};
/// let m = App::new("myprog")
/// .setting(AppSettings::NoBinaryName)
/// .arg(Arg::from_usage("<cmd>... 'commands to run'"))
/// .get_matches_from(vec!["some_command", "-r", "set"]);
///
/// assert_eq!(m.values_of("cmd").unwrap(), &["some_command", "-r", "set"]);
/// ```
NoBinaryName,
#[doc(hidden)]
NeedsLongVersion,
#[doc(hidden)]
Expand Down
13 changes: 13 additions & 0 deletions tests/app_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,19 @@ fn arg_required_else_help() {
assert_eq!(err.error_type, ClapErrorType::MissingRequiredArgument);
}

#[test]
fn no_bin_name() {
let result = App::new("arg_required")
.setting(AppSettings::NoBinaryName)
.arg(Arg::with_name("test")
.required(true)
.index(1))
.get_matches_from_safe(vec!["testing"]);
assert!(result.is_ok());
let matches = result.unwrap();
assert_eq!(matches.value_of("test").unwrap(), "testing");
}

#[test]
fn unified_help() {
let mut app = App::new("test")
Expand Down

0 comments on commit aff89d5

Please sign in to comment.