@@ -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,17 +105,43 @@ struct StepDescription {
105
105
should_run : fn ( ShouldRun < ' _ > ) -> ShouldRun < ' _ > ,
106
106
make_run : fn ( RunConfig < ' _ > ) ,
107
107
name : & ' static str ,
108
+ kind : Kind ,
108
109
}
109
110
110
- #[ derive( Debug , Clone , PartialOrd , Ord , PartialEq , Eq ) ]
111
+ #[ derive( Clone , PartialOrd , Ord , PartialEq , Eq ) ]
111
112
pub struct TaskPath {
112
113
pub path : PathBuf ,
113
- pub module : Option < String > ,
114
+ pub kind : Option < Kind > ,
114
115
}
115
116
116
117
impl TaskPath {
117
118
pub fn parse ( path : impl Into < PathBuf > ) -> TaskPath {
118
- TaskPath { path : path. into ( ) , module : None }
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( ) )
119
145
}
120
146
}
121
147
@@ -142,16 +168,24 @@ impl PathSet {
142
168
PathSet :: Set ( BTreeSet :: new ( ) )
143
169
}
144
170
145
- fn one < P : Into < PathBuf > > ( path : P ) -> PathSet {
171
+ fn one < P : Into < PathBuf > > ( path : P , kind : Kind ) -> PathSet {
146
172
let mut set = BTreeSet :: new ( ) ;
147
- set. insert ( TaskPath :: parse ( path ) ) ;
173
+ set. insert ( TaskPath { path : path . into ( ) , kind : Some ( kind . into ( ) ) } ) ;
148
174
PathSet :: Set ( set)
149
175
}
150
176
151
- 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
+
152
186
match self {
153
- PathSet :: Set ( set) => set. iter ( ) . any ( |p| p . path . ends_with ( needle ) ) ,
154
- PathSet :: Suite ( suite) => suite . path . ends_with ( needle ) ,
187
+ PathSet :: Set ( set) => set. iter ( ) . any ( check ) ,
188
+ PathSet :: Suite ( suite) => check ( suite ) ,
155
189
}
156
190
}
157
191
@@ -166,13 +200,14 @@ impl PathSet {
166
200
}
167
201
168
202
impl StepDescription {
169
- fn from < S : Step > ( ) -> StepDescription {
203
+ fn from < S : Step > ( kind : Kind ) -> StepDescription {
170
204
StepDescription {
171
205
default : S :: DEFAULT ,
172
206
only_hosts : S :: ONLY_HOSTS ,
173
207
should_run : S :: should_run,
174
208
make_run : S :: make_run,
175
209
name : std:: any:: type_name :: < S > ( ) ,
210
+ kind,
176
211
}
177
212
}
178
213
@@ -191,7 +226,7 @@ impl StepDescription {
191
226
}
192
227
193
228
fn is_excluded ( & self , builder : & Builder < ' _ > , pathset : & PathSet ) -> bool {
194
- if builder. config . exclude . iter ( ) . any ( |e| pathset. has ( e ) ) {
229
+ if builder. config . exclude . iter ( ) . any ( |e| pathset. has ( & e . path , e . kind ) ) {
195
230
eprintln ! ( "Skipping {:?} because it is excluded" , pathset) ;
196
231
return true ;
197
232
}
@@ -206,8 +241,10 @@ impl StepDescription {
206
241
}
207
242
208
243
fn run ( v : & [ StepDescription ] , builder : & Builder < ' _ > , paths : & [ PathBuf ] ) {
209
- let should_runs =
210
- 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 < _ > > ( ) ;
211
248
212
249
// sanity checks on rules
213
250
for ( desc, should_run) in v. iter ( ) . zip ( & should_runs) {
@@ -240,7 +277,7 @@ impl StepDescription {
240
277
if let Some ( suite) = should_run. is_suite_path ( path) {
241
278
attempted_run = true ;
242
279
desc. maybe_run ( builder, suite) ;
243
- } 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 ) {
244
281
attempted_run = true ;
245
282
desc. maybe_run ( builder, pathset) ;
246
283
}
@@ -260,6 +297,8 @@ enum ReallyDefault<'a> {
260
297
261
298
pub struct ShouldRun < ' a > {
262
299
pub builder : & ' a Builder < ' a > ,
300
+ kind : Kind ,
301
+
263
302
// use a BTreeSet to maintain sort order
264
303
paths : BTreeSet < PathSet > ,
265
304
@@ -269,9 +308,10 @@ pub struct ShouldRun<'a> {
269
308
}
270
309
271
310
impl < ' a > ShouldRun < ' a > {
272
- fn new ( builder : & ' a Builder < ' _ > ) -> ShouldRun < ' a > {
311
+ fn new ( builder : & ' a Builder < ' _ > , kind : Kind ) -> ShouldRun < ' a > {
273
312
ShouldRun {
274
313
builder,
314
+ kind,
275
315
paths : BTreeSet :: new ( ) ,
276
316
is_really_default : ReallyDefault :: Bool ( true ) , // by default no additional conditions
277
317
}
@@ -307,7 +347,7 @@ impl<'a> ShouldRun<'a> {
307
347
let mut set = BTreeSet :: new ( ) ;
308
348
for krate in self . builder . in_tree_crates ( name, None ) {
309
349
let path = krate. local_path ( self . builder ) ;
310
- set. insert ( TaskPath :: parse ( path ) ) ;
350
+ set. insert ( TaskPath { path , kind : Some ( self . kind ) } ) ;
311
351
}
312
352
self . paths . insert ( PathSet :: Set ( set) ) ;
313
353
self
@@ -320,7 +360,7 @@ impl<'a> ShouldRun<'a> {
320
360
pub fn krate ( mut self , name : & str ) -> Self {
321
361
for krate in self . builder . in_tree_crates ( name, None ) {
322
362
let path = krate. local_path ( self . builder ) ;
323
- self . paths . insert ( PathSet :: one ( path) ) ;
363
+ self . paths . insert ( PathSet :: one ( path, self . kind ) ) ;
324
364
}
325
365
self
326
366
}
@@ -332,7 +372,12 @@ impl<'a> ShouldRun<'a> {
332
372
333
373
// multiple aliases for the same job
334
374
pub fn paths ( mut self , paths : & [ & str ] ) -> Self {
335
- self . paths . insert ( PathSet :: Set ( paths. iter ( ) . map ( |p| TaskPath :: parse ( p) ) . 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
+ ) ) ;
336
381
self
337
382
}
338
383
@@ -344,7 +389,8 @@ impl<'a> ShouldRun<'a> {
344
389
}
345
390
346
391
pub fn suite_path ( mut self , suite : & str ) -> Self {
347
- self . paths . insert ( PathSet :: Suite ( TaskPath :: parse ( suite) ) ) ;
392
+ self . paths
393
+ . insert ( PathSet :: Suite ( TaskPath { path : suite. into ( ) , kind : Some ( self . kind . into ( ) ) } ) ) ;
348
394
self
349
395
}
350
396
@@ -354,12 +400,12 @@ impl<'a> ShouldRun<'a> {
354
400
self
355
401
}
356
402
357
- fn pathset_for_path ( & self , path : & Path ) -> Option < & PathSet > {
358
- 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 ) ) )
359
405
}
360
406
}
361
407
362
- #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
408
+ #[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Debug ) ]
363
409
pub enum Kind {
364
410
Build ,
365
411
Check ,
@@ -373,11 +419,44 @@ pub enum Kind {
373
419
Run ,
374
420
}
375
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
+
376
455
impl < ' a > Builder < ' a > {
377
456
fn get_step_descriptions ( kind : Kind ) -> Vec < StepDescription > {
378
457
macro_rules! describe {
379
458
( $( $rule: ty) ,+ $( , ) ?) => { {
380
- vec![ $( StepDescription :: from:: <$rule>( ) ) ,+]
459
+ vec![ $( StepDescription :: from:: <$rule>( kind ) ) ,+]
381
460
} } ;
382
461
}
383
462
match kind {
@@ -554,8 +633,11 @@ impl<'a> Builder<'a> {
554
633
555
634
let builder = Self :: new_internal ( build, kind, vec ! [ ] ) ;
556
635
let builder = & builder;
557
- 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 ) ;
558
639
for desc in Builder :: get_step_descriptions ( builder. kind ) {
640
+ should_run. kind = desc. kind ;
559
641
should_run = ( desc. should_run ) ( should_run) ;
560
642
}
561
643
let mut help = String :: from ( "Available paths:\n " ) ;
@@ -1640,9 +1722,10 @@ impl<'a> Builder<'a> {
1640
1722
pub ( crate ) fn ensure_if_default < T , S : Step < Output = Option < T > > > (
1641
1723
& ' a self ,
1642
1724
step : S ,
1725
+ kind : Kind ,
1643
1726
) -> S :: Output {
1644
- let desc = StepDescription :: from :: < S > ( ) ;
1645
- 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 ) ) ;
1646
1729
1647
1730
// Avoid running steps contained in --exclude
1648
1731
for pathset in & should_run. paths {
@@ -1656,13 +1739,16 @@ impl<'a> Builder<'a> {
1656
1739
}
1657
1740
1658
1741
/// Checks if any of the "should_run" paths is in the `Builder` paths.
1659
- pub ( crate ) fn was_invoked_explicitly < S : Step > ( & ' a self ) -> bool {
1660
- let desc = StepDescription :: from :: < S > ( ) ;
1661
- 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 ) ) ;
1662
1745
1663
1746
for path in & self . paths {
1664
- if should_run. paths . iter ( ) . any ( |s| s. has ( path) )
1665
- && !desc. is_excluded ( self , & PathSet :: Suite ( TaskPath :: parse ( path) ) )
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
+ )
1666
1752
{
1667
1753
return true ;
1668
1754
}
0 commit comments