@@ -5,7 +5,7 @@ use clap::Parser;
5
5
use collector:: category:: Category ;
6
6
use database:: { ArtifactId , Commit } ;
7
7
use log:: debug;
8
- use std:: collections:: HashSet ;
8
+ use std:: collections:: HashMap ;
9
9
use std:: fs;
10
10
use std:: fs:: File ;
11
11
use std:: io:: BufWriter ;
@@ -331,26 +331,37 @@ fn get_benchmarks(
331
331
paths. push ( ( path, name) ) ;
332
332
}
333
333
334
- let mut includes = include. map ( |list| list. split ( ',' ) . collect :: < HashSet < & str > > ( ) ) ;
335
- let mut excludes = exclude. map ( |list| list. split ( ',' ) . collect :: < HashSet < & str > > ( ) ) ;
334
+ // For each --include/--exclude entry, we count how many times it's used,
335
+ // to enable `check_for_unused` below.
336
+ fn to_hashmap ( xyz : Option < & str > ) -> Option < HashMap < & str , usize > > {
337
+ xyz. map ( |list| {
338
+ list. split ( ',' )
339
+ . map ( |x| ( x, 0 ) )
340
+ . collect :: < HashMap < & str , usize > > ( )
341
+ } )
342
+ }
343
+
344
+ let mut includes = to_hashmap ( include) ;
345
+ let mut excludes = to_hashmap ( exclude) ;
336
346
337
347
for ( path, name) in paths {
338
348
let mut skip = false ;
339
- if let Some ( includes ) = includes . as_mut ( ) {
340
- if !includes . remove ( name . as_str ( ) ) {
341
- debug ! (
342
- "benchmark {} - not named by --include argument, skipping" ,
343
- name
344
- ) ;
345
- skip = true ;
349
+
350
+ let name_matches = | prefixes : & mut HashMap < & str , usize > | {
351
+ for ( prefix , n ) in prefixes . iter_mut ( ) {
352
+ if name . as_str ( ) . starts_with ( prefix ) {
353
+ * n += 1 ;
354
+ return true ;
355
+ }
346
356
}
347
- }
357
+ false
358
+ } ;
348
359
360
+ if let Some ( includes) = includes. as_mut ( ) {
361
+ skip |= !name_matches ( includes) ;
362
+ }
349
363
if let Some ( excludes) = excludes. as_mut ( ) {
350
- if excludes. remove ( name. as_str ( ) ) {
351
- debug ! ( "benchmark {} - named by --exclude argument, skipping" , name) ;
352
- skip = true ;
353
- }
364
+ skip |= name_matches ( excludes) ;
354
365
}
355
366
if skip {
356
367
continue ;
@@ -360,22 +371,26 @@ fn get_benchmarks(
360
371
benchmarks. push ( Benchmark :: new ( name, path) ?) ;
361
372
}
362
373
363
- if let Some ( includes ) = includes {
364
- if !includes . is_empty ( ) {
365
- bail ! (
366
- "Warning: one or more invalid --include entries: {:?}" ,
367
- includes
368
- ) ;
369
- }
370
- }
371
- if let Some ( excludes ) = excludes {
372
- if !excludes . is_empty ( ) {
373
- bail ! (
374
- "Warning: one or more invalid --exclude entries: {:?}" ,
375
- excludes
376
- ) ;
374
+ // All prefixes must be used at least once. This is to catch typos.
375
+ let check_for_unused = |option , prefixes : Option < HashMap < & str , usize > > | {
376
+ if let Some ( prefixes ) = prefixes {
377
+ let unused : Vec < _ > = prefixes
378
+ . into_iter ( )
379
+ . filter_map ( | ( i , n ) | if n == 0 { Some ( i ) } else { None } )
380
+ . collect ( ) ;
381
+ if !unused . is_empty ( ) {
382
+ bail ! (
383
+ "Warning: one or more unused --{} entries: {:?}" ,
384
+ option ,
385
+ unused
386
+ ) ;
387
+ }
377
388
}
378
- }
389
+ Ok ( ( ) )
390
+ } ;
391
+
392
+ check_for_unused ( "include" , includes) ?;
393
+ check_for_unused ( "exclude" , excludes) ?;
379
394
380
395
benchmarks. sort_by_key ( |benchmark| benchmark. name . clone ( ) ) ;
381
396
@@ -729,11 +744,11 @@ struct LocalOptions {
729
744
#[ clap( long, parse( from_os_str) ) ]
730
745
cargo : Option < PathBuf > ,
731
746
732
- /// Exclude all benchmarks in this comma-separated list
747
+ /// Exclude all benchmarks matching a prefix in this comma-separated list
733
748
#[ clap( long) ]
734
749
exclude : Option < String > ,
735
750
736
- /// Include only benchmarks in this comma-separated list
751
+ /// Include only benchmarks matching a prefix in this comma-separated list
737
752
#[ clap( long) ]
738
753
include : Option < String > ,
739
754
0 commit comments