Skip to content

Commit 5e29870

Browse files
committed
Auto merge of #9707 - Alexendoo:file-depinfo, r=flip1995
Track `clippy.toml` and `Cargo.toml` in `file_depinfo` Causes cargo to re-run clippy when those paths are modified Also tracks the path to `clippy-driver` in debug mode to remove the workarounds in `cargo dev lint` and `lintcheck` (cc `@matthiaskrgr)` changelog: Automatically re-run Clippy if `Cargo.toml` or `clippy.toml` are modified Fixes #2130 Fixes #8512 r? `@flip1995`
2 parents 9a42501 + bd83690 commit 5e29870

File tree

6 files changed

+47
-59
lines changed

6 files changed

+47
-59
lines changed

clippy_dev/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ indoc = "1.0"
1010
itertools = "0.10.1"
1111
opener = "0.5"
1212
shell-escape = "0.1"
13-
tempfile = "3.2"
1413
walkdir = "2.3"
1514

1615
[features]

clippy_dev/src/lint.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,12 @@ pub fn run<'a>(path: &str, args: impl Iterator<Item = &'a String>) {
3636
} else {
3737
exit_if_err(Command::new("cargo").arg("build").status());
3838

39-
// Run in a tempdir as changes to clippy do not retrigger linting
40-
let target = tempfile::Builder::new()
41-
.prefix("clippy")
42-
.tempdir()
43-
.expect("failed to create tempdir");
44-
4539
let status = Command::new(cargo_clippy_path())
4640
.arg("clippy")
4741
.args(args)
4842
.current_dir(path)
49-
.env("CARGO_TARGET_DIR", target.as_ref())
5043
.status();
5144

52-
target.close().expect("failed to remove tempdir");
5345
exit_if_err(status);
5446
}
5547
}

clippy_lints/src/lib.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ extern crate clippy_utils;
4949
#[macro_use]
5050
extern crate declare_clippy_lint;
5151

52+
use std::io;
53+
use std::path::PathBuf;
54+
5255
use clippy_utils::parse_msrv;
5356
use rustc_data_structures::fx::FxHashSet;
5457
use rustc_lint::{Lint, LintId};
@@ -304,8 +307,8 @@ mod zero_div_zero;
304307
mod zero_sized_map_values;
305308
// end lints modules, do not remove this comment, it’s used in `update_lints`
306309

307-
pub use crate::utils::conf::Conf;
308310
use crate::utils::conf::{format_error, TryConf};
311+
pub use crate::utils::conf::{lookup_conf_file, Conf};
309312

310313
/// Register all pre expansion lints
311314
///
@@ -362,8 +365,8 @@ fn read_msrv(conf: &Conf, sess: &Session) -> Option<RustcVersion> {
362365
}
363366

364367
#[doc(hidden)]
365-
pub fn read_conf(sess: &Session) -> Conf {
366-
let file_name = match utils::conf::lookup_conf_file() {
368+
pub fn read_conf(sess: &Session, path: &io::Result<Option<PathBuf>>) -> Conf {
369+
let file_name = match path {
367370
Ok(Some(path)) => path,
368371
Ok(None) => return Conf::default(),
369372
Err(error) => {
@@ -373,7 +376,7 @@ pub fn read_conf(sess: &Session) -> Conf {
373376
},
374377
};
375378

376-
let TryConf { conf, errors, warnings } = utils::conf::read(&file_name);
379+
let TryConf { conf, errors, warnings } = utils::conf::read(file_name);
377380
// all conf errors are non-fatal, we just use the default conf in case of error
378381
for error in errors {
379382
sess.err(format!(

clippy_lints/src/utils/conf.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,10 @@ define_Conf! {
401401
}
402402

403403
/// Search for the configuration file.
404+
///
405+
/// # Errors
406+
///
407+
/// Returns any unexpected filesystem error encountered when searching for the config file
404408
pub fn lookup_conf_file() -> io::Result<Option<PathBuf>> {
405409
/// Possible filename to search for.
406410
const CONFIG_FILE_NAMES: [&str; 2] = [".clippy.toml", "clippy.toml"];

lintcheck/src/main.rs

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -544,34 +544,6 @@ fn gather_stats(clippy_warnings: &[ClippyWarning]) -> (String, HashMap<&String,
544544
(stats_string, counter)
545545
}
546546

547-
/// check if the latest modification of the logfile is older than the modification date of the
548-
/// clippy binary, if this is true, we should clean the lintchec shared target directory and recheck
549-
fn lintcheck_needs_rerun(lintcheck_logs_path: &Path, paths: [&Path; 2]) -> bool {
550-
if !lintcheck_logs_path.exists() {
551-
return true;
552-
}
553-
554-
let clippy_modified: std::time::SystemTime = {
555-
let [cargo, driver] = paths.map(|p| {
556-
std::fs::metadata(p)
557-
.expect("failed to get metadata of file")
558-
.modified()
559-
.expect("failed to get modification date")
560-
});
561-
// the oldest modification of either of the binaries
562-
std::cmp::max(cargo, driver)
563-
};
564-
565-
let logs_modified: std::time::SystemTime = std::fs::metadata(lintcheck_logs_path)
566-
.expect("failed to get metadata of file")
567-
.modified()
568-
.expect("failed to get modification date");
569-
570-
// time is represented in seconds since X
571-
// logs_modified 2 and clippy_modified 5 means clippy binary is older and we need to recheck
572-
logs_modified < clippy_modified
573-
}
574-
575547
#[allow(clippy::too_many_lines)]
576548
fn main() {
577549
// We're being executed as a `RUSTC_WRAPPER` as part of `--recursive`
@@ -594,23 +566,6 @@ fn main() {
594566
let cargo_clippy_path = fs::canonicalize(format!("target/debug/cargo-clippy{EXE_SUFFIX}")).unwrap();
595567
let clippy_driver_path = fs::canonicalize(format!("target/debug/clippy-driver{EXE_SUFFIX}")).unwrap();
596568

597-
// if the clippy bin is newer than our logs, throw away target dirs to force clippy to
598-
// refresh the logs
599-
if lintcheck_needs_rerun(
600-
&config.lintcheck_results_path,
601-
[&cargo_clippy_path, &clippy_driver_path],
602-
) {
603-
let shared_target_dir = "target/lintcheck/shared_target_dir";
604-
// if we get an Err here, the shared target dir probably does simply not exist
605-
if let Ok(metadata) = std::fs::metadata(shared_target_dir) {
606-
if metadata.is_dir() {
607-
println!("Clippy is newer than lint check logs, clearing lintcheck shared target dir...");
608-
std::fs::remove_dir_all(shared_target_dir)
609-
.expect("failed to remove target/lintcheck/shared_target_dir");
610-
}
611-
}
612-
}
613-
614569
// assert that clippy is found
615570
assert!(
616571
cargo_clippy_path.is_file(),

src/driver.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(rustc_private)]
2+
#![feature(let_chains)]
23
#![feature(once_cell)]
34
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
45
// warn on lints, that are included in `rust-lang/rust`s bootstrap
@@ -71,6 +72,32 @@ fn track_clippy_args(parse_sess: &mut ParseSess, args_env_var: &Option<String>)
7172
));
7273
}
7374

75+
/// Track files that may be accessed at runtime in `file_depinfo` so that cargo will re-run clippy
76+
/// when any of them are modified
77+
fn track_files(parse_sess: &mut ParseSess, conf_path_string: Option<String>) {
78+
let file_depinfo = parse_sess.file_depinfo.get_mut();
79+
80+
// Used by `clippy::cargo` lints and to determine the MSRV. `cargo clippy` executes `clippy-driver`
81+
// with the current directory set to `CARGO_MANIFEST_DIR` so a relative path is fine
82+
if Path::new("Cargo.toml").exists() {
83+
file_depinfo.insert(Symbol::intern("Cargo.toml"));
84+
}
85+
86+
// `clippy.toml`
87+
if let Some(path) = conf_path_string {
88+
file_depinfo.insert(Symbol::intern(&path));
89+
}
90+
91+
// During development track the `clippy-driver` executable so that cargo will re-run clippy whenever
92+
// it is rebuilt
93+
if cfg!(debug_assertions)
94+
&& let Ok(current_exe) = env::current_exe()
95+
&& let Some(current_exe) = current_exe.to_str()
96+
{
97+
file_depinfo.insert(Symbol::intern(current_exe));
98+
}
99+
}
100+
74101
struct DefaultCallbacks;
75102
impl rustc_driver::Callbacks for DefaultCallbacks {}
76103

@@ -97,10 +124,18 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
97124
// JUSTIFICATION: necessary in clippy driver to set `mir_opt_level`
98125
#[allow(rustc::bad_opt_access)]
99126
fn config(&mut self, config: &mut interface::Config) {
127+
let conf_path = clippy_lints::lookup_conf_file();
128+
let conf_path_string = if let Ok(Some(path)) = &conf_path {
129+
path.to_str().map(String::from)
130+
} else {
131+
None
132+
};
133+
100134
let previous = config.register_lints.take();
101135
let clippy_args_var = self.clippy_args_var.take();
102136
config.parse_sess_created = Some(Box::new(move |parse_sess| {
103137
track_clippy_args(parse_sess, &clippy_args_var);
138+
track_files(parse_sess, conf_path_string);
104139
}));
105140
config.register_lints = Some(Box::new(move |sess, lint_store| {
106141
// technically we're ~guaranteed that this is none but might as well call anything that
@@ -109,7 +144,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
109144
(previous)(sess, lint_store);
110145
}
111146

112-
let conf = clippy_lints::read_conf(sess);
147+
let conf = clippy_lints::read_conf(sess, &conf_path);
113148
clippy_lints::register_plugins(lint_store, sess, &conf);
114149
clippy_lints::register_pre_expansion_lints(lint_store, sess, &conf);
115150
clippy_lints::register_renamed(lint_store);

0 commit comments

Comments
 (0)