@@ -4,8 +4,9 @@ use std::collections::BTreeSet;
44use std:: env;
55use std:: ffi:: OsStr ;
66use std:: fmt:: { Debug , Write } ;
7- use std:: fs:: { self } ;
7+ use std:: fs:: { self , File } ;
88use std:: hash:: Hash ;
9+ use std:: io:: { BufRead , BufReader } ;
910use std:: ops:: Deref ;
1011use std:: path:: { Component , Path , PathBuf } ;
1112use std:: process:: Command ;
@@ -28,8 +29,11 @@ use crate::{clean, dist};
2829use crate :: { Build , CLang , DocTests , GitRepo , Mode } ;
2930
3031pub use crate :: Compiler ;
31- // FIXME: replace with std::lazy after it gets stabilized and reaches beta
32- use once_cell:: sync:: Lazy ;
32+ // FIXME:
33+ // - use std::lazy for `Lazy`
34+ // - use std::cell for `OnceCell`
35+ // Once they get stabilized and reach beta.
36+ use once_cell:: sync:: { Lazy , OnceCell } ;
3337
3438pub struct Builder < ' a > {
3539 pub build : & ' a Build ,
@@ -484,17 +488,43 @@ impl<'a> ShouldRun<'a> {
484488
485489 // multiple aliases for the same job
486490 pub fn paths ( mut self , paths : & [ & str ] ) -> Self {
491+ static SUBMODULES_PATHS : OnceCell < Vec < String > > = OnceCell :: new ( ) ;
492+
493+ let init_submodules_paths = |src : & PathBuf | {
494+ let file = File :: open ( src. join ( ".gitmodules" ) ) . unwrap ( ) ;
495+
496+ let mut submodules_paths = vec ! [ ] ;
497+ for line in BufReader :: new ( file) . lines ( ) {
498+ if let Ok ( line) = line {
499+ let line = line. trim ( ) ;
500+
501+ if line. starts_with ( "path" ) {
502+ let actual_path =
503+ line. split ( ' ' ) . last ( ) . expect ( "Couldn't get value of path" ) ;
504+ submodules_paths. push ( actual_path. to_owned ( ) ) ;
505+ }
506+ }
507+ }
508+
509+ submodules_paths
510+ } ;
511+
512+ let submodules_paths =
513+ SUBMODULES_PATHS . get_or_init ( || init_submodules_paths ( & self . builder . src ) ) ;
514+
487515 self . paths . insert ( PathSet :: Set (
488516 paths
489517 . iter ( )
490518 . map ( |p| {
491- // FIXME(#96188): make sure this is actually a path.
492- // This currently breaks for paths within submodules.
493- //assert!(
494- // self.builder.src.join(p).exists(),
495- // "`should_run.paths` should correspond to real on-disk paths - use `alias` if there is no relevant path: {}",
496- // p
497- //);
519+ // assert only if `p` isn't submodule
520+ if !submodules_paths. iter ( ) . find ( |sm_p| p. contains ( * sm_p) ) . is_some ( ) {
521+ assert ! (
522+ self . builder. src. join( p) . exists( ) ,
523+ "`should_run.paths` should correspond to real on-disk paths - use `alias` if there is no relevant path: {}" ,
524+ p
525+ ) ;
526+ }
527+
498528 TaskPath { path : p. into ( ) , kind : Some ( self . kind ) }
499529 } )
500530 . collect ( ) ,
0 commit comments