1
0
Fork 0

Refactor + Remove structopt

This commit is contained in:
Florian RICHER (MrDev023) 2021-08-09 20:19:10 +02:00
parent 988c78b615
commit c6e652c12b
24 changed files with 163 additions and 338 deletions

132
Cargo.lock generated
View file

@ -8,26 +8,6 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.0.1" version = "1.0.1"
@ -44,7 +24,6 @@ dependencies = [
"serde", "serde",
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"structopt",
"tar", "tar",
"winreg 0.9.0", "winreg 0.9.0",
"zip", "zip",
@ -113,21 +92,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "2.33.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.9.1" version = "0.9.1"
@ -322,15 +286,6 @@ version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.19" version = "0.1.19"
@ -630,30 +585,6 @@ version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.28" version = "1.0.28"
@ -869,36 +800,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "structopt"
version = "0.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69b041cdcb67226aca307e6e7be44c8806423d83e018bd662360a93dabce4d71"
dependencies = [
"clap",
"lazy_static",
"structopt-derive",
]
[[package]]
name = "structopt-derive"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7813934aecf5f51a54775e00068c237de98489463968231a51746bbbc03f9c10"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.74" version = "1.0.74"
@ -935,15 +836,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.26" version = "1.0.26"
@ -1079,18 +971,6 @@ dependencies = [
"tinyvec", "tinyvec",
] ]
[[package]]
name = "unicode-segmentation"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.2" version = "0.2.2"
@ -1115,18 +995,6 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]] [[package]]
name = "want" name = "want"
version = "0.3.0" version = "0.3.0"

View file

@ -6,7 +6,6 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
structopt = "0.3.22"
reqwest = { version = "0.11.4", features = ["blocking"] } reqwest = { version = "0.11.4", features = ["blocking"] }
serde = "1.0" serde = "1.0"
serde_json = "1.0" serde_json = "1.0"

View file

@ -1,5 +0,0 @@
pub static TEMP_FOLDER: &str = "temp";
pub static INSTALL_FOLDER: &str = ".autoconfig";
pub mod utils;
pub mod packages;

View file

@ -1,26 +0,0 @@
use crate::common::utils::git;
fn get_prefix_from_arch() -> Option<String> {
if std::env::consts::ARCH == "x86_64" {
Some(format!("x64"))
} else if std::env::consts::ARCH == "x86" {
Some(format!("ia32"))
} else {
None
}
}
pub fn get_file_url() -> Result<String, String> {
let git_response = git::get_git_latest_release("leoafarias/fvm")
.ok_or(format!("Failed to get git release"))?;
let arch_prefix = get_prefix_from_arch().ok_or(format!("Arch not supported"))?;
for asset in git_response.assets {
if asset.name.contains(std::env::consts::OS) && asset.name.contains(arch_prefix.as_str()) {
return Ok(asset.browser_download_url);
}
}
Err(format!("OS not supported"))
}

View file

@ -1,25 +0,0 @@
mod git;
use crate::common::utils::downloader;
use crate::common::utils::extractor;
use crate::common::utils::installer;
pub fn install() -> Result<(), String> {
println!("Installing FVM");
let url = git::get_file_url()?;
let filename = url.split('/').last()
.ok_or(format!("Failed to download file"))?;
let file = downloader::download_file(&url, &filename)
.ok_or(format!("Failed to download file"))?;
extractor::extract_file(&file, "fvm")?;
installer::install("fvm/fvm", installer::InstallType::Command).ok_or(format!("Failed to install"))?;
println!("FVM Installed");
Ok(())
}

View file

@ -1 +0,0 @@
pub mod fvm;

View file

@ -1,5 +0,0 @@
pub mod downloader;
pub mod extractor;
pub mod git;
pub mod installer;
pub mod configure;

70
src/installer/git/mod.rs Normal file
View file

@ -0,0 +1,70 @@
use std::env::consts;
use super::utils::{configure, downloader, extractor, git, file_utils};
pub struct GitFileIdentifier {
pub os_name: String,
pub arch: String,
pub os_identifier: String,
pub arch_identifier: String,
}
/// Git configuration structure
pub struct GitConfig {
/// base url from git url (ex: fvm url is https://github.com/leoafarias/fvm so the package name is leoafarias/fvm)
pub package: String,
/// Must exist in Release of git repo (default to latest)
pub version: String,
pub git_identifiers: Vec<GitFileIdentifier>,
pub archive_subfolder: String,
pub install_type: file_utils::InstallType,
}
fn _get_file_url(package: &str, version: &str, git_identifiers: Vec<GitFileIdentifier>) -> Result<String, String> {
let git_response = git::get_git_release_by_version(package, version)
.ok_or(format!("Failed to get git release"))?;
let git_identifier = git_identifiers.into_iter()
.find(|id| {
id.arch == consts::ARCH && (id.os_name == consts::OS || id.os_name == consts::FAMILY)
})
.ok_or(format!("CPU ARCH or OS not supported"))?;
for asset in git_response.assets {
if asset.name.contains(git_identifier.arch_identifier.as_str()) && asset.name.contains(git_identifier.os_identifier.as_str()) {
return Ok(asset.browser_download_url);
}
}
Err(format!("{} not support current OS or CPU ARCH", package))
}
fn _install(config: GitConfig) -> Result<(), String> {
let url = _get_file_url(config.package.as_str(), config.version.as_str(), config.git_identifiers)?;
let filename = url.split('/').last()
.ok_or(format!("Failed to get name of file"))?;
let file = downloader::download_file(&url, &filename)
.ok_or(format!("Failed to download file"))?;
extractor::extract_file(&file, config.package.as_str())?;
let package_temp_folder = std::path::Path::new(config.package.as_str());
let extractor_package_temp_folder = package_temp_folder.join(config.archive_subfolder.as_str());
let extractor_package_temp_folder_str = extractor_package_temp_folder
.as_os_str()
.to_str()
.ok_or(format!("Failed to get extracted folder"))?;
file_utils::install(extractor_package_temp_folder_str, config.install_type).ok_or(format!("Failed to install"))?;
Ok(())
}
pub fn process(config: GitConfig, config_mode: configure::ConfigMode) -> Result<(), String> {
match config_mode {
configure::ConfigMode::INSTALL => _install(config),
configure::ConfigMode::UNINSTALL => Err(format!("not yet implemented")),
}
}

17
src/installer/mod.rs Normal file
View file

@ -0,0 +1,17 @@
pub mod git;
pub mod utils;
use utils::configure::ConfigMode;
use self::git::GitConfig;
pub enum Installer {
GIT(GitConfig),
}
pub fn process(installer: Installer, config_mode: ConfigMode) -> Result<(), String> {
match installer {
Installer::GIT(config) => git::process(config, config_mode),
}
}

View file

@ -2,14 +2,14 @@ use std::path::Path;
use std::fs::{create_dir_all, remove_dir_all}; use std::fs::{create_dir_all, remove_dir_all};
use super::ConfigMode; use super::ConfigMode;
use super::super::installer; use super::super::file_utils;
fn folder_exist(folder: &str) -> bool { fn folder_exist(folder: &str) -> bool {
Path::new(folder).is_dir() Path::new(folder).is_dir()
} }
pub fn configure_folder(mode: &ConfigMode) -> Option<()> { pub fn configure_folder(mode: &ConfigMode) -> Option<()> {
let binary_folder_path = installer::get_install_dir(installer::InstallType::Root).ok()?; let binary_folder_path = file_utils::get_install_dir(file_utils::InstallType::Root).ok()?;
let binary_folder_str = binary_folder_path.to_str()?; let binary_folder_str = binary_folder_path.to_str()?;
match mode { match mode {

View file

@ -1,7 +1,7 @@
use winreg::RegKey; use winreg::RegKey;
use winreg::enums::*; use winreg::enums::*;
use crate::common::utils::installer;
use super::ConfigMode; use super::ConfigMode;
use super::super::super::file_utils;
fn env_exist(path_env: &str, binary_folder: &str) -> bool { fn env_exist(path_env: &str, binary_folder: &str) -> bool {
for env in path_env.split(';') { for env in path_env.split(';') {
@ -17,7 +17,7 @@ pub fn configure_env(mode: &ConfigMode) -> Option<()> {
let hklm = RegKey::predef(HKEY_CURRENT_USER); let hklm = RegKey::predef(HKEY_CURRENT_USER);
let environment = hklm.open_subkey_with_flags("Environment", KEY_READ | KEY_WRITE).ok()?; let environment = hklm.open_subkey_with_flags("Environment", KEY_READ | KEY_WRITE).ok()?;
let mut reg_value : String = environment.get_value("PATH").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_path = file_utils::get_install_dir(file_utils::InstallType::Command).ok()?;
let binary_folder_str = binary_folder_path.to_str()?; let binary_folder_str = binary_folder_path.to_str()?;
match mode { match mode {

View file

@ -1,14 +1,14 @@
use std::{fs, path::PathBuf}; use std::{fs, path::PathBuf};
fn create_download_folder() -> Option<()> { fn create_download_folder() -> Option<()> {
fs::create_dir_all(super::super::TEMP_FOLDER).ok() fs::create_dir_all(super::TEMP_FOLDER).ok()
} }
pub fn download_file(url : &String, filename: &str) -> Option<PathBuf> { pub fn download_file(url : &String, filename: &str) -> Option<PathBuf> {
create_download_folder()?; create_download_folder()?;
let mut response = reqwest::blocking::get(url).ok()?; let mut response = reqwest::blocking::get(url).ok()?;
let fname = std::path::Path::new(super::super::TEMP_FOLDER).join(filename); let fname = std::path::Path::new(super::TEMP_FOLDER).join(filename);
let mut dest = fs::File::create(fname.clone()).ok()?; let mut dest = fs::File::create(fname.clone()).ok()?;
response.copy_to(&mut dest).ok()?; response.copy_to(&mut dest).ok()?;

View file

@ -1,14 +1,13 @@
use std::{fs::File, path::{Path, PathBuf}}; use std::{fs::File, path::{Path, PathBuf}};
use flate2::read::GzDecoder; use flate2::read::GzDecoder;
use tar::Archive; use tar::Archive;
use crate::common;
pub fn extract_file(path: &PathBuf, outdir: &str) -> Option<()> { pub fn extract_file(path: &PathBuf, outdir: &str) -> Option<()> {
let file = File::open(path).ok()?; let file = File::open(path).ok()?;
let tar = GzDecoder::new(file); let tar = GzDecoder::new(file);
let mut archive = Archive::new(tar); let mut archive = Archive::new(tar);
let path = Path::new(common::TEMP_FOLDER).join(outdir); let path = Path::new(super::super::TEMP_FOLDER).join(outdir);
archive.unpack(path).ok()?; archive.unpack(path).ok()?;
Some(()) Some(())

View file

@ -1,4 +1,3 @@
use crate::common;
use std::{fs::{ use std::{fs::{
File, File,
create_dir_all create_dir_all
@ -8,7 +7,7 @@ pub fn extract_file(path: &PathBuf, outdir: &str) -> Option<()> {
let file = File::open(&path).ok()?; let file = File::open(&path).ok()?;
let mut archive = zip::ZipArchive::new(file).ok()?; let mut archive = zip::ZipArchive::new(file).ok()?;
let path = path::Path::new(common::TEMP_FOLDER).join(outdir); let path = path::Path::new(super::super::TEMP_FOLDER).join(outdir);
for i in 0..archive.len() { for i in 0..archive.len() {
let mut file = archive.by_index(i).ok()?; let mut file = archive.by_index(i).ok()?;

View file

@ -17,7 +17,7 @@ pub fn get_install_dir(install_type: InstallType) -> Result<PathBuf, String> {
InstallType::Root => "" InstallType::Root => ""
}; };
Ok(home_dir.join(super::super::INSTALL_FOLDER).join(subfolder)) Ok(home_dir.join(super::INSTALL_FOLDER).join(subfolder))
} }
fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> { fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
@ -35,7 +35,7 @@ fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()>
} }
pub fn install(source_path: &str, install_type: InstallType) -> Option <()> { 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 source_folder = std::path::Path::new(super::TEMP_FOLDER).join(source_path);
let install_folder = get_install_dir(install_type).ok()?; let install_folder = get_install_dir(install_type).ok()?;
copy_dir_all(source_folder, install_folder).ok()?; copy_dir_all(source_folder, install_folder).ok()?;

View file

@ -36,7 +36,3 @@ pub fn get_git_release_by_version(repo: &str, version: &str) -> Option<GitRespon
Some(git_response) Some(git_response)
} }
pub fn get_git_latest_release(repo: &str) -> Option<GitResponse> {
Some(get_git_release_by_version(repo, "latest")?)
}

View file

@ -0,0 +1,8 @@
pub(self) static TEMP_FOLDER: &str = "temp";
pub(self) static INSTALL_FOLDER: &str = ".autoconfig";
pub mod downloader;
pub mod extractor;
pub mod git;
pub mod file_utils;
pub mod configure;

View file

@ -1,35 +0,0 @@
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<Tool>,
}
pub fn start() {
let opt = Opt::from_args();
for tool in &opt.tools {
let result = match tool {
Tool::Fvm => super::common::packages::fvm::install()
};
if let Err(err) = result {
eprintln!("[ERROR] {}", err);
}
}
}

View file

@ -1,35 +0,0 @@
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<Tool>,
}
pub fn start() {
let opt = Opt::from_args();
for tool in &opt.tools {
let result = match tool {
Tool::Fvm => super::common::packages::fvm::install()
};
if let Err(err) = result {
eprintln!("[ERROR] {}", err);
}
}
}

View file

@ -1,31 +1,67 @@
#[cfg(target_os = "windows")] use crate::installer::{
mod windows; Installer,
utils::{
file_utils::InstallType,
configure::{
configure,
ConfigMode
}
},
git::{
GitConfig,
GitFileIdentifier
}
};
#[cfg(target_os = "linux")] mod installer;
mod linux;
#[cfg(target_os = "macos")]
mod macos;
pub mod common;
fn main() { fn main() {
if let Err(err) = common::utils::configure::configure(&common::utils::configure::ConfigMode::INSTALL) { if let Err(err) = configure(&ConfigMode::INSTALL) {
eprintln!("[ERROR] {}", err); eprintln!("[ERROR] {}", err);
return; return;
} }
#[cfg(target_os = "windows")] let fvm_config : GitConfig = GitConfig {
windows::start(); package: String::from("leoafarias/fvm"),
version: String::from("latest"),
git_identifiers: vec![
GitFileIdentifier {
os_name: String::from("windows"),
arch: String::from("x86_64"),
os_identifier: String::from("windows"),
arch_identifier: String::from("x64")
},
GitFileIdentifier {
os_name: String::from("windows"),
arch: String::from("x86"),
os_identifier: String::from("windows"),
arch_identifier: String::from("ia32")
},
GitFileIdentifier {
os_name: String::from("macos"),
arch: String::from("x86_64"),
os_identifier: String::from("macos"),
arch_identifier: String::from("x64")
},
GitFileIdentifier {
os_name: String::from("linux"),
arch: String::from("x86_64"),
os_identifier: String::from("linux"),
arch_identifier: String::from("x64")
},
GitFileIdentifier {
os_name: String::from("linux"),
arch: String::from("x86"),
os_identifier: String::from("linux"),
arch_identifier: String::from("ia32")
}
],
install_type: InstallType::Command,
archive_subfolder: String::from("fvm")
};
#[cfg(target_os = "linux")] if let Err(err) = installer::process(Installer::GIT(fvm_config), ConfigMode::INSTALL) {
linux::start(); eprintln!("[ERROR] {}", err);
return;
#[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");
} }

View file

@ -1,35 +0,0 @@
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<Tool>,
}
pub fn start() {
let opt = Opt::from_args();
for tool in &opt.tools {
let result = match tool {
Tool::Fvm => super::common::packages::fvm::install()
};
if let Err(err) = result {
eprintln!("[ERROR] {}", err);
}
}
}