diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2020-09-10 10:24:59 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2020-09-10 11:04:12 +0200 |
commit | 30b34be5779927424ea74464134139e27ed6b3e3 (patch) | |
tree | e3c88ce12c4da961453535696d217ef6ae666828 | |
parent | ef1e753d6d0f5e216b6ddbc41e2ea0a8c6e8942a (diff) |
Add helper to get latest version of a package
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/cli.rs | 19 | ||||
-rw-r--r-- | src/main.rs | 36 |
3 files changed, 53 insertions, 3 deletions
@@ -31,6 +31,7 @@ prettytable-rs = "0.8" filters = "0.3" boolinator = "2" itertools = "0.8" +semver = "0.10" [dependencies.clap] version = ">=2.33" @@ -79,6 +79,23 @@ pub fn build_cli<'a>() -> App<'a, 'a> { .help("Sort output by repository") .conflicts_with("sort-version") ) + .arg(Arg::with_name("latest") + .long("latest") + .required(false) + .multiple(false) + .takes_value(false) + .help("Try to find the lastest version (version is string-compared if not used with --semver)") + .conflicts_with("sort-version") + .conflicts_with("sort-repo") + ) + .arg(Arg::with_name("semver") + .long("semver") + .required(false) + .multiple(false) + .takes_value(false) + .requires("latest") + .help("Try to find latest version using semver. If semver could not be parsed, equality is assumed, which might yield bogus results.") + ) ) .subcommand(SubCommand::with_name("problems") @@ -161,4 +178,4 @@ pub fn build_cli<'a>() -> App<'a, 'a> { In this case, repolocli is only a easier-to-use 'jq' (if you don't know jq, look it up NOW!). "#) -}
\ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index 4c29ab2..6c3442e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ extern crate flexi_logger; extern crate filters; extern crate boolinator; extern crate itertools; +extern crate semver; #[cfg(feature = "compare_csv")] extern crate csv; @@ -23,6 +24,7 @@ mod cli; mod compare; use std::path::PathBuf; +use std::cmp::Ordering; #[cfg(feature = "compare_csv")] use std::io::Cursor; @@ -35,11 +37,13 @@ use clap::ArgMatches; use filters::filter::Filter; use boolinator::Boolinator; use itertools::Itertools; +use semver::Version as SemverVersion; use config::Configuration; use compare::ComparePackage; use librepology::v1::api::Api; use librepology::v1::types::Repo; +use librepology::v1::types::Package; fn initialize_logging(app: &ArgMatches) -> Result<()> { let verbosity = app.occurrences_of("verbose"); @@ -85,7 +89,12 @@ fn deserialize_package_list(s: String, filepath: &str) -> Result<Vec<ComparePack "csv" => { let cursor = Cursor::new(s); let mut v : Vec<ComparePackage> = vec![]; - for element in csv::Reader::from_reader(cursor).deserialize() { + let mut reader = csv::ReaderBuilder::new() + .has_headers(true) + .delimiter(b';') + .from_reader(cursor); + + for element in reader.deserialize() { v.push(element?); } Ok(v) @@ -163,7 +172,7 @@ fn app() -> Result<()> { mtch.value_of("project_name").unwrap() // safe by clap }; - let packages = { + let mut packages: Vec<Package> = { let iter = backend .project(&name)? .into_iter() @@ -181,6 +190,29 @@ fn app() -> Result<()> { iter.collect() } }; + + let packages = if mtch.is_present("latest") { + if mtch.is_present("semver") { + let comp = |a: &Package, b: &Package| { + let av = SemverVersion::parse(a.version()); + let bv = SemverVersion::parse(b.version()); + + if let (Ok(av), Ok(bv)) = (av, bv) { + av.partial_cmp(&bv).unwrap_or(Ordering::Equal) + } else { + Ordering::Equal + } + }; + + packages.sort_by(comp); + } else { + packages.sort_by(|a, b| a.version().partial_cmp(b.version()).unwrap_or(Ordering::Equal)); + } + packages.pop().into_iter().collect::<Vec<_>>() + } else { + packages + }; + frontend.list_packages(packages) }, ("problems", Some(mtch)) => { |