mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
tsort: move from getopts to clap (#1867)
This commit is contained in:
parent
f593cf53b2
commit
d86ee34bc6
3 changed files with 52 additions and 33 deletions
|
@ -15,7 +15,7 @@ edition = "2018"
|
|||
path = "src/tsort.rs"
|
||||
|
||||
[dependencies]
|
||||
getopts = "0.2.18"
|
||||
clap= "2.33"
|
||||
uucore = { version=">=0.0.7", package="uucore", path="../../uucore" }
|
||||
uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" }
|
||||
|
||||
|
|
|
@ -9,49 +9,35 @@
|
|||
#[macro_use]
|
||||
extern crate uucore;
|
||||
|
||||
use clap::{App, Arg};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::fs::File;
|
||||
use std::io::{stdin, BufRead, BufReader, Read};
|
||||
use std::path::Path;
|
||||
|
||||
static NAME: &str = "tsort";
|
||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
static SUMMARY: &str = "Topological sort the strings in FILE.
|
||||
Strings are defined as any sequence of tokens separated by whitespace (tab, space, or newline).
|
||||
If FILE is not passed in, stdin is used instead.";
|
||||
static USAGE: &str = "tsort [OPTIONS] FILE";
|
||||
|
||||
mod options {
|
||||
pub const FILE: &str = "file";
|
||||
}
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let args = args.collect_str();
|
||||
|
||||
let mut opts = getopts::Options::new();
|
||||
let matches = App::new(executable!())
|
||||
.version(VERSION)
|
||||
.usage(USAGE)
|
||||
.about(SUMMARY)
|
||||
.arg(Arg::with_name(options::FILE).hidden(true))
|
||||
.get_matches_from(args);
|
||||
|
||||
opts.optflag("h", "help", "display this help and exit");
|
||||
opts.optflag("V", "version", "output version information and exit");
|
||||
|
||||
let matches = match opts.parse(&args[1..]) {
|
||||
Ok(m) => m,
|
||||
Err(f) => crash!(1, "{}", f),
|
||||
};
|
||||
|
||||
if matches.opt_present("h") {
|
||||
println!("{} {}", NAME, VERSION);
|
||||
println!();
|
||||
println!("Usage:");
|
||||
println!(" {} [OPTIONS] FILE", NAME);
|
||||
println!();
|
||||
println!("{}", opts.usage("Topological sort the strings in FILE. Strings are defined as any sequence of tokens separated by whitespace (tab, space, or newline). If FILE is not passed in, stdin is used instead."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if matches.opt_present("V") {
|
||||
println!("{} {}", NAME, VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
let files = matches.free.clone();
|
||||
let input = if files.len() > 1 {
|
||||
crash!(1, "{}, extra operand '{}'", NAME, matches.free[1]);
|
||||
} else if files.is_empty() {
|
||||
"-".to_owned()
|
||||
} else {
|
||||
files[0].clone()
|
||||
let input = match matches.value_of(options::FILE) {
|
||||
Some(v) => v,
|
||||
None => "-",
|
||||
};
|
||||
|
||||
let mut stdin_buf;
|
||||
|
|
|
@ -15,3 +15,36 @@ fn test_sort_self_loop() {
|
|||
.succeeds()
|
||||
.stdout_only("first\nsecond\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_such_file() {
|
||||
let result = new_ucmd!().arg("invalid_file_txt").run();
|
||||
|
||||
assert_eq!(true, result.stderr.contains("No such file or directory"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_version_flag() {
|
||||
let version_short = new_ucmd!().arg("-V").run();
|
||||
let version_long = new_ucmd!().arg("--version").run();
|
||||
|
||||
assert_eq!(version_short.stdout, version_long.stdout);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_help_flag() {
|
||||
let help_short = new_ucmd!().arg("-h").run();
|
||||
let help_long = new_ucmd!().arg("--help").run();
|
||||
|
||||
assert_eq!(help_short.stdout, help_long.stdout);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_arguments() {
|
||||
let result = new_ucmd!()
|
||||
.arg("call_graph.txt")
|
||||
.arg("invalid_file.txt")
|
||||
.run();
|
||||
|
||||
assert_eq!(true, result.stderr.contains("error: Found argument 'invalid_file.txt' which wasn't expected, or isn't valid in this context"))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue