mirror of
https://github.com/uutils/coreutils.git
synced 2025-12-23 08:47:37 +00:00
Merge pull request #8864 from Alonely0/fix_cp
cp: fix crash on -T/--no-preserve-target
This commit is contained in:
commit
daa828b270
2 changed files with 60 additions and 6 deletions
|
|
@ -9,8 +9,9 @@
|
|||
#[cfg(windows)]
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::convert::identity;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::fs::{self, exists};
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf, StripPrefixError};
|
||||
|
||||
|
|
@ -20,10 +21,9 @@ use uucore::error::UIoError;
|
|||
use uucore::fs::{
|
||||
FileInformation, MissingHandling, ResolveMode, canonicalize, path_ends_with_terminator,
|
||||
};
|
||||
use uucore::translate;
|
||||
|
||||
use uucore::show;
|
||||
use uucore::show_error;
|
||||
use uucore::translate;
|
||||
use uucore::uio_error;
|
||||
use walkdir::{DirEntry, WalkDir};
|
||||
|
||||
|
|
@ -194,15 +194,23 @@ impl Entry {
|
|||
get_local_to_root_parent(&source_absolute, context.root_parent.as_deref())?;
|
||||
if no_target_dir {
|
||||
let source_is_dir = source.is_dir();
|
||||
if path_ends_with_terminator(context.target) && source_is_dir {
|
||||
if path_ends_with_terminator(context.target)
|
||||
&& source_is_dir
|
||||
&& !exists(context.target).is_ok_and(identity)
|
||||
{
|
||||
if let Err(e) = fs::create_dir_all(context.target) {
|
||||
eprintln!(
|
||||
"{}",
|
||||
translate!("cp-error-failed-to-create-directory", "error" => e)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
descendant = descendant.strip_prefix(context.root)?.to_path_buf();
|
||||
} else if let Some(stripped) = context
|
||||
.root
|
||||
.components()
|
||||
.next_back()
|
||||
.and_then(|stripped| descendant.strip_prefix(stripped).ok())
|
||||
{
|
||||
descendant = stripped.to_path_buf();
|
||||
}
|
||||
} else if context.root == Path::new(".") && context.target.is_dir() {
|
||||
// Special case: when copying current directory (.) to an existing directory,
|
||||
|
|
|
|||
|
|
@ -7090,3 +7090,49 @@ fn test_cp_recursive_files_ending_in_backslash() {
|
|||
ts.ucmd().args(&["-r", "a", "b"]).succeeds();
|
||||
assert!(at.file_exists("b/foo\\"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_no_preserve_target_directory() {
|
||||
/* Expected result:
|
||||
├── a
|
||||
│ └── b
|
||||
│ └── c
|
||||
│ └── d
|
||||
│ └── f1
|
||||
├── d
|
||||
│ └── f1
|
||||
└── e
|
||||
├── b
|
||||
│ └── c
|
||||
│ └── d
|
||||
│ ├── c
|
||||
│ │ └── d
|
||||
│ │ └── f1
|
||||
│ └── f1
|
||||
├── d
|
||||
│ └── f1
|
||||
├── f2
|
||||
└── f3
|
||||
*/
|
||||
|
||||
let ts = TestScenario::new(util_name!());
|
||||
let at = &ts.fixtures;
|
||||
at.mkdir_all("a/b/c/d");
|
||||
at.touch("a/b/c/d/f1");
|
||||
ts.ucmd().args(&["-rT", "a", "e"]).succeeds();
|
||||
at.touch("e/f2");
|
||||
ts.ucmd().args(&["-rT", "a/", "e/"]).succeeds();
|
||||
at.touch("e/f3");
|
||||
ts.ucmd().args(&["-rvT", "a/b/c", "e/"]).succeeds();
|
||||
ts.ucmd().args(&["-rvT", "a/b/", "e/b/c/d/"]).succeeds();
|
||||
ts.ucmd().args(&["-rT", "a/b/c", "."]).succeeds();
|
||||
assert!(!at.dir_exists("e/a"));
|
||||
assert!(at.file_exists("e/b/c/d/f1"));
|
||||
assert!(at.file_exists("e/b/c/d/c/d/f1"));
|
||||
assert!(!at.dir_exists("e/c"));
|
||||
assert!(!at.dir_exists("e/c/d/b"));
|
||||
assert!(at.file_exists("e/d/f1"));
|
||||
assert!(at.file_exists("./d/f1"));
|
||||
assert!(at.file_exists("e/f2"));
|
||||
assert!(at.file_exists("e/f3"));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue