4
4
//! checking entire repositories.
5
5
6
6
use std:: fmt:: { Display , Formatter } ;
7
- use std:: io :: stdout ;
7
+ use std:: fs :: File ;
8
8
use std:: io:: Write ;
9
+ use std:: io:: { stdout, BufWriter } ;
9
10
use std:: panic:: catch_unwind;
10
11
use std:: path:: { Path , PathBuf } ;
11
12
use std:: process:: ExitCode ;
@@ -49,6 +50,9 @@ pub(crate) struct Args {
49
50
/// Checks each project inside a directory
50
51
#[ arg( long) ]
51
52
pub ( crate ) multi_project : bool ,
53
+ /// Write all errors to this file in addition to stdout
54
+ #[ arg( long) ]
55
+ pub ( crate ) error_file : Option < PathBuf > ,
52
56
}
53
57
54
58
/// Generate ourself a `try_parse_from` impl for `CheckArgs`. This is a strange way to use clap but
@@ -69,6 +73,12 @@ pub(crate) fn main(args: &Args) -> anyhow::Result<ExitCode> {
69
73
#[ allow( clippy:: print_stdout) ]
70
74
{
71
75
print ! ( "{}" , result. display( args. format) ) ;
76
+ println ! (
77
+ "Found {} stability errors in {} files in {:.2}s" ,
78
+ result. diagnostics. len( ) ,
79
+ result. file_count,
80
+ result. duration. as_secs_f32( ) ,
81
+ ) ;
72
82
}
73
83
74
84
result. is_success ( )
@@ -114,6 +124,7 @@ fn check_multi_project(args: &Args) -> bool {
114
124
115
125
match check_repo ( & Args {
116
126
files : vec ! [ path. clone( ) ] ,
127
+ error_file : args. error_file . clone ( ) ,
117
128
..* args
118
129
} ) {
119
130
Ok ( result) => sender. send ( Message :: Finished { result, path } ) ,
@@ -126,6 +137,9 @@ fn check_multi_project(args: &Args) -> bool {
126
137
127
138
scope. spawn ( |_| {
128
139
let mut stdout = stdout ( ) . lock ( ) ;
140
+ let mut error_file = args. error_file . as_ref ( ) . map ( |error_file| {
141
+ BufWriter :: new ( File :: create ( error_file) . expect ( "Couldn't open error file" ) )
142
+ } ) ;
129
143
130
144
for message in receiver {
131
145
match message {
@@ -135,13 +149,19 @@ fn check_multi_project(args: &Args) -> bool {
135
149
Message :: Finished { path, result } => {
136
150
total_errors += result. diagnostics . len ( ) ;
137
151
total_files += result. file_count ;
152
+
138
153
writeln ! (
139
154
stdout,
140
- "Finished {}\n {} \n " ,
155
+ "Finished {} with {} files in {:.2}s " ,
141
156
path. display( ) ,
142
- result. display( args. format)
157
+ result. file_count,
158
+ result. duration. as_secs_f32( ) ,
143
159
)
144
160
. unwrap ( ) ;
161
+ write ! ( stdout, "{}" , result. display( args. format) ) . unwrap ( ) ;
162
+ if let Some ( error_file) = & mut error_file {
163
+ write ! ( error_file, "{}" , result. display( args. format) ) . unwrap ( ) ;
164
+ }
145
165
all_success = all_success && result. is_success ( ) ;
146
166
}
147
167
Message :: Failed { path, error } => {
@@ -157,8 +177,10 @@ fn check_multi_project(args: &Args) -> bool {
157
177
158
178
#[ allow( clippy:: print_stdout) ]
159
179
{
160
- println ! ( "{total_errors} stability errors in {total_files} files" ) ;
161
- println ! ( "Finished in {}s" , duration. as_secs_f32( ) ) ;
180
+ println ! (
181
+ "{total_errors} stability errors in {total_files} files in {}s" ,
182
+ duration. as_secs_f32( )
183
+ ) ;
162
184
}
163
185
164
186
all_success
@@ -295,23 +317,11 @@ struct DisplayCheckRepoResult<'a> {
295
317
}
296
318
297
319
impl Display for DisplayCheckRepoResult < ' _ > {
298
- fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
299
- let CheckRepoResult {
300
- duration,
301
- file_count,
302
- diagnostics,
303
- } = self . result ;
304
-
305
- for diagnostic in diagnostics {
320
+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
321
+ for diagnostic in & self . result . diagnostics {
306
322
write ! ( f, "{}" , diagnostic. display( self . format) ) ?;
307
323
}
308
-
309
- writeln ! (
310
- f,
311
- "Formatting {} files twice took {:.2}s" ,
312
- file_count,
313
- duration. as_secs_f32( )
314
- )
324
+ Ok ( ( ) )
315
325
}
316
326
}
317
327
0 commit comments