Merge pull request #1630 from sylvestre/clap-mkdir

refactor(mkdir): Move to clap + add a test
This commit is contained in:
Sylvestre Ledru 2020-11-17 13:01:09 +01:00 committed by GitHub
commit 62265656b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 42 deletions

2
Cargo.lock generated
View file

@ -1749,7 +1749,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",
"uucore_procs 0.0.4",

View file

@ -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", path="../../uucore", features=["fs", "mode"] }
uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" }

View file

@ -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<String> = 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> = 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"))]

View file

@ -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!());