Repository: dathere/qsv (language: rust)

Issue:
move --help from stderr to stout
If I run `--help` I have to add `2>&1` before I can pipe it through `less` which I don't have to do for `--list`.

I often forget and then have to quit `less`, repeat the command, with the redirection.


Discussion / hints:
This requires tweaking docopt a bit.

Added it to the backlog @ondohotola .
Thanks.
To confirm, looking at GNU guidelines...

https://www.gnu.org/prep/standards/standards.html#g_t_002d_002dhelp

It does specify that `--help` and `--version` should both go to stdout, not stderr.
Moved qsv_docopt crate to https://github.com/dathere/qsv-docopt.

Fixes will be done there going forward.

@rzmk, also will implement the enhancement there so qsv pro can show usage text. Thinking of using markdown on all usage text so it looks prettier on qsv pro...  
If switching to markdown for the usage text then it may be neat to render it as formatted in the terminal too:

- This crate may be useful: https://github.com/Canop/termimad
- This other one's in alpha: https://github.com/guilhermeprokisch/see I think it's a CLI tool actually
termimad looks awesome @rzmk!

Apart from styling, it handles scrolling too!

Fix patch:
diff --git a/src/clitypes.rs b/src/clitypes.rs
index 3ad8af545..7df045400 100644
--- a/src/clitypes.rs
+++ b/src/clitypes.rs
@@ -145,6 +145,7 @@ pub type CliResult<T> = Result<T, CliError>;
 #[derive(Debug)]
 pub enum CliError {
     Flag(docopt::Error),
+    Help(String),
     Csv(csv::Error),
     Io(io::Error),
     NoMatch(),
@@ -159,6 +160,7 @@ impl fmt::Display for CliError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             CliError::Flag(ref e) => e.fmt(f),
+            CliError::Help(ref e) => e.fmt(f),
             CliError::Csv(ref e) => e.fmt(f),
             CliError::Io(ref e) => e.fmt(f),
             CliError::NoMatch() => f.write_str("no_match"),
@@ -173,7 +175,15 @@ impl fmt::Display for CliError {
 
 impl From<docopt::Error> for CliError {
     fn from(err: docopt::Error) -> CliError {
-        CliError::Flag(err)
+        if let docopt::Error::WithProgramUsage(ref errtype, ref usage_text) = err {
+            if let docopt::Error::Help = **errtype {
+                CliError::Help(usage_text.to_string())
+            } else {
+                CliError::Flag(err)
+            }
+        } else {
+            CliError::Flag(err)
+        }
     }
 }
 
@@ -182,9 +192,11 @@ impl From<csv::Error> for CliError {
         if !err.is_io_error() {
             return CliError::Csv(err);
         }
-        match err.into_kind() {
-            csv::ErrorKind::Io(v) => From::from(v),
-            _ => unreachable!(),
+        if let csv::ErrorKind::Io(v) = err.into_kind() {
+            From::from(v)
+        } else {
+            // safety: we checked for !is_io_error above
+            unreachable!()
         }
     }
 }
diff --git a/src/main.rs b/src/main.rs
index 7958ba927..9021bdbb8 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -271,6 +271,11 @@ sponsored by datHere - Data Infrastructure Engineering (https://qsv.datHere.com)
                 util::log_end(qsv_args, now);
                 QsvExitCode::Good
             },
+            Err(CliError::Help(usage_text)) => {
+                wout!("{usage_text}");
+                util::log_end(qsv_args, now);
+                QsvExitCode::Good
+            },
             Err(CliError::Flag(err)) => {
                 werr!("{err}");
                 util::log_end(qsv_args, now);
diff --git a/src/maindp.rs b/src/maindp.rs
index cc03bd5f1..91f3f5ccb 100644
--- a/src/maindp.rs
+++ b/src/maindp.rs
@@ -182,6 +182,11 @@ Please choose one of the following commands:",
                 util::log_end(qsv_args, now);
                 QsvExitCode::Good
             },
+            Err(CliError::Help(usage_text)) => {
+                wout!("{usage_text}");
+                util::log_end(qsv_args, now);
+                QsvExitCode::Good
+            },
             Err(CliError::Flag(err)) => {
                 werr!("{err}");
                 util::log_end(qsv_args, now);
diff --git a/src/mainlite.rs b/src/mainlite.rs
index c6886091b..709ea5bc5 100644
--- a/src/mainlite.rs
+++ b/src/mainlite.rs
@@ -171,6 +171,11 @@ Please choose one of the following commands:",
                 util::log_end(qsv_args, now);
                 QsvExitCode::Good
             },
+            Err(CliError::Help(usage_text)) => {
+                wout!("{usage_text}");
+                util::log_end(qsv_args, now);
+                QsvExitCode::Good
+            },
             Err(CliError::Flag(err)) => {
                 werr!("{err}");
                 util::log_end(qsv_args, now);


Test patch: