]> git.lizzy.rs Git - rust.git/blobdiff - src/tools/clippy/lintcheck/src/main.rs
Add 'library/portable-simd/' from commit '1ce1c645cf27c4acdefe6ec8a11d1f0491954a99'
[rust.git] / src / tools / clippy / lintcheck / src / main.rs
index 7d2f3173fb0e7cd4d5d475decac18787b14f60b0..97d3794fb84f0a951de6acd2e8a0e3eced02d357 100644 (file)
     env, fmt,
     fs::write,
     path::{Path, PathBuf},
+    thread,
+    time::Duration,
 };
 
 use clap::{App, Arg, ArgMatches};
 use rayon::prelude::*;
 use serde::{Deserialize, Serialize};
 use serde_json::Value;
+use walkdir::{DirEntry, WalkDir};
 
 #[cfg(not(windows))]
 const CLIPPY_DRIVER_PATH: &str = "target/debug/clippy-driver";
@@ -108,6 +111,22 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
+fn get(path: &str) -> Result<ureq::Response, ureq::Error> {
+    const MAX_RETRIES: u8 = 4;
+    let mut retries = 0;
+    loop {
+        match ureq::get(path).call() {
+            Ok(res) => return Ok(res),
+            Err(e) if retries >= MAX_RETRIES => return Err(e),
+            Err(ureq::Error::Transport(e)) => eprintln!("Error: {}", e),
+            Err(e) => return Err(e),
+        }
+        eprintln!("retrying in {} seconds...", retries);
+        thread::sleep(Duration::from_secs(retries as u64));
+        retries += 1;
+    }
+}
+
 impl CrateSource {
     /// Makes the sources available on the disk for clippy to check.
     /// Clones a git repo and checks out the specified commit or downloads a crate from crates.io or
@@ -128,7 +147,7 @@ fn download_and_extract(&self) -> Crate {
                 if !krate_file_path.is_file() {
                     // create a file path to download and write the crate data into
                     let mut krate_dest = std::fs::File::create(&krate_file_path).unwrap();
-                    let mut krate_req = ureq::get(&url).call().unwrap().into_reader();
+                    let mut krate_req = get(&url).unwrap().into_reader();
                     // copy the crate into the file
                     std::io::copy(&mut krate_req, &mut krate_dest).unwrap();
 
@@ -193,32 +212,41 @@ fn download_and_extract(&self) -> Crate {
                 }
             },
             CrateSource::Path { name, path, options } => {
-                use fs_extra::dir;
-
-                // simply copy the entire directory into our target dir
-                let copy_dest = PathBuf::from(format!("{}/", LINTCHECK_SOURCES));
+                // copy path into the dest_crate_root but skip directories that contain a CACHEDIR.TAG file.
+                // The target/ directory contains a CACHEDIR.TAG file so it is the most commonly skipped directory
+                // as a result of this filter.
+                let dest_crate_root = PathBuf::from(LINTCHECK_SOURCES).join(name);
+                if dest_crate_root.exists() {
+                    println!("Deleting existing directory at {:?}", dest_crate_root);
+                    std::fs::remove_dir_all(&dest_crate_root).unwrap();
+                }
 
-                // the source path of the crate we copied,  ${copy_dest}/crate_name
-                let crate_root = copy_dest.join(name); // .../crates/local_crate
+                println!("Copying {:?} to {:?}", path, dest_crate_root);
 
-                if crate_root.exists() {
-                    println!(
-                        "Not copying {} to {}, destination already exists",
-                        path.display(),
-                        crate_root.display()
-                    );
-                } else {
-                    println!("Copying {} to {}", path.display(), copy_dest.display());
+                fn is_cache_dir(entry: &DirEntry) -> bool {
+                    std::fs::read(entry.path().join("CACHEDIR.TAG"))
+                        .map(|x| x.starts_with(b"Signature: 8a477f597d28d172789f06886806bc55"))
+                        .unwrap_or(false)
+                }
 
-                    dir::copy(path, &copy_dest, &dir::CopyOptions::new()).unwrap_or_else(|_| {
-                        panic!("Failed to copy from {}, to  {}", path.display(), crate_root.display())
-                    });
+                for entry in WalkDir::new(path).into_iter().filter_entry(|e| !is_cache_dir(e)) {
+                    let entry = entry.unwrap();
+                    let entry_path = entry.path();
+                    let relative_entry_path = entry_path.strip_prefix(path).unwrap();
+                    let dest_path = dest_crate_root.join(relative_entry_path);
+                    let metadata = entry_path.symlink_metadata().unwrap();
+
+                    if metadata.is_dir() {
+                        std::fs::create_dir(dest_path).unwrap();
+                    } else if metadata.is_file() {
+                        std::fs::copy(entry_path, dest_path).unwrap();
+                    }
                 }
 
                 Crate {
                     version: String::from("local"),
                     name: name.clone(),
-                    path: crate_root,
+                    path: dest_crate_root,
                     options: options.clone(),
                 }
             },