Merge pull request #57 from NixOS/cleanup-outpath-parsing

Parse the results of the out paths sooner
This commit is contained in:
Graham Christensen 2018-02-03 08:05:16 -05:00 committed by GitHub
commit eaeb97f596
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 120 additions and 46 deletions

View file

@ -12,8 +12,8 @@ use std::io::Write;
pub struct OutPathDiff { pub struct OutPathDiff {
calculator: OutPaths, calculator: OutPaths,
pub original: Option<HashMap<String, String>>, pub original: Option<PackageOutPaths>,
pub current: Option<HashMap<String, String>>, pub current: Option<PackageOutPaths>,
} }
impl OutPathDiff { impl OutPathDiff {
@ -25,36 +25,11 @@ impl OutPathDiff {
} }
} }
fn parse(&self, f: File) -> HashMap<String, String> {
let mut result: HashMap<String, String>;
result = HashMap::new();
{
BufReader::new(f)
.lines()
.filter_map(|line| match line {
Ok(line) => Some(line),
Err(_) => None,
})
.map(|x| {
let split: Vec<&str> = x.split_whitespace().collect();
if split.len() == 2 {
result.insert(String::from(split[0]), String::from(split[1]));
} else {
info!("Warning: not 2 word segments in {:?}", split);
}
})
.count();
}
return result;
}
pub fn find_before(&mut self) -> Result<bool, File> { pub fn find_before(&mut self) -> Result<bool, File> {
let x = self.run(); let x = self.run();
match x { match x {
Ok(f) => { Ok(f) => {
self.original = Some(self.parse(f)); self.original = Some(f);
return Ok(true); return Ok(true);
} }
Err(e) => { Err(e) => {
@ -73,7 +48,7 @@ impl OutPathDiff {
let x = self.run(); let x = self.run();
match x { match x {
Ok(f) => { Ok(f) => {
self.current = Some(self.parse(f)); self.current = Some(f);
return Ok(true); return Ok(true);
} }
Err(e) => { Err(e) => {
@ -83,13 +58,13 @@ impl OutPathDiff {
} }
} }
pub fn calculate_rebuild(self) -> Option<Vec<String>> { pub fn calculate_rebuild(self) -> Option<Vec<PackageArch>> {
let mut rebuild: Vec<String> = vec![]; let mut rebuild: Vec<PackageArch> = vec![];
if let Some(cur) = self.current { if let Some(cur) = self.current {
if let Some(orig) = self.original { if let Some(orig) = self.original {
for key in cur.keys() { for key in cur.keys() {
trace!("Checking out {}", key); trace!("Checking out {:?}", key);
if cur.get(key) != orig.get(key) { if cur.get(key) != orig.get(key) {
trace!(" {:?} != {:?}", cur.get(key), orig.get(key)); trace!(" {:?} != {:?}", cur.get(key), orig.get(key));
rebuild.push(key.clone()) rebuild.push(key.clone())
@ -105,11 +80,22 @@ impl OutPathDiff {
return None; return None;
} }
fn run(&mut self) -> Result<File, File> { fn run(&mut self) -> Result<PackageOutPaths, File> {
self.calculator.find() self.calculator.find()
} }
} }
type PackageOutPaths = HashMap<PackageArch, OutPath>;
#[derive(Debug, PartialEq, Hash, Eq, Clone)]
pub struct PackageArch {
pub package: Package,
pub architecture: Architecture,
}
type Package = String;
type Architecture = String;
type OutPath = String;
pub struct OutPaths { pub struct OutPaths {
path: PathBuf, path: PathBuf,
nix: nix::Nix, nix: nix::Nix,
@ -125,15 +111,19 @@ impl OutPaths {
} }
} }
pub fn find(&self) -> Result<File, File> { pub fn find(&self) -> Result<PackageOutPaths, File> {
self.run() self.run()
} }
fn run(&self) -> Result<File, File> { fn run(&self) -> Result<PackageOutPaths, File> {
self.place_nix(); self.place_nix();
let ret = self.execute(); let ret = self.execute();
self.remove_nix(); self.remove_nix();
return ret;
match ret {
Ok(file) => Ok(parse_lines(&mut BufReader::new(file))),
Err(e) => Err(e),
}
} }
fn place_nix(&self) { fn place_nix(&self) {
@ -179,3 +169,89 @@ impl OutPaths {
) )
} }
} }
fn parse_lines(data: &mut BufRead) -> PackageOutPaths {
data.lines()
.filter_map(|line| match line {
Ok(line) => Some(line),
Err(_) => None,
})
.filter_map(|line| {
let split: Vec<&str> = line.split_whitespace().collect();
if split.len() == 2 {
let outpaths = String::from(split[1]);
let path: Vec<&str> = split[0].rsplitn(2, ".").collect();
if path.len() == 2 {
Some((
PackageArch {
package: String::from(path[1]),
architecture: String::from(path[0]),
},
outpaths,
))
} else {
info!("Warning: Didn't detect an architecture for {:?}", path);
None
}
} else {
info!("Warning: not 2 word segments in {:?}", split);
None
}
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
use std::io::Cursor;
const TEST_LINES: &'static str = "
kindlegen.x86_64-darwin /nix/store/sgabv7byhan6b0rjspd3p1bd7yw91f30-kindlegen-2.9
python27Packages.pyinotify.i686-linux /nix/store/rba0hbq6i4camvhpj9723dvs4b511ryn-python2.7-pyinotify-0.9.6
pan.i686-linux /nix/store/6djnw9s2z5iy0c741qa8yk0k2v6bxrra-pan-0.139
gnome3.evolution_data_server.aarch64-linux /nix/store/fmxf25kyxb62v9arc64fypb2ilxifsh0-evolution-data-server-3.26.3
";
#[test]
fn test_parse_outputs() {
let mut expect: PackageOutPaths = HashMap::new();
expect.insert(
PackageArch {
package: "kindlegen".to_owned(),
architecture: "x86_64-darwin".to_owned(),
},
"/nix/store/sgabv7byhan6b0rjspd3p1bd7yw91f30-kindlegen-2.9".to_owned(),
);
expect.insert(
PackageArch {
architecture: "aarch64-linux".to_owned(),
package: "gnome3.evolution_data_server".to_owned(),
},
"/nix/store/fmxf25kyxb62v9arc64fypb2ilxifsh0-evolution-data-server-3.26.3".to_owned(),
);
expect.insert(
PackageArch {
architecture: "i686-linux".to_owned(),
package: "python27Packages.pyinotify".to_owned(),
},
"/nix/store/rba0hbq6i4camvhpj9723dvs4b511ryn-python2.7-pyinotify-0.9.6".to_owned(),
);
expect.insert(
PackageArch {
architecture: "i686-linux".to_owned(),
package: "pan".to_owned(),
},
"/nix/store/6djnw9s2z5iy0c741qa8yk0k2v6bxrra-pan-0.139".to_owned(),
);
assert_eq!(parse_lines(&mut Cursor::new(TEST_LINES)), expect);
}
}

View file

@ -1,4 +1,5 @@
use ofborg::tasks; use ofborg::tasks;
use ofborg::outpathdiff::PackageArch;
pub struct StdenvTagger { pub struct StdenvTagger {
possible: Vec<String>, possible: Vec<String>,
@ -85,26 +86,23 @@ impl RebuildTagger {
return t; return t;
} }
pub fn parse_attrs(&mut self, attrs: Vec<String>) { pub fn parse_attrs(&mut self, attrs: Vec<PackageArch>) {
let mut counter_darwin = 0; let mut counter_darwin = 0;
let mut counter_linux = 0; let mut counter_linux = 0;
for attr in attrs { for attr in attrs {
match attr.rsplit(".").next() { match attr.architecture.as_ref() {
Some("x86_64-darwin") => { "x86_64-darwin" => {
counter_darwin += 1; counter_darwin += 1;
} }
Some("x86_64-linux") => { "x86_64-linux" => {
counter_linux += 1; counter_linux += 1;
} }
Some("aarch64-linux") => {} "aarch64-linux" => {}
Some("i686-linux") => {} "i686-linux" => {}
Some(arch) => { arch => {
info!("Unknown arch: {:?}", arch); info!("Unknown arch: {:?}", arch);
} }
None => {
info!("Cannot grok attr: {:?}", attr);
}
} }
} }