Skip to content

Commit b8a5140

Browse files
authored
Merge pull request #14 from jyn514/symlinks
Give a better error message for broken symbolic links
2 parents 5bf52e7 + 597e879 commit b8a5140

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
- The directory `target/` inside local crates won't be copied into the build
1111
anymore.
12+
- Symbolic links will be followed instead of copied as links.
13+
Better error messages will be given for broken symbolic links.
1214

1315
## [0.3.2] - 2019-10-08
1416

src/crates/local.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ fn copy_dir(src: &Path, dest: &Path) -> Result<(), Error> {
4848
let dest = crate::utils::normalize_path(dest);
4949

5050
let src_components = src.components().count();
51-
let mut entries = WalkDir::new(&src).into_iter();
51+
let mut entries = WalkDir::new(&src).follow_links(true).into_iter();
5252
while let Some(entry) = entries.next() {
5353
let entry = entry?;
5454

@@ -112,7 +112,51 @@ mod tests {
112112
println!("copied");
113113

114114
assert!(!dest.path().join("target").exists());
115+
Ok(())
116+
}
117+
118+
#[test]
119+
fn test_copy_symlinks() -> Result<(), Error> {
120+
use std::{fs, os, path::Path};
121+
122+
let tmp_src = tempfile::tempdir()?;
123+
let tmp_dest = tempfile::tempdir()?;
124+
let assert_copy_err_has_filename = || {
125+
match super::copy_dir(tmp_src.path(), tmp_dest.path()) {
126+
Ok(_) => panic!("copy with bad symbolic link did not fail"),
127+
Err(err) => assert!(err.downcast::<walkdir::Error>().unwrap().path().is_some()),
128+
};
129+
};
130+
131+
// Create some files in the src dir
132+
fs::create_dir(tmp_src.path().join("dir"))?;
133+
fs::write(tmp_src.path().join("foo"), b"Hello world")?;
134+
fs::write(tmp_src.path().join("dir").join("bar"), b"Rustwide")?;
135+
let bad_link = tmp_src.path().join("symlink");
136+
137+
// test link to non-existent file
138+
#[cfg(unix)]
139+
os::unix::fs::symlink(Path::new("/does_not_exist"), &bad_link)?;
140+
#[cfg(windows)]
141+
os::windows::fs::symlink_file(Path::new(r"C:\does_not_exist"), &bad_link)?;
142+
#[cfg(not(any(unix, windows)))]
143+
panic!("testing symbolic links not supported except on windows and linux");
144+
145+
println!("{} should cause copy to fail", bad_link.display());
146+
assert_copy_err_has_filename();
147+
148+
fs::remove_file(&bad_link)?;
149+
// make sure it works without that link
150+
super::copy_dir(tmp_src.path(), tmp_dest.path())?;
151+
152+
// test link to self
153+
#[cfg(unix)]
154+
os::unix::fs::symlink(&bad_link, &bad_link)?;
155+
#[cfg(windows)]
156+
os::windows::fs::symlink_file(&bad_link, &bad_link)?;
115157

158+
println!("{} should cause copy to fail", bad_link.display());
159+
assert_copy_err_has_filename();
116160
Ok(())
117161
}
118162
}

0 commit comments

Comments
 (0)