Log the reasons things can't be instantiated

This commit is contained in:
Graham Christensen 2018-03-18 16:15:05 -04:00
parent f971b7b22d
commit 69502ec69a
No known key found for this signature in database
GPG key ID: ACA1C1D120C83D5C
2 changed files with 61 additions and 26 deletions

View file

@ -6,6 +6,8 @@ use std::io::SeekFrom;
use std::path::Path; use std::path::Path;
use std::process::{Command, Stdio}; use std::process::{Command, Stdio};
use tempfile::tempfile; use tempfile::tempfile;
use std::io::BufReader;
use std::io::BufRead;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Operation { pub enum Operation {
@ -102,16 +104,35 @@ impl Nix {
nixpkgs: &Path, nixpkgs: &Path,
file: &str, file: &str,
attrs: Vec<String>, attrs: Vec<String>,
) -> (Vec<String>, Vec<String>) { ) -> (Vec<String>, Vec<(String,Vec<String>)>) {
attrs let attr_instantiations: Vec<Result<String, (String, Vec<String>)>> =
attrs
.into_iter() .into_iter()
.partition(|attr| { .map(|attr|
self.safely_instantiate_attrs( match self.safely_instantiate_attrs(
nixpkgs, nixpkgs,
file, file,
vec![attr.clone()] vec![attr.clone()]
).is_ok() ) {
}) Ok(_) => Ok(attr.clone()),
Err(f) => Err((attr.clone(), lines_from_file(f)))
}
)
.collect();
let (ok, err): (
Vec<Result<String, (String, Vec<String>)>>,
Vec<Result<String, (String, Vec<String>)>>) = attr_instantiations
.into_iter()
.partition(|x| x.is_ok());
let ok_ret: Vec<String> = ok.into_iter().map(|x| x.unwrap()).collect();
let err_ret: Vec<(String, Vec<String>)> = err.into_iter().map(|x| x.unwrap_err()).collect();
return (
ok_ret,
err_ret
)
} }
pub fn safely_instantiate_attrs( pub fn safely_instantiate_attrs(
@ -253,6 +274,15 @@ impl Nix {
} }
} }
fn lines_from_file(file: File) -> Vec<String> {
BufReader::new(file)
.lines()
.into_iter()
.filter(|line| line.is_ok())
.map(|line| line.unwrap())
.collect()
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
fn nix() -> Nix { fn nix() -> Nix {
@ -291,15 +321,6 @@ mod tests {
Fail, Fail,
} }
fn lines_from_file(file: File) -> Vec<String> {
BufReader::new(file)
.lines()
.into_iter()
.filter(|line| line.is_ok())
.map(|line| line.unwrap())
.collect()
}
fn assert_run(res: Result<File, File>, expected: Expect, require: Vec<&str>) { fn assert_run(res: Result<File, File>, expected: Expect, require: Vec<&str>) {
let expectation_held: bool = match expected { let expectation_held: bool = match expected {
Expect::Pass => res.is_ok(), Expect::Pass => res.is_ok(),
@ -378,8 +399,6 @@ mod tests {
} }
use super::*; use super::*;
use std::io::BufReader;
use std::io::BufRead;
use std::path::PathBuf; use std::path::PathBuf;
use std::env; use std::env;
@ -567,7 +586,7 @@ mod tests {
fn partition_instantiable_attributes() { fn partition_instantiable_attributes() {
let nix = nix(); let nix = nix();
let ret: (Vec<String>, Vec<String>) = nix.safely_partition_instantiable_attrs( let ret: (Vec<String>, Vec<(String, Vec<String>)>) = nix.safely_partition_instantiable_attrs(
individual_eval_path().as_path(), individual_eval_path().as_path(),
"default.nix", "default.nix",
vec![ vec![
@ -578,7 +597,12 @@ mod tests {
); );
assert_eq!(ret.0, vec!["passes-instantiation"]); assert_eq!(ret.0, vec!["passes-instantiation"]);
assert_eq!(ret.1, vec!["fails-instantiation", "missing-attr"]);
assert_eq!(ret.1[0].0, "fails-instantiation");
assert_eq!(ret.1[0].1[0], "trace: You just can\'t frooble the frozz on this particular system.");
assert_eq!(ret.1[1].0, "missing-attr");
assert_eq!(ret.1[1].1[0], "error: attribute missing-attr in selection path missing-attr not found");
} }
#[test] #[test]

View file

@ -342,12 +342,22 @@ impl notifyworker::SimpleNotifyWorker for BuildWorker {
job.attrs.clone(), job.attrs.clone(),
); );
let cannot_build_attrs: Vec<String> = cannot_build
.clone()
.into_iter()
.map(|(attr,_)| attr)
.collect();
println!("Can build: '{}', Cannot build: '{}'", println!("Can build: '{}', Cannot build: '{}'",
can_build.join(", "), can_build.join(", "),
cannot_build.join(", ")); cannot_build_attrs.join(", "));
actions.log_started(can_build.clone(), cannot_build_attrs.clone());
actions.log_instantiation_errors(cannot_build);
if can_build.len() == 0 { if can_build.len() == 0 {
actions.build_not_attempted(cannot_build); actions.build_not_attempted(cannot_build_attrs);
return; return;
} }
@ -358,7 +368,6 @@ impl notifyworker::SimpleNotifyWorker for BuildWorker {
); );
println!("About to execute {:?}", cmd); println!("About to execute {:?}", cmd);
actions.log_started(can_build.clone(), cannot_build.clone());
let acmd = AsyncCmd::new(cmd); let acmd = AsyncCmd::new(cmd);
let mut spawned = acmd.spawn(); let mut spawned = acmd.spawn();
@ -381,7 +390,7 @@ impl notifyworker::SimpleNotifyWorker for BuildWorker {
let last10lines: Vec<String> = actions.log_snippet().into_iter().collect::<Vec<String>>(); let last10lines: Vec<String> = actions.log_snippet().into_iter().collect::<Vec<String>>();
actions.build_finished(success, last10lines.clone(), can_build, cannot_build); actions.build_finished(success, last10lines.clone(), can_build, cannot_build_attrs);
println!("Done!"); println!("Done!");
} }
} }
@ -541,6 +550,8 @@ mod tests {
println!("Total actions: {:?}", dummyreceiver.actions.len()); println!("Total actions: {:?}", dummyreceiver.actions.len());
let mut actions = dummyreceiver.actions.into_iter(); let mut actions = dummyreceiver.actions.into_iter();
assert_contains_job(&mut actions, "\"line_number\":1,\"output\":\"Cannot nix-instantiate `not-real\' because:\"");
assert_contains_job(&mut actions, "\"line_number\":2,\"output\":\"error: attribute not-real in selection path not-real not found\"}");
assert_contains_job(&mut actions, "skipped_attrs\":[\"not-real"); // First one to the github poster assert_contains_job(&mut actions, "skipped_attrs\":[\"not-real"); // First one to the github poster
assert_contains_job(&mut actions, "skipped_attrs\":[\"not-real"); // This one to the logs assert_contains_job(&mut actions, "skipped_attrs\":[\"not-real"); // This one to the logs
assert_eq!(actions.next(), Some(worker::Action::Ack)); assert_eq!(actions.next(), Some(worker::Action::Ack));