@@ -44,6 +44,7 @@ struct CompilationUnit {
44
44
}
45
45
46
46
/// A structure that represents a single notification parsed from clang-tidy's stdout.
47
+ #[ derive( Debug ) ]
47
48
pub struct TidyNotification {
48
49
/// The file's path and name (supposedly relative to the repository root folder).
49
50
pub filename : String ,
@@ -86,6 +87,7 @@ impl TidyNotification {
86
87
}
87
88
88
89
/// A struct to hold notification from clang-tidy about a single file
90
+ #[ derive( Debug ) ]
89
91
pub struct TidyAdvice {
90
92
/// A list of notifications parsed from clang-tidy stdout.
91
93
pub notes : Vec < TidyNotification > ,
@@ -98,7 +100,7 @@ pub struct TidyAdvice {
98
100
fn parse_tidy_output (
99
101
tidy_stdout : & [ u8 ] ,
100
102
database_json : & Option < CompilationDatabase > ,
101
- ) -> TidyAdvice {
103
+ ) -> Option < TidyAdvice > {
102
104
let note_header = Regex :: new ( r"^(.+):(\d+):(\d+):\s(\w+):(.*)\[([a-zA-Z\d\-\.]+)\]$" ) . unwrap ( ) ;
103
105
let mut notification = None ;
104
106
let mut result = Vec :: new ( ) ;
@@ -163,19 +165,39 @@ fn parse_tidy_output(
163
165
if let Some ( note) = notification {
164
166
result. push ( note) ;
165
167
}
166
- TidyAdvice { notes : result }
168
+ if result. is_empty ( ) {
169
+ None
170
+ } else {
171
+ Some ( TidyAdvice { notes : result } )
172
+ }
173
+ }
174
+
175
+ /// Get a total count of clang-tidy advice from the given list of [FileObj]s.
176
+ pub fn tally_tidy_advice ( files : & [ FileObj ] ) -> u64 {
177
+ let mut total = 0 ;
178
+ for file in files {
179
+ if let Some ( advice) = & file. tidy_advice {
180
+ for tidy_note in & advice. notes {
181
+ let file_path = PathBuf :: from ( & tidy_note. filename ) ;
182
+ if file_path == file. name {
183
+ total += 1 ;
184
+ }
185
+ }
186
+ }
187
+ }
188
+ total
167
189
}
168
190
169
191
/// Run clang-tidy, then parse and return it's output.
170
192
pub fn run_clang_tidy (
171
193
cmd : & mut Command ,
172
- file : & FileObj ,
194
+ file : & mut FileObj ,
173
195
checks : & str ,
174
196
lines_changed_only : & LinesChangedOnly ,
175
197
database : & Option < PathBuf > ,
176
198
extra_args : & Option < Vec < & str > > ,
177
199
database_json : & Option < CompilationDatabase > ,
178
- ) -> TidyAdvice {
200
+ ) {
179
201
if !checks. is_empty ( ) {
180
202
cmd. args ( [ "-checks" , checks] ) ;
181
203
}
@@ -222,7 +244,7 @@ pub fn run_clang_tidy(
222
244
String :: from_utf8( output. stderr) . unwrap( )
223
245
) ;
224
246
}
225
- parse_tidy_output ( & output. stdout , database_json)
247
+ file . tidy_advice = parse_tidy_output ( & output. stdout , database_json) ;
226
248
}
227
249
228
250
#[ cfg( test) ]
@@ -265,11 +287,11 @@ mod test {
265
287
)
266
288
. unwrap ( ) ;
267
289
let mut cmd = Command :: new ( exe_path) ;
268
- let file = FileObj :: new ( PathBuf :: from ( "tests/demo/demo.cpp" ) ) ;
290
+ let mut file = FileObj :: new ( PathBuf :: from ( "tests/demo/demo.cpp" ) ) ;
269
291
let extra_args = vec ! [ "-std=c++17" , "-Wall" ] ;
270
- let tidy_advice = run_clang_tidy (
292
+ run_clang_tidy (
271
293
& mut cmd,
272
- & file,
294
+ & mut file,
273
295
"" , // use .clang-tidy config file
274
296
& LinesChangedOnly :: Off , // check all lines
275
297
& None , // no database path
@@ -286,6 +308,8 @@ mod test {
286
308
vec![ "--extra-arg" , "\" -std=c++17\" " , "--extra-arg" , "\" -Wall\" " ] ,
287
309
args
288
310
) ;
289
- assert ! ( !tidy_advice. notes. is_empty( ) ) ;
311
+ assert ! ( !file
312
+ . tidy_advice
313
+ . is_some_and( |advice| advice. notes. is_empty( ) ) ) ;
290
314
}
291
315
}
0 commit comments