diff --git a/Cargo.lock b/Cargo.lock index 5d43008..f61f451 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,6 +38,7 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" name = "autoconfig" version = "0.1.0" dependencies = [ + "dirs", "flate2", "reqwest", "serde", @@ -151,6 +152,26 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "dirs" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "encoding_rs" version = "0.8.28" @@ -699,6 +720,16 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom", + "redox_syscall", +] + [[package]] name = "remove_dir_all" version = "0.5.3" diff --git a/Cargo.toml b/Cargo.toml index f3a3628..3a42b39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,5 @@ serde_json = "1.0" serde_derive = "1.0" zip = "0.5" tar = "0.4" -flate2 = "1.0" \ No newline at end of file +flate2 = "1.0" +dirs = "3.0" \ No newline at end of file diff --git a/src/windows/fvm/git.rs b/src/common/fvm/git.rs similarity index 100% rename from src/windows/fvm/git.rs rename to src/common/fvm/git.rs diff --git a/src/windows/fvm/mod.rs b/src/common/fvm/mod.rs similarity index 56% rename from src/windows/fvm/mod.rs rename to src/common/fvm/mod.rs index 7f3daab..f1c80b5 100644 --- a/src/windows/fvm/mod.rs +++ b/src/common/fvm/mod.rs @@ -2,11 +2,12 @@ mod git; 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!("Install FVM"); + println!("Installing FVM"); let url = git::get_file_url()?; @@ -18,15 +19,9 @@ pub fn install() -> Result<(), String> { extractor::extract_file(&file, "fvm")?; - println!("{}", url); + installer::install("fvm/fvm", installer::InstallType::Command).ok_or(format!("Failed to install"))?; - // let output = Command::new("winget") - // .args(&[""]) - // .output() - // .map_err(|_| format!("Permision refused ! Please run as administrator."))?; - - - // println!("{}", std::str::from_utf8(&output.stdout).map_err(|_| format!("Internal error"))?); + println!("FVM Installed"); Ok(()) } \ No newline at end of file diff --git a/src/common/mod.rs b/src/common/mod.rs index a69022b..208b49b 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -1,3 +1,5 @@ pub static TEMP_FOLDER: &str = "temp"; +pub static INSTALL_FOLDER: &str = ".autoconfig"; -pub mod utils; \ No newline at end of file +pub mod utils; +pub mod fvm; \ No newline at end of file diff --git a/src/common/utils/extractor/zip.rs b/src/common/utils/extractor/zip.rs index 304dfb3..08229a0 100644 --- a/src/common/utils/extractor/zip.rs +++ b/src/common/utils/extractor/zip.rs @@ -6,13 +6,7 @@ use std::{fs::{ pub fn extract_file(path: &PathBuf, outdir: &str) -> Option<()> { let file = File::open(&path).ok()?; - let mut archive = match zip::ZipArchive::new(file) { - Ok(archive) => archive, - Err(err) => { - println!("[ERROR][EXTRACTOR] {}", err); - return None - } - }; + let mut archive = zip::ZipArchive::new(file).ok()?; let path = path::Path::new(common::TEMP_FOLDER).join(outdir); @@ -22,15 +16,8 @@ pub fn extract_file(path: &PathBuf, outdir: &str) -> Option<()> { let output_path = path.join(file_path); if (&*file.name()).ends_with('/') { - println!("File {} extracted to \"{}\"", i, output_path.display()); create_dir_all(&output_path).ok()?; } else { - println!( - "File {} extracted to \"{}\" ({} bytes)", - i, - output_path.display(), - file.size() - ); if let Some(p) = output_path.parent() { if !p.exists() { create_dir_all(&p).ok()?; diff --git a/src/common/utils/git.rs b/src/common/utils/git.rs index 6dcc071..d48d6d7 100644 --- a/src/common/utils/git.rs +++ b/src/common/utils/git.rs @@ -9,6 +9,9 @@ pub struct Asset { #[derive(Serialize, Deserialize, Debug)] pub struct GitResponse { + pub tag_name: String, + pub prerelease: bool, + pub draft: bool, pub assets: Vec } diff --git a/src/common/utils/installer.rs b/src/common/utils/installer.rs new file mode 100644 index 0000000..2042a94 --- /dev/null +++ b/src/common/utils/installer.rs @@ -0,0 +1,41 @@ +use std::path::{PathBuf, Path}; +use std::{io, fs}; + +pub enum InstallType { + Command, + Config +} + +pub fn get_install_dir() -> Result { + let home_dir = dirs::home_dir() + .ok_or(format!("Failed to get home_directory"))?; + + Ok(home_dir.join(super::super::INSTALL_FOLDER)) +} + +fn copy_dir_all(src: impl AsRef, dst: impl AsRef) -> io::Result<()> { + fs::create_dir_all(&dst)?; + for entry in fs::read_dir(src)? { + let entry = entry?; + let ty = entry.file_type()?; + if ty.is_dir() { + copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?; + } else { + fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?; + } + } + Ok(()) +} + +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); + 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 47631b3..f2d5c1a 100644 --- a/src/common/utils/mod.rs +++ b/src/common/utils/mod.rs @@ -1,3 +1,4 @@ pub mod downloader; pub mod extractor; -pub mod git; \ No newline at end of file +pub mod git; +pub mod installer; \ No newline at end of file diff --git a/src/linux/mod.rs b/src/linux/mod.rs new file mode 100644 index 0000000..4f23280 --- /dev/null +++ b/src/linux/mod.rs @@ -0,0 +1,35 @@ + +use structopt::{ + StructOpt, + clap::{ + arg_enum + } +}; + +arg_enum! { + #[derive(Debug)] + enum Tool { + Fvm + } +} + +#[derive(Debug, StructOpt)] +#[structopt(name = "autoconfig", about = "Auto install local config.")] +struct Opt { + #[structopt(short = "i", long = "install", help = "Available values : fvm (Flutter version manager)")] + tools: Vec, +} + + +pub fn start() { + let opt = Opt::from_args(); + for tool in &opt.tools { + let result = match tool { + Tool::Fvm => super::common::fvm::install() + }; + + if let Err(err) = result { + eprintln!("[ERROR] {}", err); + } + } +} \ No newline at end of file diff --git a/src/macos/mod.rs b/src/macos/mod.rs new file mode 100644 index 0000000..4f23280 --- /dev/null +++ b/src/macos/mod.rs @@ -0,0 +1,35 @@ + +use structopt::{ + StructOpt, + clap::{ + arg_enum + } +}; + +arg_enum! { + #[derive(Debug)] + enum Tool { + Fvm + } +} + +#[derive(Debug, StructOpt)] +#[structopt(name = "autoconfig", about = "Auto install local config.")] +struct Opt { + #[structopt(short = "i", long = "install", help = "Available values : fvm (Flutter version manager)")] + tools: Vec, +} + + +pub fn start() { + let opt = Opt::from_args(); + for tool in &opt.tools { + let result = match tool { + Tool::Fvm => super::common::fvm::install() + }; + + if let Err(err) = result { + eprintln!("[ERROR] {}", err); + } + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index d5ed53b..7dd15e1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,26 @@ +#[cfg(target_os = "windows")] mod windows; + +#[cfg(target_os = "linux")] +mod linux; + +#[cfg(target_os = "macos")] +mod macos; + pub mod common; fn main() { + #[cfg(target_os = "windows")] windows::start(); + + #[cfg(target_os = "linux")] + linux::start(); + + #[cfg(target_os = "macos")] + macos::start(); + + #[cfg(not(target_os = "windows"))] + #[cfg(not(target_os = "linux"))] + #[cfg(not(target_os = "macos"))] + println!("[ERROR] Operating system not supported"); } diff --git a/src/windows/mod.rs b/src/windows/mod.rs index 90a0837..4f23280 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -1,4 +1,3 @@ -mod fvm; use structopt::{ StructOpt, @@ -26,7 +25,7 @@ pub fn start() { let opt = Opt::from_args(); for tool in &opt.tools { let result = match tool { - Tool::Fvm => fvm::install() + Tool::Fvm => super::common::fvm::install() }; if let Err(err) = result {