Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ln: refactor argument handling and fix #2359 #2370

Merged
merged 1 commit into from
Jun 10, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 56 additions & 55 deletions src/uu/ln/src/ln.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,19 @@ fn get_long_usage() -> String {

static ABOUT: &str = "change file owner and group";

static OPT_B: &str = "b";
static OPT_BACKUP: &str = "backup";
static OPT_FORCE: &str = "force";
static OPT_INTERACTIVE: &str = "interactive";
static OPT_NO_DEREFERENCE: &str = "no-dereference";
static OPT_SYMBOLIC: &str = "symbolic";
static OPT_SUFFIX: &str = "suffix";
static OPT_TARGET_DIRECTORY: &str = "target-directory";
static OPT_NO_TARGET_DIRECTORY: &str = "no-target-directory";
static OPT_RELATIVE: &str = "relative";
static OPT_VERBOSE: &str = "verbose";
mod options {
pub const B: &str = "b";
pub const BACKUP: &str = "backup";
pub const FORCE: &str = "force";
pub const INTERACTIVE: &str = "interactive";
pub const NO_DEREFERENCE: &str = "no-dereference";
pub const SYMBOLIC: &str = "symbolic";
pub const SUFFIX: &str = "suffix";
pub const TARGET_DIRECTORY: &str = "target-directory";
pub const NO_TARGET_DIRECTORY: &str = "no-target-directory";
pub const RELATIVE: &str = "relative";
pub const VERBOSE: &str = "verbose";
}

static ARG_FILES: &str = "files";

Expand All @@ -101,47 +103,42 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.about(ABOUT)
.usage(&usage[..])
.after_help(&long_usage[..])
.arg(Arg::with_name(OPT_B).short(OPT_B).help(
.arg(Arg::with_name(options::B).short(options::B).help(
"make a backup of each file that would otherwise be overwritten or \
removed",
))
.arg(
Arg::with_name(OPT_BACKUP)
.long(OPT_BACKUP)
Arg::with_name(options::BACKUP)
.long(options::BACKUP)
.help(
"make a backup of each file that would otherwise be overwritten \
or removed",
)
.takes_value(true)
.possible_value("simple")
.possible_value("never")
.possible_value("numbered")
.possible_value("t")
.possible_value("existing")
.possible_value("nil")
.possible_value("none")
.possible_value("off")
.possible_values(&[
"simple", "never", "numbered", "t", "existing", "nil", "none", "off",
])
.value_name("METHOD"),
)
// TODO: opts.arg(
// Arg::with_name(("d", "directory", "allow users with appropriate privileges to attempt \
// to make hard links to directories");
.arg(
Arg::with_name(OPT_FORCE)
Arg::with_name(options::FORCE)
.short("f")
.long(OPT_FORCE)
.long(options::FORCE)
.help("remove existing destination files"),
)
.arg(
Arg::with_name(OPT_INTERACTIVE)
Arg::with_name(options::INTERACTIVE)
.short("i")
.long(OPT_INTERACTIVE)
.long(options::INTERACTIVE)
.help("prompt whether to remove existing destination files"),
)
.arg(
Arg::with_name(OPT_NO_DEREFERENCE)
Arg::with_name(options::NO_DEREFERENCE)
.short("n")
.long(OPT_NO_DEREFERENCE)
.long(options::NO_DEREFERENCE)
.help(
"treat LINK_executable!() as a normal file if it is a \
symbolic link to a directory",
Expand All @@ -153,43 +150,45 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
// TODO: opts.arg(
// Arg::with_name(("P", "physical", "make hard links directly to symbolic links");
.arg(
Arg::with_name(OPT_SYMBOLIC)
Arg::with_name(options::SYMBOLIC)
.short("s")
.long("symbolic")
.help("make symbolic links instead of hard links"),
.help("make symbolic links instead of hard links")
// override added for https://github.com/uutils/coreutils/issues/2359
.overrides_with(options::SYMBOLIC),
)
.arg(
Arg::with_name(OPT_SUFFIX)
Arg::with_name(options::SUFFIX)
.short("S")
.long(OPT_SUFFIX)
.long(options::SUFFIX)
.help("override the usual backup suffix")
.value_name("SUFFIX")
.takes_value(true),
)
.arg(
Arg::with_name(OPT_TARGET_DIRECTORY)
Arg::with_name(options::TARGET_DIRECTORY)
.short("t")
.long(OPT_TARGET_DIRECTORY)
.long(options::TARGET_DIRECTORY)
.help("specify the DIRECTORY in which to create the links")
.value_name("DIRECTORY")
.conflicts_with(OPT_NO_TARGET_DIRECTORY),
.conflicts_with(options::NO_TARGET_DIRECTORY),
)
.arg(
Arg::with_name(OPT_NO_TARGET_DIRECTORY)
Arg::with_name(options::NO_TARGET_DIRECTORY)
.short("T")
.long(OPT_NO_TARGET_DIRECTORY)
.long(options::NO_TARGET_DIRECTORY)
.help("treat LINK_executable!() as a normal file always"),
)
.arg(
Arg::with_name(OPT_RELATIVE)
Arg::with_name(options::RELATIVE)
.short("r")
.long(OPT_RELATIVE)
.long(options::RELATIVE)
.help("create symbolic links relative to link location"),
)
.arg(
Arg::with_name(OPT_VERBOSE)
Arg::with_name(options::VERBOSE)
.short("v")
.long(OPT_VERBOSE)
.long(options::VERBOSE)
.help("print name of each linked file"),
)
.arg(
Expand All @@ -209,18 +208,18 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.map(PathBuf::from)
.collect();

let overwrite_mode = if matches.is_present(OPT_FORCE) {
let overwrite_mode = if matches.is_present(options::FORCE) {
OverwriteMode::Force
} else if matches.is_present(OPT_INTERACTIVE) {
} else if matches.is_present(options::INTERACTIVE) {
OverwriteMode::Interactive
} else {
OverwriteMode::NoClobber
};

let backup_mode = if matches.is_present(OPT_B) {
let backup_mode = if matches.is_present(options::B) {
BackupMode::ExistingBackup
} else if matches.is_present(OPT_BACKUP) {
match matches.value_of(OPT_BACKUP) {
} else if matches.is_present(options::BACKUP) {
match matches.value_of(options::BACKUP) {
None => BackupMode::ExistingBackup,
Some(mode) => match mode {
"simple" | "never" => BackupMode::SimpleBackup,
Expand All @@ -234,23 +233,25 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
BackupMode::NoBackup
};

let backup_suffix = if matches.is_present(OPT_SUFFIX) {
matches.value_of(OPT_SUFFIX).unwrap()
let backup_suffix = if matches.is_present(options::SUFFIX) {
matches.value_of(options::SUFFIX).unwrap()
} else {
"~"
};

let settings = Settings {
overwrite: overwrite_mode,
backup: backup_mode,
force: matches.is_present(OPT_FORCE),
force: matches.is_present(options::FORCE),
suffix: backup_suffix.to_string(),
symbolic: matches.is_present(OPT_SYMBOLIC),
relative: matches.is_present(OPT_RELATIVE),
target_dir: matches.value_of(OPT_TARGET_DIRECTORY).map(String::from),
no_target_dir: matches.is_present(OPT_NO_TARGET_DIRECTORY),
no_dereference: matches.is_present(OPT_NO_DEREFERENCE),
verbose: matches.is_present(OPT_VERBOSE),
symbolic: matches.is_present(options::SYMBOLIC),
relative: matches.is_present(options::RELATIVE),
target_dir: matches
.value_of(options::TARGET_DIRECTORY)
.map(String::from),
no_target_dir: matches.is_present(options::NO_TARGET_DIRECTORY),
no_dereference: matches.is_present(options::NO_DEREFERENCE),
verbose: matches.is_present(options::VERBOSE),
};

exec(&paths[..], &settings)
Expand Down