Skip to content

Commit 326d0a5

Browse files
authored
Merge pull request clap-rs#1045 from kbknapp/issues-1043,1044
Issues 1043,1044
2 parents 2094c28 + cbd813c commit 326d0a5

File tree

9 files changed

+120
-22
lines changed

9 files changed

+120
-22
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
<a name="v2.26.1"></a>
2+
### v2.26.1 (2017-09-14)
3+
4+
5+
#### Bug Fixes
6+
7+
* fixes using require_equals(true) and min_values(0) together ([10ae208f](https://github.com/kbknapp/clap-rs/commit/10ae208f68518eff6e98166724065745f4083174), closes [#1044](https://github.com/kbknapp/clap-rs/issues/1044))
8+
* escape special characters in zsh and fish completions ([87e019fc](https://github.com/kbknapp/clap-rs/commit/87e019fc84ba6193a8c4ddc26c61eb99efffcd25))
9+
* avoid panic generating default help msg if term width set to 0 due to bug in textwrap 0.7.0 ([b3eadb0d](https://github.com/kbknapp/clap-rs/commit/b3eadb0de516106db4e08f078ad32e8f6d6e7a57))
10+
* Change `who's` -> `whose` ([53c1ffe8](https://github.com/kbknapp/clap-rs/commit/53c1ffe87f38b05d8804a0f7832412a952845349))
11+
* adds a debug assertion to ensure all args added to groups actually exist ([7ad123e2](https://github.com/kbknapp/clap-rs/commit/7ad123e2c02577e3ca30f7e205181e896b157d11), closes [#917](https://github.com/kbknapp/clap-rs/issues/917))
12+
* fixes a bug where args that allow values to start with a hyphen couldnt contain a double hyphen -- as a value ([ab2f4c9e](https://github.com/kbknapp/clap-rs/commit/ab2f4c9e563e36ec739a4b55d5a5b76fdb9e9fa4), closes [#960](https://github.com/kbknapp/clap-rs/issues/960))
13+
* fixes a bug where positional argument help text is misaligned ([54c16836](https://github.com/kbknapp/clap-rs/commit/54c16836dea4651806a2cfad53146a83fa3abf21))
14+
* **Help Message:** fixes long_about not being usable ([a8257ea0](https://github.com/kbknapp/clap-rs/commit/a8257ea0ffb812e552aca256c4a3d2aebfd8065b), closes [#1043](https://github.com/kbknapp/clap-rs/issues/1043))
15+
* **Suggestions:** output for flag after subcommand ([434ea5ba](https://github.com/kbknapp/clap-rs/commit/434ea5ba71395d8c1afcf88e69f0b0d8339b01a1))
16+
17+
18+
119
<a name="v2.26.0"></a>
220
## v2.26.0 (2017-07-29)
321

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22

33
name = "clap"
4-
version = "2.26.0"
4+
version = "2.26.1"
55
authors = ["Kevin K. <[email protected]>"]
66
exclude = ["examples/*", "clap-test/*", "tests/*", "benches/*", "*.png", "clap-perf/*", "*.dot"]
77
repository = "https://github.com/kbknapp/clap-rs.git"
@@ -23,7 +23,6 @@ appveyor = { repository = "kbknapp/clap-rs" }
2323
bitflags = "0.9"
2424
vec_map = "0.8"
2525
unicode-width = "0.1.4"
26-
unicode-segmentation = "1.2.0"
2726
textwrap = "0.8.0"
2827
strsim = { version = "0.6.0", optional = true }
2928
ansi_term = { version = "0.9.0", optional = true }

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,21 @@ Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc)
4545

4646
## What's New
4747

48-
Here's the highlights for v2.26.0
48+
Here's what's new in 2.26.1:
4949

50-
* **The minimum required version of Rust is now 1.13.0 (Stable)**
51-
* bumps unicode-segmentation to v1.2
52-
* update textwrap to version 0.7.0 which increases the performance of writing help strings
50+
* fixes using require_equals(true) and min_values(0) together
51+
* escape special characters in zsh and fish completions
52+
* avoid panic generating default help msg if term width set to 0 due to bug in textwrap 0.7.0
53+
* Change `who's` -> `whose` in documentation
54+
* **Help Message:** fixes `App::long_about` not being displayed
55+
* **Suggestions:** output for flag after subcommand
5356

5457

55-
Here's the highlights for v2.21.0 to v2.25.1
58+
Here's the highlights for v2.21.0 to v2.26.0
5659

60+
* **The minimum required version of Rust is now 1.13.0 (Stable)**
61+
* bumps unicode-segmentation to v1.2
62+
* update textwrap to version 0.7.0 which increases the performance of writing help strings
5763
* impl Default for Values + OsValues for any lifetime.
5864
* use textwrap crate for wrapping help texts
5965
* suggests to use flag after subcommand when applicable

src/app/help.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,8 +657,22 @@ impl<'a> Help<'a> {
657657
if let Some(author) = parser.meta.author {
658658
write_thing!(author)
659659
}
660-
if let Some(about) = parser.meta.about {
661-
write_thing!(about)
660+
if self.use_long {
661+
if let Some(about) = parser.meta.long_about {
662+
debugln!("Help::write_default_help: writing long about");
663+
write_thing!(about)
664+
} else if let Some(about) = parser.meta.about {
665+
debugln!("Help::write_default_help: writing about");
666+
write_thing!(about)
667+
}
668+
} else {
669+
if let Some(about) = parser.meta.about {
670+
debugln!("Help::write_default_help: writing about");
671+
write_thing!(about)
672+
} else if let Some(about) = parser.meta.long_about {
673+
debugln!("Help::write_default_help: writing long about");
674+
write_thing!(about)
675+
}
662676
}
663677

664678
color!(self, "\nUSAGE:", warning)?;
@@ -861,6 +875,11 @@ impl<'a> Help<'a> {
861875
"{}",
862876
parser.meta.about.unwrap_or("unknown about"))?;
863877
}
878+
b"long-about" => {
879+
write!(self.writer,
880+
"{}",
881+
parser.meta.long_about.unwrap_or("unknown about"))?;
882+
}
864883
b"usage" => {
865884
write!(self.writer, "{}", usage::create_usage_no_title(parser, &[]))?;
866885
}

src/app/parser.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,7 +1339,8 @@ impl<'a, 'b> Parser<'a, 'b>
13391339

13401340
#[cfg_attr(feature = "cargo-clippy", allow(let_and_return))]
13411341
fn use_long_help(&self) -> bool {
1342-
let ul = self.flags.iter().any(|f| f.b.long_help.is_some()) ||
1342+
let ul = self.meta.long_about.is_some() ||
1343+
self.flags.iter().any(|f| f.b.long_help.is_some()) ||
13431344
self.opts.iter().any(|o| o.b.long_help.is_some()) ||
13441345
self.positionals.values().any(|p| p.b.long_help.is_some()) ||
13451346
self.subcommands
@@ -1529,13 +1530,17 @@ impl<'a, 'b> Parser<'a, 'b>
15291530
debugln!("Parser::parse_opt; opt={}, val={:?}", opt.b.name, val);
15301531
debugln!("Parser::parse_opt; opt.settings={:?}", opt.b.settings);
15311532
let mut has_eq = false;
1533+
let no_val = val.is_none();
1534+
let empty_vals = opt.is_set(ArgSettings::EmptyValues);
1535+
let min_vals_zero = opt.v.min_vals.unwrap_or(1) == 0;
1536+
let needs_eq = opt.is_set(ArgSettings::RequireEquals);
15321537

15331538
debug!("Parser::parse_opt; Checking for val...");
15341539
if let Some(fv) = val {
15351540
has_eq = fv.starts_with(&[b'=']) || had_eq;
15361541
let v = fv.trim_left_matches(b'=');
1537-
if !opt.is_set(ArgSettings::EmptyValues) &&
1538-
(v.len_() == 0 || (opt.is_set(ArgSettings::RequireEquals) && !has_eq)) {
1542+
if !empty_vals &&
1543+
(v.len_() == 0 || (needs_eq && !has_eq)) {
15391544
sdebugln!("Found Empty - Error");
15401545
return Err(Error::empty_value(opt,
15411546
&*usage::create_error_usage(self, matcher, None),
@@ -1546,7 +1551,7 @@ impl<'a, 'b> Parser<'a, 'b>
15461551
fv,
15471552
fv.starts_with(&[b'=']));
15481553
self.add_val_to_arg(opt, v, matcher)?;
1549-
} else if opt.is_set(ArgSettings::RequireEquals) && !opt.is_set(ArgSettings::EmptyValues) {
1554+
} else if needs_eq && !(empty_vals || min_vals_zero) {
15501555
sdebugln!("None, but requires equals...Error");
15511556
return Err(Error::empty_value(opt,
15521557
&*usage::create_error_usage(self, matcher, None),
@@ -1561,10 +1566,12 @@ impl<'a, 'b> Parser<'a, 'b>
15611566
self.groups_for_arg(opt.b.name)
15621567
.and_then(|vec| Some(matcher.inc_occurrences_of(&*vec)));
15631568

1564-
if val.is_none() ||
1565-
!has_eq &&
1566-
(opt.is_set(ArgSettings::Multiple) && !opt.is_set(ArgSettings::RequireDelimiter) &&
1567-
matcher.needs_more_vals(opt)) {
1569+
let needs_delim = opt.is_set(ArgSettings::RequireDelimiter);
1570+
let mult = opt.is_set(ArgSettings::Multiple);
1571+
if no_val && min_vals_zero && !has_eq && needs_eq {
1572+
debugln!("Parser::parse_opt: More arg vals not required...");
1573+
return Ok(ParseResult::ValuesDone);
1574+
} else if no_val || (mult && !needs_delim) && !has_eq && matcher.needs_more_vals(opt) {
15681575
debugln!("Parser::parse_opt: More arg vals required...");
15691576
return Ok(ParseResult::Opt(opt.b.name));
15701577
}

src/app/validator.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,9 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
294294
self.0.color()));
295295
}
296296
}
297-
if let Some(num) = a.min_vals() {
297+
let min_vals_zero = if let Some(num) = a.min_vals() {
298298
debugln!("Validator::validate_arg_num_vals: min_vals set: {}", num);
299-
if (ma.vals.len() as u64) < num {
299+
if (ma.vals.len() as u64) < num && num != 0 {
300300
debugln!("Validator::validate_arg_num_vals: Sending error TooFewValues");
301301
return Err(Error::too_few_values(a,
302302
num,
@@ -306,9 +306,10 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
306306
None),
307307
self.0.color()));
308308
}
309-
}
309+
num == 0
310+
} else { false };
310311
// Issue 665 (https://github.com/kbknapp/clap-rs/issues/665)
311-
if a.takes_value() && !a.is_set(ArgSettings::EmptyValues) && ma.vals.is_empty() {
312+
if a.takes_value() && !(a.is_set(ArgSettings::EmptyValues) || min_vals_zero) && ma.vals.is_empty() {
312313
return Err(Error::empty_value(a,
313314
&*usage::create_error_usage(self.0, matcher, None),
314315
self.0.color()));

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,6 @@ extern crate vec_map;
542542
#[cfg(feature = "wrap_help")]
543543
extern crate term_size;
544544
extern crate textwrap;
545-
extern crate unicode_segmentation;
546545
#[cfg(feature = "color")]
547546
extern crate atty;
548547

tests/help.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,26 @@ FLAGS:
440440
-h, --help Prints help information
441441
-V, --version Prints version information";
442442

443+
static LONG_ABOUT: &'static str = "myapp 1.0
444+
foo
445+
something really really long, with
446+
multiple lines of text
447+
that should be displayed
448+
449+
USAGE:
450+
myapp [arg1]
451+
452+
FLAGS:
453+
-h, --help
454+
Prints help information
455+
456+
-V, --version
457+
Prints version information
458+
459+
460+
ARGS:
461+
<arg1>
462+
some option";
443463
#[test]
444464
fn help_short() {
445465
let m = App::new("test")
@@ -784,6 +804,17 @@ fn issue_702_multiple_values() {
784804
assert!(test::compare_output(app, "myapp --help", ISSUE_702, false));
785805
}
786806

807+
#[test]
808+
fn long_about() {
809+
let app = App::new("myapp")
810+
.version("1.0")
811+
.author("foo")
812+
.about("bar")
813+
.long_about("something really really long, with\nmultiple lines of text\nthat should be displayed")
814+
.arg(Arg::with_name("arg1").help("some option"));
815+
assert!(test::compare_output(app, "myapp --help", LONG_ABOUT, false));
816+
}
817+
787818
#[test]
788819
fn issue_760() {
789820
let app = App::new("ctest")

tests/opts.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,24 @@ fn require_equals_fail() {
2828
assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
2929
}
3030

31+
#[test]
32+
fn require_equals_min_values_zero() {
33+
let res = App::new("prog")
34+
.arg(Arg::with_name("cfg")
35+
.require_equals(true)
36+
.takes_value(true)
37+
.min_values(0)
38+
.long("config"))
39+
.arg(Arg::with_name("cmd"))
40+
.get_matches_from_safe(vec![
41+
"prog", "--config", "cmd"
42+
]);
43+
assert!(res.is_ok());
44+
let m = res.unwrap();
45+
assert!(m.is_present("cfg"));
46+
assert_eq!(m.value_of("cmd"), Some("cmd"));
47+
}
48+
3149
#[test]
3250
fn double_hyphen_as_value() {
3351
let res = App::new("prog")

0 commit comments

Comments
 (0)