about summary refs log tree commit diff
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2024-03-03 17:33:07 +0100
committerProfpatsch <mail@profpatsch.de>2024-03-03 17:46:41 +0100
commit02d9594c5533036ad1dee18fa89de74bcf0962b8 (patch)
tree4679c074aed6cd46801e84e9736cd9df8a651f8b
parent6e9330977b8a0ca10195f16645053e1838a46beb (diff)
pkgs/profpatsch/nman: add a `--verbose` flag
And only print debug stuff iff we enabled it.
-rw-r--r--pkgs/profpatsch/nman/nman.115
-rw-r--r--pkgs/profpatsch/nman/nman.rs54
2 files changed, 44 insertions, 25 deletions
diff --git a/pkgs/profpatsch/nman/nman.1 b/pkgs/profpatsch/nman/nman.1
index 2ef6797c..1d598c83 100644
--- a/pkgs/profpatsch/nman/nman.1
+++ b/pkgs/profpatsch/nman/nman.1
@@ -6,7 +6,7 @@
 .Nd nix-shell for man pages
 .Sh SYNOPSIS
 .Nm
-.Op Fl h
+.Op Fl hv
 .Ar ATTR
 .Op Ar PAGE | SECTION Op PAGE
 .Sh DESCRIPTION
@@ -70,11 +70,22 @@ just like invoking
 .Xr man 1
 with two arguments.
 .El
+
+The following options modify the behavior of nman:
+
+.Bl -tag -width Ds
+.It Fl -help | -usage | h
+Print usage information.
+.It Fl -verbose | v
+Put
+.Nm
+into verbose mode, where it prints all commands it executes.
+.El
+
 .Sh EXAMPLES
 .Bd -literal
 # open lowdown(1)
 nman lowdown
-
 # open lowdown(3) from the same package
 nman lowdown 3
 
diff --git a/pkgs/profpatsch/nman/nman.rs b/pkgs/profpatsch/nman/nman.rs
index a3fbfc57..80cea4d6 100644
--- a/pkgs/profpatsch/nman/nman.rs
+++ b/pkgs/profpatsch/nman/nman.rs
@@ -23,7 +23,6 @@ enum CliResult<'a> {
 
 fn main() {
     use CliResult::*;
-    // let main = Main{is_debug: false};
     let (opts, args) : (Vec<String>, Vec<String>) =
             std::env::args().partition(|s| s.starts_with("-"));
 
@@ -40,14 +39,18 @@ fn main() {
         _ => ShowUsage { err_msg: Some("Unexpected number of arguments") },
     };
 
+    let mut is_debug: bool = false;
     for opt in opts {
         match &opt[..] {
             "--help" | "--usage" | "-h" =>
                 cli_res = ShowUsage{err_msg: None},
+            "--verbose" | "-v" =>
+                is_debug = true,
             _ => cli_res = ShowUsage{err_msg: Some("Unknown option")},
         }
     }
 
+    let main = Main{is_debug};
     match cli_res {
         ShowUsage{err_msg} => {
             if let Some(msg) = err_msg {
@@ -58,7 +61,7 @@ fn main() {
         },
         Action(action) => match action {
             CliAction::Man(attr, section, page) =>
-            match Main::open_man_page(attr, section, page) {
+            match main.open_man_page(attr, section, page) {
                 Ok(_) => (),
                 Err(t) => {
                     let msg = t.msg();
@@ -230,7 +233,8 @@ impl<'a> DrvWithOutput<'a> {
 }
 
 struct Main {
-    // is_debug: bool
+    /// Whether the program is running in debug mode
+    is_debug: bool
 }
 
 impl Main {
@@ -243,12 +247,12 @@ impl Main {
     /// Both GNU's `man-db` and OpenBSD's `mandoc` work
     /// (any man implementation that implements `-l` should
     /// for that matter).
-    fn open_man_page<'a>(attr: &'a str, section: Option<&'a str>, page: &'a str) -> Result<(), NmanError<'a>> {
+    fn open_man_page<'a>(&self, attr: &'a str, section: Option<&'a str>, page: &'a str) -> Result<(), NmanError<'a>> {
         let tmpdir = TempDir::new("nman").map_err(NmanError::IO)?;
         // TODO(sterni): allow selecting other base package sets,
         //               like <vuizvui>, /home/lukas/src/nix/nixpkgs, …
         let expr = format!("with (import <nixpkgs> {{}}); builtins.map (o: {}.\"${{o}}\") {}.outputs", attr, attr);
-        let inst = debug_log_command(
+        let inst = self.debug_log_command(
                             Command::new("nix-instantiate")
                                 .arg("-E")
                                 .arg(expr)
@@ -281,12 +285,12 @@ impl Main {
         drvs.sort_unstable_by(|a, b| a.output.cmp(&b.output));
 
         for drv in drvs {
-            let man_file = Main::build_man_page(drv, section, page, &tmpdir)?;
+            let man_file = self.build_man_page(drv, section, page, &tmpdir)?;
 
             match man_file {
                 None => continue,
                 Some(f) => {
-                    let res = debug_log_command(Command::new("man")
+                    let res = self.debug_log_command(Command::new("man")
                                     .arg("-l").arg(f))
                                     .and_then(|cmd| cmd.spawn())
                                     .and_then(|mut c| c.wait())
@@ -315,8 +319,8 @@ impl Main {
     /// then searches all man section directories for any matching page. If multiple
     /// matches exist, the one with an alphanumerically lower section is preferred,
     /// e. g. section 1 is preferred over section 3.
-    fn build_man_page<'a>(drv: DrvWithOutput, section: Option<&str>, page: &str, tempdir: &TempDir) -> Result<Option<PathBuf>, NmanError<'a>> {
-        let build = debug_log_command(
+    fn build_man_page<'a>(&self, drv: DrvWithOutput, section: Option<&str>, page: &str, tempdir: &TempDir) -> Result<Option<PathBuf>, NmanError<'a>> {
+        let build = self.debug_log_command(
                                 Command::new("nix-store")
                                 .arg("--realise")
                                 .arg(drv.render())
@@ -402,6 +406,24 @@ impl Main {
         Ok(None)
     }
 
+    /// Log the given command to stderr, but only in debug mode
+    fn debug_log_command<'a>(&self, cmd: &'a mut Command) -> Result<&'a mut Command, std::io::Error> {
+        if self.is_debug {
+            let mut formatted = vec![b'$', b' '];
+            formatted.extend(
+                vec![cmd.get_program()]
+                .into_iter()
+                .chain(cmd.get_args())
+                .map(|arg| simple_bash_escape(arg.as_bytes()))
+                .collect::<Vec<_>>()
+                .join(&b' '));
+            formatted.push(b'\n');
+            std::io::stderr().write_all(&formatted).map(|()| cmd)
+        } else {
+            Ok(cmd)
+        }
+    }
+
 }
 
 /// Match if a file name is a man file matching the given
@@ -445,20 +467,6 @@ fn parse_man_section(section: &str) -> Result<&str, &str> {
     }
 }
 
-fn debug_log_command(cmd: &mut Command) -> Result<&mut Command, std::io::Error> {
-
-    let mut formatted = vec![b'$', b' '];
-    formatted.extend(
-        vec![cmd.get_program()]
-        .into_iter()
-        .chain(cmd.get_args())
-        .map(|arg| simple_bash_escape(arg.as_bytes()))
-        .collect::<Vec<_>>()
-        .join(&b' '));
-    formatted.push(b'\n');
-    std::io::stderr().write_all(&formatted).map(|()| cmd)
-}
-
 /// Simple escaping for bash words. If they contain anything that’s not ascii chars
 /// and a bunch of often-used special characters, put the word in single quotes.
 fn simple_bash_escape(arg: &[u8]) -> Cow<[u8]> {