1+ use crate :: builder:: { Builder , RunConfig , ShouldRun , Step } ;
12use crate :: Config ;
23use crate :: { t, VERSION } ;
34use std:: env:: consts:: EXE_SUFFIX ;
@@ -9,7 +10,7 @@ use std::process::Command;
910use std:: str:: FromStr ;
1011use std:: { fmt, fs, io} ;
1112
12- #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
13+ #[ derive( Clone , Copy , Debug , Eq , PartialEq , Hash ) ]
1314pub enum Profile {
1415 Compiler ,
1516 Codegen ,
@@ -48,6 +49,16 @@ impl Profile {
4849 }
4950 out
5051 }
52+
53+ pub fn as_str ( & self ) -> & ' static str {
54+ match self {
55+ Profile :: Compiler => "compiler" ,
56+ Profile :: Codegen => "codegen" ,
57+ Profile :: Library => "library" ,
58+ Profile :: Tools => "tools" ,
59+ Profile :: User => "user" ,
60+ }
61+ }
5162}
5263
5364impl FromStr for Profile {
@@ -69,24 +80,58 @@ impl FromStr for Profile {
6980
7081impl fmt:: Display for Profile {
7182 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
72- match self {
73- Profile :: Compiler => write ! ( f, "compiler" ) ,
74- Profile :: Codegen => write ! ( f, "codegen" ) ,
75- Profile :: Library => write ! ( f, "library" ) ,
76- Profile :: User => write ! ( f, "user" ) ,
77- Profile :: Tools => write ! ( f, "tools" ) ,
83+ f. write_str ( self . as_str ( ) )
84+ }
85+ }
86+
87+ impl Step for Profile {
88+ type Output = ( ) ;
89+ const DEFAULT : bool = true ;
90+
91+ fn should_run ( mut run : ShouldRun < ' _ > ) -> ShouldRun < ' _ > {
92+ for choice in Profile :: all ( ) {
93+ run = run. alias ( choice. as_str ( ) ) ;
7894 }
95+ run
96+ }
97+
98+ fn make_run ( run : RunConfig < ' _ > ) {
99+ // for Profile, `run.paths` will have 1 and only 1 element
100+ // this is because we only accept at most 1 path from user input.
101+ // If user calls `x.py setup` without arguments, the interactive TUI
102+ // will guide user to provide one.
103+ let profile = if run. paths . len ( ) > 1 {
104+ // HACK: `builder` runs this step with all paths if no path was passed.
105+ t ! ( interactive_path( ) )
106+ } else {
107+ run. paths
108+ . first ( )
109+ . unwrap ( )
110+ . assert_single_path ( )
111+ . path
112+ . as_path ( )
113+ . as_os_str ( )
114+ . to_str ( )
115+ . unwrap ( )
116+ . parse ( )
117+ . unwrap ( )
118+ } ;
119+
120+ run. builder . ensure ( profile) ;
121+ }
122+
123+ fn run ( self , builder : & Builder < ' _ > ) {
124+ setup ( & builder. build . config , self )
79125 }
80126}
81127
82- pub fn setup ( config : & Config , profile : Option < Profile > ) {
83- let profile = profile. unwrap_or_else ( || t ! ( interactive_path( ) ) ) ;
128+ pub fn setup ( config : & Config , profile : Profile ) {
84129 let stage_path =
85130 [ "build" , config. build . rustc_target_arg ( ) , "stage1" ] . join ( & MAIN_SEPARATOR . to_string ( ) ) ;
86131
87132 if !rustup_installed ( ) && profile != Profile :: User {
88133 eprintln ! ( "`rustup` is not installed; cannot link `stage1` toolchain" ) ;
89- } else if stage_dir_exists ( & stage_path[ ..] ) {
134+ } else if stage_dir_exists ( & stage_path[ ..] ) && !config . dry_run ( ) {
90135 attempt_toolchain_link ( & stage_path[ ..] ) ;
91136 }
92137
@@ -104,7 +149,9 @@ pub fn setup(config: &Config, profile: Option<Profile>) {
104149 Profile :: User => & [ "dist" , "build" ] ,
105150 } ;
106151
107- t ! ( install_git_hook_maybe( & config) ) ;
152+ if !config. dry_run ( ) {
153+ t ! ( install_git_hook_maybe( & config) ) ;
154+ }
108155
109156 println ! ( ) ;
110157
@@ -144,6 +191,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
144191 changelog-seen = {}\n ",
145192 profile, VERSION
146193 ) ;
194+
147195 t ! ( fs:: write( path, settings) ) ;
148196
149197 let include_path = profile. include_path ( & config. src ) ;
0 commit comments