From 41ab5d5e88e14cc819b42d80a9155ffaaa04429e Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Thu, 1 Feb 2018 13:50:16 -0500 Subject: [PATCH] Parse the results of the out paths sooner Prior, the OutPath just returned a file containing a bunch of data, leaving it up to consumers to parse it as needed. Now, parse the data in to a hashmap of (name, arch) => out path and return structured data. --- ofborg/src/outpathdiff.rs | 148 ++++++++++++++++++++++++++++---------- ofborg/src/tagger.rs | 18 +++-- 2 files changed, 120 insertions(+), 46 deletions(-) diff --git a/ofborg/src/outpathdiff.rs b/ofborg/src/outpathdiff.rs index 7b4351f..b5f02ec 100644 --- a/ofborg/src/outpathdiff.rs +++ b/ofborg/src/outpathdiff.rs @@ -12,8 +12,8 @@ use std::io::Write; pub struct OutPathDiff { calculator: OutPaths, - pub original: Option>, - pub current: Option>, + pub original: Option, + pub current: Option, } impl OutPathDiff { @@ -25,36 +25,11 @@ impl OutPathDiff { } } - fn parse(&self, f: File) -> HashMap { - let mut result: HashMap; - 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 { let x = self.run(); match x { Ok(f) => { - self.original = Some(self.parse(f)); + self.original = Some(f); return Ok(true); } Err(e) => { @@ -73,7 +48,7 @@ impl OutPathDiff { let x = self.run(); match x { Ok(f) => { - self.current = Some(self.parse(f)); + self.current = Some(f); return Ok(true); } Err(e) => { @@ -83,13 +58,13 @@ impl OutPathDiff { } } - pub fn calculate_rebuild(self) -> Option> { - let mut rebuild: Vec = vec![]; + pub fn calculate_rebuild(self) -> Option> { + let mut rebuild: Vec = vec![]; if let Some(cur) = self.current { if let Some(orig) = self.original { for key in cur.keys() { - trace!("Checking out {}", key); + trace!("Checking out {:?}", key); if cur.get(key) != orig.get(key) { trace!(" {:?} != {:?}", cur.get(key), orig.get(key)); rebuild.push(key.clone()) @@ -105,11 +80,22 @@ impl OutPathDiff { return None; } - fn run(&mut self) -> Result { + fn run(&mut self) -> Result { self.calculator.find() } } +type PackageOutPaths = HashMap; + +#[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 { path: PathBuf, nix: nix::Nix, @@ -125,15 +111,19 @@ impl OutPaths { } } - pub fn find(&self) -> Result { + pub fn find(&self) -> Result { self.run() } - fn run(&self) -> Result { + fn run(&self) -> Result { self.place_nix(); let ret = self.execute(); self.remove_nix(); - return ret; + + match ret { + Ok(file) => Ok(parse_lines(&mut BufReader::new(file))), + Err(e) => Err(e), + } } 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); + } + +} diff --git a/ofborg/src/tagger.rs b/ofborg/src/tagger.rs index 490caba..efe5cc6 100644 --- a/ofborg/src/tagger.rs +++ b/ofborg/src/tagger.rs @@ -1,4 +1,5 @@ use ofborg::tasks; +use ofborg::outpathdiff::PackageArch; pub struct StdenvTagger { possible: Vec, @@ -85,26 +86,23 @@ impl RebuildTagger { return t; } - pub fn parse_attrs(&mut self, attrs: Vec) { + pub fn parse_attrs(&mut self, attrs: Vec) { let mut counter_darwin = 0; let mut counter_linux = 0; for attr in attrs { - match attr.rsplit(".").next() { - Some("x86_64-darwin") => { + match attr.architecture.as_ref() { + "x86_64-darwin" => { counter_darwin += 1; } - Some("x86_64-linux") => { + "x86_64-linux" => { counter_linux += 1; } - Some("aarch64-linux") => {} - Some("i686-linux") => {} - Some(arch) => { + "aarch64-linux" => {} + "i686-linux" => {} + arch => { info!("Unknown arch: {:?}", arch); } - None => { - info!("Cannot grok attr: {:?}", attr); - } } }