diff options
author | sternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org> | 2021-02-19 21:43:54 +0100 |
---|---|---|
committer | sternenseemann <sternenseemann@systemli.org> | 2021-02-25 19:52:33 +0100 |
commit | e55e41bd2b3c674d47d66b84f9ad7e4d23384245 (patch) | |
tree | e782ad920d49f05937a65f9110103fbe6278b0e6 /pkgs/profpatsch/nman/nman.rs | |
parent | 2ae3808cc2ee54f564e66fe4aa773c737d6d790c (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/nman/nman.rs')
-rw-r--r-- | pkgs/profpatsch/nman/nman.rs | 37 |
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> = |