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

Issue 421, 427, and 429 #425

Merged
merged 8 commits into from
Feb 19, 2016
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
<a name="v2.1.1"></a>
### v2.1.1 (2016-02-19)


#### Documentation

* **AppSettings:** clarifies that AppSettings do not propagate ([3c8db0e9](https://github.com/kbknapp/clap-rs/commit/3c8db0e9be1d24edaad364359513cbb02abb4186), closes [#429](https://github.com/kbknapp/clap-rs/issues/429))
* **Arg Examples:** adds better examples ([1e79cccc](https://github.com/kbknapp/clap-rs/commit/1e79cccc12937bc0e7cd2aad8e404410798e9fff))

#### Improvements

* **Help:** adds setting for next line help by arg ([066df748](https://github.com/kbknapp/clap-rs/commit/066df7486e684cf50a8479a356a12ba972c34ce1), closes [#427](https://github.com/kbknapp/clap-rs/issues/427))


<a name="v2.1.0"></a>
## v2.1.0 (2016-02-10)

Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]

name = "clap"
version = "2.1.0"
version = "2.1.1"
authors = ["Kevin K. <[email protected]>"]
exclude = ["examples/*", "clap-tests/*", "tests/*", "benches/*", "*.png", "clap-perf/*"]
description = "A simple to use, efficient, and full featured Command Line Argument Parser"
Expand Down
68 changes: 6 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,72 +38,16 @@ Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc)

## What's New

v**2.0** has been released! This means fixing some pain points, new features, better documentation, improved ergonomics, and also some minor breaking changes if you're used to v1.x
In v2.1.1

#### New Features

Here are some key points about the 2.x release
* **Default Values**: Args can now specify default values
* **Next Line Help**: Args can have help strings on the line following the argument (useful for long arguments, or those with many values). This can be set command-wide or for individual args

* Support for arguments with invalid UTF-8 values!: Helps with POSIX and Unix like OSs
* Even better performance boost!
* Far better documentation
* Support for delimited values
* Support for custom delimiter in values
* Support for external subcommands
* Support for options that act as flags (i.e., ones which optionally have no value)
* Support for negative numbers as arguments (i.e., `-10`, etc.)
* Better Errors and error handling
* Improved "from usage" strings
* Better support for generics, instead of being locked in to `Vec` at key points
* Improved macros
* Better regression testing
* Vastly improved ergonomics
* Numerous bug fixes
#### Improvements

![clap Performance Graph](https://github.com/kbknapp/clap-rs/blob/master/clap-perf/clap_perf.png)

#### Breaking Changes

Below is a list of breaking changes between 1.x and 2.x and how you can change your code to update.

* **Fewer lifetimes! Yay!**
* `App<'a, 'b, 'c, 'd, 'e, 'f>` => `App<'a, 'b>`
* `Arg<'a, 'b, 'c, 'd, 'e, 'f>` => `Arg<'a, 'b>`
* `ArgMatches<'a, 'b>` => `ArgMatches<'a>`
* **Simply Renamed**
* `App::arg_group` => `App::group`
* `App::arg_groups` => `App::groups`
* `ArgGroup::add` => `ArgGroup::arg`
* `ArgGroup::add_all` => `ArgGroup::args`
* `ClapError` => `Error`
* `ClapResult` => `Result`
* `ClapErrorType` => `ErrorKind`
* struct field `ClapError::error_type` => `Error::kind`
* **Removed Deprecated Functions and Methods**
* `App::subcommands_negate_reqs`
* `App::subcommand_required`
* `App::arg_required_else_help`
* `App::global_version(bool)`
* `App::versionless_subcommands`
* `App::unified_help_messages`
* `App::wait_on_error`
* `App::subcommand_required_else_help`
* `SubCommand::new`
* `App::error_on_no_subcommand`
* `Arg::new`
* `Arg::mutually_excludes`
* `Arg::mutually_excludes_all`
* `Arg::mutually_overrides_with`
* `simple_enum!`
* **Renamed Errors Variants**
* `InvalidUnicode` => `InvalidUtf8`
* `InvalidArgument` => `UnknownArgument`
* **Usage Parser**
* Value names can now be specified inline: `-o, --option <FILE> <FILE2> 'some option which takes two files'`
* **There is now a priority of order to determine the name** - This is perhaps the biggest breaking change. See the documentation for full details. Prior to this change, the value name took precedence. **Ensure your args are using the proper names (i.e. typically the long or short and NOT the value name) throughout the code**
* `ArgMatches::values_of` returns an `Values` now which implements `Iterator` (should not break any code)
* `crate_version!` returns `&'static str` instead of `String`
* Using the `clap_app!` macro requires compiling with the `unstable` feature because the syntax could change slightly in the future
* **Documenation Examples**: The examples in the documentation have been vastly improved

For full details, see [CHANGELOG.md](https://github.com/kbknapp/clap-rs/blob/master/CHANGELOG.md)

Expand Down Expand Up @@ -609,6 +553,6 @@ As of 2.0.0 (From 1.x)

Old method names will be left around for several minor version bumps, or one major version bump.

As of 2.0.0:
As of 2.1.1:

* None!
8 changes: 4 additions & 4 deletions clap-tests/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
-o, --option <opt>... tests options

ARGS:
positional tests positionals
positional2 tests positionals with exclusions
positional3... tests positionals with specific values [values: vi, emacs]
<positional> tests positionals
<positional2> tests positionals with exclusions
<positional3>... tests positionals with specific values [values: vi, emacs]

SUBCOMMANDS:
help Prints this message
Expand Down Expand Up @@ -152,7 +152,7 @@
-o, --option <scoption>... tests options

ARGS:
scpositional tests positionals'''
<scpositional> tests positionals'''

_scfop = '''flag NOT present
option NOT present
Expand Down
19 changes: 10 additions & 9 deletions src/app/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1358,7 +1358,7 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {

fn write_version<W: Write>(&self, w: &mut W) -> io::Result<()> {
if let Some(bn) = self.meta.bin_name.as_ref() {
if bn.contains(" ") {
if bn.contains(' ') {
// Incase we're dealing with subcommands i.e. git mv is translated to git-mv
writeln!(w, "{} {}", bn.replace(" ", "-"), self.meta.version.unwrap_or("".into()))
} else {
Expand Down Expand Up @@ -1400,15 +1400,15 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {

let mut longest_flag = 0;
for fl in self.flags.iter()
.filter(|f| f.long.is_some() && !f.settings.is_set(ArgSettings::Hidden))
.filter(|f| f.long.is_some() && !(f.settings.is_set(ArgSettings::Hidden) || f.settings.is_set(ArgSettings::NextLineHelp)))
.map(|a| a.to_string().len()) {
if fl > longest_flag {
longest_flag = fl;
}
}
let mut longest_opt = 0;
for ol in self.opts.iter()
.filter(|o| !o.settings.is_set(ArgSettings::Hidden))
.filter(|o| !(o.settings.is_set(ArgSettings::Hidden) || o.settings.is_set(ArgSettings::NextLineHelp)))
.map(|a| a.to_string().len()) {
if ol > longest_opt {
longest_opt = ol;
Expand All @@ -1417,7 +1417,7 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
let mut longest_pos = 0;
for pl in self.positionals
.values()
.filter(|p| !p.settings.is_set(ArgSettings::Hidden))
.filter(|p| !(p.settings.is_set(ArgSettings::Hidden) || p.settings.is_set(ArgSettings::NextLineHelp)))
.map(|f| f.to_string().len()) {
if pl > longest_pos {
longest_pos = pl;
Expand All @@ -1443,17 +1443,18 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
} else {
longest_opt
};
let nlh = self.settings.is_set(AppSettings::NextLineHelp);
if unified_help && (flags || opts) {
try!(write!(w, "\nOPTIONS:\n"));
let mut combined = BTreeMap::new();
for f in self.flags.iter().filter(|f| !f.settings.is_set(ArgSettings::Hidden)) {
let mut v = vec![];
try!(f.write_help(&mut v, tab, longest));
try!(f.write_help(&mut v, tab, longest, nlh));
combined.insert(f.name, v);
}
for o in self.opts.iter().filter(|o| !o.settings.is_set(ArgSettings::Hidden)) {
let mut v = vec![];
try!(o.write_help(&mut v, tab, longest, self.is_set(AppSettings::HidePossibleValuesInHelp)));
try!(o.write_help(&mut v, tab, longest, self.is_set(AppSettings::HidePossibleValuesInHelp), nlh));
combined.insert(o.name, v);
}
for (_, a) in combined {
Expand All @@ -1468,7 +1469,7 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
.map(|f| (f.name, f))
.collect::<BTreeMap<_, _>>()
.values() {
try!(f.write_help(w, tab, longest));
try!(f.write_help(w, tab, longest, nlh));
}
}
if opts {
Expand All @@ -1478,15 +1479,15 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
.map(|o| (o.name, o))
.collect::<BTreeMap<_, _>>()
.values() {
try!(o.write_help(w, tab, longest_opt, self.is_set(AppSettings::HidePossibleValuesInHelp)));
try!(o.write_help(w, tab, longest_opt, self.is_set(AppSettings::HidePossibleValuesInHelp), nlh));
}
}
}
if pos {
try!(write!(w, "\nARGS:\n"));
for v in self.positionals.values()
.filter(|p| !p.settings.is_set(ArgSettings::Hidden)) {
try!(v.write_help(w, tab, longest_pos, self.is_set(AppSettings::HidePossibleValuesInHelp)));
try!(v.write_help(w, tab, longest_pos, self.is_set(AppSettings::HidePossibleValuesInHelp), nlh));
}
}
if subcmds {
Expand Down
66 changes: 43 additions & 23 deletions src/app/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,27 @@ use std::ascii::AsciiExt;

bitflags! {
flags Flags: u32 {
const SC_NEGATE_REQS = 0b00000000000000000001,
const SC_REQUIRED = 0b00000000000000000010,
const A_REQUIRED_ELSE_HELP = 0b00000000000000000100,
const GLOBAL_VERSION = 0b00000000000000001000,
const VERSIONLESS_SC = 0b00000000000000010000,
const UNIFIED_HELP = 0b00000000000000100000,
const WAIT_ON_ERROR = 0b00000000000001000000,
const SC_REQUIRED_ELSE_HELP= 0b00000000000010000000,
const NEEDS_LONG_HELP = 0b00000000000100000000,
const NEEDS_LONG_VERSION = 0b00000000001000000000,
const NEEDS_SC_HELP = 0b00000000010000000000,
const DISABLE_VERSION = 0b00000000100000000000,
const HIDDEN = 0b00000001000000000000,
const TRAILING_VARARG = 0b00000010000000000000,
const NO_BIN_NAME = 0b00000100000000000000,
const ALLOW_UNK_SC = 0b00001000000000000000,
const UTF8_STRICT = 0b00010000000000000000,
const UTF8_NONE = 0b00100000000000000000,
const LEADING_HYPHEN = 0b01000000000000000000,
const NO_POS_VALUES = 0b10000000000000000000,
const SC_NEGATE_REQS = 0b000000000000000000001,
const SC_REQUIRED = 0b000000000000000000010,
const A_REQUIRED_ELSE_HELP = 0b000000000000000000100,
const GLOBAL_VERSION = 0b000000000000000001000,
const VERSIONLESS_SC = 0b000000000000000010000,
const UNIFIED_HELP = 0b000000000000000100000,
const WAIT_ON_ERROR = 0b000000000000001000000,
const SC_REQUIRED_ELSE_HELP= 0b000000000000010000000,
const NEEDS_LONG_HELP = 0b000000000000100000000,
const NEEDS_LONG_VERSION = 0b000000000001000000000,
const NEEDS_SC_HELP = 0b000000000010000000000,
const DISABLE_VERSION = 0b000000000100000000000,
const HIDDEN = 0b000000001000000000000,
const TRAILING_VARARG = 0b000000010000000000000,
const NO_BIN_NAME = 0b000000100000000000000,
const ALLOW_UNK_SC = 0b000001000000000000000,
const UTF8_STRICT = 0b000010000000000000000,
const UTF8_NONE = 0b000100000000000000000,
const LEADING_HYPHEN = 0b001000000000000000000,
const NO_POS_VALUES = 0b010000000000000000000,
const NEXT_LINE_HELP = 0b100000000000000000000,
}
}

Expand Down Expand Up @@ -55,11 +56,15 @@ impl AppFlags {
StrictUtf8 => UTF8_STRICT,
AllowInvalidUtf8 => UTF8_NONE,
AllowLeadingHyphen => LEADING_HYPHEN,
HidePossibleValuesInHelp => NO_POS_VALUES
HidePossibleValuesInHelp => NO_POS_VALUES,
NextLineHelp => NEXT_LINE_HELP
}
}

/// Application level settings, which affect how `App` operates
///
/// **NOTE:** When these settings are used, they apply only to current command, and are *not*
/// propagated down or up through child or parent subcommands
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum AppSettings {
/// Allows subcommands to override all requirements of the parent command. For example
Expand Down Expand Up @@ -374,7 +379,8 @@ pub enum AppSettings {
/// assert_eq!(m.value_of_os("arg").unwrap().as_bytes(), &[0xe9]);
/// ```
AllowInvalidUtf8,
/// Specifies that leading hyphens are allowed in argument values, such as `-10`
/// Specifies that leading hyphens are allowed in argument *values*, such as negative numbers
/// `-10`
///
/// **NOTE:** This can only be set application wide and not on a per argument basis.
///
Expand All @@ -398,9 +404,22 @@ pub enum AppSettings {
/// # ;
/// ```
AllowLeadingHyphen,
/// Tells `clap` *not* to print possible values when displaying help information. This can be
/// 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.
HidePossibleValuesInHelp,
/// Places the help string for all arguments on the line after the argument
///
/// **NOTE:** This setting is cosmetic only and does not affect any functionality.
///
/// # Examples
///
/// ```no_run
/// # use clap::{App, Arg, SubCommand, AppSettings};
/// App::new("myprog")
/// .setting(AppSettings::NextLineHelp)
/// .get_matches();
/// ```
NextLineHelp,
#[doc(hidden)]
NeedsLongVersion,
#[doc(hidden)]
Expand Down Expand Up @@ -431,6 +450,7 @@ impl FromStr for AppSettings {
"allowinvalidutf8" => Ok(AppSettings::AllowInvalidUtf8),
"allowleadinghyphen" => Ok(AppSettings::AllowLeadingHyphen),
"hidepossiblevaluesinhelp" => Ok(AppSettings::HidePossibleValuesInHelp),
"nextlinehelp" => Ok(AppSettings::NextLineHelp),
_ => Err("unknown AppSetting, cannot convert from str".to_owned()),
}
}
Expand Down
Loading