nixenv: describe what went wrong when io fails

Instead of just propagating a raw `std::io::Error`, wrap that in our own
`Error` enum to provide more context for what actually went wrong.
This commit is contained in:
Cole Helbling 2020-04-03 10:17:04 -07:00
parent f9086a62ec
commit 2b2b675011
No known key found for this signature in database
GPG key ID: B37E0F2371016A4C

View file

@ -5,7 +5,7 @@ use crate::nixstats::EvaluationStats;
use crate::outpathdiff; use crate::outpathdiff;
use std::fs::{self, File}; use std::fs::{self, File};
use std::io::{BufRead, BufReader, Read, Seek, SeekFrom, Write}; use std::io::{self, BufRead, BufReader, Read, Seek, SeekFrom, Write};
use std::path::PathBuf; use std::path::PathBuf;
pub struct HydraNixEnv { pub struct HydraNixEnv {
@ -59,16 +59,32 @@ impl HydraNixEnv {
/// Put outpaths.nix in to the project root, which is what /// Put outpaths.nix in to the project root, which is what
/// emulates Hydra's behavior. /// emulates Hydra's behavior.
fn place_nix(&self) -> Result<(), std::io::Error> { fn place_nix(&self) -> Result<(), Error> {
let mut file = File::create(self.outpath_nix_path())?; let outpath = self.outpath_nix_path();
file.write_all(include_bytes!("outpaths.nix"))?;
Ok(()) let mut file = match File::create(&outpath) {
Ok(f) => f,
Err(e) => return Err(Error::CreateFile(outpath, e)),
};
match file.write_all(include_bytes!("outpaths.nix")) {
Ok(_) => Ok(()),
Err(e) => Err(Error::WriteFile(file, e)),
}
}
fn remove_nix(&self) -> Result<(), Error> {
let outpath_nix = self.outpath_nix_path();
let outpath_stats = self.outpath_stats_path();
if let Err(e) = fs::remove_file(&outpath_nix) {
return Err(Error::RemoveFile(outpath_nix, e));
}
if let Err(e) = fs::remove_file(&outpath_stats) {
return Err(Error::RemoveFile(outpath_stats, e));
} }
fn remove_nix(&self) -> Result<(), std::io::Error> {
fs::remove_file(self.outpath_nix_path())?;
fs::remove_file(self.outpath_stats_path())?;
Ok(()) Ok(())
} }
@ -80,7 +96,7 @@ impl HydraNixEnv {
self.path.join(".gc-of-borg-stats.json") self.path.join(".gc-of-borg-stats.json")
} }
fn run_nix_env(&self) -> (bool, File, File, Result<File, std::io::Error>) { fn run_nix_env(&self) -> (bool, File, File, Result<File, io::Error>) {
let check_meta = if self.check_meta { "true" } else { "false" }; let check_meta = if self.check_meta { "true" } else { "false" };
let mut cmd = self.nix.safe_command( let mut cmd = self.nix.safe_command(
@ -106,14 +122,17 @@ impl HydraNixEnv {
} }
pub enum Error { pub enum Error {
Io(std::io::Error), Io(io::Error),
CreateFile(PathBuf, io::Error),
RemoveFile(PathBuf, io::Error),
WriteFile(File, io::Error),
CommandFailed(File), CommandFailed(File),
StatsParse(File, Result<u64, std::io::Error>, serde_json::Error), StatsParse(File, Result<u64, io::Error>, serde_json::Error),
UncleanEvaluation(Vec<String>), UncleanEvaluation(Vec<String>),
} }
impl From<std::io::Error> for Error { impl From<io::Error> for Error {
fn from(e: std::io::Error) -> Error { fn from(e: io::Error) -> Error {
Error::Io(e) Error::Io(e)
} }
} }
@ -122,6 +141,15 @@ impl Error {
pub fn display(self) -> String { pub fn display(self) -> String {
match self { match self {
Error::Io(e) => format!("Failed during the setup of executing nix-env: {:?}", e), Error::Io(e) => format!("Failed during the setup of executing nix-env: {:?}", e),
Error::CreateFile(path, err) => {
format!("Failed to create file '{:?}': {:?}", path, err)
}
Error::RemoveFile(path, err) => {
format!("Failed to remove file '{:?}': {:?}", path, err)
}
Error::WriteFile(file, err) => {
format!("Failed to write to file '{:?}': {:?}", file, err)
}
Error::CommandFailed(mut fd) => { Error::CommandFailed(mut fd) => {
let mut buffer = Vec::new(); let mut buffer = Vec::new();
let read_result = fd.read_to_end(&mut buffer); let read_result = fd.read_to_end(&mut buffer);