1 //! `bless` updates the reference files in the repo with changed output files
2 //! from the last test run.
6 use std::lazy::SyncLazy;
7 use std::path::{Path, PathBuf};
8 use walkdir::{DirEntry, WalkDir};
11 static CARGO_CLIPPY_EXE: &str = "cargo-clippy";
13 static CARGO_CLIPPY_EXE: &str = "cargo-clippy.exe";
15 static CLIPPY_BUILD_TIME: SyncLazy<Option<std::time::SystemTime>> = SyncLazy::new(|| {
16 let mut path = std::env::current_exe().unwrap();
17 path.set_file_name(CARGO_CLIPPY_EXE);
18 fs::metadata(path).ok()?.modified().ok()
23 /// Panics if the path to a test file is broken
24 pub fn bless(ignore_timestamp: bool) {
25 let extensions = ["stdout", "stderr", "fixed"].map(OsStr::new);
27 WalkDir::new(build_dir())
30 .filter(|entry| entry.path().extension().map_or(false, |ext| extensions.contains(&ext)))
31 .for_each(|entry| update_reference_file(&entry, ignore_timestamp));
34 fn update_reference_file(test_output_entry: &DirEntry, ignore_timestamp: bool) {
35 let test_output_path = test_output_entry.path();
37 let reference_file_name = test_output_entry.file_name().to_str().unwrap().replace(".stage-id", "");
38 let reference_file_path = Path::new("tests")
39 .join(test_output_path.strip_prefix(build_dir()).unwrap())
40 .with_file_name(reference_file_name);
42 // If the test output was not updated since the last clippy build, it may be outdated
43 if !ignore_timestamp && !updated_since_clippy_build(test_output_entry).unwrap_or(true) {
47 let test_output_file = fs::read(&test_output_path).expect("Unable to read test output file");
48 let reference_file = fs::read(&reference_file_path).unwrap_or_default();
50 if test_output_file != reference_file {
51 // If a test run caused an output file to change, update the reference file
52 println!("updating {}", reference_file_path.display());
53 fs::copy(test_output_path, &reference_file_path).expect("Could not update reference file");
57 fn updated_since_clippy_build(entry: &DirEntry) -> Option<bool> {
58 let clippy_build_time = (*CLIPPY_BUILD_TIME)?;
59 let modified = entry.metadata().ok()?.modified().ok()?;
60 Some(modified >= clippy_build_time)
63 fn build_dir() -> PathBuf {
64 let mut path = std::env::current_exe().unwrap();
65 path.set_file_name("test");