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.
This commit is contained in:
Graham Christensen 2018-02-01 13:50:16 -05:00
parent dd2bac70d5
commit 41ab5d5e88
No known key found for this signature in database
GPG key ID: ACA1C1D120C83D5C
2 changed files with 120 additions and 46 deletions

View file

@ -12,8 +12,8 @@ use std::io::Write;
pub struct OutPathDiff {
calculator: OutPaths,
pub original: Option<HashMap<String, String>>,
pub current: Option<HashMap<String, String>>,
pub original: Option<PackageOutPaths>,
pub current: Option<PackageOutPaths>,
}
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> {
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<Vec<String>> {
let mut rebuild: Vec<String> = vec![];
pub fn calculate_rebuild(self) -> Option<Vec<PackageArch>> {
let mut rebuild: Vec<PackageArch> = 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<File, File> {
fn run(&mut self) -> Result<PackageOutPaths, File> {
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 {
path: PathBuf,
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()
}
fn run(&self) -> Result<File, File> {
fn run(&self) -> Result<PackageOutPaths, File> {
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);
}
}

View file

@ -1,4 +1,5 @@
use ofborg::tasks;
use ofborg::outpathdiff::PackageArch;
pub struct StdenvTagger {
possible: Vec<String>,
@ -85,26 +86,23 @@ impl RebuildTagger {
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_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);
}
}
}