envhub_ext/
rustup.rs

1use std::{
2    env,
3    process::{Command, Stdio},
4};
5
6use anyhow::Error;
7use envhub_types::configuration::Configuration;
8
9use crate::Extension;
10
11pub struct Rustup {}
12
13impl Rustup {
14    pub fn new() -> Self {
15        Self {}
16    }
17
18    pub fn set_default_toolchain(&self, toolchain: &str) -> Result<(), Error> {
19        let mut child = Command::new("sh")
20            .arg("-c")
21            .arg(format!(
22                "rustup toolchain install {} && rustup default {}",
23                toolchain, toolchain
24            ))
25            .stdin(Stdio::inherit())
26            .stdout(Stdio::inherit())
27            .stderr(Stdio::inherit())
28            .spawn()?;
29        child.wait()?;
30        Ok(())
31    }
32
33    pub fn install_toolchains(&self, toolchains: Vec<String>) -> Result<(), Error> {
34        for toolchain in toolchains {
35            let mut child = Command::new("sh")
36                .arg("-c")
37                .arg(format!("rustup toolchain install {}", toolchain))
38                .stdin(Stdio::inherit())
39                .stdout(Stdio::inherit())
40                .stderr(Stdio::inherit())
41                .spawn()?;
42            child.wait()?;
43        }
44        Ok(())
45    }
46
47    pub fn install_components(&self, components: Vec<String>) -> Result<(), Error> {
48        for component in components {
49            let mut child = Command::new("sh")
50                .arg("-c")
51                .arg(format!("rustup component add {}", component))
52                .stdin(Stdio::inherit())
53                .stdout(Stdio::inherit())
54                .stderr(Stdio::inherit())
55                .spawn()?;
56            child.wait()?;
57        }
58        Ok(())
59    }
60
61    pub fn add_targets(&self, targets: Vec<String>) -> Result<(), Error> {
62        for target in targets {
63            let mut child = Command::new("sh")
64                .arg("-c")
65                .arg(format!("rustup target add {}", target))
66                .stdin(Stdio::inherit())
67                .stdout(Stdio::inherit())
68                .stderr(Stdio::inherit())
69                .spawn()?;
70            child.wait()?;
71        }
72        Ok(())
73    }
74}
75
76impl Extension for Rustup {
77    fn load(&self, config: &Configuration) -> Result<(), Error> {
78        self.setup()?;
79        match config.rustup {
80            Some(ref rustup) => {
81                if let Some(value) = &rustup.default {
82                    self.set_default_toolchain(value)?;
83                }
84                if let Some(value) = &rustup.toolchains {
85                    self.install_toolchains(value.clone())?;
86                }
87                if let Some(value) = &rustup.components {
88                    self.install_components(value.clone())?;
89                }
90                if let Some(value) = &rustup.targets {
91                    self.add_targets(value.clone())?;
92                }
93            }
94            None => {}
95        }
96        Ok(())
97    }
98
99    fn setup(&self) -> Result<(), Error> {
100        env::set_var(
101            "PATH",
102            format!("{}/.cargo/bin:{}", env::var("HOME")?, env::var("PATH")?),
103        );
104        let mut child = Command::new("sh")
105            .arg("-c")
106            .arg("type rustup > /dev/null || curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh")
107            .stdin(Stdio::inherit())
108            .stdout(Stdio::inherit())
109            .stderr(Stdio::inherit())
110            .spawn()?;
111        child.wait()?;
112
113        Ok(())
114    }
115}