1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 19:17:43 +00:00

sort: Version sort support

This commit is contained in:
palaviv 2016-06-14 20:33:09 +03:00
parent d4ffbe0526
commit 87455f998a
5 changed files with 35 additions and 0 deletions

View file

@ -10,6 +10,7 @@ path = "sort.rs"
[dependencies]
getopts = "*"
libc = "*"
semver = "*"
uucore = { path="../uucore" }
[[bin]]

View file

@ -13,6 +13,7 @@
extern crate getopts;
extern crate libc;
extern crate semver;
#[macro_use]
extern crate uucore;
@ -22,6 +23,7 @@ use std::fs::File;
use std::io::{BufRead, BufReader, BufWriter, Read, stdin, stdout, Write};
use std::path::Path;
use uucore::fs::is_stdin_interactive;
use semver::Version;
static NAME: &'static str = "sort";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");
@ -33,6 +35,7 @@ enum SortMode {
Numeric,
HumanNumeric,
Month,
Version,
Default,
}
@ -66,6 +69,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
opts.optflag("", "version", "output version information and exit");
opts.optopt("o", "output", "write output to FILENAME instead of stdout", "FILENAME");
opts.optflag("u", "unique", "output only the first of an equal run");
opts.optflag("V", "version-sort", "Sort by SemVer version number, eg 1.12.2 > 1.1.2");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
@ -97,6 +101,8 @@ With no FILE, or when FILE is -, read standard input.", NAME, VERSION);
SortMode::HumanNumeric
} else if matches.opt_present("month-sort") {
SortMode::Month
} else if matches.opt_present("version-sort") {
SortMode::Version
} else {
SortMode::Default
};
@ -139,6 +145,7 @@ fn exec(files: Vec<String>, settings: &Settings) {
SortMode::Numeric => lines.sort_by(numeric_compare),
SortMode::HumanNumeric => lines.sort_by(human_numeric_size_compare),
SortMode::Month => lines.sort_by(month_compare),
SortMode::Version => lines.sort_by(version_compare),
SortMode::Default => lines.sort()
}
@ -263,6 +270,20 @@ fn month_compare(a: &String, b: &String) -> Ordering {
month_parse(a).cmp(&month_parse(b))
}
fn version_compare(a: &String, b: &String) -> Ordering {
let ver_a = Version::parse(a);
let ver_b = Version::parse(b);
if ver_a > ver_b {
Ordering::Greater
}
else if ver_a < ver_b {
Ordering::Less
}
else {
Ordering::Equal
}
}
fn print_sorted<S, T: Iterator<Item=S>>(iter: T, outfile: &Option<String>) where S: std::fmt::Display {
let mut file: Box<Write> = match *outfile {
Some(ref filename) => {

4
tests/fixtures/sort/version.expected vendored Normal file
View file

@ -0,0 +1,4 @@
1.2.3-alpha
1.2.3-alpha2
1.12.4
11.2.3

4
tests/fixtures/sort/version.txt vendored Normal file
View file

@ -0,0 +1,4 @@
11.2.3
1.2.3-alpha2
1.2.3-alpha
1.12.4

View file

@ -47,6 +47,11 @@ fn test_numeric_unique_ints() {
test_helper("numeric_unsorted_ints_unique", "-nu");
}
#[test]
fn test_version() {
test_helper("version", "-V");
}
fn test_helper(file_name: &str, args: &str) {
let (at, mut ucmd) = testing(UTIL_NAME);
ucmd.arg(args);