summaryrefslogtreecommitdiff
path: root/src/pkgtoolkit
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkgtoolkit')
-rw-r--r--src/pkgtoolkit/mod.rs2
-rw-r--r--src/pkgtoolkit/pkgtools.rs385
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
+}