@@ -7,7 +7,7 @@ use std::fmt::Debug;
77use std:: fs;
88use std:: hash:: Hash ;
99use std:: ops:: Deref ;
10- use std:: path:: { Path , PathBuf } ;
10+ use std:: path:: { Component , Path , PathBuf } ;
1111use std:: process:: Command ;
1212use std:: time:: { Duration , Instant } ;
1313
@@ -105,17 +105,43 @@ struct StepDescription {
105105 should_run : fn ( ShouldRun < ' _ > ) -> ShouldRun < ' _ > ,
106106 make_run : fn ( RunConfig < ' _ > ) ,
107107 name : & ' static str ,
108+ kind : Kind ,
108109}
109110
110- #[ derive( Debug , Clone , PartialOrd , Ord , PartialEq , Eq ) ]
111+ #[ derive( Clone , PartialOrd , Ord , PartialEq , Eq ) ]
111112pub struct TaskPath {
112113 pub path : PathBuf ,
113- pub module : Option < String > ,
114+ pub kind : Option < Kind > ,
114115}
115116
116117impl TaskPath {
117118 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( ) )
119145 }
120146}
121147
@@ -142,16 +168,24 @@ impl PathSet {
142168 PathSet :: Set ( BTreeSet :: new ( ) )
143169 }
144170
145- fn one < P : Into < PathBuf > > ( path : P ) -> PathSet {
171+ fn one < P : Into < PathBuf > > ( path : P , kind : Kind ) -> PathSet {
146172 let mut set = BTreeSet :: new ( ) ;
147- set. insert ( TaskPath :: parse ( path ) ) ;
173+ set. insert ( TaskPath { path : path . into ( ) , kind : Some ( kind . into ( ) ) } ) ;
148174 PathSet :: Set ( set)
149175 }
150176
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+
152186 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 ) ,
155189 }
156190 }
157191
@@ -166,13 +200,14 @@ impl PathSet {
166200}
167201
168202impl StepDescription {
169- fn from < S : Step > ( ) -> StepDescription {
203+ fn from < S : Step > ( kind : Kind ) -> StepDescription {
170204 StepDescription {
171205 default : S :: DEFAULT ,
172206 only_hosts : S :: ONLY_HOSTS ,
173207 should_run : S :: should_run,
174208 make_run : S :: make_run,
175209 name : std:: any:: type_name :: < S > ( ) ,
210+ kind,
176211 }
177212 }
178213
@@ -191,7 +226,7 @@ impl StepDescription {
191226 }
192227
193228 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 ) ) {
195230 eprintln ! ( "Skipping {:?} because it is excluded" , pathset) ;
196231 return true ;
197232 }
@@ -206,8 +241,10 @@ impl StepDescription {
206241 }
207242
208243 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 < _ > > ( ) ;
211248
212249 // sanity checks on rules
213250 for ( desc, should_run) in v. iter ( ) . zip ( & should_runs) {
@@ -240,7 +277,7 @@ impl StepDescription {
240277 if let Some ( suite) = should_run. is_suite_path ( path) {
241278 attempted_run = true ;
242279 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 ) {
244281 attempted_run = true ;
245282 desc. maybe_run ( builder, pathset) ;
246283 }
@@ -260,6 +297,8 @@ enum ReallyDefault<'a> {
260297
261298pub struct ShouldRun < ' a > {
262299 pub builder : & ' a Builder < ' a > ,
300+ kind : Kind ,
301+
263302 // use a BTreeSet to maintain sort order
264303 paths : BTreeSet < PathSet > ,
265304
@@ -269,9 +308,10 @@ pub struct ShouldRun<'a> {
269308}
270309
271310impl < ' a > ShouldRun < ' a > {
272- fn new ( builder : & ' a Builder < ' _ > ) -> ShouldRun < ' a > {
311+ fn new ( builder : & ' a Builder < ' _ > , kind : Kind ) -> ShouldRun < ' a > {
273312 ShouldRun {
274313 builder,
314+ kind,
275315 paths : BTreeSet :: new ( ) ,
276316 is_really_default : ReallyDefault :: Bool ( true ) , // by default no additional conditions
277317 }
@@ -307,7 +347,7 @@ impl<'a> ShouldRun<'a> {
307347 let mut set = BTreeSet :: new ( ) ;
308348 for krate in self . builder . in_tree_crates ( name, None ) {
309349 let path = krate. local_path ( self . builder ) ;
310- set. insert ( TaskPath :: parse ( path ) ) ;
350+ set. insert ( TaskPath { path , kind : Some ( self . kind ) } ) ;
311351 }
312352 self . paths . insert ( PathSet :: Set ( set) ) ;
313353 self
@@ -320,7 +360,7 @@ impl<'a> ShouldRun<'a> {
320360 pub fn krate ( mut self , name : & str ) -> Self {
321361 for krate in self . builder . in_tree_crates ( name, None ) {
322362 let path = krate. local_path ( self . builder ) ;
323- self . paths . insert ( PathSet :: one ( path) ) ;
363+ self . paths . insert ( PathSet :: one ( path, self . kind ) ) ;
324364 }
325365 self
326366 }
@@ -332,7 +372,12 @@ impl<'a> ShouldRun<'a> {
332372
333373 // multiple aliases for the same job
334374 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+ ) ) ;
336381 self
337382 }
338383
@@ -344,7 +389,8 @@ impl<'a> ShouldRun<'a> {
344389 }
345390
346391 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 ( ) ) } ) ) ;
348394 self
349395 }
350396
@@ -354,12 +400,12 @@ impl<'a> ShouldRun<'a> {
354400 self
355401 }
356402
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 ) ) )
359405 }
360406}
361407
362- #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
408+ #[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Debug ) ]
363409pub enum Kind {
364410 Build ,
365411 Check ,
@@ -373,11 +419,44 @@ pub enum Kind {
373419 Run ,
374420}
375421
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+
376455impl < ' a > Builder < ' a > {
377456 fn get_step_descriptions ( kind : Kind ) -> Vec < StepDescription > {
378457 macro_rules! describe {
379458 ( $( $rule: ty) ,+ $( , ) ?) => { {
380- vec![ $( StepDescription :: from:: <$rule>( ) ) ,+]
459+ vec![ $( StepDescription :: from:: <$rule>( kind ) ) ,+]
381460 } } ;
382461 }
383462 match kind {
@@ -554,8 +633,11 @@ impl<'a> Builder<'a> {
554633
555634 let builder = Self :: new_internal ( build, kind, vec ! [ ] ) ;
556635 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 ) ;
558639 for desc in Builder :: get_step_descriptions ( builder. kind ) {
640+ should_run. kind = desc. kind ;
559641 should_run = ( desc. should_run ) ( should_run) ;
560642 }
561643 let mut help = String :: from ( "Available paths:\n " ) ;
@@ -1640,9 +1722,10 @@ impl<'a> Builder<'a> {
16401722 pub ( crate ) fn ensure_if_default < T , S : Step < Output = Option < T > > > (
16411723 & ' a self ,
16421724 step : S ,
1725+ kind : Kind ,
16431726 ) -> 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 ) ) ;
16461729
16471730 // Avoid running steps contained in --exclude
16481731 for pathset in & should_run. paths {
@@ -1656,13 +1739,16 @@ impl<'a> Builder<'a> {
16561739 }
16571740
16581741 /// 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 ) ) ;
16621745
16631746 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+ )
16661752 {
16671753 return true ;
16681754 }
0 commit comments