@@ -191,6 +191,7 @@ pub fn crate_description(crates: &[impl AsRef<str>]) -> String {
191
191
descr
192
192
}
193
193
194
+ #[ derive( PartialEq ) ]
194
195
struct StepDescription {
195
196
default : bool ,
196
197
only_hosts : bool ,
@@ -265,23 +266,9 @@ impl PathSet {
265
266
}
266
267
}
267
268
268
- /// Return all `TaskPath`s in `Self` that contain any of the `needles`, removing the
269
- /// matched needles.
270
- ///
271
- /// This is used for `StepDescription::krate`, which passes all matching crates at once to
272
- /// `Step::make_run`, rather than calling it many times with a single crate.
273
- /// See `tests.rs` for examples.
274
- fn intersection_removing_matches ( & self , needles : & mut Vec < PathBuf > , module : Kind ) -> PathSet {
275
- let mut check = |p| {
276
- for ( i, n) in needles. iter ( ) . enumerate ( ) {
277
- let matched = Self :: check ( p, n, module) ;
278
- if matched {
279
- needles. remove ( i) ;
280
- return true ;
281
- }
282
- }
283
- false
284
- } ;
269
+ /// Return all `TaskPath`s in `Self` that contain the `path`.
270
+ fn intersection_pathset ( & self , path : & Path , module : Kind ) -> PathSet {
271
+ let check = |p| Self :: check ( p, path, module) ;
285
272
match self {
286
273
PathSet :: Set ( set) => PathSet :: Set ( set. iter ( ) . filter ( |& p| check ( p) ) . cloned ( ) . collect ( ) ) ,
287
274
PathSet :: Suite ( suite) => {
@@ -473,12 +460,35 @@ impl StepDescription {
473
460
return ;
474
461
}
475
462
476
- // Handle all PathSets.
477
- for ( desc, should_run) in v. iter ( ) . zip ( & should_runs) {
478
- let pathsets = should_run. pathset_for_paths_removing_matches ( & mut paths, desc. kind ) ;
479
- if !pathsets. is_empty ( ) {
480
- desc. maybe_run ( builder, pathsets) ;
463
+ // Special type that helps bootstrap to:
464
+ // 1. keep the given CLI order on step execution
465
+ // 2. keep all matching crates so we can pass them to `Step::make_run` at once,
466
+ // rather than calling it many times with a single crate.
467
+ let mut steps_to_run: Vec < ( & StepDescription , Vec < PathSet > ) > = vec ! [ ] ;
468
+
469
+ // Start given steps and remove them from `paths`.
470
+ paths. retain ( |path| {
471
+ for ( desc, should_run) in v. iter ( ) . zip ( & should_runs) {
472
+ let pathsets = should_run. resolve_pathsets ( path, desc. kind ) ;
473
+ if !pathsets. is_empty ( ) {
474
+ if let Some ( ( _, paths) ) =
475
+ steps_to_run. iter_mut ( ) . find ( |( step_desc, _) | * step_desc == desc)
476
+ {
477
+ paths. extend ( pathsets) ;
478
+ } else {
479
+ steps_to_run. push ( ( desc, pathsets) ) ;
480
+ }
481
+
482
+ return false ;
483
+ }
481
484
}
485
+
486
+ true
487
+ } ) ;
488
+
489
+ // Execute steps
490
+ for ( desc, pathsets) in steps_to_run {
491
+ desc. maybe_run ( builder, pathsets) ;
482
492
}
483
493
484
494
if !paths. is_empty ( ) {
@@ -632,23 +642,18 @@ impl<'a> ShouldRun<'a> {
632
642
self
633
643
}
634
644
635
- /// Given a set of requested paths, return the subset which match the Step for this `ShouldRun`,
636
- /// removing the matches from `paths`.
645
+ /// Return the subset from given `path` and `kind` which match the `Step` for this `ShouldRun`.
637
646
///
638
647
/// NOTE: this returns multiple PathSets to allow for the possibility of multiple units of work
639
648
/// within the same step. For example, `test::Crate` allows testing multiple crates in the same
640
649
/// cargo invocation, which are put into separate sets because they aren't aliases.
641
650
///
642
651
/// The reason we return PathSet instead of PathBuf is to allow for aliases that mean the same thing
643
652
/// (for now, just `all_krates` and `paths`, but we may want to add an `aliases` function in the future?)
644
- fn pathset_for_paths_removing_matches (
645
- & self ,
646
- paths : & mut Vec < PathBuf > ,
647
- kind : Kind ,
648
- ) -> Vec < PathSet > {
653
+ fn resolve_pathsets ( & self , path : & Path , kind : Kind ) -> Vec < PathSet > {
649
654
let mut sets = vec ! [ ] ;
650
655
for pathset in & self . paths {
651
- let subset = pathset. intersection_removing_matches ( paths , kind) ;
656
+ let subset = pathset. intersection_pathset ( path , kind) ;
652
657
if subset != PathSet :: empty ( ) {
653
658
sets. push ( subset) ;
654
659
}
0 commit comments