Repository: kbknapp/clap-rs
Pull request #1283 (2018-06-02 14:14:34)

Issue 897


<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/kbknapp/clap-rs/1283)
<!-- Reviewable:end -->



Patch:
diff --git a/src/app/help.rs b/src/app/help.rs
index 78b3d44f..34f97ac3 100644
--- a/src/app/help.rs
+++ b/src/app/help.rs
@@ -7,27 +7,31 @@ use std::io::{self, Cursor, Read, Write};
 use std::usize;
 
 // Internal
-use app::{App, AppSettings};
 use app::parser::Parser;
+use app::usage;
+use app::{App, AppSettings};
 use args::{AnyArg, ArgSettings, DispOrder};
 use errors::{Error, Result as ClapResult};
 use fmt::{Colorizer, ColorizerOption, Format};
-use app::usage;
 use map::VecMap;
 use INTERNAL_ERROR_MSG;
 
 // Third Party
-use unicode_width::UnicodeWidthStr;
 #[cfg(feature = "wrap_help")]
 use term_size;
 use textwrap;
+use unicode_width::UnicodeWidthStr;
 
 #[cfg(not(feature = "wrap_help"))]
 mod term_size {
-    pub fn dimensions() -> Option<(usize, usize)> { None }
+    pub fn dimensions() -> Option<(usize, usize)> {
+        None
+    }
 }
 
-fn str_width(s: &str) -> usize { UnicodeWidthStr::width(s) }
+fn str_width(s: &str) -> usize {
+    UnicodeWidthStr::width(s)
+}
 
 const TAB: &'static str = "    ";
 
@@ -46,13 +50,19 @@ impl<'b, 'c, T> ArgWithOrder<'b, 'c> for T
 where
     T: ArgWithDisplay<'b, 'c> + DispOrder,
 {
-    fn as_base(&self) -> &ArgWithDisplay<'b, 'c> { self }
+    fn as_base(&self) -> &ArgWithDisplay<'b, 'c> {
+        self
+    }
 }
 
-fn as_arg_trait<'a, 'b, T: ArgWithOrder<'a, 'b>>(x: &T) -> &ArgWithOrder<'a, 'b> { x }
+fn as_arg_trait<'a, 'b, T: ArgWithOrder<'a, 'b>>(x: &T) -> &ArgWithOrder<'a, 'b> {
+    x
+}
 
 impl<'b, 'c> DispOrder for App<'b, 'c> {
-    fn disp_ord(&self) -> usize { 999 }
+    fn disp_ord(&self) -> usize {
+        999
+    }
 }
 
 macro_rules! color {
@@ -203,9 +213,7 @@ impl<'a> Help<'a> {
         self.longest = 2;
         let mut arg_v = Vec::with_capacity(10);
         let use_long = self.use_long;
-        for arg in args.filter(|arg| {
-            should_show_arg(use_long, *arg)
-        }) {
+        for arg in args.filter(|arg| should_show_arg(use_long, *arg)) {
             if arg.longest_filter() {
                 self.longest = cmp::max(self.longest, str_width(arg.to_string().as_str()));
             }
@@ -444,13 +452,13 @@ impl<'a> Help<'a> {
     /// Writes argument's help to the wrapped stream.
     fn help<'b, 'c>(&mut self, arg: &ArgWithDisplay<'b, 'c>, spec_vals: &str) -> io::Result<()> {
         debugln!("Help::help;");
-        let h = if self.use_long {
+        let h = if self.use_long && arg.name() != "" {
             arg.long_help().unwrap_or_else(|| arg.help().unwrap_or(""))
         } else {
             arg.help().unwrap_or_else(|| arg.long_help().unwrap_or(""))
         };
         let mut help = String::from(h) + spec_vals;
-        let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp) || self.use_long;
+        let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp) || (self.use_long && arg.name() != "");
         debugln!("Help::help: Next Line...{:?}", nlh);
 
         let spcs = if nlh || self.force_next_line {
@@ -508,15 +516,14 @@ impl<'a> Help<'a> {
                 env.1
             );
             let env_val = if !a.is_set(ArgSettings::HideEnvValues) {
-                format!("={}", env.1.map_or(Cow::Borrowed(""), |val| val.to_string_lossy()))
+                format!(
+                    "={}",
+                    env.1.map_or(Cow::Borrowed(""), |val| val.to_string_lossy())
+                )
             } else {
                 String::new()
             };
-            let env_info = format!(
-                " [env: {}{}]",
-                env.0.to_string_lossy(),
-                env_val
-            );
+            let env_info = format!(" [env: {}{}]", env.0.to_string_lossy(), env_val);
             spec_vals.push(env_info);
         }
         if !a.is_set(ArgSettings::HideDefaultValue) {
@@ -572,9 +579,9 @@ fn should_show_arg(use_long: bool, arg: &ArgWithOrder) -> bool {
         return false;
     }
 
-    (!arg.is_set(ArgSettings::HiddenLongHelp) && use_long) ||
-        (!arg.is_set(ArgSettings::HiddenShortHelp) && !use_long) ||
-    arg.is_set(ArgSettings::NextLineHelp)
+    (!arg.is_set(ArgSettings::HiddenLongHelp) && use_long)
+        || (!arg.is_set(ArgSettings::HiddenShortHelp) && !use_long)
+        || arg.is_set(ArgSettings::NextLineHelp)
 }
 
 // Methods to write Parser help.
@@ -714,8 +721,7 @@ impl<'a> Help<'a> {
             ($thing:expr) => {{
                 let mut owned_thing = $thing.to_owned();
                 owned_thing = owned_thing.replace("{n}", "\n");
-                write!(self.writer, "{}\n",
-                            wrap_help(&owned_thing, self.term_w))?
+                write!(self.writer, "{}\n", wrap_help(&owned_thing, self.term_w))?
             }};
         }
         // Print the version
@@ -726,20 +732,21 @@ impl<'a> Help<'a> {
         if let Some(author) = parser.meta.author {
             write_thing!(author)
         }
-        if self.use_long {
-            if let Some(about) = parser.meta.long_about {
-                debugln!("Help::write_default_help: writing long about");
-                write_thing!(about)
-            } else if let Some(about) = parser.meta.about {
-                debugln!("Help::write_default_help: writing about");
-                write_thing!(about)
-            }
+        // if self.use_long {
+        //     if let Some(about) = parser.meta.long_about {
+        //         debugln!("Help::write_default_help: writing long about");
+        //         write_thing!(about)
+        //     } else if let Some(about) = parser.meta.about {
+        //         debugln!("Help::write_default_help: writing about");
+        //         write_thing!(about)
+        //     }
+        // } else
+        if let Some(about) = parser.meta.long_about {
+            debugln!("Help::write_default_help: writing long about");
+            write_thing!(about)
         } else if let Some(about) = parser.meta.about {
             debugln!("Help::write_default_help: writing about");
             write_thing!(about)
-        } else if let Some(about) = parser.meta.long_about {
-            debugln!("Help::write_default_help: writing long about");
-            write_thing!(about)
         }
 
         color!(self, "\nUSAGE:", warning)?;
@@ -867,7 +874,6 @@ fn copy_and_capture<R: Read, W: Write>(
     }
 }
 
-
 // Methods to write Parser help using templates.
 impl<'a> Help<'a> {
     /// Write help to stream for the parser in the format defined by the template.
diff --git a/src/app/mod.rs b/src/app/mod.rs
index 5facbfb7..f2d9d52b 100644
--- a/src/app/mod.rs
+++ b/src/app/mod.rs
@@ -1671,6 +1671,7 @@ impl<'a> From<&'a Yaml> for App<'a, 'a> {
         yaml_str!(a, yaml, author);
         yaml_str!(a, yaml, bin_name);
         yaml_str!(a, yaml, about);
+        yaml_str!(a, yaml, long_about);
         yaml_str!(a, yaml, before_help);
         yaml_str!(a, yaml, after_help);
         yaml_str!(a, yaml, template);
@@ -1788,7 +1789,7 @@ impl<'a, 'b> Clone for App<'a, 'b> {
 
 impl<'n, 'e> AnyArg<'n, 'e> for App<'n, 'e> {
     fn name(&self) -> &'n str {
-        unreachable!("App struct does not support AnyArg::name, this is a bug!")
+        ""
     }
     fn overrides(&self) -> Option<&[&'e str]> { None }
     fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> { None }


Test patch:
diff --git a/tests/help.rs b/tests/help.rs
index 97f26ac0..4b15281f 100644
--- a/tests/help.rs
+++ b/tests/help.rs
@@ -1158,3 +1158,48 @@ fn show_env_vals() {
             .takes_value(true));
     assert!(test::compare_output(app, "ctest --help", SHOW_ENV_VALS, false));
 }
+
+static ISSUE_897: &'static str = "ctest-foo 0.1
+Long about foo
+
+USAGE:
+    ctest foo
+
+FLAGS:
+    -h, --help       
+            Prints help information
+
+    -V, --version    
+            Prints version information";
+
+#[test]
+fn show_long_about_issue_897() {
+    let app = App::new("ctest")
+        .version("0.1")
+        .subcommand(SubCommand::with_name("foo")
+            .version("0.1")
+            .about("About foo")
+            .long_about("Long about foo"));
+    assert!(test::compare_output(app, "ctest foo --help", ISSUE_897, false));
+}
+
+static ISSUE_897_SHORT: &'static str = "ctest-foo 0.1
+Long about foo
+
+USAGE:
+    ctest foo
+
+FLAGS:
+    -h, --help       Prints help information
+    -V, --version    Prints version information";
+
+#[test]
+fn show_short_about_issue_897() {
+    let app = App::new("ctest")
+        .version("0.1")
+        .subcommand(SubCommand::with_name("foo")
+            .version("0.1")
+            .about("About foo")
+            .long_about("Long about foo"));
+    assert!(test::compare_output(app, "ctest foo -h", ISSUE_897_SHORT, false));
+}