Begin implement symlink system
This commit is contained in:
parent
e91115cbe4
commit
ec5d28731c
6 changed files with 84 additions and 12 deletions
|
@ -20,7 +20,7 @@ pub struct GitConfig {
|
|||
pub install_type: file_utils::InstallType,
|
||||
}
|
||||
|
||||
fn _get_file_url(package: &str, version: &str, git_identifiers: Vec<GitFileIdentifier>) -> Result<String, String> {
|
||||
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"))?;
|
||||
|
||||
|
@ -39,8 +39,8 @@ fn _get_file_url(package: &str, version: &str, git_identifiers: Vec<GitFileIdent
|
|||
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)?;
|
||||
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"))?;
|
||||
|
@ -57,14 +57,14 @@ fn _install(config: GitConfig) -> Result<(), String> {
|
|||
.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"))?;
|
||||
file_utils::install(extractor_package_temp_folder_str, config.package.as_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::INSTALL => install(config),
|
||||
configure::ConfigMode::UNINSTALL => Err(format!("not yet implemented")),
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ fn folder_exist(folder: &str) -> bool {
|
|||
}
|
||||
|
||||
pub fn configure_folder(mode: &ConfigMode) -> Option<()> {
|
||||
let binary_folder_path = file_utils::get_install_dir(file_utils::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()?;
|
||||
|
||||
match mode {
|
||||
|
|
|
@ -17,7 +17,7 @@ pub fn configure_env(mode: &ConfigMode) -> 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 = file_utils::get_install_dir(file_utils::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()?;
|
||||
|
||||
match mode {
|
||||
|
|
56
src/installer/utils/file_utils/binary_utils.rs
Normal file
56
src/installer/utils/file_utils/binary_utils.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
use std::env::consts;
|
||||
use std::path::PathBuf;
|
||||
use std::fs;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
use std::os::windows::fs::symlink_file;
|
||||
|
||||
fn file_is_executable(path: &PathBuf) -> bool {
|
||||
if consts::FAMILY == "windows" {
|
||||
match path.extension() {
|
||||
Some(ext) => {
|
||||
let extension = match ext.to_str() {
|
||||
Some(r) => r,
|
||||
None => ""
|
||||
};
|
||||
match extension {
|
||||
"bat" | "exe" | "ps1" => true,
|
||||
_ => false,
|
||||
}
|
||||
},
|
||||
None => false
|
||||
}
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_binary_files(install_package_folder: &PathBuf) -> Result<Vec<PathBuf>, String> {
|
||||
let mut files: Vec<PathBuf> = vec![];
|
||||
let paths = fs::read_dir(install_package_folder).map_err(|_| format!("Failed to get binary files"))?;
|
||||
|
||||
for path_result in paths {
|
||||
let path = path_result.map_err(|_| format!("Failed to get file"))?;
|
||||
let metadata = path.metadata().map_err(|_| format!("Failed to get metadata"))?;
|
||||
if metadata.is_file() && file_is_executable(&path.path()) {
|
||||
files.push(path.path().clone());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(files)
|
||||
}
|
||||
|
||||
pub fn create_symlink_of_binary_files(install_package_folder: &PathBuf, binary_package_folder: &PathBuf) -> Result<(), String> {
|
||||
let files = get_binary_files(install_package_folder)?;
|
||||
|
||||
fs::create_dir_all(&binary_package_folder).map_err(|_| format!("Failed to create bin folder"))?;
|
||||
|
||||
for file in files {
|
||||
let output_path = binary_package_folder.join(file.file_name().ok_or(format!("Failed to get filename"))?);
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
symlink_file(file.as_os_str(), output_path.as_os_str()).map_err(|_| format!("Failed to create symlink"))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
mod binary_utils;
|
||||
|
||||
use std::path::{PathBuf, Path};
|
||||
use std::{io, fs};
|
||||
|
||||
|
@ -7,7 +9,7 @@ pub enum InstallType {
|
|||
Root
|
||||
}
|
||||
|
||||
pub fn get_install_dir(install_type: InstallType) -> Result<PathBuf, String> {
|
||||
pub fn get_install_dir(install_type: &InstallType) -> Result<PathBuf, String> {
|
||||
let home_dir = dirs::home_dir()
|
||||
.ok_or(format!("Failed to get home_directory"))?;
|
||||
|
||||
|
@ -20,6 +22,12 @@ pub fn get_install_dir(install_type: InstallType) -> Result<PathBuf, String> {
|
|||
Ok(home_dir.join(super::INSTALL_FOLDER).join(subfolder))
|
||||
}
|
||||
|
||||
pub fn get_packages_dir(package: &str) -> Result<PathBuf, String> {
|
||||
let home_dir = dirs::home_dir()
|
||||
.ok_or(format!("Failed to get home_directory"))?;
|
||||
Ok(home_dir.join(super::INSTALL_FOLDER).join(super::PACKAGE_FOLDER).join(package))
|
||||
}
|
||||
|
||||
fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
|
||||
fs::create_dir_all(&dst)?;
|
||||
for entry in fs::read_dir(src)? {
|
||||
|
@ -34,10 +42,17 @@ fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()>
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn install(source_path: &str, install_type: InstallType) -> Option <()> {
|
||||
pub fn install(source_path: &str, package: &str, install_type: InstallType) -> Option <()> {
|
||||
let source_folder = std::path::Path::new(super::TEMP_FOLDER).join(source_path);
|
||||
let package_folder = get_packages_dir(package).ok()?;
|
||||
|
||||
let install_folder = get_install_dir(install_type).ok()?;
|
||||
copy_dir_all(source_folder, install_folder).ok()?;
|
||||
Some(())
|
||||
copy_dir_all(source_folder, package_folder.clone()).ok()?;
|
||||
|
||||
let install_folder = get_install_dir(&install_type).ok()?;
|
||||
|
||||
match install_type {
|
||||
InstallType::Command => binary_utils::create_symlink_of_binary_files(&package_folder, &install_folder).ok(),
|
||||
InstallType::Config => todo!(),
|
||||
InstallType::Root => todo!(),
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
pub(self) static TEMP_FOLDER: &str = "temp";
|
||||
pub(self) static INSTALL_FOLDER: &str = ".autoconfig";
|
||||
pub(self) static PACKAGE_FOLDER : &str = "packages";
|
||||
|
||||
pub mod downloader;
|
||||
pub mod extractor;
|
||||
|
|
Reference in a new issue