1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 11:07:44 +00:00

Merge pull request #2430 from tertsdiepraam/cp/update-options

`cp`: use `options` module and update list op implemented args
This commit is contained in:
Sylvestre Ledru 2021-06-18 18:50:36 +02:00 committed by GitHub
commit 7739080e6e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 172 additions and 169 deletions

View file

@ -7,37 +7,37 @@
### To Do
- [ ] archive
- [ ] attributes-only
- [ ] copy-contents
- [ ] no-dereference-preserve-linkgs
- [ ] dereference
- [ ] no-dereference
- [ ] preserve-default-attributes
- [ ] preserve
- [ ] no-preserve
- [ ] parents
- [ ] reflink
- [ ] sparse
- [ ] strip-trailing-slashes
- [ ] update
- [ ] one-file-system
- [ ] context
- [ ] cli-symbolic-links
- [ ] context
- [ ] copy-contents
- [ ] sparse
### Completed
- [x] archive
- [x] attributes-only
- [x] backup
- [x] dereference
- [x] force (Not implemented on Windows)
- [x] interactive
- [x] link
- [x] no-clobber
- [x] no-dereference
- [x] no-dereference-preserve-links
- [x] no-preserve
- [x] no-target-directory
- [x] one-file-system
- [x] parents
- [x] paths
- [x] preserve
- [x] preserve-default-attributes
- [x] recursive
- [x] reflink
- [x] remove-destination (On Windows, current only works for writeable files)
- [x] strip-trailing-slashes
- [x] suffix
- [x] symbolic-link
- [x] target-directory
- [x] update
- [x] verbose
- [x] version

View file

@ -226,39 +226,41 @@ fn get_usage() -> String {
}
// Argument constants
static OPT_ARCHIVE: &str = "archive";
static OPT_ATTRIBUTES_ONLY: &str = "attributes-only";
static OPT_BACKUP: &str = "backup";
static OPT_BACKUP_NO_ARG: &str = "b";
static OPT_CLI_SYMBOLIC_LINKS: &str = "cli-symbolic-links";
static OPT_CONTEXT: &str = "context";
static OPT_COPY_CONTENTS: &str = "copy-contents";
static OPT_DEREFERENCE: &str = "dereference";
static OPT_FORCE: &str = "force";
static OPT_INTERACTIVE: &str = "interactive";
static OPT_LINK: &str = "link";
static OPT_NO_CLOBBER: &str = "no-clobber";
static OPT_NO_DEREFERENCE: &str = "no-dereference";
static OPT_NO_DEREFERENCE_PRESERVE_LINKS: &str = "no-dereference-preserve-linkgs";
static OPT_NO_PRESERVE: &str = "no-preserve";
static OPT_NO_TARGET_DIRECTORY: &str = "no-target-directory";
static OPT_ONE_FILE_SYSTEM: &str = "one-file-system";
static OPT_PARENT: &str = "parent";
static OPT_PARENTS: &str = "parents";
static OPT_PATHS: &str = "paths";
static OPT_PRESERVE: &str = "preserve";
static OPT_PRESERVE_DEFAULT_ATTRIBUTES: &str = "preserve-default-attributes";
static OPT_RECURSIVE: &str = "recursive";
static OPT_RECURSIVE_ALIAS: &str = "recursive_alias";
static OPT_REFLINK: &str = "reflink";
static OPT_REMOVE_DESTINATION: &str = "remove-destination";
static OPT_SPARSE: &str = "sparse";
static OPT_STRIP_TRAILING_SLASHES: &str = "strip-trailing-slashes";
static OPT_SUFFIX: &str = "suffix";
static OPT_SYMBOLIC_LINK: &str = "symbolic-link";
static OPT_TARGET_DIRECTORY: &str = "target-directory";
static OPT_UPDATE: &str = "update";
static OPT_VERBOSE: &str = "verbose";
mod options {
pub const ARCHIVE: &str = "archive";
pub const ATTRIBUTES_ONLY: &str = "attributes-only";
pub const BACKUP: &str = "backup";
pub const BACKUP_NO_ARG: &str = "b";
pub const CLI_SYMBOLIC_LINKS: &str = "cli-symbolic-links";
pub const CONTEXT: &str = "context";
pub const COPY_CONTENTS: &str = "copy-contents";
pub const DEREFERENCE: &str = "dereference";
pub const FORCE: &str = "force";
pub const INTERACTIVE: &str = "interactive";
pub const LINK: &str = "link";
pub const NO_CLOBBER: &str = "no-clobber";
pub const NO_DEREFERENCE: &str = "no-dereference";
pub const NO_DEREFERENCE_PRESERVE_LINKS: &str = "no-dereference-preserve-linkgs";
pub const NO_PRESERVE: &str = "no-preserve";
pub const NO_TARGET_DIRECTORY: &str = "no-target-directory";
pub const ONE_FILE_SYSTEM: &str = "one-file-system";
pub const PARENT: &str = "parent";
pub const PARENTS: &str = "parents";
pub const PATHS: &str = "paths";
pub const PRESERVE: &str = "preserve";
pub const PRESERVE_DEFAULT_ATTRIBUTES: &str = "preserve-default-attributes";
pub const RECURSIVE: &str = "recursive";
pub const RECURSIVE_ALIAS: &str = "recursive_alias";
pub const REFLINK: &str = "reflink";
pub const REMOVE_DESTINATION: &str = "remove-destination";
pub const SPARSE: &str = "sparse";
pub const STRIP_TRAILING_SLASHES: &str = "strip-trailing-slashes";
pub const SUFFIX: &str = "suffix";
pub const SYMBOLIC_LINK: &str = "symbolic-link";
pub const TARGET_DIRECTORY: &str = "target-directory";
pub const UPDATE: &str = "update";
pub const VERBOSE: &str = "verbose";
}
#[cfg(unix)]
static PRESERVABLE_ATTRIBUTES: &[&str] = &[
@ -295,67 +297,67 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.about(ABOUT)
.after_help(&*format!("{}\n{}", LONG_HELP, backup_control::BACKUP_CONTROL_LONG_HELP))
.usage(&usage[..])
.arg(Arg::with_name(OPT_TARGET_DIRECTORY)
.arg(Arg::with_name(options::TARGET_DIRECTORY)
.short("t")
.conflicts_with(OPT_NO_TARGET_DIRECTORY)
.long(OPT_TARGET_DIRECTORY)
.value_name(OPT_TARGET_DIRECTORY)
.conflicts_with(options::NO_TARGET_DIRECTORY)
.long(options::TARGET_DIRECTORY)
.value_name(options::TARGET_DIRECTORY)
.takes_value(true)
.help("copy all SOURCE arguments into target-directory"))
.arg(Arg::with_name(OPT_NO_TARGET_DIRECTORY)
.arg(Arg::with_name(options::NO_TARGET_DIRECTORY)
.short("T")
.long(OPT_NO_TARGET_DIRECTORY)
.conflicts_with(OPT_TARGET_DIRECTORY)
.long(options::NO_TARGET_DIRECTORY)
.conflicts_with(options::TARGET_DIRECTORY)
.help("Treat DEST as a regular file and not a directory"))
.arg(Arg::with_name(OPT_INTERACTIVE)
.arg(Arg::with_name(options::INTERACTIVE)
.short("i")
.long(OPT_INTERACTIVE)
.conflicts_with(OPT_NO_CLOBBER)
.long(options::INTERACTIVE)
.conflicts_with(options::NO_CLOBBER)
.help("ask before overwriting files"))
.arg(Arg::with_name(OPT_LINK)
.arg(Arg::with_name(options::LINK)
.short("l")
.long(OPT_LINK)
.overrides_with(OPT_REFLINK)
.long(options::LINK)
.overrides_with(options::REFLINK)
.help("hard-link files instead of copying"))
.arg(Arg::with_name(OPT_NO_CLOBBER)
.arg(Arg::with_name(options::NO_CLOBBER)
.short("n")
.long(OPT_NO_CLOBBER)
.conflicts_with(OPT_INTERACTIVE)
.long(options::NO_CLOBBER)
.conflicts_with(options::INTERACTIVE)
.help("don't overwrite a file that already exists"))
.arg(Arg::with_name(OPT_RECURSIVE)
.arg(Arg::with_name(options::RECURSIVE)
.short("r")
.long(OPT_RECURSIVE)
.long(options::RECURSIVE)
// --archive sets this option
.help("copy directories recursively"))
.arg(Arg::with_name(OPT_RECURSIVE_ALIAS)
.arg(Arg::with_name(options::RECURSIVE_ALIAS)
.short("R")
.help("same as -r"))
.arg(Arg::with_name(OPT_STRIP_TRAILING_SLASHES)
.long(OPT_STRIP_TRAILING_SLASHES)
.arg(Arg::with_name(options::STRIP_TRAILING_SLASHES)
.long(options::STRIP_TRAILING_SLASHES)
.help("remove any trailing slashes from each SOURCE argument"))
.arg(Arg::with_name(OPT_VERBOSE)
.arg(Arg::with_name(options::VERBOSE)
.short("v")
.long(OPT_VERBOSE)
.long(options::VERBOSE)
.help("explicitly state what is being done"))
.arg(Arg::with_name(OPT_SYMBOLIC_LINK)
.arg(Arg::with_name(options::SYMBOLIC_LINK)
.short("s")
.long(OPT_SYMBOLIC_LINK)
.conflicts_with(OPT_LINK)
.overrides_with(OPT_REFLINK)
.long(options::SYMBOLIC_LINK)
.conflicts_with(options::LINK)
.overrides_with(options::REFLINK)
.help("make symbolic links instead of copying"))
.arg(Arg::with_name(OPT_FORCE)
.arg(Arg::with_name(options::FORCE)
.short("f")
.long(OPT_FORCE)
.long(options::FORCE)
.help("if an existing destination file cannot be opened, remove it and \
try again (this option is ignored when the -n option is also used). \
Currently not implemented for Windows."))
.arg(Arg::with_name(OPT_REMOVE_DESTINATION)
.long(OPT_REMOVE_DESTINATION)
.conflicts_with(OPT_FORCE)
.arg(Arg::with_name(options::REMOVE_DESTINATION)
.long(options::REMOVE_DESTINATION)
.conflicts_with(options::FORCE)
.help("remove each existing destination file before attempting to open it \
(contrast with --force). On Windows, current only works for writeable files."))
.arg(Arg::with_name(OPT_BACKUP)
.long(OPT_BACKUP)
.arg(Arg::with_name(options::BACKUP)
.long(options::BACKUP)
.help("make a backup of each existing destination file")
.takes_value(true)
.require_equals(true)
@ -363,104 +365,104 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.possible_values(backup_control::BACKUP_CONTROL_VALUES)
.value_name("CONTROL")
)
.arg(Arg::with_name(OPT_BACKUP_NO_ARG)
.short(OPT_BACKUP_NO_ARG)
.arg(Arg::with_name(options::BACKUP_NO_ARG)
.short(options::BACKUP_NO_ARG)
.help("like --backup but does not accept an argument")
)
.arg(Arg::with_name(OPT_SUFFIX)
.arg(Arg::with_name(options::SUFFIX)
.short("S")
.long(OPT_SUFFIX)
.long(options::SUFFIX)
.takes_value(true)
.value_name("SUFFIX")
.help("override the usual backup suffix"))
.arg(Arg::with_name(OPT_UPDATE)
.arg(Arg::with_name(options::UPDATE)
.short("u")
.long(OPT_UPDATE)
.long(options::UPDATE)
.help("copy only when the SOURCE file is newer than the destination file\
or when the destination file is missing"))
.arg(Arg::with_name(OPT_REFLINK)
.long(OPT_REFLINK)
.arg(Arg::with_name(options::REFLINK)
.long(options::REFLINK)
.takes_value(true)
.value_name("WHEN")
.help("control clone/CoW copies. See below"))
.arg(Arg::with_name(OPT_ATTRIBUTES_ONLY)
.long(OPT_ATTRIBUTES_ONLY)
.conflicts_with(OPT_COPY_CONTENTS)
.overrides_with(OPT_REFLINK)
.arg(Arg::with_name(options::ATTRIBUTES_ONLY)
.long(options::ATTRIBUTES_ONLY)
.conflicts_with(options::COPY_CONTENTS)
.overrides_with(options::REFLINK)
.help("Don't copy the file data, just the attributes"))
.arg(Arg::with_name(OPT_PRESERVE)
.long(OPT_PRESERVE)
.arg(Arg::with_name(options::PRESERVE)
.long(options::PRESERVE)
.takes_value(true)
.multiple(true)
.use_delimiter(true)
.possible_values(PRESERVABLE_ATTRIBUTES)
.min_values(0)
.value_name("ATTR_LIST")
.conflicts_with_all(&[OPT_PRESERVE_DEFAULT_ATTRIBUTES, OPT_NO_PRESERVE])
.conflicts_with_all(&[options::PRESERVE_DEFAULT_ATTRIBUTES, options::NO_PRESERVE])
// -d sets this option
// --archive sets this option
.help("Preserve the specified attributes (default: mode(unix only),ownership,timestamps),\
if possible additional attributes: context, links, xattr, all"))
.arg(Arg::with_name(OPT_PRESERVE_DEFAULT_ATTRIBUTES)
.arg(Arg::with_name(options::PRESERVE_DEFAULT_ATTRIBUTES)
.short("-p")
.long(OPT_PRESERVE_DEFAULT_ATTRIBUTES)
.conflicts_with_all(&[OPT_PRESERVE, OPT_NO_PRESERVE, OPT_ARCHIVE])
.long(options::PRESERVE_DEFAULT_ATTRIBUTES)
.conflicts_with_all(&[options::PRESERVE, options::NO_PRESERVE, options::ARCHIVE])
.help("same as --preserve=mode(unix only),ownership,timestamps"))
.arg(Arg::with_name(OPT_NO_PRESERVE)
.long(OPT_NO_PRESERVE)
.arg(Arg::with_name(options::NO_PRESERVE)
.long(options::NO_PRESERVE)
.takes_value(true)
.value_name("ATTR_LIST")
.conflicts_with_all(&[OPT_PRESERVE_DEFAULT_ATTRIBUTES, OPT_PRESERVE, OPT_ARCHIVE])
.conflicts_with_all(&[options::PRESERVE_DEFAULT_ATTRIBUTES, options::PRESERVE, options::ARCHIVE])
.help("don't preserve the specified attributes"))
.arg(Arg::with_name(OPT_PARENTS)
.long(OPT_PARENTS)
.alias(OPT_PARENT)
.arg(Arg::with_name(options::PARENTS)
.long(options::PARENTS)
.alias(options::PARENT)
.help("use full source file name under DIRECTORY"))
.arg(Arg::with_name(OPT_NO_DEREFERENCE)
.arg(Arg::with_name(options::NO_DEREFERENCE)
.short("-P")
.long(OPT_NO_DEREFERENCE)
.conflicts_with(OPT_DEREFERENCE)
.long(options::NO_DEREFERENCE)
.conflicts_with(options::DEREFERENCE)
// -d sets this option
.help("never follow symbolic links in SOURCE"))
.arg(Arg::with_name(OPT_DEREFERENCE)
.arg(Arg::with_name(options::DEREFERENCE)
.short("L")
.long(OPT_DEREFERENCE)
.conflicts_with(OPT_NO_DEREFERENCE)
.long(options::DEREFERENCE)
.conflicts_with(options::NO_DEREFERENCE)
.help("always follow symbolic links in SOURCE"))
.arg(Arg::with_name(OPT_ARCHIVE)
.arg(Arg::with_name(options::ARCHIVE)
.short("a")
.long(OPT_ARCHIVE)
.conflicts_with_all(&[OPT_PRESERVE_DEFAULT_ATTRIBUTES, OPT_PRESERVE, OPT_NO_PRESERVE])
.long(options::ARCHIVE)
.conflicts_with_all(&[options::PRESERVE_DEFAULT_ATTRIBUTES, options::PRESERVE, options::NO_PRESERVE])
.help("Same as -dR --preserve=all"))
.arg(Arg::with_name(OPT_NO_DEREFERENCE_PRESERVE_LINKS)
.arg(Arg::with_name(options::NO_DEREFERENCE_PRESERVE_LINKS)
.short("d")
.help("same as --no-dereference --preserve=links"))
.arg(Arg::with_name(OPT_ONE_FILE_SYSTEM)
.arg(Arg::with_name(options::ONE_FILE_SYSTEM)
.short("x")
.long(OPT_ONE_FILE_SYSTEM)
.long(options::ONE_FILE_SYSTEM)
.help("stay on this file system"))
// TODO: implement the following args
.arg(Arg::with_name(OPT_COPY_CONTENTS)
.long(OPT_COPY_CONTENTS)
.conflicts_with(OPT_ATTRIBUTES_ONLY)
.arg(Arg::with_name(options::COPY_CONTENTS)
.long(options::COPY_CONTENTS)
.conflicts_with(options::ATTRIBUTES_ONLY)
.help("NotImplemented: copy contents of special files when recursive"))
.arg(Arg::with_name(OPT_SPARSE)
.long(OPT_SPARSE)
.arg(Arg::with_name(options::SPARSE)
.long(options::SPARSE)
.takes_value(true)
.value_name("WHEN")
.help("NotImplemented: control creation of sparse files. See below"))
.arg(Arg::with_name(OPT_CONTEXT)
.long(OPT_CONTEXT)
.arg(Arg::with_name(options::CONTEXT)
.long(options::CONTEXT)
.takes_value(true)
.value_name("CTX")
.help("NotImplemented: set SELinux security context of destination file to default type"))
.arg(Arg::with_name(OPT_CLI_SYMBOLIC_LINKS)
.arg(Arg::with_name(options::CLI_SYMBOLIC_LINKS)
.short("H")
.help("NotImplemented: follow command-line symbolic links in SOURCE"))
// END TODO
.arg(Arg::with_name(OPT_PATHS)
.arg(Arg::with_name(options::PATHS)
.multiple(true))
.get_matches_from(args);
@ -472,7 +474,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
}
let paths: Vec<String> = matches
.values_of(OPT_PATHS)
.values_of(options::PATHS)
.map(|v| v.map(ToString::to_string).collect())
.unwrap_or_default();
@ -494,9 +496,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
impl ClobberMode {
fn from_matches(matches: &ArgMatches) -> ClobberMode {
if matches.is_present(OPT_FORCE) {
if matches.is_present(options::FORCE) {
ClobberMode::Force
} else if matches.is_present(OPT_REMOVE_DESTINATION) {
} else if matches.is_present(options::REMOVE_DESTINATION) {
ClobberMode::RemoveDestination
} else {
ClobberMode::Standard
@ -506,9 +508,9 @@ impl ClobberMode {
impl OverwriteMode {
fn from_matches(matches: &ArgMatches) -> OverwriteMode {
if matches.is_present(OPT_INTERACTIVE) {
if matches.is_present(options::INTERACTIVE) {
OverwriteMode::Interactive(ClobberMode::from_matches(matches))
} else if matches.is_present(OPT_NO_CLOBBER) {
} else if matches.is_present(options::NO_CLOBBER) {
OverwriteMode::NoClobber
} else {
OverwriteMode::Clobber(ClobberMode::from_matches(matches))
@ -518,15 +520,15 @@ impl OverwriteMode {
impl CopyMode {
fn from_matches(matches: &ArgMatches) -> CopyMode {
if matches.is_present(OPT_LINK) {
if matches.is_present(options::LINK) {
CopyMode::Link
} else if matches.is_present(OPT_SYMBOLIC_LINK) {
} else if matches.is_present(options::SYMBOLIC_LINK) {
CopyMode::SymLink
} else if matches.is_present(OPT_SPARSE) {
} else if matches.is_present(options::SPARSE) {
CopyMode::Sparse
} else if matches.is_present(OPT_UPDATE) {
} else if matches.is_present(options::UPDATE) {
CopyMode::Update
} else if matches.is_present(OPT_ATTRIBUTES_ONLY) {
} else if matches.is_present(options::ATTRIBUTES_ONLY) {
CopyMode::AttrOnly
} else {
CopyMode::Copy
@ -574,13 +576,13 @@ fn add_all_attributes() -> Vec<Attribute> {
impl Options {
fn from_matches(matches: &ArgMatches) -> CopyResult<Options> {
let not_implemented_opts = vec![
OPT_COPY_CONTENTS,
OPT_SPARSE,
options::COPY_CONTENTS,
options::SPARSE,
#[cfg(not(any(windows, unix)))]
OPT_ONE_FILE_SYSTEM,
OPT_CONTEXT,
options::ONE_FILE_SYSTEM,
options::CONTEXT,
#[cfg(windows)]
OPT_FORCE,
options::FORCE,
];
for not_implemented_opt in not_implemented_opts {
@ -589,27 +591,28 @@ impl Options {
}
}
let recursive = matches.is_present(OPT_RECURSIVE)
|| matches.is_present(OPT_RECURSIVE_ALIAS)
|| matches.is_present(OPT_ARCHIVE);
let recursive = matches.is_present(options::RECURSIVE)
|| matches.is_present(options::RECURSIVE_ALIAS)
|| matches.is_present(options::ARCHIVE);
let backup_mode = backup_control::determine_backup_mode(
matches.is_present(OPT_BACKUP_NO_ARG) || matches.is_present(OPT_BACKUP),
matches.value_of(OPT_BACKUP),
matches.is_present(options::BACKUP_NO_ARG) || matches.is_present(options::BACKUP),
matches.value_of(options::BACKUP),
);
let backup_suffix = backup_control::determine_backup_suffix(matches.value_of(OPT_SUFFIX));
let backup_suffix =
backup_control::determine_backup_suffix(matches.value_of(options::SUFFIX));
let overwrite = OverwriteMode::from_matches(matches);
// Parse target directory options
let no_target_dir = matches.is_present(OPT_NO_TARGET_DIRECTORY);
let no_target_dir = matches.is_present(options::NO_TARGET_DIRECTORY);
let target_dir = matches
.value_of(OPT_TARGET_DIRECTORY)
.value_of(options::TARGET_DIRECTORY)
.map(ToString::to_string);
// Parse attributes to preserve
let preserve_attributes: Vec<Attribute> = if matches.is_present(OPT_PRESERVE) {
match matches.values_of(OPT_PRESERVE) {
let preserve_attributes: Vec<Attribute> = if matches.is_present(options::PRESERVE) {
match matches.values_of(options::PRESERVE) {
None => DEFAULT_ATTRIBUTES.to_vec(),
Some(attribute_strs) => {
let mut attributes = Vec::new();
@ -624,34 +627,34 @@ impl Options {
attributes
}
}
} else if matches.is_present(OPT_ARCHIVE) {
} else if matches.is_present(options::ARCHIVE) {
// --archive is used. Same as --preserve=all
add_all_attributes()
} else if matches.is_present(OPT_NO_DEREFERENCE_PRESERVE_LINKS) {
} else if matches.is_present(options::NO_DEREFERENCE_PRESERVE_LINKS) {
vec![Attribute::Links]
} else if matches.is_present(OPT_PRESERVE_DEFAULT_ATTRIBUTES) {
} else if matches.is_present(options::PRESERVE_DEFAULT_ATTRIBUTES) {
DEFAULT_ATTRIBUTES.to_vec()
} else {
vec![]
};
let options = Options {
attributes_only: matches.is_present(OPT_ATTRIBUTES_ONLY),
copy_contents: matches.is_present(OPT_COPY_CONTENTS),
attributes_only: matches.is_present(options::ATTRIBUTES_ONLY),
copy_contents: matches.is_present(options::COPY_CONTENTS),
copy_mode: CopyMode::from_matches(matches),
// No dereference is set with -p, -d and --archive
dereference: !(matches.is_present(OPT_NO_DEREFERENCE)
|| matches.is_present(OPT_NO_DEREFERENCE_PRESERVE_LINKS)
|| matches.is_present(OPT_ARCHIVE)
dereference: !(matches.is_present(options::NO_DEREFERENCE)
|| matches.is_present(options::NO_DEREFERENCE_PRESERVE_LINKS)
|| matches.is_present(options::ARCHIVE)
|| recursive)
|| matches.is_present(OPT_DEREFERENCE),
one_file_system: matches.is_present(OPT_ONE_FILE_SYSTEM),
parents: matches.is_present(OPT_PARENTS),
update: matches.is_present(OPT_UPDATE),
verbose: matches.is_present(OPT_VERBOSE),
strip_trailing_slashes: matches.is_present(OPT_STRIP_TRAILING_SLASHES),
|| matches.is_present(options::DEREFERENCE),
one_file_system: matches.is_present(options::ONE_FILE_SYSTEM),
parents: matches.is_present(options::PARENTS),
update: matches.is_present(options::UPDATE),
verbose: matches.is_present(options::VERBOSE),
strip_trailing_slashes: matches.is_present(options::STRIP_TRAILING_SLASHES),
reflink_mode: {
if let Some(reflink) = matches.value_of(OPT_REFLINK) {
if let Some(reflink) = matches.value_of(options::REFLINK) {
match reflink {
"always" => ReflinkMode::Always,
"auto" => ReflinkMode::Auto,
@ -1180,7 +1183,7 @@ fn copy_file(source: &Path, dest: &Path, options: &Options) -> CopyResult<()> {
CopyMode::SymLink => {
symlink_file(source, dest, &*context_for(source, dest))?;
}
CopyMode::Sparse => return Err(Error::NotImplemented(OPT_SPARSE.to_string())),
CopyMode::Sparse => return Err(Error::NotImplemented(options::SPARSE.to_string())),
CopyMode::Update => {
if dest.exists() {
let src_metadata = fs::metadata(source)?;