about summary refs log tree commit diff
path: root/pkgs/profpatsch
diff options
context:
space:
mode:
authorsternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org>2021-02-19 21:43:54 +0100
committersternenseemann <sternenseemann@systemli.org>2021-02-25 19:52:33 +0100
commite55e41bd2b3c674d47d66b84f9ad7e4d23384245 (patch)
treee782ad920d49f05937a65f9110103fbe6278b0e6 /pkgs/profpatsch
parent2ae3808cc2ee54f564e66fe4aa773c737d6d790c (diff)
pkgs/profpatsch/nman: let nix tools inherit stderr handle
This relieves us of the burden to print the error message and lets the
user see what's going on, for example why they have to wait for years
when running `nman duplicity` (we have to fetch all transitive python
dependencies). We also print the exit status in case of errors and
the signal that killed a process (in the case of SIGKILL, SIGSEGV and
maybe more?).
Diffstat (limited to 'pkgs/profpatsch')
-rw-r--r--pkgs/profpatsch/nman/nman.rs37
1 files changed, 25 insertions, 12 deletions
diff --git a/pkgs/profpatsch/nman/nman.rs b/pkgs/profpatsch/nman/nman.rs
index 1672e449..234057b4 100644
--- a/pkgs/profpatsch/nman/nman.rs
+++ b/pkgs/profpatsch/nman/nman.rs
@@ -2,10 +2,22 @@ extern crate temp;
 
 use std::ffi::{OsStr, OsString};
 use std::os::unix::ffi::OsStrExt;
+use std::os::unix::process::ExitStatusExt;
 use std::path::PathBuf;
-use std::process::Command;
+use std::process::{Stdio, ExitStatus, Command};
 use temp::TempDir;
 
+/// Pretty print an [`ExitStatus`]
+fn pretty_exit_status(status: &ExitStatus) -> String {
+    match status.code() {
+        Some(i) => format!("exited with {}", i),
+        None => match status.signal() {
+            Some(s) => format!("was killed by signal {}", s),
+            None => String::from("exited for unknown reason"),
+        }
+    }
+}
+
 /// Represents all errors that can occurr in `nman`.
 /// The inner structure of this type is rather messy
 /// as it is highly specific to the location it may
@@ -19,8 +31,8 @@ use temp::TempDir;
 /// really matters for an interactive tool).
 enum NmanError<'a> {
     IO(std::io::Error),
-    Instantiate(&'a str, Vec<u8>),
-    Build(OsString, Vec<u8>),
+    Instantiate(&'a str, ExitStatus),
+    Build(OsString, ExitStatus),
     Man,
     NotFound(&'a str, Option<&'a str>),
     ParseError(&'a str),
@@ -47,13 +59,12 @@ impl NmanError<'_> {
     fn msg(&self) -> String {
         match self {
             NmanError::IO(err) => format!("unexpected IO error occurred: {}", err),
-            NmanError::Instantiate(attr, stderr) =>
-                format!("could not instantiate \"{}\". nix-instantiate reported:\n{}", attr,
-                        std::str::from_utf8(&stderr).unwrap_or("<invalid utf-8>")),
-            NmanError::Build(drv_path, stderr) =>
-                format!("failed to build \"{}\". nix-store reported:\n{}",
-                        drv_path.to_str().unwrap_or("<invalid utf-8>"),
-                        std::str::from_utf8(&stderr).unwrap_or("<malformed utf-8>")),
+            NmanError::Instantiate(attr, s) =>
+                format!("could not instantiate \"{}\", nix-instantiate {}.",
+                        attr, pretty_exit_status(s)),
+            NmanError::Build(drv_path, s) =>
+                format!("failed to build \"{}\", nix-store {}.",
+                        drv_path.to_str().unwrap_or("<invalid utf-8>"), pretty_exit_status(s)),
             NmanError::Man => String::from("man failed while opening while opening man page"),
             NmanError::NotFound(page, sec) => format!("man page {}({}) could not be found", page, sec.unwrap_or("?")),
             NmanError::ParseError(exec) => format!("could not parse output of {}", exec),
@@ -167,11 +178,12 @@ fn build_man_page<'a>(drv: DrvWithOutput, section: Option<&str>, page: &str, tem
                             .arg("--add-root")
                             .arg(tempdir.as_ref().join("build-result"))
                             .arg("--indirect")
+                            .stderr(Stdio::inherit())
                             .output()
                             .map_err(|_| NmanError::Execution("nix-store"))?;
 
     if !build.status.success() {
-        return Err(NmanError::Build(drv.render(), build.stderr));
+        return Err(NmanError::Build(drv.render(), build.status));
     }
 
     // get the first line of the output, usually only one line
@@ -255,11 +267,12 @@ fn open_man_page<'a>(attr: &'a str, section: Option<&'a str>, page: &'a str) ->
                        .arg("--add-root")
                        .arg(tmpdir.as_ref().join("instantiation-result"))
                        .arg("--indirect")
+                       .stderr(Stdio::inherit())
                        .output()
                        .map_err(|_| NmanError::Execution("nix-instantiate"))?;
 
     if !inst.status.success() {
-        return Err(NmanError::Instantiate(attr, inst.stderr));
+        return Err(NmanError::Instantiate(attr, inst.status));
     }
 
     let mut drvs: Vec<DrvWithOutput> =