diff options
| -rw-r--r-- | src/main.rs | 40 | ||||
| -rw-r--r-- | src/pkgtoolkit/pkgtools.rs | 111 |
2 files changed, 142 insertions, 9 deletions
diff --git a/src/main.rs b/src/main.rs index 9a0d103..4515896 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,22 +16,31 @@ struct Cli { #[derive(Subcommand)] enum Commands { + #[command(about = "Validate .mesk package archive")] Validate { pkgname: String, }, + #[command(about = "Build package from .mesk ")] Build{ pkgname: String, }, + #[command(about = "Install package from remote or local sources")] Install{ pkgname: String, }, + #[command(about = "Uninstall package")] Uninstall{ pkgname: String, }, + #[command(about = "Get package source")] + GetSource{ + pkgname: String + } } #[derive(Args, Clone)] +#[command(about = "Remote install arguments")] struct RemoteInstallArgs { Verbose: bool, Debug: bool, @@ -40,6 +49,33 @@ struct RemoteInstallArgs { I2P: bool, } -fn main() { - +fn main() -> Result<(), std::io::Error> { + let cli: Cli = Cli::parse(); + + // Plug in these functions only until the backend is ready for testing (Aplha versions) + // It is necessary for me to understand the I/O model of the future mesk. + match &cli.command { + Commands::Validate { pkgname } => { + println!("Validating {}", pkgname); + return Ok(()) + }, + Commands::Build { pkgname } => { + println!("Building {}", pkgname); + return Ok(()) + }, + Commands::Install { pkgname } => { + println!("Installing {}", pkgname); + return Ok(()) + }, + Commands::Uninstall { pkgname } => { + println!("Uninstalling {}", pkgname); + return Ok(()) + }, + Commands::GetSource { pkgname } => { + println!("Getting source of {}", pkgname); + return Ok(()) + + } +} +Ok(()) }
\ No newline at end of file diff --git a/src/pkgtoolkit/pkgtools.rs b/src/pkgtoolkit/pkgtools.rs index 1577a50..100c5e2 100644 --- a/src/pkgtoolkit/pkgtools.rs +++ b/src/pkgtoolkit/pkgtools.rs @@ -1,23 +1,30 @@ +// I think I should split this file into a few smaller ones. + use crate::cfg::config::Config; +use core::arch; use std::{io, fs::{self, File, create_dir_all}, str, - path::Path}; + path::Path, + process::Command,}; +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; -#[derive(Serialize, Debug, Deserialize)] +#[derive(Serialize, Debug, Deserialize, Clone)] pub enum archs { X86_64, Aarch64, X86, + ArmV7, + ArmV8, } -#[derive(Serialize, Debug, Deserialize)] +#[derive(Serialize, Debug, Deserialize, Clone)] pub struct Package { name: String, version: String, @@ -25,7 +32,7 @@ pub struct Package { descr: Option<String>, } -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, Clone)] struct Install { package: Package, path: String, @@ -57,7 +64,25 @@ struct Build { script: Option<String>, } +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", + _ => "unknown", + } + } +} + impl Package { + fn builder_backend(BuildParameters: Build) -> Result<bool, std::io::Error> { + todo!() + } + + /// Load meta information from the .mesk archive. /// /// This function parses the meta information from the .mesk archive, @@ -72,7 +97,7 @@ impl Package { /// /// 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: Package) -> Result<(Install, Option<Setts>, Option<Build>), Box<dyn std::error::Error>> { // Changed return type for more flexibility + 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] @@ -211,11 +236,83 @@ impl Package { } } + 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.unwrap().package.arch.as_str() { + log::error!("Arch mismatch. Package arch: {:?}, Host arch: {}", install_content.clone().unwrap().package.arch, std::env::consts::ARCH); + return Err(std::io::Error::new( + std::io::ErrorKind::InvalidData, + "Arch mismatch", + )); + } + + + Ok(true) } - pub fn build() -> Result<bool, std::io::Error> { - todo!(); + /// Builds the package according to the BUILD file in the archive. + /// + /// There are two strategies for building 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 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 build_meta = meta.2; + + // BUILD NOT EMPTY. SOURCE: -> BUILD -> INSTALL -> SETTS + // BUILD EMPTY. BIN: -> INSTALL -> SETTS + enum strategies { + BIN, + SOURCE + } + + let mut strategy = strategies::SOURCE; //default + + if build_meta.is_none() { + log::info!("BUILD file is empty. Skipping build, preparing to install"); + strategy = strategies::BIN; + } else { + 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() { + log::info!("Strategy: BIN; No custom script. Running default install hook."); + } else { + 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)); + } else { + let output = std::process::Command::new(format!("/bin/sh '{}'", script)); + } + + } + } + strategies::SOURCE => { + log::info!("Strategy: SOURCE; Running default build hook."); + todo!(); + } + } + + Ok(true) } pub fn install() -> Result<bool, std::io::Error> { todo!(); |
