use std::ffi::OsStr;
use std::fs;
use std::lazy::SyncLazy;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
use walkdir::WalkDir;
use crate::clippy_project_root;
None => env::current_dir().unwrap().join("target"),
});
-pub fn bless() {
+static CLIPPY_BUILD_TIME: SyncLazy<Option<std::time::SystemTime>> = SyncLazy::new(|| {
+ let profile = env::var("PROFILE").unwrap_or_else(|_| "debug".to_string());
+ let mut path = PathBuf::from(&**CARGO_TARGET_DIR);
+ path.push(profile);
+ path.push("cargo-clippy");
+ fs::metadata(path).ok()?.modified().ok()
+});
+
+pub fn bless(ignore_timestamp: bool) {
let test_suite_dirs = [
clippy_project_root().join("tests").join("ui"),
clippy_project_root().join("tests").join("ui-toml"),
.filter(|f| f.path().extension() == Some(OsStr::new("rs")))
.for_each(|f| {
let test_name = f.path().strip_prefix(test_suite_dir).unwrap();
-
- update_reference_file(f.path().with_extension("stdout"), test_name.with_extension("stdout"));
- update_reference_file(f.path().with_extension("stderr"), test_name.with_extension("stderr"));
- update_reference_file(f.path().with_extension("fixed"), test_name.with_extension("fixed"));
+ for &ext in &["stdout", "stderr", "fixed"] {
+ update_reference_file(
+ f.path().with_extension(ext),
+ test_name.with_extension(ext),
+ ignore_timestamp,
+ );
+ }
});
}
}
-fn update_reference_file(reference_file_path: PathBuf, test_name: PathBuf) {
+fn update_reference_file(reference_file_path: PathBuf, test_name: PathBuf, ignore_timestamp: bool) {
let test_output_path = build_dir().join(test_name);
let relative_reference_file_path = reference_file_path.strip_prefix(clippy_project_root()).unwrap();
return;
}
+ // If the test output was not updated since the last clippy build, it may be outdated
+ if !ignore_timestamp && !updated_since_clippy_build(&test_output_path).unwrap_or(true) {
+ return;
+ }
+
let test_output_file = fs::read(&test_output_path).expect("Unable to read test output file");
let reference_file = fs::read(&reference_file_path).unwrap_or_default();
}
}
+fn updated_since_clippy_build(path: &Path) -> Option<bool> {
+ let clippy_build_time = (*CLIPPY_BUILD_TIME)?;
+ let modified = fs::metadata(path).ok()?.modified().ok()?;
+ Some(modified >= clippy_build_time)
+}
+
fn build_dir() -> PathBuf {
let profile = env::var("PROFILE").unwrap_or_else(|_| "debug".to_string());
let mut path = PathBuf::new();
let matches = get_clap_config();
match matches.subcommand() {
- ("bless", Some(_)) => {
- bless::bless();
+ ("bless", Some(matches)) => {
+ bless::bless(matches.is_present("ignore-timestamp"));
},
("fmt", Some(matches)) => {
fmt::run(matches.is_present("check"), matches.is_present("verbose"));
fn get_clap_config<'a>() -> ArgMatches<'a> {
App::new("Clippy developer tooling")
- .subcommand(SubCommand::with_name("bless").about("bless the test output changes"))
+ .subcommand(
+ SubCommand::with_name("bless")
+ .about("bless the test output changes")
+ .arg(
+ Arg::with_name("ignore-timestamp")
+ .long("ignore-timestamp")
+ .help("Include files updated before clippy was built"),
+ ),
+ )
.subcommand(
SubCommand::with_name("fmt")
.about("Run rustfmt on all projects and tests")