1
+ use crate :: builder:: { Builder , RunConfig , ShouldRun , Step } ;
1
2
use crate :: Config ;
2
3
use crate :: { t, VERSION } ;
3
4
use std:: env:: consts:: EXE_SUFFIX ;
@@ -9,7 +10,7 @@ use std::process::Command;
9
10
use std:: str:: FromStr ;
10
11
use std:: { fmt, fs, io} ;
11
12
12
- #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
13
+ #[ derive( Clone , Copy , Debug , Eq , PartialEq , Hash ) ]
13
14
pub enum Profile {
14
15
Compiler ,
15
16
Codegen ,
@@ -48,6 +49,16 @@ impl Profile {
48
49
}
49
50
out
50
51
}
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
+ }
51
62
}
52
63
53
64
impl FromStr for Profile {
@@ -69,24 +80,58 @@ impl FromStr for Profile {
69
80
70
81
impl fmt:: Display for Profile {
71
82
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 ( ) ) ;
78
94
}
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 )
79
125
}
80
126
}
81
127
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 ) {
84
129
let stage_path =
85
130
[ "build" , config. build . rustc_target_arg ( ) , "stage1" ] . join ( & MAIN_SEPARATOR . to_string ( ) ) ;
86
131
87
132
if !rustup_installed ( ) && profile != Profile :: User {
88
133
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 ( ) {
90
135
attempt_toolchain_link ( & stage_path[ ..] ) ;
91
136
}
92
137
@@ -104,7 +149,9 @@ pub fn setup(config: &Config, profile: Option<Profile>) {
104
149
Profile :: User => & [ "dist" , "build" ] ,
105
150
} ;
106
151
107
- t ! ( install_git_hook_maybe( & config) ) ;
152
+ if !config. dry_run ( ) {
153
+ t ! ( install_git_hook_maybe( & config) ) ;
154
+ }
108
155
109
156
println ! ( ) ;
110
157
@@ -144,6 +191,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
144
191
changelog-seen = {}\n ",
145
192
profile, VERSION
146
193
) ;
194
+
147
195
t ! ( fs:: write( path, settings) ) ;
148
196
149
197
let include_path = profile. include_path ( & config. src ) ;
0 commit comments