Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: NixOS/ofborg
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: d1976841c311
Choose a base ref
...
head repository: NixOS/ofborg
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0d08106b495f
Choose a head ref
  • 3 commits
  • 3 files changed
  • 2 contributors

Commits on Jan 14, 2019

  1. nix: pass '--arg nixpkgs' for nixos and generalize argument handling

    This makes sure nixpkgs isn't passed in using fetchGit or filterSource,
    which isn't allowed to be imported with restricted eval.  And avoids
    of of the duplication between safely_instantiate_attrs_cmd and
    safely_build_attrs_cmd making that easier to test.
    LnL7 committed Jan 14, 2019
    Copy the full SHA
    6f5f58e View commit details
  2. nix: cleanup and fix warnings

    LnL7 committed Jan 14, 2019
    Copy the full SHA
    69263d7 View commit details

Commits on Jan 15, 2019

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

    nix: pass '--arg nixpkgs' for nixos and generalize argument handling
    grahamc authored Jan 15, 2019
    Copy the full SHA
    0d08106 View commit details
Showing with 116 additions and 68 deletions.
  1. +2 −1 ofborg/src/bin/simple-build.rs
  2. +111 −64 ofborg/src/nix.rs
  3. +3 −3 ofborg/src/tasks/build.rs
3 changes: 2 additions & 1 deletion ofborg/src/bin/simple-build.rs
Original file line number Diff line number Diff line change
@@ -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) => {
175 changes: 111 additions & 64 deletions ofborg/src/nix.rs
Original file line number Diff line number Diff line change
@@ -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,
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,
file: File,
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")],
Loading