11//! `bless` updates the reference files in the repo with changed output files
22//! from the last test run.
33
4+ use crate :: cargo_clippy_path;
45use std:: ffi:: OsStr ;
56use std:: fs;
67use std:: lazy:: SyncLazy ;
78use std:: path:: { Path , PathBuf } ;
8- use walkdir:: WalkDir ;
9+ use walkdir:: { DirEntry , WalkDir } ;
910
10- use crate :: clippy_project_root;
11-
12- #[ cfg( not( windows) ) ]
13- static CARGO_CLIPPY_EXE : & str = "cargo-clippy" ;
14- #[ cfg( windows) ]
15- static CARGO_CLIPPY_EXE : & str = "cargo-clippy.exe" ;
16-
17- static CLIPPY_BUILD_TIME : SyncLazy < Option < std:: time:: SystemTime > > = SyncLazy :: new ( || {
18- let mut path = std:: env:: current_exe ( ) . unwrap ( ) ;
19- path. set_file_name ( CARGO_CLIPPY_EXE ) ;
20- fs:: metadata ( path) . ok ( ) ?. modified ( ) . ok ( )
21- } ) ;
11+ static CLIPPY_BUILD_TIME : SyncLazy < Option < std:: time:: SystemTime > > =
12+ SyncLazy :: new ( || cargo_clippy_path ( ) . metadata ( ) . ok ( ) ?. modified ( ) . ok ( ) ) ;
2213
2314/// # Panics
2415///
2516/// Panics if the path to a test file is broken
2617pub fn bless ( ignore_timestamp : bool ) {
27- let test_suite_dirs = [
28- clippy_project_root ( ) . join ( "tests" ) . join ( "ui" ) ,
29- clippy_project_root ( ) . join ( "tests" ) . join ( "ui-internal" ) ,
30- clippy_project_root ( ) . join ( "tests" ) . join ( "ui-toml" ) ,
31- clippy_project_root ( ) . join ( "tests" ) . join ( "ui-cargo" ) ,
32- ] ;
33- for test_suite_dir in & test_suite_dirs {
34- WalkDir :: new ( test_suite_dir)
35- . into_iter ( )
36- . filter_map ( Result :: ok)
37- . filter ( |f| f. path ( ) . extension ( ) == Some ( OsStr :: new ( "rs" ) ) )
38- . for_each ( |f| {
39- let test_name = f. path ( ) . strip_prefix ( test_suite_dir) . unwrap ( ) ;
40- for & ext in & [ "stdout" , "stderr" , "fixed" ] {
41- let test_name_ext = format ! ( "stage-id.{}" , ext) ;
42- update_reference_file (
43- f. path ( ) . with_extension ( ext) ,
44- test_name. with_extension ( test_name_ext) ,
45- ignore_timestamp,
46- ) ;
47- }
48- } ) ;
49- }
18+ let extensions = [ "stdout" , "stderr" , "fixed" ] . map ( OsStr :: new) ;
19+
20+ WalkDir :: new ( build_dir ( ) )
21+ . into_iter ( )
22+ . map ( Result :: unwrap)
23+ . filter ( |entry| entry. path ( ) . extension ( ) . map_or ( false , |ext| extensions. contains ( & ext) ) )
24+ . for_each ( |entry| update_reference_file ( & entry, ignore_timestamp) ) ;
5025}
5126
52- fn update_reference_file ( reference_file_path : PathBuf , test_name : PathBuf , ignore_timestamp : bool ) {
53- let test_output_path = build_dir ( ) . join ( test_name) ;
54- let relative_reference_file_path = reference_file_path. strip_prefix ( clippy_project_root ( ) ) . unwrap ( ) ;
27+ fn update_reference_file ( test_output_entry : & DirEntry , ignore_timestamp : bool ) {
28+ let test_output_path = test_output_entry. path ( ) ;
5529
56- // If compiletest did not write any changes during the test run,
57- // we don't have to update anything
58- if !test_output_path. exists ( ) {
59- return ;
60- }
30+ let reference_file_name = test_output_entry. file_name ( ) . to_str ( ) . unwrap ( ) . replace ( ".stage-id" , "" ) ;
31+ let reference_file_path = Path :: new ( "tests" )
32+ . join ( test_output_path. strip_prefix ( build_dir ( ) ) . unwrap ( ) )
33+ . with_file_name ( reference_file_name) ;
6134
6235 // If the test output was not updated since the last clippy build, it may be outdated
63- if !ignore_timestamp && !updated_since_clippy_build ( & test_output_path ) . unwrap_or ( true ) {
36+ if !ignore_timestamp && !updated_since_clippy_build ( test_output_entry ) . unwrap_or ( true ) {
6437 return ;
6538 }
6639
@@ -69,23 +42,14 @@ fn update_reference_file(reference_file_path: PathBuf, test_name: PathBuf, ignor
6942
7043 if test_output_file != reference_file {
7144 // If a test run caused an output file to change, update the reference file
72- println ! ( "updating {}" , & relative_reference_file_path . display( ) ) ;
45+ println ! ( "updating {}" , reference_file_path . display( ) ) ;
7346 fs:: copy ( test_output_path, & reference_file_path) . expect ( "Could not update reference file" ) ;
74-
75- // We need to re-read the file now because it was potentially updated from copying
76- let reference_file = fs:: read ( & reference_file_path) . unwrap_or_default ( ) ;
77-
78- if reference_file. is_empty ( ) {
79- // If we copied over an empty output file, we remove the now empty reference file
80- println ! ( "removing {}" , & relative_reference_file_path. display( ) ) ;
81- fs:: remove_file ( reference_file_path) . expect ( "Could not remove reference file" ) ;
82- }
8347 }
8448}
8549
86- fn updated_since_clippy_build ( path : & Path ) -> Option < bool > {
50+ fn updated_since_clippy_build ( entry : & DirEntry ) -> Option < bool > {
8751 let clippy_build_time = ( * CLIPPY_BUILD_TIME ) ?;
88- let modified = fs :: metadata ( path ) . ok ( ) ?. modified ( ) . ok ( ) ?;
52+ let modified = entry . metadata ( ) . ok ( ) ?. modified ( ) . ok ( ) ?;
8953 Some ( modified >= clippy_build_time)
9054}
9155
0 commit comments