From 897bcb2e67a4a38dd2f2e941662adbb6036affdf Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 8 Nov 2020 17:49:41 +0100 Subject: [PATCH] refactor(mkdir): Move to clap + add a test --- Cargo.lock | 2 +- src/uu/mkdir/Cargo.toml | 2 +- src/uu/mkdir/src/mkdir.rs | 91 +++++++++++++++++++++---------------- tests/by-util/test_mkdir.rs | 10 ++++ 4 files changed, 63 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76dd02abc..5bdcea2ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1748,7 +1748,7 @@ dependencies = [ name = "uu_mkdir" version = "0.0.1" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", diff --git a/src/uu/mkdir/Cargo.toml b/src/uu/mkdir/Cargo.toml index 89c391fb0..5478e501f 100644 --- a/src/uu/mkdir/Cargo.toml +++ b/src/uu/mkdir/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" path = "src/mkdir.rs" [dependencies] -getopts = "0.2.18" +clap = "2.33" libc = "0.2.42" uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["fs", "mode"] } uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } diff --git a/src/uu/mkdir/src/mkdir.rs b/src/uu/mkdir/src/mkdir.rs index c1c03d8f2..7e53ed8e7 100644 --- a/src/uu/mkdir/src/mkdir.rs +++ b/src/uu/mkdir/src/mkdir.rs @@ -5,53 +5,78 @@ // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. -extern crate getopts; +extern crate clap; #[macro_use] extern crate uucore; +use clap::{App, Arg}; use std::fs; use std::path::Path; -static NAME: &str = "mkdir"; +static ABOUT: &str = "Create the given DIRECTORY(ies) if they do not exist"; static VERSION: &str = env!("CARGO_PKG_VERSION"); +static OPT_MODE: &str = "mode"; +static OPT_PARENTS: &str = "parents"; +static OPT_VERBOSE: &str = "verbose"; + +static ARG_DIRS: &str = "dirs"; + +fn get_usage() -> String { + format!("{0} [OPTION]... [USER]", executable!()) +} /** * Handles option parsing */ pub fn uumain(args: impl uucore::Args) -> i32 { - let args = args.collect_str(); - - let mut opts = getopts::Options::new(); + let usage = get_usage(); // Linux-specific options, not implemented // opts.optflag("Z", "context", "set SELinux security context" + // " of each created directory to CTX"), - opts.optopt("m", "mode", "set file mode", "755"); - opts.optflag("p", "parents", "make parent directories as needed"); - opts.optflag("v", "verbose", "print a message for each printed directory"); - opts.optflag("h", "help", "display this help"); - opts.optflag("V", "version", "display this version"); + let matches = App::new(executable!()) + .version(VERSION) + .about(ABOUT) + .usage(&usage[..]) + .arg( + Arg::with_name(OPT_MODE) + .short("m") + .long(OPT_MODE) + .help("set file mode") + .default_value("755"), + ) + .arg( + Arg::with_name(OPT_PARENTS) + .short("p") + .long(OPT_PARENTS) + .help("make parent directories as needed"), + ) + .arg( + Arg::with_name(OPT_VERBOSE) + .short("v") + .long(OPT_VERBOSE) + .help("print a message for each printed directory"), + ) + .arg( + Arg::with_name(ARG_DIRS) + .multiple(true) + .takes_value(true) + .min_values(1), + ) + .get_matches_from(args); - let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(f) => crash!(1, "Invalid options\n{}", f), - }; + let dirs: Vec = matches + .values_of(ARG_DIRS) + .map(|v| v.map(ToString::to_string).collect()) + .unwrap_or_default(); - if args.len() == 1 || matches.opt_present("help") { - print_help(&opts); - return 0; - } - if matches.opt_present("version") { - println!("{} {}", NAME, VERSION); - return 0; - } - let verbose = matches.opt_present("verbose"); - let recursive = matches.opt_present("parents"); + let verbose = matches.is_present(OPT_VERBOSE); + let recursive = matches.is_present(OPT_PARENTS); // Translate a ~str in octal form to u16, default to 755 // Not tested on Windows - let mode_match = matches.opts_str(&["mode".to_owned()]); + let mode_match = matches.value_of(OPT_MODE); let mode: u16 = match mode_match { Some(m) => { let res: Option = u16::from_str_radix(&m, 8).ok(); @@ -63,23 +88,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 { _ => 0o755 as u16, }; - let dirs = matches.free; - if dirs.is_empty() { - crash!(1, "missing operand"); - } exec(dirs, recursive, mode, verbose) } -fn print_help(opts: &getopts::Options) { - println!("{} {}", NAME, VERSION); - println!(); - println!("Usage:"); - print!( - "{}", - opts.usage("Create the given DIRECTORY(ies) if they do not exist") - ); -} - /** * Create the list of new directories */ @@ -120,7 +131,7 @@ fn mkdir(path: &Path, recursive: bool, mode: u16, verbose: bool) -> i32 { } if verbose { - show_info!("created directory '{}'", path.display()); + println!("{}: created directory '{}'", executable!(), path.display()); } #[cfg(any(unix, target_os = "redox"))] diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index 70e4e414c..73be9b253 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -13,6 +13,16 @@ fn test_mkdir_mkdir() { new_ucmd!().arg(TEST_DIR1).succeeds(); } +#[test] +fn test_mkdir_verbose() { + let expected = "mkdir: created directory 'mkdir_test1'\n"; + new_ucmd!() + .arg(TEST_DIR1) + .arg("-v") + .run() + .stdout_is(expected); +} + #[test] fn test_mkdir_dup_dir() { let scene = TestScenario::new(util_name!());