Auto merge of #7521 - rukai:fix_lintcheck_local_path_handling, r=camsteffen

lintcheck always copies in a fresh crate when provided with a crate path

changelog: none

When lintcheck is run on local crates it copies the crate to `target/lintcheck/sources/crate_name` on the first run only.
Then in subsequent runs of lintcheck it reuses this same copy.
This caching behaviour makes sense when dealing with immutable crates.io releases and git commits.
However it is quite surprising that the changes to my local crate are not used when I run lintcheck.

To fix this I removed the copy, instead clippy runs directly off the provided crate folder.
I have tested this and have not observed any negative effects from doing this.
But maybe i'm missing something as im not familiar with clippy!

Alternatively we could make it copy the entire crate every run, but that seems problematic to me as multi-gigabyte target folders will take a long time to copy and wear down SSDs for developers who frequently run lintcheck.
This commit is contained in:
bors 2021-08-16 00:20:31 +00:00
commit d4e2fcabb1
2 changed files with 28 additions and 17 deletions

View File

@ -19,6 +19,7 @@ serde_json = {version = "1.0"}
tar = {version = "0.4.30"} tar = {version = "0.4.30"}
toml = {version = "0.5"} toml = {version = "0.5"}
ureq = {version = "2.0.0-rc3"} ureq = {version = "2.0.0-rc3"}
walkdir = {version = "2.3.2"}
[features] [features]
deny-warnings = [] deny-warnings = []

View File

@ -21,6 +21,7 @@
use rayon::prelude::*; use rayon::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use walkdir::{DirEntry, WalkDir};
#[cfg(not(windows))] #[cfg(not(windows))]
const CLIPPY_DRIVER_PATH: &str = "target/debug/clippy-driver"; const CLIPPY_DRIVER_PATH: &str = "target/debug/clippy-driver";
@ -193,32 +194,41 @@ fn download_and_extract(&self) -> Crate {
} }
}, },
CrateSource::Path { name, path, options } => { CrateSource::Path { name, path, options } => {
use fs_extra::dir; // 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();
}
// simply copy the entire directory into our target dir println!("Copying {:?} to {:?}", path, dest_crate_root);
let copy_dest = PathBuf::from(format!("{}/", LINTCHECK_SOURCES));
// the source path of the crate we copied, ${copy_dest}/crate_name fn is_cache_dir(entry: &DirEntry) -> bool {
let crate_root = copy_dest.join(name); // .../crates/local_crate std::fs::read(entry.path().join("CACHEDIR.TAG"))
.map(|x| x.starts_with(b"Signature: 8a477f597d28d172789f06886806bc55"))
.unwrap_or(false)
}
if crate_root.exists() { for entry in WalkDir::new(path).into_iter().filter_entry(|e| !is_cache_dir(e)) {
println!( let entry = entry.unwrap();
"Not copying {} to {}, destination already exists", let entry_path = entry.path();
path.display(), let relative_entry_path = entry_path.strip_prefix(path).unwrap();
crate_root.display() let dest_path = dest_crate_root.join(relative_entry_path);
); let metadata = entry_path.symlink_metadata().unwrap();
} else {
println!("Copying {} to {}", path.display(), copy_dest.display());
dir::copy(path, &copy_dest, &dir::CopyOptions::new()).unwrap_or_else(|_| { if metadata.is_dir() {
panic!("Failed to copy from {}, to {}", path.display(), crate_root.display()) std::fs::create_dir(dest_path).unwrap();
}); } else if metadata.is_file() {
std::fs::copy(entry_path, dest_path).unwrap();
}
} }
Crate { Crate {
version: String::from("local"), version: String::from("local"),
name: name.clone(), name: name.clone(),
path: crate_root, path: dest_crate_root,
options: options.clone(), options: options.clone(),
} }
}, },