@@ -619,7 +619,7 @@ impl Config {
619619 config
620620 }
621621
622- pub fn parse ( args : & [ String ] ) -> Config {
622+ pub fn parse ( args : & [ String ] , unit_test : bool ) -> Config {
623623 let flags = Flags :: parse ( & args) ;
624624
625625 let mut config = Config :: default_opts ( ) ;
@@ -682,11 +682,26 @@ impl Config {
682682 let build = toml. build . unwrap_or_default ( ) ;
683683
684684 set ( & mut config. out , build. build_dir . map ( String :: into) ) ;
685- t ! ( fs:: create_dir_all( & config. out) ) ;
686- config. out = t ! (
687- config. out. canonicalize( ) ,
688- format!( "failed to canonicalize {}" , config. out. display( ) )
689- ) ;
685+ // NOTE: Bootstrap spawns various commands with different working directories.
686+ // To avoid writing to random places on the file system, `config.out` needs to be an absolute path.
687+
688+ // FIXME: using `canonicalize()` makes this a lot more complicated than it needs to be -
689+ // if/when `std::path::absolute` lands, we should use that instead.
690+
691+ // HACK: in tests, we override the build directory manually.
692+ // Avoid creating a directory we won't actually need.
693+ // (The original motivation for this is that CI uses read-only directories.)
694+ if !config. out . is_absolute ( ) && !unit_test {
695+ // canonicalize() gives a hard error if the directory doesn't exist
696+ t ! (
697+ fs:: create_dir_all( & config. out) ,
698+ format!( "failed to create build dir: {}" , config. out. display( ) )
699+ ) ;
700+ config. out = t ! (
701+ config. out. canonicalize( ) ,
702+ format!( "failed to canonicalize {}" , config. out. display( ) )
703+ ) ;
704+ }
690705
691706 if config. dry_run {
692707 let dir = config. out . join ( "tmp-dry-run" ) ;
0 commit comments