From d86ee34bc60846650aa1ca5e0179e31a8fd923f3 Mon Sep 17 00:00:00 2001 From: Yagiz Degirmenci <62724709+ycd@users.noreply.github.com> Date: Mon, 22 Mar 2021 20:16:28 +0300 Subject: [PATCH] tsort: move from getopts to clap (#1867) --- src/uu/tsort/Cargo.toml | 2 +- src/uu/tsort/src/tsort.rs | 50 +++++++++++++------------------------ tests/by-util/test_tsort.rs | 33 ++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 33 deletions(-) diff --git a/src/uu/tsort/Cargo.toml b/src/uu/tsort/Cargo.toml index 10672a9e0..d870e0155 100644 --- a/src/uu/tsort/Cargo.toml +++ b/src/uu/tsort/Cargo.toml @@ -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" } diff --git a/src/uu/tsort/src/tsort.rs b/src/uu/tsort/src/tsort.rs index 0a0023031..3440972a2 100644 --- a/src/uu/tsort/src/tsort.rs +++ b/src/uu/tsort/src/tsort.rs @@ -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; diff --git a/tests/by-util/test_tsort.rs b/tests/by-util/test_tsort.rs index c743868ec..159b80025 100644 --- a/tests/by-util/test_tsort.rs +++ b/tests/by-util/test_tsort.rs @@ -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")) +}