1use log::info;
5
6use assemble_core::dependencies::configurations::Configuration;
7use assemble_core::error::PayloadError;
8use assemble_core::exception::BuildException;
9
10use assemble_core::file_collection::FileCollection;
11
12use assemble_core::plugins::extensions::ExtensionAware;
13
14use assemble_core::project::error::{ProjectError, ProjectResult};
15use assemble_core::task::create_task::CreateTask;
16
17use assemble_core::task::up_to_date::UpToDate;
18
19use assemble_std::dependencies::web::{WebDependency, WebRegistry};
20use assemble_std::specs::exec_spec::Output;
21
22use assemble_std::ProjectExec;
23
24use crate::extensions::RustPluginExtension;
25use crate::plugin::RustBasePlugin;
26use crate::prelude::*;
27use crate::rustup::install::InstallToolchain;
28
29pub mod install;
30
31pub fn configure_rustup_tasks(project: &mut Project) -> ProjectResult<()> {
33 let mut install = project
34 .task_container_mut()
35 .register_task::<Empty>("install-rustup")?;
36
37 install.configure_with(|t, _| {
38 t.set_description("installs rustup on to the system if not already present");
39 t.set_group("rustup");
40
41 t.up_to_date(|_| which::which("rustup").is_ok());
42
43 Ok(())
44 })?;
45
46 let rustup_install_config = if cfg!(windows) {
47 configure_windows_install(project)?
48 } else if cfg!(unix) {
49 configure_unix_install(project)?
50 } else {
51 return Err(ProjectError::custom("unsupported os for rustup").into());
52 };
53
54 install.configure_with(move |task, _project| -> ProjectResult<()> {
55 task.depends_on(rustup_install_config.clone());
56 task.do_first(move |_task, project| {
57 if which::which("rustup").is_ok() {
58 return Err(BuildException::StopTask.into());
59 }
60
61 let configuration = rustup_install_config
62 .resolved()
63 .map_err(|e| PayloadError::<ProjectError>::new(e))?;
64 let rustup_init_file = configuration.files().into_iter().next().unwrap();
65 println!("rustup file = {:?}", rustup_init_file);
66
67 match project.exec_with(move |exec| {
68 exec.exec(rustup_init_file)
69 .args(["--default-toolchain", "none"])
70 .args(["--profile", "minimal"])
71 .arg("-v")
72 .stdout(Output::Bytes)
73 .stderr(Output::Bytes);
74 }) {
75 Ok(handle) => {
76 let string = handle
77 .utf8_string_err()
78 .unwrap()
79 .map_err(PayloadError::<ProjectError>::new)?;
80 info!("rustup log: {}", string);
81 if string.contains("error: cannot install while Rust is installed") {
82 info!("assuming ok");
83 return Ok(());
84 }
85 if !handle.success() {
86 return Err(BuildException::custom(
87 "installing rustup fail. Check console log for more info.",
88 )
89 .into());
90 }
91 }
92 Err(e) => return Err(BuildException::from(e).into()),
93 }
94
95 Ok(())
96 })?;
97
98 Ok(())
99 })?;
100 project
101 .task_container_mut()
102 .register_task_with::<InstallToolchain, _>(
103 RustBasePlugin::INSTALL_DEFAULT_TOOLCHAIN,
104 |t, p| {
105 t.set_description("installs the default toolchain used by this project");
106 t.set_group("rustup");
107
108 let extension = p.extension::<RustPluginExtension>().unwrap();
109 t.depends_on(install);
110 t.toolchain.set_with(extension.toolchain.clone())?;
111 Ok(())
112 },
113 )?;
114
115 Ok(())
116}
117
118fn configure_unix_install(project: &mut Project) -> ProjectResult<Configuration> {
119 project.registries_mut(|reg| {
120 let registry = WebRegistry::new("rust-site", "https://sh.rustup.rs/").unwrap();
121 reg.add_registry(registry);
122 Ok(())
123 })?;
124 let rustup_install_config = project
125 .configurations_mut()
126 .create_with("rustupInstall", |config| {
127 config.add_dependency(
128 WebDependency::new("", "rust-site").with_file_name("rustup-startup.sh"),
129 )
130 })
131 .clone();
132
133 Ok(rustup_install_config)
134}
135
136fn configure_windows_install(project: &mut Project) -> ProjectResult<Configuration> {
137 project.registries_mut(|reg| {
138 let registry = WebRegistry::new("rust-site", "https://static.rust-lang.org/").unwrap();
139 reg.add_registry(registry);
140 Ok(())
141 })?;
142 let rustup_install_config = project
143 .configurations_mut()
144 .create_with("rustup-install", |config| {
145 #[cfg(target_pointer_width = "64")]
146 config.add_dependency(WebDependency::new(
147 "/rustup/dist/x86_64-pc-windows-msvc/rustup-startup.exe",
148 "rust-site",
149 ));
150 #[cfg(target_pointer_width = "32")]
151 config.add_dependency(WebDependency::new(
152 "/rustup/dist/i686-pc-windows-msvc/rustup-startup.exe",
153 "rust-site",
154 ));
155 })
156 .clone();
157
158 Ok(rustup_install_config)
159}