1- use std:: fs;
1+ use std:: collections:: HashSet ;
2+ use std:: fs:: { self , File } ;
3+ use std:: io:: { BufRead , BufReader , ErrorKind } ;
24use std:: path:: { Path , PathBuf } ;
35
46use crate :: core:: builder:: { Builder , ShouldRun , Step } ;
@@ -31,9 +33,9 @@ impl Step for SetupFailedTestsFile {
3133 return RecordFailedTests { failed_tests_path : None } ;
3234 }
3335
34- let failed_tests_path = builder. out . join ( & builder . config . record_failed_tests_path ) ;
36+ let failed_tests_path = builder. config . record_failed_tests_path . clone ( ) ;
3537 println ! (
36- "setting up tracking of failed tests in {} (--record was passed)" ,
38+ "setting up tracking of failed tests in {} (` --record` was passed)" ,
3739 failed_tests_path. display( )
3840 ) ;
3941 if failed_tests_path. exists ( ) {
@@ -43,3 +45,58 @@ impl Step for SetupFailedTestsFile {
4345 RecordFailedTests { failed_tests_path : Some ( failed_tests_path) }
4446 }
4547}
48+
49+ pub fn collect_previously_failed_tests ( failed_tests_file_path : & PathBuf , paths : & mut Vec < PathBuf > ) {
50+ println ! (
51+ "`--rerun` passed so looking for failed tests in {}" ,
52+ failed_tests_file_path. display( )
53+ ) ;
54+
55+ let lines: Vec < String > = match File :: open ( failed_tests_file_path) {
56+ Ok ( f) => t ! ( BufReader :: new( f) . lines( ) . collect( ) ) ,
57+ Err ( e) if e. kind ( ) == ErrorKind :: NotFound => {
58+ println ! (
59+ "WARNING: failed tests file doesn't exist: `--rerun` only makes sense after a previous test run with `--record`"
60+ ) ;
61+ return ;
62+ }
63+ Err ( e) => t ! ( Err ( e) ) ,
64+ } ;
65+
66+ let mut set_tracking_duplicates = HashSet :: new ( ) ;
67+ let mut num_printed = 0 ;
68+ const MAX_RERUN_PRINTS : usize = 10 ;
69+
70+ for line in lines {
71+ let trimmed = line. as_str ( ) . trim ( ) ;
72+ let without_revision =
73+ trimmed. rsplit_once ( "#" ) . map ( |( before, _) | before) . unwrap_or ( & trimmed) ;
74+ let without_suite_prefix = without_revision
75+ . strip_prefix ( "[" )
76+ . and_then ( |rest| rest. split_once ( "]" ) )
77+ . map ( |( _, after) | after. trim ( ) )
78+ . unwrap_or ( without_revision) ;
79+
80+ let failed_test_path = PathBuf :: from ( without_suite_prefix. to_string ( ) ) ;
81+ if set_tracking_duplicates. insert ( failed_test_path. clone ( ) ) {
82+ if num_printed == 0 {
83+ println ! ( "rerunning previousy failed tests:" ) ;
84+ }
85+ if num_printed < MAX_RERUN_PRINTS {
86+ println ! ( " {}" , failed_test_path. display( ) ) ;
87+ num_printed += 1 ;
88+ }
89+ paths. push ( failed_test_path) ;
90+ }
91+ }
92+
93+ if num_printed == MAX_RERUN_PRINTS && set_tracking_duplicates. len ( ) > MAX_RERUN_PRINTS {
94+ println ! ( " and {} more..." , set_tracking_duplicates. len( ) - MAX_RERUN_PRINTS )
95+ }
96+
97+ if set_tracking_duplicates. is_empty ( ) {
98+ println ! (
99+ "WARNING: failed tests file doesn't contain any failed tests: `--rerun` only makes sense after a previous test run with `--record`"
100+ ) ;
101+ }
102+ }
0 commit comments