1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 19:47:45 +00:00

cp: implement --strip-trailing-slashes

This commit is contained in:
Benjamin Fox 2021-03-09 12:59:26 +02:00
parent 2dcc60d624
commit 5446ea2abf
2 changed files with 30 additions and 5 deletions

View file

@ -207,6 +207,7 @@ pub struct Options {
one_file_system: bool, one_file_system: bool,
overwrite: OverwriteMode, overwrite: OverwriteMode,
parents: bool, parents: bool,
strip_trailing_slashes: bool,
reflink: bool, reflink: bool,
reflink_mode: ReflinkMode, reflink_mode: ReflinkMode,
preserve_attributes: Vec<Attribute>, preserve_attributes: Vec<Attribute>,
@ -333,6 +334,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.arg(Arg::with_name(OPT_RECURSIVE_ALIAS) .arg(Arg::with_name(OPT_RECURSIVE_ALIAS)
.short("R") .short("R")
.help("same as -r")) .help("same as -r"))
.arg(Arg::with_name(OPT_STRIP_TRAILING_SLASHES)
.long(OPT_STRIP_TRAILING_SLASHES)
.help("remove any trailing slashes from each SOURCE argument"))
.arg(Arg::with_name(OPT_VERBOSE) .arg(Arg::with_name(OPT_VERBOSE)
.short("v") .short("v")
.long(OPT_VERBOSE) .long(OPT_VERBOSE)
@ -436,9 +440,6 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
.takes_value(true) .takes_value(true)
.value_name("WHEN") .value_name("WHEN")
.help("NotImplemented: control creation of sparse files. See below")) .help("NotImplemented: control creation of sparse files. See below"))
.arg(Arg::with_name(OPT_STRIP_TRAILING_SLASHES)
.long(OPT_STRIP_TRAILING_SLASHES)
.help("NotImplemented: remove any trailing slashes from each SOURCE argument"))
.arg(Arg::with_name(OPT_ONE_FILE_SYSTEM) .arg(Arg::with_name(OPT_ONE_FILE_SYSTEM)
.short("x") .short("x")
.long(OPT_ONE_FILE_SYSTEM) .long(OPT_ONE_FILE_SYSTEM)
@ -561,7 +562,6 @@ impl Options {
OPT_COPY_CONTENTS, OPT_COPY_CONTENTS,
OPT_PARENTS, OPT_PARENTS,
OPT_SPARSE, OPT_SPARSE,
OPT_STRIP_TRAILING_SLASHES,
OPT_ONE_FILE_SYSTEM, OPT_ONE_FILE_SYSTEM,
OPT_CONTEXT, OPT_CONTEXT,
#[cfg(windows)] #[cfg(windows)]
@ -629,6 +629,7 @@ impl Options {
backup_suffix: matches.value_of(OPT_SUFFIX).unwrap().to_string(), backup_suffix: matches.value_of(OPT_SUFFIX).unwrap().to_string(),
update: matches.is_present(OPT_UPDATE), update: matches.is_present(OPT_UPDATE),
verbose: matches.is_present(OPT_VERBOSE), verbose: matches.is_present(OPT_VERBOSE),
strip_trailing_slashes: matches.is_present(OPT_STRIP_TRAILING_SLASHES),
reflink: matches.is_present(OPT_REFLINK), reflink: matches.is_present(OPT_REFLINK),
reflink_mode: { reflink_mode: {
if let Some(reflink) = matches.value_of(OPT_REFLINK) { if let Some(reflink) = matches.value_of(OPT_REFLINK) {
@ -686,7 +687,7 @@ fn parse_path_args(path_args: &[String], options: &Options) -> CopyResult<(Vec<S
return Err(format!("extra operand {:?}", paths[2]).into()); return Err(format!("extra operand {:?}", paths[2]).into());
} }
let (sources, target) = match options.target_dir { let (mut sources, target) = match options.target_dir {
Some(ref target) => { Some(ref target) => {
// All path args are sources, and the target dir was // All path args are sources, and the target dir was
// specified separately // specified separately
@ -700,6 +701,12 @@ fn parse_path_args(path_args: &[String], options: &Options) -> CopyResult<(Vec<S
} }
}; };
if options.strip_trailing_slashes {
for source in sources.iter_mut() {
*source = source.components().as_path().to_owned()
}
}
Ok((sources, target)) Ok((sources, target))
} }

View file

@ -479,6 +479,24 @@ fn test_cp_no_deref() {
assert_eq!(at.read(&path_to_check), "Hello, World!\n"); assert_eq!(at.read(&path_to_check), "Hello, World!\n");
} }
#[test]
fn test_cp_strip_trailing_slashes() {
let (at, mut ucmd) = at_and_ucmd!();
//using --strip-trailing-slashes option
let result = ucmd
.arg("--strip-trailing-slashes")
.arg(format!("{}/", TEST_HELLO_WORLD_SOURCE))
.arg(TEST_HELLO_WORLD_DEST)
.run();
// Check that the exit code represents a successful copy.
assert!(result.success);
// Check the content of the destination file that was copied.
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}
#[test] #[test]
// For now, disable the test on Windows. Symlinks aren't well support on Windows. // For now, disable the test on Windows. Symlinks aren't well support on Windows.
// It works on Unix for now and it works locally when run from a powershell // It works on Unix for now and it works locally when run from a powershell