mirror of
https://github.com/uutils/coreutils.git
synced 2025-12-23 08:47:37 +00:00
cp: display symlink creation with --verbose
cp: display removed files with --verbose
This commit is contained in:
parent
e2e5c76a7c
commit
37d00ae89b
5 changed files with 83 additions and 21 deletions
|
|
@ -108,6 +108,7 @@ cp-warning-source-specified-more-than-once = source { $file_type } { $source } s
|
|||
# Verbose and debug messages
|
||||
cp-verbose-copied = { $source } -> { $dest }
|
||||
cp-debug-skipped = skipped { $path }
|
||||
cp-verbose-removed = removed { $path }
|
||||
cp-verbose-created-directory = { $source } -> { $dest }
|
||||
cp-debug-copy-offload = copy offload: { $offload }, reflink: { $reflink }, sparse detection: { $sparse }
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ cp-warning-source-specified-more-than-once = { $file_type } source { $source } s
|
|||
# Messages verbeux et de débogage
|
||||
cp-verbose-copied = { $source } -> { $dest }
|
||||
cp-debug-skipped = { $path } ignoré
|
||||
cp-verbose-removed = removed { $path }
|
||||
cp-verbose-created-directory = { $source } -> { $dest }
|
||||
cp-debug-copy-offload = copy offload : { $offload }, reflink : { $reflink }, sparse detection : { $sparse }
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ use walkdir::{DirEntry, WalkDir};
|
|||
|
||||
use crate::{
|
||||
CopyResult, CpError, Options, aligned_ancestors, context_for, copy_attributes, copy_file,
|
||||
copy_link,
|
||||
};
|
||||
|
||||
/// Ensure a Windows path starts with a `\\?`.
|
||||
|
|
@ -259,17 +258,6 @@ fn copy_direntry(
|
|||
entry_is_dir_no_follow
|
||||
};
|
||||
|
||||
// If the source is a symbolic link and the options tell us not to
|
||||
// dereference the link, then copy the link object itself.
|
||||
if source_is_symlink && !options.dereference {
|
||||
return copy_link(
|
||||
&entry.source_absolute,
|
||||
&entry.local_to_target,
|
||||
symlinked_files,
|
||||
options,
|
||||
);
|
||||
}
|
||||
|
||||
// If the source is a directory and the destination does not
|
||||
// exist, ...
|
||||
if source_is_dir && !entry.local_to_target.exists() {
|
||||
|
|
|
|||
|
|
@ -1937,7 +1937,6 @@ fn delete_dest_if_needed_and_allowed(
|
|||
let delete_dest = match options.overwrite {
|
||||
OverwriteMode::Clobber(cl) | OverwriteMode::Interactive(cl) => {
|
||||
match cl {
|
||||
// FIXME: print that the file was removed if --verbose is enabled
|
||||
ClobberMode::Force => {
|
||||
// TODO
|
||||
// Using `readonly` here to check if `dest` needs to be deleted is not correct:
|
||||
|
|
@ -1976,13 +1975,26 @@ fn delete_dest_if_needed_and_allowed(
|
|||
};
|
||||
|
||||
if delete_dest {
|
||||
match fs::remove_file(dest) {
|
||||
Ok(()) => {}
|
||||
Err(err) if err.kind() == io::ErrorKind::NotFound => {
|
||||
// target could have been deleted earlier (e.g. same-file with --remove-destination)
|
||||
delete_path(dest, options)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn delete_path(path: &Path, options: &Options) -> CopyResult<()> {
|
||||
match fs::remove_file(path) {
|
||||
Ok(()) => {
|
||||
if options.verbose {
|
||||
println!(
|
||||
"{}",
|
||||
translate!("cp-verbose-removed", "path" => path.quote())
|
||||
);
|
||||
}
|
||||
Err(err) => return Err(err.into()),
|
||||
}
|
||||
Err(err) if err.kind() == io::ErrorKind::NotFound => {
|
||||
// target could have been deleted earlier (e.g. same-file with --remove-destination)
|
||||
}
|
||||
Err(err) => return Err(err.into()),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
@ -2666,7 +2678,7 @@ fn copy_link(
|
|||
// we always need to remove the file to be able to create a symlink,
|
||||
// even if it is writeable.
|
||||
if dest.is_symlink() || dest.is_file() {
|
||||
fs::remove_file(dest)?;
|
||||
delete_path(dest, options)?;
|
||||
}
|
||||
symlink_file(&link, dest, symlinked_files)?;
|
||||
copy_attributes(source, dest, &options.attributes)
|
||||
|
|
|
|||
|
|
@ -385,7 +385,6 @@ fn test_cp_arg_no_target_directory_with_recursive() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "disabled until https://github.com/uutils/coreutils/issues/7455 is fixed"]
|
||||
fn test_cp_arg_no_target_directory_with_recursive_target_does_not_exists() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
|
|
@ -768,7 +767,7 @@ fn test_cp_f_i_verbose_non_writeable_destination_y() {
|
|||
.pipe_in("y")
|
||||
.succeeds()
|
||||
.stderr_is("cp: replace 'b', overriding mode 0000 (---------)? ")
|
||||
.stdout_is("'a' -> 'b'\n");
|
||||
.stdout_is("removed 'b'\n'a' -> 'b'\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -7167,3 +7166,64 @@ fn test_cp_recurse_verbose_output() {
|
|||
.no_stderr()
|
||||
.stdout_is(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_recurse_verbose_output_with_symlink() {
|
||||
let source_dir = "source_dir";
|
||||
let target_dir = "target_dir";
|
||||
let file = "file";
|
||||
let symlink = "symlink";
|
||||
#[cfg(not(windows))]
|
||||
let output = format!(
|
||||
"'{source_dir}' -> '{target_dir}/'\n'{source_dir}/{symlink}' -> '{target_dir}/{symlink}'\n"
|
||||
);
|
||||
#[cfg(windows)]
|
||||
let output = format!(
|
||||
"'{source_dir}' -> '{target_dir}\\'\n'{source_dir}\\{symlink}' -> '{target_dir}\\{symlink}'\n"
|
||||
);
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
at.mkdir(source_dir);
|
||||
at.touch(file);
|
||||
at.symlink_file(file, format!("{source_dir}/{symlink}").as_str());
|
||||
|
||||
ucmd.arg(source_dir)
|
||||
.arg(target_dir)
|
||||
.arg("-r")
|
||||
.arg("--verbose")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_is(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_recurse_verbose_output_with_symlink_already_exists() {
|
||||
let source_dir = "source_dir";
|
||||
let target_dir = "target_dir";
|
||||
let file = "file";
|
||||
let symlink = "symlink";
|
||||
#[cfg(not(windows))]
|
||||
let output = format!(
|
||||
"removed '{target_dir}/{symlink}'\n'{source_dir}/{symlink}' -> '{target_dir}/{symlink}'\n"
|
||||
);
|
||||
#[cfg(windows)]
|
||||
let output = format!(
|
||||
"removed '{target_dir}\\{symlink}'\n'{source_dir}\\{symlink}' -> '{target_dir}\\{symlink}'\n"
|
||||
);
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
at.mkdir(source_dir);
|
||||
at.touch(file);
|
||||
at.symlink_file(file, format!("{source_dir}/{symlink}").as_str());
|
||||
at.mkdir(target_dir);
|
||||
at.symlink_file(file, format!("{target_dir}/{symlink}").as_str());
|
||||
|
||||
ucmd.arg(source_dir)
|
||||
.arg(target_dir)
|
||||
.arg("-r")
|
||||
.arg("--verbose")
|
||||
.arg("-T")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_is(output);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue