skip pre-releases when determining latest release

This commit is contained in:
Sam Rijs 2018-02-03 17:52:08 +11:00
parent 281be47b20
commit f4fa88e204
2 changed files with 91 additions and 8 deletions

View file

@ -23,6 +23,7 @@ impl DependencyAnalyzer {
dep.latest_that_matches = Some(ver.clone()); dep.latest_that_matches = Some(ver.clone());
} }
} }
if !ver.is_prerelease() {
if let Some(ref mut current_latest) = dep.latest { if let Some(ref mut current_latest) = dep.latest {
if *current_latest < *ver { if *current_latest < *ver {
*current_latest = ver.clone(); *current_latest = ver.clone();
@ -31,6 +32,7 @@ impl DependencyAnalyzer {
dep.latest = Some(ver.clone()); dep.latest = Some(ver.clone());
} }
} }
}
pub fn process<I: IntoIterator<Item=CrateRelease>>(&mut self, releases: I) { pub fn process<I: IntoIterator<Item=CrateRelease>>(&mut self, releases: I) {
for release in releases.into_iter().filter(|r| !r.yanked) { for release in releases.into_iter().filter(|r| !r.yanked) {
@ -50,3 +52,77 @@ impl DependencyAnalyzer {
self.deps self.deps
} }
} }
#[cfg(test)]
mod tests {
use super::{CrateDeps, CrateRelease, DependencyAnalyzer};
#[test]
fn tracks_latest_without_matching() {
let mut deps = CrateDeps::default();
deps.main.insert("hyper".parse().unwrap(), "^0.11.0".parse().unwrap());
let mut analyzer = DependencyAnalyzer::new(&deps);
analyzer.process(vec![
CrateRelease { name: "hyper".parse().unwrap(), version: "0.10.0".parse().unwrap(), yanked: false },
CrateRelease { name: "hyper".parse().unwrap(), version: "0.10.1".parse().unwrap(), yanked: false }
]);
let analyzed = analyzer.finalize();
assert_eq!(analyzed.main.get("hyper").unwrap().latest_that_matches, None);
assert_eq!(analyzed.main.get("hyper").unwrap().latest, Some("0.10.1".parse().unwrap()));
}
#[test]
fn tracks_latest_that_matches() {
let mut deps = CrateDeps::default();
deps.main.insert("hyper".parse().unwrap(), "^0.10.0".parse().unwrap());
let mut analyzer = DependencyAnalyzer::new(&deps);
analyzer.process(vec![
CrateRelease { name: "hyper".parse().unwrap(), version: "0.10.0".parse().unwrap(), yanked: false },
CrateRelease { name: "hyper".parse().unwrap(), version: "0.10.1".parse().unwrap(), yanked: false },
CrateRelease { name: "hyper".parse().unwrap(), version: "0.11.0".parse().unwrap(), yanked: false }
]);
let analyzed = analyzer.finalize();
assert_eq!(analyzed.main.get("hyper").unwrap().latest_that_matches, Some("0.10.1".parse().unwrap()));
assert_eq!(analyzed.main.get("hyper").unwrap().latest, Some("0.11.0".parse().unwrap()));
}
#[test]
fn skips_yanked_releases() {
let mut deps = CrateDeps::default();
deps.main.insert("hyper".parse().unwrap(), "^0.10.0".parse().unwrap());
let mut analyzer = DependencyAnalyzer::new(&deps);
analyzer.process(vec![
CrateRelease { name: "hyper".parse().unwrap(), version: "0.10.0".parse().unwrap(), yanked: false },
CrateRelease { name: "hyper".parse().unwrap(), version: "0.10.1".parse().unwrap(), yanked: true },
]);
let analyzed = analyzer.finalize();
assert_eq!(analyzed.main.get("hyper").unwrap().latest_that_matches, Some("0.10.0".parse().unwrap()));
assert_eq!(analyzed.main.get("hyper").unwrap().latest, Some("0.10.0".parse().unwrap()));
}
#[test]
fn skips_prereleases() {
let mut deps = CrateDeps::default();
deps.main.insert("hyper".parse().unwrap(), "^0.10.0".parse().unwrap());
let mut analyzer = DependencyAnalyzer::new(&deps);
analyzer.process(vec![
CrateRelease { name: "hyper".parse().unwrap(), version: "0.10.0".parse().unwrap(), yanked: false },
CrateRelease { name: "hyper".parse().unwrap(), version: "0.10.1-alpha".parse().unwrap(), yanked: false },
]);
let analyzed = analyzer.finalize();
assert_eq!(analyzed.main.get("hyper").unwrap().latest_that_matches, Some("0.10.0".parse().unwrap()));
assert_eq!(analyzed.main.get("hyper").unwrap().latest, Some("0.10.0".parse().unwrap()));
}
}

View file

@ -1,3 +1,4 @@
use std::borrow::Borrow;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::str::FromStr; use std::str::FromStr;
@ -12,8 +13,11 @@ impl Into<String> for CrateName {
} }
} }
#[derive(Debug)] impl Borrow<str> for CrateName {
pub struct CrateNameValidationError; fn borrow(&self) -> &str {
&self.0
}
}
impl AsRef<str> for CrateName { impl AsRef<str> for CrateName {
fn as_ref(&self) -> &str { fn as_ref(&self) -> &str {
@ -21,6 +25,9 @@ impl AsRef<str> for CrateName {
} }
} }
#[derive(Debug)]
pub struct CrateNameValidationError;
impl FromStr for CrateName { impl FromStr for CrateName {
type Err = CrateNameValidationError; type Err = CrateNameValidationError;
@ -44,7 +51,7 @@ pub struct CrateRelease {
pub yanked: bool pub yanked: bool
} }
#[derive(Debug)] #[derive(Debug, Default)]
pub struct CrateDeps { pub struct CrateDeps {
pub main: BTreeMap<CrateName, VersionReq>, pub main: BTreeMap<CrateName, VersionReq>,
pub dev: BTreeMap<CrateName, VersionReq>, pub dev: BTreeMap<CrateName, VersionReq>,