@@ -7,7 +7,7 @@ use std::fmt::Debug;
7
7
use std:: fs;
8
8
use std:: hash:: Hash ;
9
9
use std:: ops:: Deref ;
10
- use std:: path:: { Path , PathBuf } ;
10
+ use std:: path:: { Component , Path , PathBuf } ;
11
11
use std:: process:: Command ;
12
12
use std:: time:: { Duration , Instant } ;
13
13
@@ -105,6 +105,44 @@ struct StepDescription {
105
105
should_run : fn ( ShouldRun < ' _ > ) -> ShouldRun < ' _ > ,
106
106
make_run : fn ( RunConfig < ' _ > ) ,
107
107
name : & ' static str ,
108
+ kind : Kind ,
109
+ }
110
+
111
+ #[ derive( Clone , PartialOrd , Ord , PartialEq , Eq ) ]
112
+ pub struct TaskPath {
113
+ pub path : PathBuf ,
114
+ pub kind : Option < Kind > ,
115
+ }
116
+
117
+ impl TaskPath {
118
+ pub fn parse ( path : impl Into < PathBuf > ) -> TaskPath {
119
+ let mut kind = None ;
120
+ let mut path = path. into ( ) ;
121
+
122
+ let mut components = path. components ( ) ;
123
+ if let Some ( Component :: Normal ( os_str) ) = components. next ( ) {
124
+ if let Some ( str) = os_str. to_str ( ) {
125
+ if let Some ( ( found_kind, found_prefix) ) = str. split_once ( "::" ) {
126
+ if found_kind. is_empty ( ) {
127
+ panic ! ( "empty kind in task path {}" , path. display( ) ) ;
128
+ }
129
+ kind = Some ( Kind :: parse ( found_kind) ) ;
130
+ path = Path :: new ( found_prefix) . join ( components. as_path ( ) ) ;
131
+ }
132
+ }
133
+ }
134
+
135
+ TaskPath { path, kind }
136
+ }
137
+ }
138
+
139
+ impl Debug for TaskPath {
140
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
141
+ if let Some ( kind) = & self . kind {
142
+ write ! ( f, "{}::" , kind. as_str( ) ) ?;
143
+ }
144
+ write ! ( f, "{}" , self . path. display( ) )
145
+ }
108
146
}
109
147
110
148
/// Collection of paths used to match a task rule.
@@ -115,50 +153,61 @@ pub enum PathSet {
115
153
/// These are generally matched as a path suffix. For example, a
116
154
/// command-line value of `libstd` will match if `src/libstd` is in the
117
155
/// set.
118
- Set ( BTreeSet < PathBuf > ) ,
156
+ Set ( BTreeSet < TaskPath > ) ,
119
157
/// A "suite" of paths.
120
158
///
121
159
/// These can match as a path suffix (like `Set`), or as a prefix. For
122
160
/// example, a command-line value of `src/test/ui/abi/variadic-ffi.rs`
123
161
/// will match `src/test/ui`. A command-line value of `ui` would also
124
162
/// match `src/test/ui`.
125
- Suite ( PathBuf ) ,
163
+ Suite ( TaskPath ) ,
126
164
}
127
165
128
166
impl PathSet {
129
167
fn empty ( ) -> PathSet {
130
168
PathSet :: Set ( BTreeSet :: new ( ) )
131
169
}
132
170
133
- fn one < P : Into < PathBuf > > ( path : P ) -> PathSet {
171
+ fn one < P : Into < PathBuf > > ( path : P , kind : Kind ) -> PathSet {
134
172
let mut set = BTreeSet :: new ( ) ;
135
- set. insert ( path. into ( ) ) ;
173
+ set. insert ( TaskPath { path : path . into ( ) , kind : Some ( kind . into ( ) ) } ) ;
136
174
PathSet :: Set ( set)
137
175
}
138
176
139
- fn has ( & self , needle : & Path ) -> bool {
177
+ fn has ( & self , needle : & Path , module : Option < Kind > ) -> bool {
178
+ let check = |p : & TaskPath | {
179
+ if let ( Some ( p_kind) , Some ( kind) ) = ( & p. kind , module) {
180
+ p. path . ends_with ( needle) && * p_kind == kind
181
+ } else {
182
+ p. path . ends_with ( needle)
183
+ }
184
+ } ;
185
+
140
186
match self {
141
- PathSet :: Set ( set) => set. iter ( ) . any ( |p| p . ends_with ( needle ) ) ,
142
- PathSet :: Suite ( suite) => suite . ends_with ( needle ) ,
187
+ PathSet :: Set ( set) => set. iter ( ) . any ( check ) ,
188
+ PathSet :: Suite ( suite) => check ( suite ) ,
143
189
}
144
190
}
145
191
146
192
fn path ( & self , builder : & Builder < ' _ > ) -> PathBuf {
147
193
match self {
148
- PathSet :: Set ( set) => set. iter ( ) . next ( ) . unwrap_or ( & builder. build . src ) . to_path_buf ( ) ,
149
- PathSet :: Suite ( path) => PathBuf :: from ( path) ,
194
+ PathSet :: Set ( set) => {
195
+ set. iter ( ) . next ( ) . map ( |p| & p. path ) . unwrap_or ( & builder. build . src ) . clone ( )
196
+ }
197
+ PathSet :: Suite ( path) => path. path . clone ( ) ,
150
198
}
151
199
}
152
200
}
153
201
154
202
impl StepDescription {
155
- fn from < S : Step > ( ) -> StepDescription {
203
+ fn from < S : Step > ( kind : Kind ) -> StepDescription {
156
204
StepDescription {
157
205
default : S :: DEFAULT ,
158
206
only_hosts : S :: ONLY_HOSTS ,
159
207
should_run : S :: should_run,
160
208
make_run : S :: make_run,
161
209
name : std:: any:: type_name :: < S > ( ) ,
210
+ kind,
162
211
}
163
212
}
164
213
@@ -177,7 +226,7 @@ impl StepDescription {
177
226
}
178
227
179
228
fn is_excluded ( & self , builder : & Builder < ' _ > , pathset : & PathSet ) -> bool {
180
- if builder. config . exclude . iter ( ) . any ( |e| pathset. has ( e ) ) {
229
+ if builder. config . exclude . iter ( ) . any ( |e| pathset. has ( & e . path , e . kind ) ) {
181
230
eprintln ! ( "Skipping {:?} because it is excluded" , pathset) ;
182
231
return true ;
183
232
}
@@ -192,8 +241,10 @@ impl StepDescription {
192
241
}
193
242
194
243
fn run ( v : & [ StepDescription ] , builder : & Builder < ' _ > , paths : & [ PathBuf ] ) {
195
- let should_runs =
196
- v. iter ( ) . map ( |desc| ( desc. should_run ) ( ShouldRun :: new ( builder) ) ) . collect :: < Vec < _ > > ( ) ;
244
+ let should_runs = v
245
+ . iter ( )
246
+ . map ( |desc| ( desc. should_run ) ( ShouldRun :: new ( builder, desc. kind ) ) )
247
+ . collect :: < Vec < _ > > ( ) ;
197
248
198
249
// sanity checks on rules
199
250
for ( desc, should_run) in v. iter ( ) . zip ( & should_runs) {
@@ -226,7 +277,7 @@ impl StepDescription {
226
277
if let Some ( suite) = should_run. is_suite_path ( path) {
227
278
attempted_run = true ;
228
279
desc. maybe_run ( builder, suite) ;
229
- } else if let Some ( pathset) = should_run. pathset_for_path ( path) {
280
+ } else if let Some ( pathset) = should_run. pathset_for_path ( path, desc . kind ) {
230
281
attempted_run = true ;
231
282
desc. maybe_run ( builder, pathset) ;
232
283
}
@@ -246,6 +297,8 @@ enum ReallyDefault<'a> {
246
297
247
298
pub struct ShouldRun < ' a > {
248
299
pub builder : & ' a Builder < ' a > ,
300
+ kind : Kind ,
301
+
249
302
// use a BTreeSet to maintain sort order
250
303
paths : BTreeSet < PathSet > ,
251
304
@@ -255,9 +308,10 @@ pub struct ShouldRun<'a> {
255
308
}
256
309
257
310
impl < ' a > ShouldRun < ' a > {
258
- fn new ( builder : & ' a Builder < ' _ > ) -> ShouldRun < ' a > {
311
+ fn new ( builder : & ' a Builder < ' _ > , kind : Kind ) -> ShouldRun < ' a > {
259
312
ShouldRun {
260
313
builder,
314
+ kind,
261
315
paths : BTreeSet :: new ( ) ,
262
316
is_really_default : ReallyDefault :: Bool ( true ) , // by default no additional conditions
263
317
}
@@ -293,7 +347,7 @@ impl<'a> ShouldRun<'a> {
293
347
let mut set = BTreeSet :: new ( ) ;
294
348
for krate in self . builder . in_tree_crates ( name, None ) {
295
349
let path = krate. local_path ( self . builder ) ;
296
- set. insert ( path) ;
350
+ set. insert ( TaskPath { path, kind : Some ( self . kind ) } ) ;
297
351
}
298
352
self . paths . insert ( PathSet :: Set ( set) ) ;
299
353
self
@@ -306,7 +360,7 @@ impl<'a> ShouldRun<'a> {
306
360
pub fn krate ( mut self , name : & str ) -> Self {
307
361
for krate in self . builder . in_tree_crates ( name, None ) {
308
362
let path = krate. local_path ( self . builder ) ;
309
- self . paths . insert ( PathSet :: one ( path) ) ;
363
+ self . paths . insert ( PathSet :: one ( path, self . kind ) ) ;
310
364
}
311
365
self
312
366
}
@@ -318,19 +372,25 @@ impl<'a> ShouldRun<'a> {
318
372
319
373
// multiple aliases for the same job
320
374
pub fn paths ( mut self , paths : & [ & str ] ) -> Self {
321
- self . paths . insert ( PathSet :: Set ( paths. iter ( ) . map ( PathBuf :: from) . collect ( ) ) ) ;
375
+ self . paths . insert ( PathSet :: Set (
376
+ paths
377
+ . iter ( )
378
+ . map ( |p| TaskPath { path : p. into ( ) , kind : Some ( self . kind . into ( ) ) } )
379
+ . collect ( ) ,
380
+ ) ) ;
322
381
self
323
382
}
324
383
325
384
pub fn is_suite_path ( & self , path : & Path ) -> Option < & PathSet > {
326
385
self . paths . iter ( ) . find ( |pathset| match pathset {
327
- PathSet :: Suite ( p) => path. starts_with ( p ) ,
386
+ PathSet :: Suite ( p) => path. starts_with ( & p . path ) ,
328
387
PathSet :: Set ( _) => false ,
329
388
} )
330
389
}
331
390
332
391
pub fn suite_path ( mut self , suite : & str ) -> Self {
333
- self . paths . insert ( PathSet :: Suite ( PathBuf :: from ( suite) ) ) ;
392
+ self . paths
393
+ . insert ( PathSet :: Suite ( TaskPath { path : suite. into ( ) , kind : Some ( self . kind . into ( ) ) } ) ) ;
334
394
self
335
395
}
336
396
@@ -340,12 +400,12 @@ impl<'a> ShouldRun<'a> {
340
400
self
341
401
}
342
402
343
- fn pathset_for_path ( & self , path : & Path ) -> Option < & PathSet > {
344
- self . paths . iter ( ) . find ( |pathset| pathset. has ( path) )
403
+ fn pathset_for_path ( & self , path : & Path , kind : Kind ) -> Option < & PathSet > {
404
+ self . paths . iter ( ) . find ( |pathset| pathset. has ( path, Some ( kind ) ) )
345
405
}
346
406
}
347
407
348
- #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
408
+ #[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Debug ) ]
349
409
pub enum Kind {
350
410
Build ,
351
411
Check ,
@@ -359,11 +419,44 @@ pub enum Kind {
359
419
Run ,
360
420
}
361
421
422
+ impl Kind {
423
+ fn parse ( string : & str ) -> Kind {
424
+ match string {
425
+ "build" => Kind :: Build ,
426
+ "check" => Kind :: Check ,
427
+ "clippy" => Kind :: Clippy ,
428
+ "fix" => Kind :: Fix ,
429
+ "test" => Kind :: Test ,
430
+ "bench" => Kind :: Bench ,
431
+ "dist" => Kind :: Dist ,
432
+ "doc" => Kind :: Doc ,
433
+ "install" => Kind :: Install ,
434
+ "run" => Kind :: Run ,
435
+ other => panic ! ( "unknown kind: {}" , other) ,
436
+ }
437
+ }
438
+
439
+ fn as_str ( & self ) -> & ' static str {
440
+ match self {
441
+ Kind :: Build => "build" ,
442
+ Kind :: Check => "check" ,
443
+ Kind :: Clippy => "clippy" ,
444
+ Kind :: Fix => "fix" ,
445
+ Kind :: Test => "test" ,
446
+ Kind :: Bench => "bench" ,
447
+ Kind :: Dist => "dist" ,
448
+ Kind :: Doc => "doc" ,
449
+ Kind :: Install => "install" ,
450
+ Kind :: Run => "run" ,
451
+ }
452
+ }
453
+ }
454
+
362
455
impl < ' a > Builder < ' a > {
363
456
fn get_step_descriptions ( kind : Kind ) -> Vec < StepDescription > {
364
457
macro_rules! describe {
365
458
( $( $rule: ty) ,+ $( , ) ?) => { {
366
- vec![ $( StepDescription :: from:: <$rule>( ) ) ,+]
459
+ vec![ $( StepDescription :: from:: <$rule>( kind ) ) ,+]
367
460
} } ;
368
461
}
369
462
match kind {
@@ -540,8 +633,11 @@ impl<'a> Builder<'a> {
540
633
541
634
let builder = Self :: new_internal ( build, kind, vec ! [ ] ) ;
542
635
let builder = & builder;
543
- let mut should_run = ShouldRun :: new ( builder) ;
636
+ // The "build" kind here is just a placeholder, it will be replaced with something else in
637
+ // the following statement.
638
+ let mut should_run = ShouldRun :: new ( builder, Kind :: Build ) ;
544
639
for desc in Builder :: get_step_descriptions ( builder. kind ) {
640
+ should_run. kind = desc. kind ;
545
641
should_run = ( desc. should_run ) ( should_run) ;
546
642
}
547
643
let mut help = String :: from ( "Available paths:\n " ) ;
@@ -552,11 +648,11 @@ impl<'a> Builder<'a> {
552
648
match pathset {
553
649
PathSet :: Set ( set) => {
554
650
for path in set {
555
- add_path ( & path) ;
651
+ add_path ( & path. path ) ;
556
652
}
557
653
}
558
654
PathSet :: Suite ( path) => {
559
- add_path ( & path. join ( "..." ) ) ;
655
+ add_path ( & path. path . join ( "..." ) ) ;
560
656
}
561
657
}
562
658
}
@@ -1626,9 +1722,10 @@ impl<'a> Builder<'a> {
1626
1722
pub ( crate ) fn ensure_if_default < T , S : Step < Output = Option < T > > > (
1627
1723
& ' a self ,
1628
1724
step : S ,
1725
+ kind : Kind ,
1629
1726
) -> S :: Output {
1630
- let desc = StepDescription :: from :: < S > ( ) ;
1631
- let should_run = ( desc. should_run ) ( ShouldRun :: new ( self ) ) ;
1727
+ let desc = StepDescription :: from :: < S > ( kind ) ;
1728
+ let should_run = ( desc. should_run ) ( ShouldRun :: new ( self , desc . kind ) ) ;
1632
1729
1633
1730
// Avoid running steps contained in --exclude
1634
1731
for pathset in & should_run. paths {
@@ -1642,13 +1739,16 @@ impl<'a> Builder<'a> {
1642
1739
}
1643
1740
1644
1741
/// Checks if any of the "should_run" paths is in the `Builder` paths.
1645
- pub ( crate ) fn was_invoked_explicitly < S : Step > ( & ' a self ) -> bool {
1646
- let desc = StepDescription :: from :: < S > ( ) ;
1647
- let should_run = ( desc. should_run ) ( ShouldRun :: new ( self ) ) ;
1742
+ pub ( crate ) fn was_invoked_explicitly < S : Step > ( & ' a self , kind : Kind ) -> bool {
1743
+ let desc = StepDescription :: from :: < S > ( kind ) ;
1744
+ let should_run = ( desc. should_run ) ( ShouldRun :: new ( self , desc . kind ) ) ;
1648
1745
1649
1746
for path in & self . paths {
1650
- if should_run. paths . iter ( ) . any ( |s| s. has ( path) )
1651
- && !desc. is_excluded ( self , & PathSet :: Suite ( path. clone ( ) ) )
1747
+ if should_run. paths . iter ( ) . any ( |s| s. has ( path, Some ( desc. kind ) ) )
1748
+ && !desc. is_excluded (
1749
+ self ,
1750
+ & PathSet :: Suite ( TaskPath { path : path. clone ( ) , kind : Some ( desc. kind . into ( ) ) } ) ,
1751
+ )
1652
1752
{
1653
1753
return true ;
1654
1754
}
0 commit comments