diff --git a/Cargo.lock b/Cargo.lock index f61f451..e9cdd28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,6 +46,7 @@ dependencies = [ "serde_json", "structopt", "tar", + "winreg 0.9.0", "zip", ] @@ -770,7 +771,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg", + "winreg 0.7.0", ] [[package]] @@ -1251,6 +1252,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "winreg" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16cdb3898397cf7f624c294948669beafaeebc5577d5ec53d0afb76633593597" +dependencies = [ + "winapi", +] + [[package]] name = "xattr" version = "0.2.2" diff --git a/Cargo.toml b/Cargo.toml index 3a42b39..0e00cde 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,4 +14,7 @@ serde_derive = "1.0" zip = "0.5" tar = "0.4" flate2 = "1.0" -dirs = "3.0" \ No newline at end of file +dirs = "3.0" + +[target.'cfg(windows)'.dependencies] +winreg = "0.9" \ No newline at end of file diff --git a/src/common/packages/fvm/mod.rs b/src/common/packages/fvm/mod.rs index f1c80b5..599ea31 100644 --- a/src/common/packages/fvm/mod.rs +++ b/src/common/packages/fvm/mod.rs @@ -4,8 +4,6 @@ use crate::common::utils::downloader; use crate::common::utils::extractor; use crate::common::utils::installer; -// use std::process::Command; - pub fn install() -> Result<(), String> { println!("Installing FVM"); diff --git a/src/common/utils/configure/mod.rs b/src/common/utils/configure/mod.rs new file mode 100644 index 0000000..ea2f705 --- /dev/null +++ b/src/common/utils/configure/mod.rs @@ -0,0 +1,19 @@ +#[cfg(target_os = "windows")] +mod windows; + +pub fn configure() -> Result<(), String> { + #[cfg(target_os = "windows")] + windows::configure().ok_or(format!("Failed to configure environment"))?; + + #[cfg(not(target_os = "windows"))] + #[cfg(not(target_os = "linux"))] + #[cfg(not(target_os = "macos"))] + { + Err(format!("OS not supported")) + } + + #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] + { + Ok(()) + } +} \ No newline at end of file diff --git a/src/common/utils/configure/windows/env.rs b/src/common/utils/configure/windows/env.rs new file mode 100644 index 0000000..04ab6ff --- /dev/null +++ b/src/common/utils/configure/windows/env.rs @@ -0,0 +1,45 @@ +use winreg::RegKey; +use winreg::enums::*; +use crate::common::utils::installer; + +pub enum ConfigEnvMode { + ADD, + REMOVE +} + +fn env_exist(path_env: &str, binary_folder: &str) -> bool { + for env in path_env.split(';') { + if env == binary_folder { + return true + } + } + + false +} + +pub fn configure_env(mode: ConfigEnvMode) -> Option<()> { + let hklm = RegKey::predef(HKEY_CURRENT_USER); + let environment = hklm.open_subkey_with_flags("Environment", KEY_READ | KEY_WRITE).ok()?; + let mut reg_value : String = environment.get_value("PATH").ok()?; + let binary_folder_path = installer::get_install_dir(installer::InstallType::Command).ok()?; + let binary_folder_str = binary_folder_path.to_str()?; + + match mode { + ConfigEnvMode::ADD => { + if !env_exist(reg_value.as_str(), binary_folder_str) { + reg_value.push_str(format!(";{}", binary_folder_str).as_str()); // Add binary folder to path + environment.set_value("PATH", ®_value).ok()?; + println!("[INFO] Folder {} added to PATH", binary_folder_str); + } + }, + ConfigEnvMode::REMOVE => { + if env_exist(reg_value.as_str(), binary_folder_str) { + let new_value = reg_value.replace(format!(";{}", binary_folder_str).as_str(), ""); // Remove binary folder to path + environment.set_value("PATH", &new_value).ok()?; + println!("[INFO] Folder {} removed to PATH", binary_folder_str); + } + } + } + + Some(()) +} \ No newline at end of file diff --git a/src/common/utils/configure/windows/mod.rs b/src/common/utils/configure/windows/mod.rs new file mode 100644 index 0000000..920fc20 --- /dev/null +++ b/src/common/utils/configure/windows/mod.rs @@ -0,0 +1,7 @@ +mod env; + +pub fn configure() -> Option<()> { + env::configure_env(env::ConfigEnvMode::ADD)?; + + Some(()) +} \ No newline at end of file diff --git a/src/common/utils/installer.rs b/src/common/utils/installer.rs index 2042a94..28afe57 100644 --- a/src/common/utils/installer.rs +++ b/src/common/utils/installer.rs @@ -6,11 +6,16 @@ pub enum InstallType { Config } -pub fn get_install_dir() -> Result { +pub fn get_install_dir(install_type: InstallType) -> Result { let home_dir = dirs::home_dir() .ok_or(format!("Failed to get home_directory"))?; - Ok(home_dir.join(super::super::INSTALL_FOLDER)) + let subfolder = match install_type { + InstallType::Command => "bin", + InstallType::Config => "configs" + }; + + Ok(home_dir.join(super::super::INSTALL_FOLDER).join(subfolder)) } fn copy_dir_all(src: impl AsRef, dst: impl AsRef) -> io::Result<()> { @@ -30,12 +35,7 @@ fn copy_dir_all(src: impl AsRef, dst: impl AsRef) -> io::Result<()> pub fn install(source_path: &str, install_type: InstallType) -> Option <()> { let source_folder = std::path::Path::new(super::super::TEMP_FOLDER).join(source_path); - let subfolder = match install_type { - InstallType::Command => "bin", - InstallType::Config => "configs" - }; - - let install_folder = get_install_dir().ok()?.join(subfolder); + let install_folder = get_install_dir(install_type).ok()?; copy_dir_all(source_folder, install_folder).ok()?; Some(()) } \ No newline at end of file diff --git a/src/common/utils/mod.rs b/src/common/utils/mod.rs index f2d5c1a..825d561 100644 --- a/src/common/utils/mod.rs +++ b/src/common/utils/mod.rs @@ -1,4 +1,5 @@ pub mod downloader; pub mod extractor; pub mod git; -pub mod installer; \ No newline at end of file +pub mod installer; +pub mod configure; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 7dd15e1..5eddeed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,11 @@ mod macos; pub mod common; fn main() { + if let Err(err) = common::utils::configure::configure() { + eprintln!("[ERROR] {}", err); + return; + } + #[cfg(target_os = "windows")] windows::start();