From 43563c2bcf4ffe264dc0c5b16cee7e0afd24ba94 Mon Sep 17 00:00:00 2001 From: Tsiry Sandratraina Date: Fri, 23 Feb 2024 07:38:27 +0000 Subject: [PATCH 1/2] feat: add builtin extension for `rustup` --- Cargo.lock | 6 +- README.md | 2 +- crates/cli/Cargo.toml | 2 +- crates/cli/src/cmd/use.rs | 7 +- crates/ext/Cargo.toml | 4 +- crates/ext/src/lib.rs | 1 + crates/ext/src/rustup.rs | 115 ++++++++++++++++++++++++++++++ crates/types/Cargo.toml | 2 +- crates/types/src/configuration.rs | 17 +++++ examples/rustup/envhub.hcl | 17 +++++ flake.nix | 2 +- 11 files changed, 165 insertions(+), 10 deletions(-) create mode 100644 crates/ext/src/rustup.rs create mode 100644 examples/rustup/envhub.hcl diff --git a/Cargo.lock b/Cargo.lock index 4443ce0..06fdac8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -383,7 +383,7 @@ checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "envhub" -version = "0.2.11" +version = "0.2.12" dependencies = [ "anyhow", "clap 3.2.25", @@ -403,7 +403,7 @@ dependencies = [ [[package]] name = "envhub-ext" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "envhub-types", @@ -446,7 +446,7 @@ dependencies = [ [[package]] name = "envhub-types" -version = "0.2.1" +version = "0.2.2" dependencies = [ "hcl-rs", "indexmap 1.9.3", diff --git a/README.md b/README.md index e93c01e..bb5dad3 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,6 @@ You can use EnvHub as a [GitHub Action](https://github.com/tsirysndr/setup-envhu ```yaml - uses: tsirysndr/setup-envhub@v1 with: - version: 'v0.2.11' + version: 'v0.2.12' - run: envhub --help ``` diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 335f40a..e07edd7 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT" name = "envhub" readme = "../../README.md" repository = "https://github.com/tsirysndr/envhub" -version = "0.2.11" +version = "0.2.12" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/cli/src/cmd/use.rs b/crates/cli/src/cmd/use.rs index 9f7edb9..f60e7f2 100644 --- a/crates/cli/src/cmd/use.rs +++ b/crates/cli/src/cmd/use.rs @@ -1,7 +1,7 @@ use std::fs; use anyhow::Error; -use envhub_ext::{rtx::Rtx, Extension}; +use envhub_ext::{rtx::Rtx, rustup::Rustup, Extension}; use envhub_hm::switch::switch_env; use envhub_providers::{github::Github, local::Local, s3::S3, Provider}; use envhub_stow::stow::stow; @@ -49,6 +49,11 @@ pub fn use_environment(name: &str, backup: bool) -> Result<(), Error> { rtx.load(&config)?; } + if config.rustup.is_some() { + let rustup: Box = Box::new(Rustup::new()); + rustup.load(&config)?; + } + switch_env(Some(&home_manager_dir), &config, backup)?; let state = toml::to_string(&config)?; diff --git a/crates/ext/Cargo.toml b/crates/ext/Cargo.toml index 76eb981..b490825 100644 --- a/crates/ext/Cargo.toml +++ b/crates/ext/Cargo.toml @@ -7,10 +7,10 @@ keywords = ["nix", "shell", "environment", "dotfiles"] license = "MIT" name = "envhub-ext" repository = "https://github.com/tsirysndr/envhub" -version = "0.1.0" +version = "0.1.1" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] anyhow = "1.0.71" -envhub-types = {version = "0.2.0", path = "../types"} +envhub-types = {version = "0.2.2", path = "../types"} diff --git a/crates/ext/src/lib.rs b/crates/ext/src/lib.rs index ab57d9d..7bd1f2f 100644 --- a/crates/ext/src/lib.rs +++ b/crates/ext/src/lib.rs @@ -2,6 +2,7 @@ use anyhow::Error; use envhub_types::configuration::Configuration; pub mod rtx; +pub mod rustup; pub trait Extension { fn load(&self, config: &Configuration) -> Result<(), Error>; diff --git a/crates/ext/src/rustup.rs b/crates/ext/src/rustup.rs new file mode 100644 index 0000000..f020234 --- /dev/null +++ b/crates/ext/src/rustup.rs @@ -0,0 +1,115 @@ +use std::{ + env, + process::{Command, Stdio}, +}; + +use anyhow::Error; +use envhub_types::configuration::Configuration; + +use crate::Extension; + +pub struct Rustup {} + +impl Rustup { + pub fn new() -> Self { + Self {} + } + + pub fn set_default_toolchain(&self, toolchain: &str) -> Result<(), Error> { + let mut child = Command::new("sh") + .arg("-c") + .arg(format!( + "rustup toolchain install {} && rustup default {}", + toolchain, toolchain + )) + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .spawn()?; + child.wait()?; + Ok(()) + } + + pub fn install_toolchains(&self, toolchains: Vec) -> Result<(), Error> { + for toolchain in toolchains { + let mut child = Command::new("sh") + .arg("-c") + .arg(format!("rustup toolchain install {}", toolchain)) + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .spawn()?; + child.wait()?; + } + Ok(()) + } + + pub fn install_components(&self, components: Vec) -> Result<(), Error> { + for component in components { + let mut child = Command::new("sh") + .arg("-c") + .arg(format!("rustup component add {}", component)) + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .spawn()?; + child.wait()?; + } + Ok(()) + } + + pub fn add_targets(&self, targets: Vec) -> Result<(), Error> { + for target in targets { + let mut child = Command::new("sh") + .arg("-c") + .arg(format!("rustup target add {}", target)) + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .spawn()?; + child.wait()?; + } + Ok(()) + } +} + +impl Extension for Rustup { + fn load(&self, config: &Configuration) -> Result<(), Error> { + self.setup()?; + match config.rustup { + Some(ref rustup) => { + if let Some(value) = &rustup.default { + self.set_default_toolchain(value)?; + } + if let Some(value) = &rustup.toolchains { + self.install_toolchains(value.clone())?; + } + if let Some(value) = &rustup.components { + self.install_components(value.clone())?; + } + if let Some(value) = &rustup.targets { + self.add_targets(value.clone())?; + } + } + None => {} + } + Ok(()) + } + + fn setup(&self) -> Result<(), Error> { + env::set_var( + "PATH", + format!("{}/.cargo/bin:{}", env::var("HOME")?, env::var("PATH")?), + ); + let mut child = Command::new("sh") + .arg("-c") + .arg("type rustup > /dev/null || curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh") + .stdin(Stdio::inherit()) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .spawn()?; + child.wait()?; + + Ok(()) + } +} diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index e38a3fb..7032410 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -7,7 +7,7 @@ keywords = ["nix", "shell", "environment", "dotfiles"] license = "MIT" name = "envhub-types" repository = "https://github.com/tsirysndr/envhub" -version = "0.2.1" +version = "0.2.2" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/types/src/configuration.rs b/crates/types/src/configuration.rs index 6babc92..13458ac 100644 --- a/crates/types/src/configuration.rs +++ b/crates/types/src/configuration.rs @@ -24,6 +24,18 @@ pub struct RtxParams { pub packages: Vec, } +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub struct RustupParams { + #[serde(skip_serializing_if = "Option::is_none")] + pub default: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub toolchains: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub components: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub targets: Option>, +} + #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct Configuration { #[serde(skip_serializing_if = "Option::is_none")] @@ -70,4 +82,9 @@ pub struct Configuration { serialize_with = "hcl::ser::block" )] pub rtx: Option, + #[serde( + skip_serializing_if = "Option::is_none", + serialize_with = "hcl::ser::block" + )] + pub rustup: Option, } diff --git a/examples/rustup/envhub.hcl b/examples/rustup/envhub.hcl new file mode 100644 index 0000000..e5fc8aa --- /dev/null +++ b/examples/rustup/envhub.hcl @@ -0,0 +1,17 @@ +packages = [ + "hello" +] + +rustup { + default = "stable" + toolchains = [ + "nightly" + ] + components = [ + "clippy", + "llvm-tools" + ] + targets = [ + "wasm32-wasi", + ] +} diff --git a/flake.nix b/flake.nix index 37cdc88..eb1555e 100644 --- a/flake.nix +++ b/flake.nix @@ -40,7 +40,7 @@ inherit src; pname = "envhub"; - version = "0.2.9"; + version = "0.2.12"; cargoExtraArgs = "--package=envhub"; buildInputs = [ From 499c3ac7013493768d7692f4b93ba6889c79ee75 Mon Sep 17 00:00:00 2001 From: Tsiry Sandratraina Date: Fri, 23 Feb 2024 07:41:09 +0000 Subject: [PATCH 2/2] update Cargo.toml --- crates/cli/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index e07edd7..7dca8c7 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -15,12 +15,12 @@ version = "0.2.12" [dependencies] anyhow = "1.0.71" clap = "3.2.20" -envhub-ext = {path = "../ext", version = "0.1.0"} +envhub-ext = {path = "../ext", version = "0.1.1"} envhub-hm = {path = "../hm", version = "0.2.0"} envhub-pkgs = {path = "../pkgs", version = "0.1.2"} envhub-providers = {path = "../providers", version = "0.2.0"} envhub-stow = {path = "../stow", version = "0.1.0"} -envhub-types = {path = "../types", version = "0.2.1"} +envhub-types = {path = "../types", version = "0.2.2"} hcl-rs = "0.14.2" indexmap = "2.2.3" inquire = "0.6.2"