1
1
use clap:: { CommandFactory , Parser } ;
2
- use clap_complete:: Shell ;
3
2
#[ cfg( windows) ]
4
3
use espup:: env:: set_environment_variable;
5
4
use espup:: {
5
+ cli:: { CompletionsOpts , InstallOpts , UninstallOpts } ,
6
6
emoji,
7
- env:: { create_export_file, export_environment, get_export_file} ,
8
7
error:: Error ,
9
- host_triple:: get_host_triple,
10
8
logging:: initialize_logger,
11
- targets:: { parse_targets, Target } ,
12
9
toolchain:: {
13
- gcc:: { uninstall_gcc_toolchains, Gcc } ,
14
- llvm:: Llvm ,
15
- rust:: { check_rust_installation, get_rustup_home, RiscVTarget , XtensaRust } ,
16
- Installable ,
10
+ gcc:: uninstall_gcc_toolchains, install as toolchain_install, llvm:: Llvm ,
11
+ rust:: get_rustup_home,
17
12
} ,
18
13
update:: check_for_update,
19
14
} ;
20
- use log:: { debug , info, warn } ;
15
+ use log:: info;
21
16
use miette:: Result ;
22
- use std:: { collections:: HashSet , env, fs:: remove_dir_all, path:: PathBuf } ;
23
- use tokio:: sync:: mpsc;
24
- use tokio_retry:: { strategy:: FixedInterval , Retry } ;
17
+ use std:: { env, fs:: remove_dir_all} ;
25
18
26
19
#[ derive( Parser ) ]
27
20
#[ command( about, version) ]
@@ -40,77 +33,7 @@ pub enum SubCommand {
40
33
/// Uninstalls Espressif Rust ecosystem.
41
34
Uninstall ( UninstallOpts ) ,
42
35
/// Updates Xtensa Rust toolchain.
43
- Update ( UpdateOpts ) ,
44
- }
45
-
46
- #[ derive( Debug , Parser ) ]
47
- pub struct CompletionsOpts {
48
- /// Verbosity level of the logs.
49
- #[ arg( short = 'l' , long, default_value = "info" , value_parser = [ "debug" , "info" , "warn" , "error" ] ) ]
50
- pub log_level : String ,
51
- /// Shell to generate completions for.
52
- pub shell : Shell ,
53
- }
54
-
55
- #[ derive( Debug , Parser ) ]
56
- pub struct InstallOpts {
57
- /// Target triple of the host.
58
- #[ arg( short = 'd' , long, value_parser = [ "x86_64-unknown-linux-gnu" , "aarch64-unknown-linux-gnu" , "x86_64-pc-windows-msvc" , "x86_64-pc-windows-gnu" , "x86_64-apple-darwin" , "aarch64-apple-darwin" ] ) ]
59
- pub default_host : Option < String > ,
60
- /// Relative or full path for the export file that will be generated. If no path is provided, the file will be generated under home directory (https://docs.rs/dirs/latest/dirs/fn.home_dir.html).
61
- #[ arg( short = 'f' , long) ]
62
- pub export_file : Option < PathBuf > ,
63
- /// Extends the LLVM installation.
64
- ///
65
- /// This will install the whole LLVM instead of only installing the libs.
66
- #[ arg( short = 'e' , long) ]
67
- pub extended_llvm : bool ,
68
- /// Verbosity level of the logs.
69
- #[ arg( short = 'l' , long, default_value = "info" , value_parser = [ "debug" , "info" , "warn" , "error" ] ) ]
70
- pub log_level : String ,
71
- /// Xtensa Rust toolchain name.
72
- #[ arg( short = 'a' , long, default_value = "esp" ) ]
73
- pub name : String ,
74
- /// Nightly Rust toolchain version.
75
- #[ arg( short = 'n' , long, default_value = "nightly" ) ]
76
- pub nightly_version : String ,
77
- /// Only install toolchains required for STD applications.
78
- ///
79
- /// With this option, espup will skip GCC installation (it will be handled by esp-idf-sys), hence you won't be able to build no_std applications.
80
- #[ arg( short = 's' , long) ]
81
- pub std : bool ,
82
- /// Comma or space separated list of targets [esp32,esp32c2,esp32c3,esp32c6,esp32h2,esp32s2,esp32s3,all].
83
- #[ arg( short = 't' , long, default_value = "all" , value_parser = parse_targets) ]
84
- pub targets : HashSet < Target > ,
85
- /// Xtensa Rust toolchain version.
86
- #[ arg( short = 'v' , long, value_parser = XtensaRust :: parse_version) ]
87
- pub toolchain_version : Option < String > ,
88
- }
89
-
90
- #[ derive( Debug , Parser ) ]
91
- pub struct UpdateOpts {
92
- /// Target triple of the host.
93
- #[ arg( short = 'd' , long, value_parser = [ "x86_64-unknown-linux-gnu" , "aarch64-unknown-linux-gnu" , "x86_64-pc-windows-msvc" , "x86_64-pc-windows-gnu" , "x86_64-apple-darwin" , "aarch64-apple-darwin" ] ) ]
94
- pub default_host : Option < String > ,
95
- /// Verbosity level of the logs.
96
- #[ arg( short = 'l' , long, default_value = "info" , value_parser = [ "debug" , "info" , "warn" , "error" ] ) ]
97
- pub log_level : String ,
98
- /// Xtensa Rust toolchain name.
99
- #[ arg( short = 'a' , long, default_value = "esp" ) ]
100
- pub name : String ,
101
- /// Xtensa Rust toolchain version.
102
- #[ arg( short = 'v' , long, value_parser = XtensaRust :: parse_version) ]
103
- pub toolchain_version : Option < String > ,
104
- }
105
-
106
- #[ derive( Debug , Parser ) ]
107
- pub struct UninstallOpts {
108
- /// Verbosity level of the logs.
109
- #[ arg( short = 'l' , long, default_value = "info" , value_parser = [ "debug" , "info" , "warn" , "error" ] ) ]
110
- pub log_level : String ,
111
- /// Xtensa Rust toolchain name.
112
- #[ arg( short = 'a' , long, default_value = "esp" ) ]
113
- pub name : String ,
36
+ Update ( Box < InstallOpts > ) ,
114
37
}
115
38
116
39
/// Updates Xtensa Rust toolchain.
@@ -142,122 +65,8 @@ async fn install(args: InstallOpts) -> Result<()> {
142
65
check_for_update ( env ! ( "CARGO_PKG_NAME" ) , env ! ( "CARGO_PKG_VERSION" ) ) ;
143
66
144
67
info ! ( "{} Installing the Espressif Rust ecosystem" , emoji:: DISC ) ;
145
-
146
- let export_file = get_export_file ( args. export_file ) ?;
147
- let mut exports: Vec < String > = Vec :: new ( ) ;
148
- let host_triple = get_host_triple ( args. default_host ) ?;
149
- let xtensa_rust_version = if let Some ( toolchain_version) = & args. toolchain_version {
150
- toolchain_version. clone ( )
151
- } else {
152
- XtensaRust :: get_latest_version ( ) . await ?
153
- } ;
154
- let install_path = get_rustup_home ( ) . join ( "toolchains" ) . join ( args. name ) ;
155
- let llvm: Llvm = Llvm :: new (
156
- & install_path,
157
- & host_triple,
158
- args. extended_llvm ,
159
- & xtensa_rust_version,
160
- ) ?;
161
- let targets = args. targets ;
162
- let xtensa_rust = if targets. contains ( & Target :: ESP32 )
163
- || targets. contains ( & Target :: ESP32S2 )
164
- || targets. contains ( & Target :: ESP32S3 )
165
- {
166
- Some ( XtensaRust :: new (
167
- & xtensa_rust_version,
168
- & host_triple,
169
- & install_path,
170
- ) )
171
- } else {
172
- None
173
- } ;
174
-
175
- debug ! (
176
- "{} Arguments:
177
- - Export file: {:?}
178
- - Host triple: {}
179
- - LLVM Toolchain: {:?}
180
- - Nightly version: {:?}
181
- - Rust Toolchain: {:?}
182
- - Targets: {:?}
183
- - Toolchain path: {:?}
184
- - Toolchain version: {:?}" ,
185
- emoji:: INFO ,
186
- & export_file,
187
- host_triple,
188
- & llvm,
189
- & args. nightly_version,
190
- xtensa_rust,
191
- targets,
192
- & install_path,
193
- args. toolchain_version,
194
- ) ;
195
-
196
- check_rust_installation ( ) . await ?;
197
-
198
- // Build up a vector of installable applications, all of which implement the
199
- // `Installable` async trait.
200
- let mut to_install = Vec :: < Box < dyn Installable + Send + Sync > > :: new ( ) ;
201
-
202
- if let Some ( ref xtensa_rust) = xtensa_rust {
203
- to_install. push ( Box :: new ( xtensa_rust. to_owned ( ) ) ) ;
204
- }
205
-
206
- to_install. push ( Box :: new ( llvm) ) ;
207
-
208
- if targets. iter ( ) . any ( |t| t. is_riscv ( ) ) {
209
- let riscv_target = RiscVTarget :: new ( & args. nightly_version ) ;
210
- to_install. push ( Box :: new ( riscv_target) ) ;
211
- }
212
-
213
- if !args. std {
214
- targets. iter ( ) . for_each ( |target| {
215
- if target. is_xtensa ( ) {
216
- let gcc = Gcc :: new ( target, & host_triple, & install_path) ;
217
- to_install. push ( Box :: new ( gcc) ) ;
218
- }
219
- } ) ;
220
- // All RISC-V targets use the same GCC toolchain
221
- // ESP32S2 and ESP32S3 also install the RISC-V toolchain for their ULP coprocessor
222
- if targets. iter ( ) . any ( |t| t != & Target :: ESP32 ) {
223
- let riscv_gcc = Gcc :: new_riscv ( & host_triple, & install_path) ;
224
- to_install. push ( Box :: new ( riscv_gcc) ) ;
225
- }
226
- }
227
-
228
- // With a list of applications to install, install them all in parallel.
229
- let installable_items = to_install. len ( ) ;
230
- let ( tx, mut rx) = mpsc:: channel :: < Result < Vec < String > , Error > > ( installable_items) ;
231
- for app in to_install {
232
- let tx = tx. clone ( ) ;
233
- let retry_strategy = FixedInterval :: from_millis ( 50 ) . take ( 3 ) ;
234
- tokio:: spawn ( async move {
235
- let res = Retry :: spawn ( retry_strategy, || async {
236
- let res = app. install ( ) . await ;
237
- if res. is_err ( ) {
238
- warn ! (
239
- "{} Installation for '{}' failed, retrying" ,
240
- emoji:: WARN ,
241
- app. name( )
242
- ) ;
243
- }
244
- res
245
- } )
246
- . await ;
247
- tx. send ( res) . await . unwrap ( ) ;
248
- } ) ;
249
- }
250
-
251
- // Read the results of the install tasks as they complete.
252
- for _ in 0 ..installable_items {
253
- let names = rx. recv ( ) . await . unwrap ( ) ?;
254
- exports. extend ( names) ;
255
- }
256
-
257
- create_export_file ( & export_file, & exports) ?;
258
-
68
+ toolchain_install ( args) . await ?;
259
69
info ! ( "{} Installation successfully completed!" , emoji:: CHECK ) ;
260
- export_environment ( & export_file) ?;
261
70
Ok ( ( ) )
262
71
}
263
72
@@ -290,34 +99,12 @@ async fn uninstall(args: UninstallOpts) -> Result<()> {
290
99
}
291
100
292
101
/// Updates Xtensa Rust toolchain.
293
- async fn update ( args : UpdateOpts ) -> Result < ( ) > {
102
+ async fn update ( args : InstallOpts ) -> Result < ( ) > {
294
103
initialize_logger ( & args. log_level ) ;
295
104
check_for_update ( env ! ( "CARGO_PKG_NAME" ) , env ! ( "CARGO_PKG_VERSION" ) ) ;
296
105
297
106
info ! ( "{} Updating Espressif Rust ecosystem" , emoji:: DISC ) ;
298
-
299
- let host_triple = get_host_triple ( args. default_host ) ?;
300
- let install_path = get_rustup_home ( ) . join ( "toolchains" ) . join ( args. name ) ;
301
- let xtensa_rust: XtensaRust = if let Some ( toolchain_version) = args. toolchain_version {
302
- XtensaRust :: new ( & toolchain_version, & host_triple, & install_path)
303
- } else {
304
- let latest_version = XtensaRust :: get_latest_version ( ) . await ?;
305
- XtensaRust :: new ( & latest_version, & host_triple, & install_path)
306
- } ;
307
-
308
- debug ! (
309
- "{} Arguments:
310
- - Host triple: {}
311
- - Install path: {:#?}
312
- - Toolchain version: {:#?}" ,
313
- emoji:: INFO ,
314
- host_triple,
315
- install_path,
316
- xtensa_rust,
317
- ) ;
318
-
319
- xtensa_rust. install ( ) . await ?;
320
-
107
+ toolchain_install ( args) . await ?;
321
108
info ! ( "{} Update successfully completed!" , emoji:: CHECK ) ;
322
109
Ok ( ( ) )
323
110
}
@@ -327,7 +114,7 @@ async fn main() -> Result<()> {
327
114
match Cli :: parse ( ) . subcommand {
328
115
SubCommand :: Completions ( args) => completions ( args) . await ,
329
116
SubCommand :: Install ( args) => install ( * args) . await ,
330
- SubCommand :: Update ( args) => update ( args) . await ,
117
+ SubCommand :: Update ( args) => update ( * args) . await ,
331
118
SubCommand :: Uninstall ( args) => uninstall ( args) . await ,
332
119
}
333
120
}
0 commit comments