Merge pull request #302 from LnL7/test-nixos-nixpkgs-arg

nix: pass '--arg nixpkgs' for nixos and generalize argument handling
This commit is contained in:
Graham Christensen 2019-01-14 19:12:49 -05:00 committed by GitHub
commit 0d08106b49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 116 additions and 68 deletions

View file

@ -5,6 +5,7 @@ extern crate ofborg;
use std::env;
use ofborg::config;
use ofborg::nix;
use std::fs::File;
use std::io::Read;
use std::path::Path;
@ -18,7 +19,7 @@ fn main() {
match nix.safely_build_attrs(
&Path::new("./"),
"./default.nix",
nix::File::DefaultNixpkgs,
vec![String::from("hello")],
) {
Ok(mut out) => {

View file

@ -3,7 +3,7 @@ use ofborg::partition_result;
use std::collections::HashMap;
use std::env;
use std::fmt;
use std::fs::File;
use std::fs;
use std::io::BufRead;
use std::io::BufReader;
use std::io::Seek;
@ -12,6 +12,21 @@ use std::path::Path;
use std::process::{Command, Stdio};
use tempfile::tempfile;
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum File {
DefaultNixpkgs,
ReleaseNixOS,
}
impl fmt::Display for File {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
File::DefaultNixpkgs => write!(f, "./default.nix"),
File::ReleaseNixOS => write!(f, "./nixos/release.nix"),
}
}
}
#[derive(Clone, Debug)]
pub enum Operation {
Evaluate,
@ -124,7 +139,7 @@ impl Nix {
pub fn safely_partition_instantiable_attrs(
&self,
nixpkgs: &Path,
file: &str,
file: File,
attrs: Vec<String>,
) -> (Vec<String>, Vec<(String, Vec<String>)>) {
let attr_instantiations: Vec<Result<String, (String, Vec<String>)>> = attrs
@ -143,28 +158,12 @@ impl Nix {
pub fn safely_instantiate_attrs(
&self,
nixpkgs: &Path,
file: &str,
file: File,
attrs: Vec<String>,
) -> Result<File, File> {
let cmd = self.safely_instantiate_attrs_cmd(nixpkgs, file, attrs);
self.run(cmd, true)
}
pub fn safely_instantiate_attrs_cmd(
&self,
nixpkgs: &Path,
file: &str,
attrs: Vec<String>,
) -> Command {
let mut attrargs: Vec<String> = Vec::with_capacity(3 + (attrs.len() * 2));
attrargs.push(file.to_owned());
for attr in attrs {
attrargs.push(String::from("-A"));
attrargs.push(attr);
}
self.safe_command(&Operation::Instantiate, nixpkgs, attrargs, &[])
) -> Result<fs::File, fs::File> {
let mut command = self.safe_command(&Operation::Instantiate, nixpkgs, vec![], &[]);
self.set_attrs_command(&mut command, file, attrs);
self.run(command, true)
}
pub fn safely_evaluate_expr_cmd(
@ -189,32 +188,40 @@ impl Nix {
pub fn safely_build_attrs(
&self,
nixpkgs: &Path,
file: &str,
file: File,
attrs: Vec<String>,
) -> Result<File, File> {
let cmd = self.safely_build_attrs_cmd(nixpkgs, file, attrs);
self.run(cmd, true)
) -> Result<fs::File, fs::File> {
let mut command = self.safe_command(&Operation::Build, nixpkgs, vec![], &[]);
self.set_attrs_command(&mut command, file, attrs);
self.run(command, true)
}
pub fn safely_build_attrs_async(
&self,
nixpkgs: &Path,
file: &str,
file: File,
attrs: Vec<String>,
) -> SpawnedAsyncCmd {
AsyncCmd::new(self.safely_build_attrs_cmd(nixpkgs, file, attrs)).spawn()
let mut command = self.safe_command(&Operation::Build, nixpkgs, vec![], &[]);
self.set_attrs_command(&mut command, file, attrs);
AsyncCmd::new(command).spawn()
}
fn safely_build_attrs_cmd(&self, nixpkgs: &Path, file: &str, attrs: Vec<String>) -> Command {
let mut attrargs: Vec<String> = Vec::with_capacity(3 + (attrs.len() * 2));
attrargs.push(file.to_owned());
fn set_attrs_command(&self, command: &mut Command, file: File, attrs: Vec<String>) {
let mut args: Vec<String> = Vec::with_capacity(3 + (attrs.len() * 2));
args.push(format!("{}", file));
for attr in attrs {
attrargs.push(String::from("-A"));
attrargs.push(attr);
args.push(String::from("-A"));
args.push(attr);
}
self.safe_command(&Operation::Build, nixpkgs, attrargs, &[])
if let File::ReleaseNixOS = file {
args.push(String::from("--arg"));
args.push(String::from("nixpkgs"));
args.push(String::from(
"{ outPath=./.; revCount=999999; shortRev=\"ofborg\"; }",
));
}
command.args(args);
}
pub fn safely(
@ -223,11 +230,11 @@ impl Nix {
nixpkgs: &Path,
args: Vec<String>,
keep_stdout: bool,
) -> Result<File, File> {
) -> Result<fs::File, fs::File> {
self.run(self.safe_command(&op, nixpkgs, args, &[]), keep_stdout)
}
pub fn run(&self, mut cmd: Command, keep_stdout: bool) -> Result<File, File> {
pub fn run(&self, mut cmd: Command, keep_stdout: bool) -> Result<fs::File, fs::File> {
let stderr = tempfile().expect("Fetching a stderr tempfile");
let mut reader = stderr.try_clone().expect("Cloning stderr to the reader");
@ -302,12 +309,11 @@ impl Nix {
}
command.args(args);
command
}
}
fn lines_from_file(file: File) -> Vec<String> {
fn lines_from_file(file: fs::File) -> Vec<String> {
BufReader::new(file)
.lines()
.filter(|line| line.is_ok())
@ -366,13 +372,13 @@ mod tests {
Fail,
}
fn assert_run(res: Result<File, File>, expected: Expect, require: Vec<&str>) {
fn assert_run(res: Result<fs::File, fs::File>, expected: Expect, require: Vec<&str>) {
let expectation_held: bool = match expected {
Expect::Pass => res.is_ok(),
Expect::Fail => res.is_err(),
};
let file: File = match res {
let file: fs::File = match res {
Ok(file) => file,
Err(file) => file,
};
@ -455,7 +461,7 @@ mod tests {
let op = noop(Operation::Build);
assert_eq!(op.to_string(), "nix-build");
let ret: Result<File, File> = nix.run(
let ret: Result<fs::File, fs::File> = nix.run(
nix.safe_command(
&op,
build_path().as_path(),
@ -478,7 +484,7 @@ mod tests {
let op = noop(Operation::Instantiate);
assert_eq!(op.to_string(), "nix-instantiate");
let ret: Result<File, File> = nix.run(
let ret: Result<fs::File, fs::File> = nix.run(
nix.safe_command(
&op,
build_path().as_path(),
@ -497,7 +503,7 @@ mod tests {
let op = noop(Operation::QueryPackagesJSON);
assert_eq!(op.to_string(), "nix-env -qa --json");
let ret: Result<File, File> = nix.run(
let ret: Result<fs::File, fs::File> = nix.run(
nix.safe_command(
&op,
build_path().as_path(),
@ -520,7 +526,7 @@ mod tests {
let op = noop(Operation::QueryPackagesOutputs);
assert_eq!(op.to_string(), "nix-env -qaP --no-name --out-path");
let ret: Result<File, File> = nix.run(
let ret: Result<fs::File, fs::File> = nix.run(
nix.safe_command(
&op,
build_path().as_path(),
@ -544,7 +550,7 @@ mod tests {
fn safe_command_environment() {
let nix = nix();
let ret: Result<File, File> = nix.run(
let ret: Result<fs::File, fs::File> = nix.run(
nix.safe_command(&env_noop(), build_path().as_path(), vec![], &[]),
true,
);
@ -571,7 +577,7 @@ mod tests {
Some("4g".to_owned()),
);
let ret: Result<File, File> = nix.run(
let ret: Result<fs::File, fs::File> = nix.run(
nix.safe_command(&env_noop(), build_path().as_path(), vec![], &[]),
true,
);
@ -594,7 +600,7 @@ mod tests {
let nix = nix();
let op = noop(Operation::Build);
let ret: Result<File, File> = nix.run(
let ret: Result<fs::File, fs::File> = nix.run(
nix.safe_command(&op, build_path().as_path(), vec![], &[]),
true,
);
@ -606,13 +612,54 @@ mod tests {
);
}
#[test]
fn set_attrs_nixpkgs() {
let nix = nix();
let op = noop(Operation::Build);
let mut command = nix.safe_command(&op, build_path().as_path(), vec![], &[]);
nix.set_attrs_command(
&mut command,
File::DefaultNixpkgs,
vec!["foo".into(), "bar".into()],
);
let ret: Result<fs::File, fs::File> = nix.run(command, true);
assert_run(ret, Expect::Pass, vec!["./default.nix", "-A foo -A bar"]);
}
#[test]
fn set_attrs_nixos() {
let nix = nix();
let op = noop(Operation::Instantiate);
let mut command = nix.safe_command(&op, build_path().as_path(), vec![], &[]);
nix.set_attrs_command(
&mut command,
File::ReleaseNixOS,
vec!["foo".into(), "bar".into()],
);
let ret: Result<fs::File, fs::File> = nix.run(command, true);
assert_run(
ret,
Expect::Pass,
vec![
"./nixos/release.nix",
"--arg nixpkgs { outPath=./.; revCount=999999; shortRev=\"ofborg\"; }",
],
);
}
#[test]
fn safely_build_attrs_success() {
let nix = nix();
let ret: Result<File, File> = nix.safely_build_attrs(
let ret: Result<fs::File, fs::File> = nix.safely_build_attrs(
build_path().as_path(),
"default.nix",
File::DefaultNixpkgs,
vec![String::from("success")],
);
@ -627,9 +674,9 @@ mod tests {
fn safely_build_attrs_failure() {
let nix = nix();
let ret: Result<File, File> = nix.safely_build_attrs(
let ret: Result<fs::File, fs::File> = nix.safely_build_attrs(
build_path().as_path(),
"default.nix",
File::DefaultNixpkgs,
vec![String::from("failed")],
);
@ -652,7 +699,7 @@ mod tests {
let ret: (Vec<String>, Vec<(String, Vec<String>)>) = nix
.safely_partition_instantiable_attrs(
individual_eval_path().as_path(),
"default.nix",
File::DefaultNixpkgs,
vec![
String::from("fails-instantiation"),
String::from("passes-instantiation"),
@ -679,9 +726,9 @@ mod tests {
fn safely_instantiate_attrs_failure() {
let nix = nix();
let ret: Result<File, File> = nix.safely_instantiate_attrs(
let ret: Result<fs::File, fs::File> = nix.safely_instantiate_attrs(
individual_eval_path().as_path(),
"default.nix",
File::DefaultNixpkgs,
vec![String::from("fails-instantiation")],
);
@ -696,9 +743,9 @@ mod tests {
fn safely_instantiate_attrs_success() {
let nix = nix();
let ret: Result<File, File> = nix.safely_instantiate_attrs(
let ret: Result<fs::File, fs::File> = nix.safely_instantiate_attrs(
individual_eval_path().as_path(),
"default.nix",
File::DefaultNixpkgs,
vec![String::from("passes-instantiation")],
);
@ -709,7 +756,7 @@ mod tests {
fn safely_evaluate_expr_success() {
let nix = nix();
let ret: Result<File, File> = nix.run(
let ret: Result<fs::File, fs::File> = nix.run(
nix.safely_evaluate_expr_cmd(
individual_eval_path().as_path(),
r#"{ foo ? "bar" }: "The magic value is ${foo}""#,
@ -724,9 +771,9 @@ mod tests {
#[test]
fn strict_sandboxing() {
let ret: Result<File, File> = nix().safely_build_attrs(
let ret: Result<fs::File, fs::File> = nix().safely_build_attrs(
build_path().as_path(),
"default.nix",
File::DefaultNixpkgs,
vec![String::from("sandbox-violation")],
);
@ -743,7 +790,7 @@ mod tests {
#[test]
fn instantiation_success() {
let ret: Result<File, File> = nix().safely(
let ret: Result<fs::File, fs::File> = nix().safely(
&Operation::Instantiate,
passing_eval_path().as_path(),
vec![],
@ -763,7 +810,7 @@ mod tests {
#[test]
fn instantiation_nixpkgs_restricted_mode() {
let ret: Result<File, File> = nix().safely(
let ret: Result<fs::File, fs::File> = nix().safely(
&Operation::Instantiate,
individual_eval_path().as_path(),
vec![String::from("-A"), String::from("nixpkgs-restricted-mode")],

View file

@ -306,11 +306,11 @@ impl notifyworker::SimpleNotifyWorker for BuildWorker {
};
let buildfile = match job.subset {
Some(commentparser::Subset::NixOS) => "./nixos/release.nix",
_ => "./default.nix",
Some(commentparser::Subset::NixOS) => nix::File::ReleaseNixOS,
_ => nix::File::DefaultNixpkgs,
};
if buildfile == "./nixos/release.nix" && self.system == "x86_64-darwin" {
if buildfile == nix::File::ReleaseNixOS && self.system == "x86_64-darwin" {
actions.nasty_hack_linux_only();
return;
}