@@ -21,6 +21,7 @@ use clap::{App, Arg, ArgMatches};
21
21
use rayon:: prelude:: * ;
22
22
use serde:: { Deserialize , Serialize } ;
23
23
use serde_json:: Value ;
24
+ use walkdir:: { DirEntry , WalkDir } ;
24
25
25
26
#[ cfg( not( windows) ) ]
26
27
const CLIPPY_DRIVER_PATH : & str = "target/debug/clippy-driver" ;
@@ -193,32 +194,41 @@ impl CrateSource {
193
194
}
194
195
} ,
195
196
CrateSource :: Path { name, path, options } => {
196
- use fs_extra:: dir;
197
-
198
- // simply copy the entire directory into our target dir
199
- let copy_dest = PathBuf :: from ( format ! ( "{}/" , LINTCHECK_SOURCES ) ) ;
197
+ // copy path into the dest_crate_root but skip directories that contain a CACHEDIR.TAG file.
198
+ // The target/ directory contains a CACHEDIR.TAG file so it is the most commonly skipped directory
199
+ // as a result of this filter.
200
+ let dest_crate_root = PathBuf :: from ( LINTCHECK_SOURCES ) . join ( name) ;
201
+ if dest_crate_root. exists ( ) {
202
+ println ! ( "Deleting existing directory at {:?}" , dest_crate_root) ;
203
+ std:: fs:: remove_dir_all ( & dest_crate_root) . unwrap ( ) ;
204
+ }
200
205
201
- // the source path of the crate we copied, ${copy_dest}/crate_name
202
- let crate_root = copy_dest. join ( name) ; // .../crates/local_crate
206
+ println ! ( "Copying {:?} to {:?}" , path, dest_crate_root) ;
203
207
204
- if crate_root. exists ( ) {
205
- println ! (
206
- "Not copying {} to {}, destination already exists" ,
207
- path. display( ) ,
208
- crate_root. display( )
209
- ) ;
210
- } else {
211
- println ! ( "Copying {} to {}" , path. display( ) , copy_dest. display( ) ) ;
208
+ fn is_cache_dir ( entry : & DirEntry ) -> bool {
209
+ std:: fs:: read ( entry. path ( ) . join ( "CACHEDIR.TAG" ) )
210
+ . map ( |x| x. starts_with ( b"Signature: 8a477f597d28d172789f06886806bc55" ) )
211
+ . unwrap_or ( false )
212
+ }
212
213
213
- dir:: copy ( path, & copy_dest, & dir:: CopyOptions :: new ( ) ) . unwrap_or_else ( |_| {
214
- panic ! ( "Failed to copy from {}, to {}" , path. display( ) , crate_root. display( ) )
215
- } ) ;
214
+ for entry in WalkDir :: new ( path) . into_iter ( ) . filter_entry ( |e| !is_cache_dir ( e) ) {
215
+ let entry = entry. unwrap ( ) ;
216
+ let entry_path = entry. path ( ) ;
217
+ let relative_entry_path = entry_path. strip_prefix ( path) . unwrap ( ) ;
218
+ let dest_path = dest_crate_root. join ( relative_entry_path) ;
219
+ let metadata = entry_path. symlink_metadata ( ) . unwrap ( ) ;
220
+
221
+ if metadata. is_dir ( ) {
222
+ std:: fs:: create_dir ( dest_path) . unwrap ( ) ;
223
+ } else if metadata. is_file ( ) {
224
+ std:: fs:: copy ( entry_path, dest_path) . unwrap ( ) ;
225
+ }
216
226
}
217
227
218
228
Crate {
219
229
version : String :: from ( "local" ) ,
220
230
name : name. clone ( ) ,
221
- path : crate_root ,
231
+ path : dest_crate_root ,
222
232
options : options. clone ( ) ,
223
233
}
224
234
} ,
0 commit comments