1 //! `bless` updates the reference files in the repo with changed output files
2 //! from the last test run.
7 use std::lazy::SyncLazy;
8 use std::path::PathBuf;
11 use crate::clippy_project_root;
13 // NOTE: this is duplicated with tests/cargo/mod.rs What to do?
14 pub static CARGO_TARGET_DIR: SyncLazy<PathBuf> = SyncLazy::new(|| match env::var_os("CARGO_TARGET_DIR") {
16 None => env::current_dir().unwrap().join("target"),
21 clippy_project_root().join("tests").join("ui"),
22 clippy_project_root().join("tests").join("ui-toml"),
23 clippy_project_root().join("tests").join("ui-cargo"),
25 for test_dir in &test_dirs {
26 WalkDir::new(test_dir)
28 .filter_map(Result::ok)
29 .filter(|f| f.path().extension() == Some(OsStr::new("rs")))
31 update_reference_file(f.path().with_extension("stdout"));
32 update_reference_file(f.path().with_extension("stderr"));
33 update_reference_file(f.path().with_extension("fixed"));
38 fn update_reference_file(reference_file_path: PathBuf) {
39 let test_output_path = build_dir().join(PathBuf::from(reference_file_path.file_name().unwrap()));
40 let relative_reference_file_path = reference_file_path.strip_prefix(clippy_project_root()).unwrap();
42 // If compiletest did not write any changes during the test run,
43 // we don't have to update anything
44 if !test_output_path.exists() {
48 let test_output_file = fs::read(&test_output_path).expect("Unable to read test output file");
49 let reference_file = fs::read(&reference_file_path).unwrap_or_default();
51 if test_output_file != reference_file {
52 // If a test run caused an output file to change, update the reference file
53 println!("updating {}", &relative_reference_file_path.display());
54 fs::copy(test_output_path, &reference_file_path).expect("Could not update reference file");
56 // We need to re-read the file now because it was potentially updated from copying
57 let reference_file = fs::read(&reference_file_path).unwrap_or_default();
59 if reference_file.is_empty() {
60 // If we copied over an empty output file, we remove the now empty reference file
61 println!("removing {}", &relative_reference_file_path.display());
62 fs::remove_file(reference_file_path).expect("Could not remove reference file");
67 fn build_dir() -> PathBuf {
68 let profile = env::var("PROFILE").unwrap_or_else(|_| "debug".to_string());
69 let mut path = PathBuf::new();
70 path.push(CARGO_TARGET_DIR.clone());
72 path.push("test_build_base");