@@ -21,6 +21,7 @@ use clap::{App, Arg, ArgMatches};
2121use rayon:: prelude:: * ;
2222use serde:: { Deserialize , Serialize } ;
2323use serde_json:: Value ;
24+ use walkdir:: { DirEntry , WalkDir } ;
2425
2526#[ cfg( not( windows) ) ]
2627const CLIPPY_DRIVER_PATH : & str = "target/debug/clippy-driver" ;
@@ -193,32 +194,41 @@ impl CrateSource {
193194 }
194195 } ,
195196 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+ }
200205
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) ;
203207
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+ }
212213
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+ }
216226 }
217227
218228 Crate {
219229 version : String :: from ( "local" ) ,
220230 name : name. clone ( ) ,
221- path : crate_root ,
231+ path : dest_crate_root ,
222232 options : options. clone ( ) ,
223233 }
224234 } ,
0 commit comments