diff --git a/ofborg/src/nix.rs b/ofborg/src/nix.rs index 8fc5421..a163db7 100644 --- a/ofborg/src/nix.rs +++ b/ofborg/src/nix.rs @@ -97,6 +97,50 @@ impl Nix { return n; } + pub fn safely_partition_instantiable_attrs( + &self, + nixpkgs: &Path, + file: &str, + attrs: Vec, + ) -> (Vec, Vec) { + attrs + .into_iter() + .partition(|attr| { + self.safely_instantiate_attrs( + nixpkgs, + file, + vec![attr.clone()] + ).is_ok() + }) + } + + pub fn safely_instantiate_attrs( + &self, + nixpkgs: &Path, + file: &str, + attrs: Vec, + ) -> Result { + let cmd = self.safely_instantiate_attrs_cmd(nixpkgs, file, attrs); + + return self.run(cmd, true); + } + + pub fn safely_instantiate_attrs_cmd( + &self, + nixpkgs: &Path, + file: &str, + attrs: Vec, + ) -> Command { + let mut attrargs: Vec = Vec::with_capacity(3 + (attrs.len() * 2)); + attrargs.push(file.to_owned()); + for attr in attrs { + attrargs.push(String::from("-A")); + attrargs.push(attr); + } + + return self.safe_command(Operation::Instantiate, nixpkgs, attrargs); + } + pub fn safely_build_attrs( &self, nixpkgs: &Path, @@ -235,6 +279,12 @@ mod tests { return cwd; } + fn individual_eval_path() -> PathBuf { + let mut cwd = env::current_dir().unwrap(); + cwd.push(Path::new("./test-srcs/eval-mixed-failure")); + return cwd; + } + #[derive(Debug)] enum Expect { Pass, @@ -509,6 +559,63 @@ mod tests { ); } + #[test] + fn partition_instantiable_attributes() { + let nix = nix(); + + let ret: (Vec, Vec) = nix.safely_partition_instantiable_attrs( + individual_eval_path().as_path(), + "default.nix", + vec![ + String::from("fails-instantiation"), + String::from("passes-instantiation"), + String::from("missing-attr"), + ], + ); + + assert_eq!(ret.0, vec!["passes-instantiation"]); + assert_eq!(ret.1, vec!["fails-instantiation", "missing-attr"]); + } + + #[test] + fn safely_instantiate_attrs_failure() { + let nix = nix(); + + let ret: Result = nix.safely_instantiate_attrs( + individual_eval_path().as_path(), + "default.nix", + vec![String::from("fails-instantiation")], + ); + + assert_run( + ret, + Expect::Fail, + vec![ + "You just can't", + "assertion failed", + ], + ); + } + + #[test] + fn safely_instantiate_attrs_success() { + let nix = nix(); + + let ret: Result = nix.safely_instantiate_attrs( + individual_eval_path().as_path(), + "default.nix", + vec![String::from("passes-instantiation")], + ); + + assert_run( + ret, + Expect::Pass, + vec![ + "-passes-instantiation.drv" + ], + ); + } + #[test] fn strict_sandboxing() { let ret: Result = nix().safely_build_attrs(