@@ -48,7 +48,7 @@ fn copy_dir(src: &Path, dest: &Path) -> Result<(), Error> {
48
48
let dest = crate :: utils:: normalize_path ( dest) ;
49
49
50
50
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 ( ) ;
52
52
while let Some ( entry) = entries. next ( ) {
53
53
let entry = entry?;
54
54
@@ -112,7 +112,51 @@ mod tests {
112
112
println ! ( "copied" ) ;
113
113
114
114
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) ?;
115
157
158
+ println ! ( "{} should cause copy to fail" , bad_link. display( ) ) ;
159
+ assert_copy_err_has_filename ( ) ;
116
160
Ok ( ( ) )
117
161
}
118
162
}
0 commit comments