Fixes #4671.
format!("failed to remove: {}", dst.display())
})?;
}
- fs::hard_link(src, dst)
- .or_else(|err| {
- debug!("hard link failed {}. falling back to fs::copy", err);
- fs::copy(src, dst).map(|_| ())
- })
- .chain_err(|| {
+
+ let link_result = if src.is_dir() {
+ #[cfg(unix)]
+ use std::os::unix::fs::symlink;
+ #[cfg(target_os = "redox")]
+ use std::os::redox::fs::symlink;
+ #[cfg(windows)]
+ use std::os::windows::fs::symlink_dir as symlink;
+
+ symlink(src, dst)
+ } else {
+ fs::hard_link(src, dst)
+ };
+ link_result
+ .or_else(|err| {
+ debug!("link failed {}. falling back to fs::copy", err);
+ fs::copy(src, dst).map(|_| ())
+ })
+ .chain_err(|| {
format!("failed to link or copy `{}` to `{}`",
src.display(), dst.display())
- })?;
+ })?;
}
if json_messages {
);
assert_that(&p.bin("foo.dSYM"), existing_dir());
assert_that(&p.bin("b.dSYM"), existing_dir());
+ assert!(
+ p.bin("b.dSYM")
+ .symlink_metadata()
+ .expect("read metadata from b.dSYM")
+ .file_type()
+ .is_symlink()
+ );
assert_that(&p.bin("c.dSYM"), is_not(existing_dir()));
assert_that(&p.bin("d.dSYM"), is_not(existing_dir()));
}
}
for file in t!(fs::read_dir(self)) {
- let file = t!(file).path();
-
- if file.is_dir() {
- file.rm_rf();
+ let file = t!(file);
+ if file.file_type().map(|m| m.is_dir()).unwrap_or(false) {
+ file.path().rm_rf();
} else {
// On windows we can't remove a readonly file, and git will
// often clone files as readonly. As a result, we have some
// special logic to remove readonly files on windows.
- do_op(&file, "remove file", |p| fs::remove_file(p));
+ do_op(&file.path(), "remove file", |p| fs::remove_file(p));
}
}
do_op(self, "remove dir", |p| fs::remove_dir(p));