From a9182ea32581a1454fff25490d4ed84b6103e404 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Sat, 3 Feb 2018 10:57:48 -0500 Subject: [PATCH] Add a PathsTagger for PR tagging based on modified paths --- ofborg/src/tagger.rs | 102 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/ofborg/src/tagger.rs b/ofborg/src/tagger.rs index efe5cc6..4672f06 100644 --- a/ofborg/src/tagger.rs +++ b/ofborg/src/tagger.rs @@ -1,5 +1,6 @@ use ofborg::tasks; use ofborg::outpathdiff::PackageArch; +use std::collections::HashMap; pub struct StdenvTagger { possible: Vec, @@ -154,3 +155,104 @@ impl RebuildTagger { } } + +pub struct PathsTagger { + possible: HashMap>, + selected: Vec, +} + +impl PathsTagger { + pub fn new(tags_and_criteria: HashMap>) -> PathsTagger { + PathsTagger { + possible: tags_and_criteria, + selected: vec![], + } + } + + pub fn path_changed(&mut self, path: &str) { + let mut tags_to_add: Vec = self.possible + .iter() + .filter(|&(ref tag, ref _paths)| !self.selected.contains(&tag)) + .filter(|&(ref _tag, ref paths)| { + paths.iter().any(|tp| path.contains(tp)) + }) + .map(|(tag, _paths)| tag.clone()) + .collect(); + self.selected.append(&mut tags_to_add); + self.selected.sort(); + } + + pub fn tags_to_add(&self) -> Vec { + self.selected.clone() + } + + pub fn tags_to_remove(&self) -> Vec { + let mut remove: Vec = self.possible.keys().map(|k| k.to_owned()).collect(); + remove.sort(); + for tag in &self.selected { + let pos = remove.binary_search(&tag).unwrap(); + remove.remove(pos); + } + + return remove; + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + pub fn test_files_changed_list() { + let mut criteria: HashMap> = HashMap::new(); + criteria.insert( + "topic: python".to_owned(), + vec![ + "pkgs/top-level/python-packages.nix".to_owned(), + "bogus".to_owned(), + ], + ); + criteria.insert( + "topic: ruby".to_owned(), + vec![ + "pkgs/development/interpreters/ruby".to_owned(), + "bogus".to_owned(), + ], + ); + + { + let mut tagger = PathsTagger::new(criteria.clone()); + tagger.path_changed("default.nix"); + assert_eq!(tagger.tags_to_add().len(), 0); + assert_eq!( + tagger.tags_to_remove(), + vec!["topic: python".to_owned(), "topic: ruby".to_owned()] + ); + + + tagger.path_changed("pkgs/development/interpreters/ruby/default.nix"); + assert_eq!(tagger.tags_to_add(), vec!["topic: ruby".to_owned()]); + assert_eq!(tagger.tags_to_remove(), vec!["topic: python".to_owned()]); + + tagger.path_changed("pkgs/development/interpreters/ruby/foobar.nix"); + assert_eq!(tagger.tags_to_add(), vec!["topic: ruby".to_owned()]); + assert_eq!(tagger.tags_to_remove(), vec!["topic: python".to_owned()]); + + + tagger.path_changed("pkgs/top-level/python-packages.nix"); + assert_eq!( + tagger.tags_to_add(), + vec!["topic: python".to_owned(), "topic: ruby".to_owned()] + ); + } + + { + let mut tagger = PathsTagger::new(criteria.clone()); + tagger.path_changed("bogus"); + assert_eq!( + tagger.tags_to_add(), + vec!["topic: python".to_owned(), "topic: ruby".to_owned()] + ); + } + } +}