summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2020-09-10 10:24:59 +0200
committerMatthias Beyer <mail@beyermatthias.de>2020-09-10 11:04:12 +0200
commit30b34be5779927424ea74464134139e27ed6b3e3 (patch)
treee3c88ce12c4da961453535696d217ef6ae666828
parentef1e753d6d0f5e216b6ddbc41e2ea0a8c6e8942a (diff)
Add helper to get latest version of a package
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--Cargo.toml1
-rw-r--r--src/cli.rs19
-rw-r--r--src/main.rs36
3 files changed, 53 insertions, 3 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 4fd13cb..b7cacfc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -31,6 +31,7 @@ prettytable-rs = "0.8"
filters = "0.3"
boolinator = "2"
itertools = "0.8"
+semver = "0.10"
[dependencies.clap]
version = ">=2.33"
diff --git a/src/cli.rs b/src/cli.rs
index c04052c..95ef9a2 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -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)) => {