Skip to content

Commit

Permalink
Auto merge of #517 - kbknapp:quick-issues, r=kbknapp
Browse files Browse the repository at this point in the history
Quick issues

Relates to #515 #516 #514
  • Loading branch information
homu committed May 31, 2016
2 parents a86d6aa + 05abb53 commit ed0fd8a
Show file tree
Hide file tree
Showing 12 changed files with 220 additions and 65 deletions.
23 changes: 21 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
<a name="v2.5.2"></a>
### v2.5.2 (2016-05-31)


#### Improvements

* removes extra newline from help output ([86e61d19](https://github.com/kbknapp/clap-rs/commit/86e61d19a748fb9870fcf1175308984e51ca1115))
* allows printing version to any io::Write object ([921f5f79](https://github.com/kbknapp/clap-rs/commit/921f5f7916597f1d028cd4a65bfe76a01c801724))
* removes extra newline when printing version ([7e2e2cbb](https://github.com/kbknapp/clap-rs/commit/7e2e2cbb4a8a0f050bb8072a376f742fc54b8589))

#### Bug Fixes

* fixes bug where args are printed out of order with templates ([3935431d](https://github.com/kbknapp/clap-rs/commit/3935431d5633f577c0826ae2142794b301f4b8ca))
* fixes bug where one can't override version or help flags ([90d7d6a2](https://github.com/kbknapp/clap-rs/commit/90d7d6a2ea8240122dd9bf8d82d3c4f5ebb5c703), closes [#514](https://github.com/kbknapp/clap-rs/issues/514))
* fixes issue where before_help wasn't printed ([b3faff60](https://github.com/kbknapp/clap-rs/commit/b3faff6030f76a23f26afcfa6a90169002ed7106))

#### Documentation

* inter-links all types and pages ([3312893d](https://github.com/kbknapp/clap-rs/commit/3312893ddaef3f44d68d8d26ed3d08010be50d97), closes [#505](https://github.com/kbknapp/clap-rs/issues/505))
* makes all publicly available types viewable in docs ([52ca6505](https://github.com/kbknapp/clap-rs/commit/52ca6505b4fec7b5c2d53d160c072d395eb21da6))

<a name="v2.5.1"></a>
### v2.5.1 (2016-05-11)

Expand All @@ -6,8 +27,6 @@

* **Subcommand Aliases**: fixes lifetime issue when setting multiple aliases at once ([ac42f6cf0](https://github.com/kbknapp/clap-rs/commit/ac42f6cf0de6c4920f703807d63061803930b18d))



<a name="v2.5.0"></a>
## v2.5.0 (2016-05-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.5.1"
version = "2.5.2"
authors = ["Kevin K. <[email protected]>"]
exclude = ["examples/*", "clap-test/*", "tests/*", "benches/*", "*.png", "clap-perf/*", "*.dot"]
description = "A simple to use, efficient, and full featured Command Line Argument Parser"
Expand Down
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc)

## What's New

Here's what's new in v.2.5.2

* Removes trailing newlines from help and version output
* Allows printing version to any io::Write object
* Inter-links all types and pages
* Makes all publicly available types viewable in docs
* Fixes bug where one can't override version or help flags
* Fixes bug where args are printed out of order when using templates
* Fixes issue where `App::before_help` wasn't printed properly

Here's what's new in v.2.5.0

* Subcommands now support aliases - think of them as hidden subcommands that dispatch to said subcommand automatically
Expand All @@ -50,12 +60,12 @@ Here's what's new in v2.4.3
* Improvements
* Positional arguments which are part of a group are now formatted in a more readable way (fewer brackets)
* Positional arguments use the standard `<>` brackets to reduce confusion
* The default help string for the `help` subcommand has been shortened to fit in 80 columns
* The default help string for the `help` subcommand has been shortened to fit in 80 columns

Here's the highlights from v2.4.0

* **Before Help:** adds support for displaying info before help message
* **Required Unless:** adds support for allowing args that are required unless certain other args are present
* **Before Help:** adds support for displaying info before help message
* **Required Unless:** adds support for allowing args that are required unless certain other args are present
* Bug fixes

Here's the highlights from v2.3.0
Expand Down
10 changes: 10 additions & 0 deletions clap-test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ mod test {
assert_eq!(str::from_utf8(&help).unwrap(), out);
}

pub fn check_version(mut a: App, out: &str) {
// We call a get_matches method to cause --help and --version to be built
let _ = a.get_matches_from_safe_borrow(vec![""]);

// Now we check the output of print_version()
let mut ver = vec![];
a.write_version(&mut ver).ok().expect("failed to print help");
assert_eq!(str::from_utf8(&ver).unwrap(), out);
}

pub fn check_complex_output(args: &str, out: &str) {
let mut w = vec![];
let matches = complex_app().get_matches_from(args.split(' ').collect::<Vec<_>>());
Expand Down
72 changes: 50 additions & 22 deletions src/app/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub struct Help<'a> {
impl<'a> Help<'a> {
/// Create a new `Help` instance.
pub fn new(w: &'a mut Write, next_line_help: bool, hide_pv: bool, color: bool) -> Self {
debugln!("fn=Help::new;");
Help {
writer: w,
next_line_help: next_line_help,
Expand All @@ -100,12 +101,14 @@ impl<'a> Help<'a> {
/// Reads help settings from an App
/// and write its help to the wrapped stream.
pub fn write_app_help(w: &'a mut Write, app: &App) -> ClapResult<()> {
debugln!("fn=Help::write_app_help;");
Self::write_parser_help(w, &app.p)
}

/// Reads help settings from a Parser
/// and write its help to the wrapped stream.
pub fn write_parser_help(w: &'a mut Write, parser: &Parser) -> ClapResult<()> {
debugln!("fn=Help::write_parser_help;");
let nlh = parser.is_set(AppSettings::NextLineHelp);
let hide_v = parser.is_set(AppSettings::HidePossibleValuesInHelp);
let color = parser.is_set(AppSettings::ColoredHelp);
Expand All @@ -114,8 +117,9 @@ impl<'a> Help<'a> {

/// Writes the parser help to the wrapped stream.
pub fn write_help(&mut self, parser: &Parser) -> ClapResult<()> {
debugln!("fn=Help::write_help;");
if let Some(h) = parser.meta.help_str {
try!(writeln!(self.writer, "{}", h).map_err(Error::from));
try!(write!(self.writer, "{}", h).map_err(Error::from));
} else if let Some(ref tmpl) = parser.meta.template {
try!(self.write_templated_help(&parser, tmpl));
} else {
Expand All @@ -131,6 +135,7 @@ impl<'a> Help<'a> {
fn write_args_unsorted<'b: 'd, 'c: 'd, 'd, I: 'd>(&mut self, args: I) -> io::Result<()>
where I: Iterator<Item = &'d ArgWithOrder<'b, 'c>>
{
debugln!("fn=write_args_unsorted;");
let mut longest = 0;
let mut arg_v = Vec::with_capacity(10);
for arg in args.filter(|arg| {
Expand All @@ -143,7 +148,13 @@ impl<'a> Help<'a> {
arg_v.push(arg)
}
}
let mut first = true;
for arg in arg_v {
if !first {
try!(self.writer.write(b"\n"));
} else {
first = false;
};
try!(self.write_arg(arg.as_base(), longest));
}
Ok(())
Expand All @@ -153,6 +164,7 @@ impl<'a> Help<'a> {
fn write_args<'b: 'd, 'c: 'd, 'd, I: 'd>(&mut self, args: I) -> io::Result<()>
where I: Iterator<Item = &'d ArgWithOrder<'b, 'c>>
{
debugln!("fn=write_args;");
let mut longest = 0;
let mut ord_m = VecMap::new();
for arg in args.filter(|arg| {
Expand All @@ -166,8 +178,14 @@ impl<'a> Help<'a> {
btm.insert(arg.name(), arg);
}
}
let mut first = true;
for (_, btm) in ord_m.into_iter() {
for (_, arg) in btm.into_iter() {
if !first {
try!(self.writer.write(b"\n"));
} else {
first = false;
}
try!(self.write_arg(arg.as_base(), longest));
}
}
Expand All @@ -179,12 +197,11 @@ impl<'a> Help<'a> {
arg: &ArgWithDisplay<'b, 'c>,
longest: usize)
-> io::Result<()> {
debugln!("fn=write_to;");
debugln!("fn=write_arg;");
try!(self.short(arg));
try!(self.long(arg, longest));
try!(self.val(arg, longest));
try!(self.help(arg, longest));
try!(self.writer.write(b"\n"));
Ok(())
}

Expand Down Expand Up @@ -458,45 +475,33 @@ impl<'a> Help<'a> {

let unified_help = parser.is_set(AppSettings::UnifiedHelpMessage);

let mut first = true;

if unified_help && (flags || opts) {
let opts_flags = parser.iter_flags()
.map(as_arg_trait)
.chain(parser.iter_opts().map(as_arg_trait));
try!(color!(self, "OPTIONS:\n", Warning));
try!(self.write_args(opts_flags));
first = false;
} else {
if flags {
try!(color!(self, "FLAGS:\n", Warning));
try!(self.write_args(parser.iter_flags()
.map(as_arg_trait)));
first = false;
}
if opts {
if !first {
try!(self.writer.write(b"\n"));
}
try!(self.writer.write(b"\n\n"));
try!(color!(self, "OPTIONS:\n", Warning));
try!(self.write_args(parser.iter_opts().map(as_arg_trait)));
first = false;
}
}

if pos {
if !first {
try!(self.writer.write(b"\n"));
}
try!(self.writer.write(b"\n\n"));
try!(color!(self, "ARGS:\n", Warning));
try!(self.write_args_unsorted(parser.iter_positionals().map(as_arg_trait)));
first = false;
}

if subcmds {
if !first {
try!(self.writer.write(b"\n"));
}
try!(self.writer.write(b"\n\n"));
try!(color!(self, "SUBCOMMANDS:\n", Warning));
try!(self.write_subcommands(&parser));
}
Expand All @@ -506,6 +511,7 @@ impl<'a> Help<'a> {

/// Writes help for subcommands of a Parser Object to the wrapped stream.
fn write_subcommands(&mut self, parser: &Parser) -> io::Result<()> {
debugln!("exec=write_subcommands;");
let mut longest = 0;

let mut ord_m = VecMap::new();
Expand All @@ -515,8 +521,16 @@ impl<'a> Help<'a> {
longest = cmp::max(longest, sc.p.meta.name.len());
}

let mut first = true;
for (_, btm) in ord_m.into_iter() {
for (_, sc) in btm.into_iter() {
if !first {
debugln!("Writing newline...");
try!(self.writer.write(b"\n"));
} else {
first = false;
}
debugln!("Writing sc...{}", sc);
try!(self.write_arg(sc, longest));
}
}
Expand Down Expand Up @@ -546,6 +560,11 @@ impl<'a> Help<'a> {

/// Writes default help for a Parser Object to the wrapped stream.
pub fn write_default_help(&mut self, parser: &Parser) -> ClapResult<()> {
debugln!("fn=write_default_help;");
if let Some(h) = parser.meta.pre_help {
try!(write!(self.writer, "{}", h));
try!(self.writer.write(b"\n\n"));
}

// Print the version
try!(self.write_bin_name(&parser));
Expand Down Expand Up @@ -575,7 +594,10 @@ impl<'a> Help<'a> {
}

if let Some(h) = parser.meta.more_help {
try!(write!(self.writer, "{}\n", h));
if flags || opts || pos || subcmds {
try!(self.writer.write(b"\n\n"));
}
try!(write!(self.writer, "{}", h));
}

self.writer.flush().map_err(Error::from)
Expand Down Expand Up @@ -708,6 +730,7 @@ impl<'a> Help<'a> {
/// The template system is, on purpose, very simple. Therefore the tags have to writen
/// in the lowercase and without spacing.
fn write_templated_help(&mut self, parser: &Parser, template: &str) -> ClapResult<()> {
debugln!("fn=write_templated_help;");
let mut tmplr = Cursor::new(&template);
let mut tag_buf = Cursor::new(vec![0u8; 15]);

Expand All @@ -725,6 +748,12 @@ impl<'a> Help<'a> {
_ => continue,
};

debugln!("iter;tag_buf={};", unsafe {
String::from_utf8_unchecked(tag_buf.get_ref()[0..tag_length]
.iter()
.map(|&i|i)
.collect::<Vec<_>>())
});
match &tag_buf.get_ref()[0..tag_length] {
b"?" => {
try!(self.writer.write(b"Could not decode tag name"));
Expand Down Expand Up @@ -768,8 +797,8 @@ impl<'a> Help<'a> {
.map(as_arg_trait)));
}
b"positionals" => {
try!(self.write_args(parser.iter_positionals()
.map(as_arg_trait)));
try!(self.write_args_unsorted(parser.iter_positionals()
.map(as_arg_trait)));
}
b"subcommands" => {
try!(self.write_subcommands(&parser));
Expand All @@ -791,7 +820,6 @@ impl<'a> Help<'a> {
try!(self.writer.write(b"}"));
}
}

}
}
}
Expand Down
16 changes: 16 additions & 0 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,22 @@ impl<'a, 'b> App<'a, 'b> {
Help::write_app_help(w, &self)
}

/// Writes the version message to the user to a [`io::Write`] object
///
/// # Examples
///
/// ```rust
/// # use clap::App;
/// use std::io;
/// let mut app = App::new("myprog");
/// let mut out = io::stdout();
/// app.write_version(&mut out).ok().expect("failed to write to stdout");
/// ```
/// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
pub fn write_version<W: Write>(&self, w: &mut W) -> ClapResult<()> {
self.p.write_version(w).map_err(From::from)
}

/// Starts the parsing process, upon a failed parse an error will be displayed to the user and
/// the process with exit with the appropriate error code. By default this method gets all user
/// provided arguments from [`env::args_os`] in order to allow for invalid UTF-8 code points,
Expand Down
Loading

0 comments on commit ed0fd8a

Please sign in to comment.