Skip to content

Commit 232233c

Browse files
committed
make it pass on windows
1 parent e2862a6 commit 232233c

File tree

1 file changed

+105
-57
lines changed

1 file changed

+105
-57
lines changed

src/uu/mv/src/mv.rs

Lines changed: 105 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -689,8 +689,10 @@ fn rename(
689689
to: &Path,
690690
opts: &Options,
691691
multi_progress: Option<&MultiProgress>,
692-
hardlink_tracker: Option<&mut HardlinkTracker>,
693-
hardlink_scanner: Option<&HardlinkGroupScanner>,
692+
#[cfg(unix)] hardlink_tracker: Option<&mut HardlinkTracker>,
693+
#[cfg(unix)] hardlink_scanner: Option<&HardlinkGroupScanner>,
694+
#[cfg(not(unix))] _hardlink_tracker: Option<()>,
695+
#[cfg(not(unix))] _hardlink_scanner: Option<()>,
694696
) -> io::Result<()> {
695697
let mut backup_path = None;
696698

@@ -770,7 +772,14 @@ fn rename(
770772
}
771773
}
772774

773-
rename_with_fallback(from, to, multi_progress, hardlink_tracker, hardlink_scanner)?;
775+
#[cfg(unix)]
776+
{
777+
rename_with_fallback(from, to, multi_progress, hardlink_tracker, hardlink_scanner)?;
778+
}
779+
#[cfg(not(unix))]
780+
{
781+
rename_with_fallback(from, to, multi_progress, None, None)?;
782+
}
774783

775784
if opts.verbose {
776785
let message = match backup_path {
@@ -817,8 +826,10 @@ fn rename_with_fallback(
817826
from: &Path,
818827
to: &Path,
819828
multi_progress: Option<&MultiProgress>,
820-
hardlink_tracker: Option<&mut HardlinkTracker>,
821-
hardlink_scanner: Option<&HardlinkGroupScanner>,
829+
#[cfg(unix)] hardlink_tracker: Option<&mut HardlinkTracker>,
830+
#[cfg(unix)] hardlink_scanner: Option<&HardlinkGroupScanner>,
831+
#[cfg(not(unix))] _hardlink_tracker: Option<()>,
832+
#[cfg(not(unix))] _hardlink_scanner: Option<()>,
822833
) -> io::Result<()> {
823834
fs::rename(from, to).or_else(|err| {
824835
#[cfg(windows)]
@@ -841,21 +852,35 @@ fn rename_with_fallback(
841852
if file_type.is_symlink() {
842853
rename_symlink_fallback(from, to)
843854
} else if file_type.is_dir() {
844-
with_optional_hardlink_context(
845-
hardlink_tracker,
846-
hardlink_scanner,
847-
|tracker, scanner| {
848-
rename_dir_fallback_with_hardlinks(from, to, multi_progress, tracker, scanner)
849-
},
850-
)
855+
#[cfg(unix)]
856+
{
857+
with_optional_hardlink_context(
858+
hardlink_tracker,
859+
hardlink_scanner,
860+
|tracker, scanner| {
861+
rename_dir_fallback(from, to, multi_progress, Some(tracker), Some(scanner))
862+
},
863+
)
864+
}
865+
#[cfg(not(unix))]
866+
{
867+
rename_dir_fallback(from, to, multi_progress)
868+
}
851869
} else if is_fifo(file_type) {
852870
rename_fifo_fallback(from, to)
853871
} else {
854-
with_optional_hardlink_context(
855-
hardlink_tracker,
856-
hardlink_scanner,
857-
|tracker, scanner| rename_file_fallback(from, to, tracker, scanner),
858-
)
872+
#[cfg(unix)]
873+
{
874+
with_optional_hardlink_context(
875+
hardlink_tracker,
876+
hardlink_scanner,
877+
|tracker, scanner| rename_file_fallback(from, to, Some(tracker), Some(scanner)),
878+
)
879+
}
880+
#[cfg(not(unix))]
881+
{
882+
rename_file_fallback(from, to)
883+
}
859884
}
860885
})
861886
}
@@ -909,12 +934,12 @@ fn rename_symlink_fallback(from: &Path, to: &Path) -> io::Result<()> {
909934
))
910935
}
911936

912-
fn rename_dir_fallback_with_hardlinks(
937+
fn rename_dir_fallback(
913938
from: &Path,
914939
to: &Path,
915940
multi_progress: Option<&MultiProgress>,
916-
hardlink_tracker: &mut HardlinkTracker,
917-
hardlink_scanner: &HardlinkGroupScanner,
941+
#[cfg(unix)] hardlink_tracker: Option<&mut HardlinkTracker>,
942+
#[cfg(unix)] hardlink_scanner: Option<&HardlinkGroupScanner>,
918943
) -> io::Result<()> {
919944
// We remove the destination directory if it exists to match the
920945
// behavior of `fs::rename`. As far as I can tell, `fs_extra`'s
@@ -943,11 +968,13 @@ fn rename_dir_fallback_with_hardlinks(
943968
#[cfg(all(unix, not(any(target_os = "macos", target_os = "redox"))))]
944969
let xattrs = fsxattr::retrieve_xattrs(from).unwrap_or_else(|_| HashMap::new());
945970

946-
// Use custom directory copying that preserves hardlinks
947-
let result = copy_dir_with_hardlinks(
971+
// Use directory copying (with or without hardlink support)
972+
let result = copy_dir_contents(
948973
from,
949974
to,
975+
#[cfg(unix)]
950976
hardlink_tracker,
977+
#[cfg(unix)]
951978
hardlink_scanner,
952979
progress_bar.as_ref(),
953980
);
@@ -963,29 +990,37 @@ fn rename_dir_fallback_with_hardlinks(
963990
Ok(())
964991
}
965992

966-
/// Copy directory recursively while preserving hardlinks
967-
fn copy_dir_with_hardlinks(
993+
/// Copy directory recursively, optionally preserving hardlinks
994+
fn copy_dir_contents(
968995
from: &Path,
969996
to: &Path,
970-
hardlink_tracker: &mut HardlinkTracker,
971-
hardlink_scanner: &HardlinkGroupScanner,
997+
#[cfg(unix)] hardlink_tracker: Option<&mut HardlinkTracker>,
998+
#[cfg(unix)] hardlink_scanner: Option<&HardlinkGroupScanner>,
972999
progress_bar: Option<&ProgressBar>,
9731000
) -> io::Result<()> {
9741001
// Create the destination directory
9751002
fs::create_dir_all(to)?;
9761003

9771004
// Recursively copy contents
978-
copy_dir_contents_with_hardlinks(from, to, hardlink_tracker, hardlink_scanner, progress_bar)?;
1005+
#[cfg(unix)]
1006+
{
1007+
if let (Some(tracker), Some(scanner)) = (hardlink_tracker, hardlink_scanner) {
1008+
copy_dir_contents_recursive(from, to, tracker, scanner, progress_bar)?;
1009+
}
1010+
}
1011+
#[cfg(not(unix))]
1012+
{
1013+
copy_dir_contents_recursive(from, to, progress_bar)?;
1014+
}
9791015

9801016
Ok(())
9811017
}
9821018

983-
/// Recursively copy directory contents while preserving hardlinks
984-
fn copy_dir_contents_with_hardlinks(
1019+
fn copy_dir_contents_recursive(
9851020
from_dir: &Path,
9861021
to_dir: &Path,
987-
hardlink_tracker: &mut HardlinkTracker,
988-
hardlink_scanner: &HardlinkGroupScanner,
1022+
#[cfg(unix)] hardlink_tracker: &mut HardlinkTracker,
1023+
#[cfg(unix)] hardlink_scanner: &HardlinkGroupScanner,
9891024
progress_bar: Option<&ProgressBar>,
9901025
) -> io::Result<()> {
9911026
let entries = fs::read_dir(from_dir)?;
@@ -1003,16 +1038,30 @@ fn copy_dir_contents_with_hardlinks(
10031038
if from_path.is_dir() {
10041039
// Recursively copy subdirectory
10051040
fs::create_dir_all(&to_path)?;
1006-
copy_dir_contents_with_hardlinks(
1041+
copy_dir_contents_recursive(
10071042
&from_path,
10081043
&to_path,
1044+
#[cfg(unix)]
10091045
hardlink_tracker,
1046+
#[cfg(unix)]
10101047
hardlink_scanner,
10111048
progress_bar,
10121049
)?;
10131050
} else {
1014-
// Copy file, preserving hardlinks
1015-
copy_file_with_hardlinks(&from_path, &to_path, hardlink_tracker, hardlink_scanner)?;
1051+
// Copy file with or without hardlink support based on platform
1052+
#[cfg(unix)]
1053+
{
1054+
copy_file_with_hardlinks_helper(
1055+
&from_path,
1056+
&to_path,
1057+
hardlink_tracker,
1058+
hardlink_scanner,
1059+
)?;
1060+
}
1061+
#[cfg(not(unix))]
1062+
{
1063+
fs::copy(&from_path, &to_path)?;
1064+
}
10161065
}
10171066

10181067
if let Some(pb) = progress_bar {
@@ -1025,8 +1074,8 @@ fn copy_dir_contents_with_hardlinks(
10251074
Ok(())
10261075
}
10271076

1028-
/// Copy a single file, creating hardlinks if it's part of a hardlink group
1029-
fn copy_file_with_hardlinks(
1077+
#[cfg(unix)]
1078+
fn copy_file_with_hardlinks_helper(
10301079
from: &Path,
10311080
to: &Path,
10321081
hardlink_tracker: &mut HardlinkTracker,
@@ -1035,23 +1084,20 @@ fn copy_file_with_hardlinks(
10351084
// Check if this file should be a hardlink to an already-copied file
10361085
use crate::hardlink::HardlinkOptions;
10371086
let hardlink_options = HardlinkOptions::default();
1038-
#[cfg(unix)]
1087+
// Create a hardlink instead of copying
1088+
if let Some(existing_target) =
1089+
hardlink_tracker.check_hardlink(from, to, hardlink_scanner, &hardlink_options)?
10391090
{
1040-
// Create a hardlink instead of copying
1041-
if let Some(existing_target) =
1042-
hardlink_tracker.check_hardlink(from, to, hardlink_scanner, &hardlink_options)?
1043-
{
1044-
fs::hard_link(&existing_target, to)?;
1045-
return Ok(());
1046-
}
1091+
fs::hard_link(&existing_target, to)?;
1092+
return Ok(());
10471093
}
10481094

10491095
// Regular file copy
10501096
#[cfg(all(unix, not(any(target_os = "macos", target_os = "redox"))))]
10511097
{
10521098
fs::copy(from, to).and_then(|_| fsxattr::copy_xattrs(&from, &to))?;
10531099
}
1054-
#[cfg(any(target_os = "macos", target_os = "redox", not(unix)))]
1100+
#[cfg(any(target_os = "macos", target_os = "redox"))]
10551101
{
10561102
fs::copy(from, to)?;
10571103
}
@@ -1062,8 +1108,8 @@ fn copy_file_with_hardlinks(
10621108
fn rename_file_fallback(
10631109
from: &Path,
10641110
to: &Path,
1065-
hardlink_tracker: &mut HardlinkTracker,
1066-
hardlink_scanner: &HardlinkGroupScanner,
1111+
#[cfg(unix)] hardlink_tracker: Option<&mut HardlinkTracker>,
1112+
#[cfg(unix)] hardlink_scanner: Option<&HardlinkGroupScanner>,
10671113
) -> io::Result<()> {
10681114
// Remove existing target file if it exists
10691115
if to.is_symlink() {
@@ -1084,17 +1130,19 @@ fn rename_file_fallback(
10841130
}
10851131

10861132
// Check if this file is part of a hardlink group and if so, create a hardlink instead of copying
1087-
use crate::hardlink::HardlinkOptions;
1088-
let hardlink_options = HardlinkOptions::default();
1089-
if let Some(existing_target) =
1090-
hardlink_tracker.check_hardlink(from, to, hardlink_scanner, &hardlink_options)?
1133+
#[cfg(unix)]
10911134
{
1092-
// Create a hardlink to the first moved file instead of copying
1093-
#[cfg(unix)]
1094-
{
1095-
fs::hard_link(&existing_target, to)?;
1096-
fs::remove_file(from)?;
1097-
return Ok(());
1135+
if let (Some(tracker), Some(scanner)) = (hardlink_tracker, hardlink_scanner) {
1136+
use crate::hardlink::HardlinkOptions;
1137+
let hardlink_options = HardlinkOptions::default();
1138+
if let Some(existing_target) =
1139+
tracker.check_hardlink(from, to, scanner, &hardlink_options)?
1140+
{
1141+
// Create a hardlink to the first moved file instead of copying
1142+
fs::hard_link(&existing_target, to)?;
1143+
fs::remove_file(from)?;
1144+
return Ok(());
1145+
}
10981146
}
10991147
}
11001148

0 commit comments

Comments
 (0)