diff options
| author | Namilskyy <alive6863@gmail.com> | 2025-11-29 20:48:12 +0300 |
|---|---|---|
| committer | Namilskyy <alive6863@gmail.com> | 2025-11-29 20:48:12 +0300 |
| commit | 5319e24d9f7b43dbfdfd368ea5ac467970061cd2 (patch) | |
| tree | 89eb1cb8f17962fe0f1bb8b97368a62875a60ded /src/pkgtoolkit | |
| parent | d10ac4cc08d679e7971296b79c6eafadcdbc78de (diff) | |
Minor warnings fixed, implemented codeberg pages action
Diffstat (limited to 'src/pkgtoolkit')
| -rw-r--r-- | src/pkgtoolkit/mod.rs | 2 | ||||
| -rw-r--r-- | src/pkgtoolkit/pkgtools.rs | 385 |
2 files changed, 220 insertions, 167 deletions
diff --git a/src/pkgtoolkit/mod.rs b/src/pkgtoolkit/mod.rs index 4741892..63c952a 100644 --- a/src/pkgtoolkit/mod.rs +++ b/src/pkgtoolkit/mod.rs @@ -1 +1 @@ -pub mod pkgtools;
\ No newline at end of file +pub mod pkgtools; diff --git a/src/pkgtoolkit/pkgtools.rs b/src/pkgtoolkit/pkgtools.rs index cfd3d59..6c37595 100644 --- a/src/pkgtoolkit/pkgtools.rs +++ b/src/pkgtoolkit/pkgtools.rs @@ -2,23 +2,23 @@ use crate::cfg::config::Config; use std::{ - fs::{self, File, create_dir_all}, + fs::{self, File, create_dir_all}, io, - path::Path, - process::Command, - str, - os::unix::fs::PermissionsExt}; + os::unix::fs::PermissionsExt, + path::Path, + process::Command, + str, +}; + +// use emissary_core::i2np::tunnel::build; - use emissary_core::i2np::tunnel::build; - // use emissary_core::i2np::tunnel::build; use flate2::read::GzDecoder; use serde::{Deserialize, Serialize}; use tar::Archive; -use toml; -use cc; +use toml; #[derive(Serialize, Debug, Deserialize, Clone)] -pub enum archs { +pub enum Archs { X86_64, Aarch64, X86, @@ -28,9 +28,9 @@ pub enum archs { #[derive(Serialize, Debug, Deserialize, Clone)] pub struct Package { - name: String, - version: String, - arch: archs, + name: String, + version: String, + arch: Archs, descr: Option<String>, } @@ -38,9 +38,9 @@ pub struct Package { #[derive(Deserialize, Debug, Clone)] struct Install { package: Package, - path: String, - user: String, - group: String, + path: String, + user: String, + group: String, mode: String, //. Cancels the previous fields and installs them using the shell script custom_script: Option<String>, @@ -49,7 +49,7 @@ struct Install { #[allow(dead_code)] #[derive(Deserialize, Debug)] struct Setts { - env: Option<String>, // Export environment variables if this needed + env: Option<String>, // Export environment variables if this needed test: Option<String>, // Test the package after installation } @@ -57,32 +57,32 @@ struct Setts { pub enum BuildSystems { Make, CMake, - Meson, - Cargo + Meson, + Cargo, } #[allow(dead_code)] #[derive(Deserialize)] struct Build { - build_system: BuildSystems, + build_system: BuildSystems, env: Option<String>, script: Option<String>, } -impl archs { +impl Archs { fn as_str(&self) -> &'static str { match self { - archs::X86_64 => "x86_64", - archs::Aarch64 => "aarch64", - archs::X86 => "x86", - archs::ArmV7 => "armv7", - archs::ArmV8 => "armv8" + Archs::X86_64 => "x86_64", + Archs::Aarch64 => "aarch64", + Archs::X86 => "x86", + Archs::ArmV7 => "armv7", + Archs::ArmV8 => "armv8", } } } #[allow(dead_code)] -impl Package { +impl Package { /// Execute the build script for the package. /// /// This function takes the `Build` meta information as an argument and @@ -95,8 +95,8 @@ impl Package { fn execute_build(&self, build_meta: &Build) -> Result<(), std::io::Error> { let config = Config::parse() .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; - let build_dir = Path::new(&config.paths.cache_dir) - .join(format!("{}-{}", self.name, self.version)); + let build_dir = + Path::new(&config.paths.cache_dir).join(format!("{}-{}", self.name, self.version)); let mut cmd = match build_meta.build_system { BuildSystems::Make => { @@ -105,33 +105,31 @@ impl Package { if build_meta.script.is_some() { c.arg("-f").arg(build_meta.script.as_ref().unwrap()); } - c.arg("all"); - c + c.arg("all"); + c } BuildSystems::CMake => { let build_dir_build = build_dir.join("build"); create_dir_all(&build_dir_build)?; let mut c = Command::new("cmake"); - c.arg("-S").arg(&build_dir) - .arg("-B").arg(&build_dir_build) - .current_dir(&build_dir); - c + c.arg("-S") + .arg(&build_dir) + .arg("-B") + .arg(&build_dir_build) + .current_dir(&build_dir); + c } BuildSystems::Meson => { let build_dir_build = build_dir.join("build"); create_dir_all(&build_dir_build)?; let mut c = Command::new("meson"); - c.arg("setup") - .arg(&build_dir_build) - .current_dir(&build_dir); - c + c.arg("setup").arg(&build_dir_build).current_dir(&build_dir); + c } BuildSystems::Cargo => { let mut c = Command::new("cargo"); - c.arg("build") - .arg("--release") - .current_dir(&build_dir); - c + c.arg("build").arg("--release").current_dir(&build_dir); + c } }; @@ -154,13 +152,13 @@ impl Package { } /// Extracts a .tar.gz archive to the cache directory specified in Config. - /// + /// /// This function handles opening the archive file, decompressing it with GzDecoder, /// and unpacking the contents into the configured cache directory. - /// + /// /// # Arguments /// * `path_to_archive` - A string representing the path to the .tar.gz file. - /// + /// /// # Returns /// * `Ok(())` if the archive is successfully unpacked. /// * `Err(std::io::Error)` if there's an issue opening, reading, or unpacking the archive. @@ -181,19 +179,22 @@ impl Package { /// /// This function parses the meta information from the .mesk archive, /// which includes the package name, version, architecture, description, - /// installation path, user, group, mode, and custom installation script + /// installation path, user, group, mode, and custom installation script /// and deserializing this information. Returns (Install, Option<Setts>, Option<Build>) - /// + /// /// The function expects the 'INSTALL', 'SETTS', and 'BUILD' files to be present /// in the `config.paths.cache_dir`. It specifically requires the 'INSTALL' file. - /// + /// /// # Errors /// /// Returns an error if the `cache_dir` cannot be created, if the required 'INSTALL' file /// is not found, or if the 'INSTALL' file is empty. - fn loadmeta(minimal_package_meta: &mut Self) -> Result<(Install, Option<Setts>, Option<Build>), Box<dyn std::error::Error>> { // Changed return type for more flexibility - /* - Example INSTALL format: + fn loadmeta( + minimal_package_meta: &mut Self, + ) -> Result<(Install, Option<Setts>, Option<Build>), Box<dyn std::error::Error>> { + // Changed return type for more flexibility + /* + Example INSTALL format: [package] name = "my-package" version = "1.0.0" @@ -206,27 +207,26 @@ impl Package { group = "root" mode = "755" - # Also [install] can be + # Also [install] can be # path = "/usr/bin/my-package" # user = "root" # group = "root" # mode = "755" - # custom_script = "./install.sh" OR + # custom_script = "./install.sh" OR # custom_script = """ # echo "Installing my-package" # sudo apt-get install my-package # """ */ - let config = Config::parse()?; // Propagate error if parsing fails // Ensure the cache directory exists fs::create_dir_all(&config.paths.cache_dir)?; - let cache_dir = &config.paths.cache_dir; - let install_path = Path::new(cache_dir).join(format!("{}/INSTALL", minimal_package_meta.name)); + let install_path = + Path::new(cache_dir).join(format!("{}/INSTALL", minimal_package_meta.name)); let setts_path = Path::new(cache_dir).join(format!("{}/SETTS", minimal_package_meta.name)); let build_path = Path::new(cache_dir).join(format!("{}/BUILD", minimal_package_meta.name)); @@ -234,8 +234,9 @@ impl Package { if !install_path.exists() { return Err(io::Error::new( io::ErrorKind::NotFound, - "File INSTALL not found in cache directory" - ).into()); // Convert to Box<dyn Error> + "File INSTALL not found in cache directory", + ) + .into()); // Convert to Box<dyn Error> } // Read and deserialize the INSTALL file @@ -259,29 +260,33 @@ impl Package { } // Log if custom script is present - if let Some(ref script) = install_meta.custom_script { - println!("Custom script found for package: {}", install_meta.package.name); + if let Some(ref _script) = install_meta.custom_script { + println!( + "Custom script found for package: {}", + install_meta.package.name + ); // Consider logging the script content or just its presence based on verbosity // e.g., log::debug!("Custom script content: {}", script); } else { - println!("No custom script for package: {}", install_meta.package.name); + println!( + "No custom script for package: {}", + install_meta.package.name + ); } Ok((install_meta, setts_meta, build_meta)) } - - /// Checks if the archive contains INSTALL, SETTS and BUILD files. /// /// Checks if INSTALL file exists and is not empty. If it does not exist or is empty, returns an error. /// /// Checks if SETTS and BUILD files exist and are not empty. If they do not exist or are empty, logs a warning. - /// # Errors + /// # Errors /// * Returns an error if INSTALL file does not exist or is empty. /// * Returns an error if INSTALL file is empty. /// - // TODO: Add meta-files validation here. + // TODO: Add meta-files validation here. pub fn check(path_to_archive: String) -> Result<bool, std::io::Error> { // Call the new extraction function Self::extract_archive(&path_to_archive)?; @@ -325,27 +330,35 @@ impl Package { } } - let content = std::fs::read_to_string(&install_path) - .map_err(|e| { + let content = std::fs::read_to_string(&install_path).map_err(|e| { log::warn!("Failed to read file: {}", e); e })?; let install_content: Result<Install, toml::de::Error> = toml::from_str(&content); - log::info!("Validating arch..."); - if std::env::consts::ARCH != install_content.as_ref().map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string()))?.package.arch.as_str() { + log::info!("Validating arch..."); + if std::env::consts::ARCH + != install_content + .as_ref() + .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string()))? + .package + .arch + .as_str() + { let pkg_arch = &install_content.unwrap().package.arch; // Safe because of previous check/unwrap - log::error!("Arch mismatch. Package arch: {:?}, Host arch: {}", pkg_arch, std::env::consts::ARCH); + log::error!( + "Arch mismatch. Package arch: {:?}, Host arch: {}", + pkg_arch, + std::env::consts::ARCH + ); return Err(std::io::Error::new( std::io::ErrorKind::InvalidData, "Arch mismatch", )); } - + Ok(true) } - - /// Builds the package according to the BUILD file in the archive. /// @@ -354,21 +367,21 @@ impl Package { /// If the BUILD file is empty and the INSTALL file contains a custom script, the custom script is run instead of the default install hook. /// If the BUILD file is not empty and the INSTALL file contains a custom script, the custom script is ignored. /// - /// + /// /// # Errors /// /// Returns an error if the BUILD file is invalid or if the build or install hook fails. pub fn build(&mut self) -> Result<bool, std::io::Error> { let meta = Self::loadmeta(self).unwrap(); let install_meta = meta.0; - let setts_meta = meta.1; + // let setts_meta = meta.1; let build_meta = meta.2; // BUILD NOT EMPTY. SOURCE: -> BUILD -> INSTALL -> SETTS // BUILD EMPTY. BIN: -> INSTALL -> SETTS enum Strategies { - BIN, - SOURCE + BIN, + SOURCE, } let strategy; //default @@ -380,7 +393,7 @@ impl Package { strategy = Strategies::SOURCE; log::info!("BUILD file is not empty. Skipping install, preparing to build"); } - + match strategy { Strategies::BIN => { if install_meta.custom_script.is_none() { @@ -389,11 +402,10 @@ impl Package { log::info!("Strategy: BIN; Running custom script."); let script = install_meta.custom_script.as_ref().unwrap(); if !script.starts_with("./") { - let _output = std::process::Command::new(format!("{}", script)); + let _output = std::process::Command::new(format!("{}", script)); } else { let _output = std::process::Command::new(format!("/bin/sh '{}'", script)); } - } } Strategies::SOURCE => { @@ -405,111 +417,152 @@ impl Package { Ok(true) } - /// Installs the package according to the INSTALL file in the archive. /// /// There are two strategies for installing the package. If the BUILD file is empty, the package is assumed to be a binary package and the default install hook is skipped. If the BUILD file is not empty, the package is assumed to be a source package and the default build hook is skipped. /// /// If the BUILD file is empty and the INSTALL file contains a custom script, the custom script is run instead of the default install hook. /// If the BUILD file is not empty and the INSTALL file contains a custom script, the custom script is ignored. - /// + /// /// # Errors /// /// Returns an error if the BUILD file is invalid or if the build or install hook fails. pub fn install(&mut self) -> Result<bool, std::io::Error> { - let config = Config::parse() - .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; - let (install_meta, _setts_meta, build_meta) = Self::loadmeta(self) - .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; - - - let is_build_present_and_not_empty = build_meta.is_some(); - - if is_build_present_and_not_empty { - log::info!("Found BUILD file, preparing to build and install package: {}", self.name); - let build_meta_ref = build_meta.as_ref().unwrap(); - self.execute_build(build_meta_ref); - - - if matches!(build_meta_ref.build_system, BuildSystems::Make) { - log::info!("Running 'make install' for package: {}", self.name); - let build_dir = Path::new(&config.paths.cache_dir) - .join(format!("{}-{}", self.name, self.version)); - let output = Command::new("make") - .arg("install") - .current_dir(&build_dir) - .output() - .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("'make install' failed: {}", e)))?; - - if !output.status.success() { - let stderr = String::from_utf8_lossy(&output.stderr); - return Err(std::io::Error::new( + let config = Config::parse() + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + let (install_meta, _setts_meta, build_meta) = Self::loadmeta(self) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; + + let is_build_present_and_not_empty = build_meta.is_some(); + + if is_build_present_and_not_empty { + log::info!( + "Found BUILD file, preparing to build and install package: {}", + self.name + ); + let build_meta_ref = build_meta.as_ref().unwrap(); + let _ = self.execute_build(build_meta_ref); + + if matches!(build_meta_ref.build_system, BuildSystems::Make) { + log::info!("Running 'make install' for package: {}", self.name); + let build_dir = Path::new(&config.paths.cache_dir) + .join(format!("{}-{}", self.name, self.version)); + let output = Command::new("make") + .arg("install") + .current_dir(&build_dir) + .output() + .map_err(|e| { + std::io::Error::new( std::io::ErrorKind::Other, - format!("'make install' failed:\n{}", stderr), - )); - } + format!("'make install' failed: {}", e), + ) + })?; + + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + format!("'make install' failed:\n{}", stderr), + )); + } + } + } else { + log::info!( + "No BUILD file or it's empty. Treating as binary package. Installing via INSTALL config or custom script." + ); + // Установка бинарного пакета + if let Some(ref script) = install_meta.custom_script { + log::info!( + "Executing custom install script for {}", + install_meta.package.name + ); + let status = if script.starts_with("./") || script.contains('/') { + Command::new("/bin/sh").arg("-c").arg(script).status() + } else { + Command::new(script).status() + } + .map_err(|e| { + std::io::Error::new( + std::io::ErrorKind::Other, + format!("Failed to run custom script: {}", e), + ) + })?; + + if !status.success() { + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + "Custom install script failed", + )); } } else { - log::info!("No BUILD file or it's empty. Treating as binary package. Installing via INSTALL config or custom script."); - // Установка бинарного пакета - if let Some(ref script) = install_meta.custom_script { - log::info!("Executing custom install script for {}", install_meta.package.name); - let status = if script.starts_with("./") || script.contains('/') { - Command::new("/bin/sh").arg("-c").arg(script).status() - } else { - Command::new(script).status() - } - .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("Failed to run custom script: {}", e)))?; - - if !status.success() { - return Err(std::io::Error::new( + log::info!( + "No custom script. Running default install hook for {}", + install_meta.package.name + ); + // --- Дефолтный хук установки --- + // 1. Копируем файл из build_dir (предположим, что бинарный файл лежит в корне распакованного архива) + let source_file_name = &self.name; // Предполагаем имя файла = имя пакета + let build_dir = Path::new(&config.paths.cache_dir) + .join(format!("{}-{}", self.name, self.version)); + let src_path = build_dir.join(source_file_name); + let dest_path = Path::new(&install_meta.path); + + // Убедимся, что целевая директория существует + if let Some(parent) = dest_path.parent() { + create_dir_all(parent).map_err(|e| { + std::io::Error::new( std::io::ErrorKind::Other, - "Custom install script failed", - )); - } - } else { - log::info!("No custom script. Running default install hook for {}", install_meta.package.name); - // --- Дефолтный хук установки --- - // 1. Копируем файл из build_dir (предположим, что бинарный файл лежит в корне распакованного архива) - let source_file_name = &self.name; // Предполагаем имя файла = имя пакета - let build_dir = Path::new(&config.paths.cache_dir) - .join(format!("{}-{}", self.name, self.version)); - let src_path = build_dir.join(source_file_name); - let dest_path = Path::new(&install_meta.path); - - // Убедимся, что целевая директория существует - if let Some(parent) = dest_path.parent() { - create_dir_all(parent) - .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("Failed to create parent dir: {}", e)))?; - } - - fs::copy(&src_path, dest_path) - .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("Failed to copy file: {}", e)))?; - - let mode = u32::from_str_radix(&install_meta.mode, 8) - .map_err(|_| std::io::Error::new(std::io::ErrorKind::InvalidData, "Invalid mode string in INSTALL"))?; - let perms = PermissionsExt::from_mode(mode); - fs::set_permissions(dest_path, perms) - .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("Failed to set permissions: {}", e)))?; - - let output = Command::new("chown") - .arg(&format!("{}:{}", install_meta.user, install_meta.group)) - .arg(dest_path) - .output() - .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("'chown' command failed: {}", e)))?; + format!("Failed to create parent dir: {}", e), + ) + })?; + } - if !output.status.success() { - let stderr = String::from_utf8_lossy(&output.stderr); - log::warn!("Warning: 'chown' command failed (requires root?):\n{}", stderr); - } + fs::copy(&src_path, dest_path).map_err(|e| { + std::io::Error::new( + std::io::ErrorKind::Other, + format!("Failed to copy file: {}", e), + ) + })?; + + let mode = u32::from_str_radix(&install_meta.mode, 8).map_err(|_| { + std::io::Error::new( + std::io::ErrorKind::InvalidData, + "Invalid mode string in INSTALL", + ) + })?; + let perms = PermissionsExt::from_mode(mode); + fs::set_permissions(dest_path, perms).map_err(|e| { + std::io::Error::new( + std::io::ErrorKind::Other, + format!("Failed to set permissions: {}", e), + ) + })?; + + let output = Command::new("chown") + .arg(&format!("{}:{}", install_meta.user, install_meta.group)) + .arg(dest_path) + .output() + .map_err(|e| { + std::io::Error::new( + std::io::ErrorKind::Other, + format!("'chown' command failed: {}", e), + ) + })?; + + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + log::warn!( + "Warning: 'chown' command failed (requires root?):\n{}", + stderr + ); } } + } log::info!("Package {} installed successfully.", self.name); Ok(true) } - pub fn gen_index() -> Result<bool, std::io::Error> { + pub fn gen_index() -> Result<bool, std::io::Error> { todo!(); - } -}
\ No newline at end of file +} |
