feat: Improve package management and testing
Some checks failed
Rhai Tests / Run Rhai Tests (push) Has been cancelled
Rhai Tests / Run Rhai Tests (pull_request) Has been cancelled

- Improve platform detection logic for more robust package management.
- Enhance error handling and reporting in package commands.
- Refactor code for better readability and maintainability.
- Add comprehensive tests to cover package management functionality.
- Improve test coverage for various scenarios and edge cases.
This commit is contained in:
Mahmoud Emad
2025-05-09 09:54:32 +03:00
parent f002445c9e
commit 22f87b320e
4 changed files with 300 additions and 232 deletions

View File

@@ -1,9 +1,9 @@
use std::collections::HashMap;
use super::{
error::RfsError,
cmd::execute_rfs_command,
error::RfsError,
types::{Mount, MountType, StoreSpec},
};
use std::collections::HashMap;
/// Builder for RFS mount operations
#[derive(Clone)]
@@ -17,6 +17,7 @@ pub struct RfsBuilder {
/// Mount options
options: HashMap<String, String>,
/// Mount ID
#[allow(dead_code)]
mount_id: Option<String>,
/// Debug mode
debug: bool,
@@ -44,7 +45,7 @@ impl RfsBuilder {
debug: false,
}
}
/// Add a mount option
///
/// # Arguments
@@ -59,7 +60,7 @@ impl RfsBuilder {
self.options.insert(key.to_string(), value.to_string());
self
}
/// Add multiple mount options
///
/// # Arguments
@@ -75,7 +76,7 @@ impl RfsBuilder {
}
self
}
/// Set debug mode
///
/// # Arguments
@@ -89,7 +90,7 @@ impl RfsBuilder {
self.debug = debug;
self
}
/// Mount the filesystem
///
/// # Returns
@@ -99,7 +100,7 @@ impl RfsBuilder {
// Build the command string
let mut cmd = String::from("mount -t ");
cmd.push_str(&self.mount_type.to_string());
// Add options if any
if !self.options.is_empty() {
cmd.push_str(" -o ");
@@ -114,35 +115,39 @@ impl RfsBuilder {
first = false;
}
}
// Add source and target
cmd.push_str(" ");
cmd.push_str(&self.source);
cmd.push_str(" ");
cmd.push_str(&self.target);
// Split the command into arguments
let args: Vec<&str> = cmd.split_whitespace().collect();
// Execute the command
let result = execute_rfs_command(&args)?;
// Parse the output to get the mount ID
let mount_id = result.stdout.trim().to_string();
if mount_id.is_empty() {
return Err(RfsError::MountFailed("Failed to get mount ID".to_string()));
}
// Create and return the Mount struct
Ok(Mount {
id: mount_id,
source: self.source,
target: self.target,
fs_type: self.mount_type.to_string(),
options: self.options.iter().map(|(k, v)| format!("{}={}", k, v)).collect(),
options: self
.options
.iter()
.map(|(k, v)| format!("{}={}", k, v))
.collect(),
})
}
/// Unmount the filesystem
///
/// # Returns
@@ -151,12 +156,15 @@ impl RfsBuilder {
pub fn unmount(&self) -> Result<(), RfsError> {
// Execute the unmount command
let result = execute_rfs_command(&["unmount", &self.target])?;
// Check for errors
if !result.success {
return Err(RfsError::UnmountFailed(format!("Failed to unmount {}: {}", self.target, result.stderr)));
return Err(RfsError::UnmountFailed(format!(
"Failed to unmount {}: {}",
self.target, result.stderr
)));
}
Ok(())
}
}
@@ -193,7 +201,7 @@ impl PackBuilder {
debug: false,
}
}
/// Add a store specification
///
/// # Arguments
@@ -207,7 +215,7 @@ impl PackBuilder {
self.store_specs.push(store_spec);
self
}
/// Add multiple store specifications
///
/// # Arguments
@@ -221,7 +229,7 @@ impl PackBuilder {
self.store_specs.extend(store_specs);
self
}
/// Set debug mode
///
/// # Arguments
@@ -235,7 +243,7 @@ impl PackBuilder {
self.debug = debug;
self
}
/// Pack the directory
///
/// # Returns
@@ -245,7 +253,7 @@ impl PackBuilder {
// Build the command string
let mut cmd = String::from("pack -m ");
cmd.push_str(&self.output);
// Add store specs if any
if !self.store_specs.is_empty() {
cmd.push_str(" -s ");
@@ -259,22 +267,25 @@ impl PackBuilder {
first = false;
}
}
// Add directory
cmd.push_str(" ");
cmd.push_str(&self.directory);
// Split the command into arguments
let args: Vec<&str> = cmd.split_whitespace().collect();
// Execute the command
let result = execute_rfs_command(&args)?;
// Check for errors
if !result.success {
return Err(RfsError::PackFailed(format!("Failed to pack {}: {}", self.directory, result.stderr)));
return Err(RfsError::PackFailed(format!(
"Failed to pack {}: {}",
self.directory, result.stderr
)));
}
Ok(())
}
}
}

View File

@@ -1,7 +1,7 @@
use crate::process::{run_command, CommandResult};
use super::error::RfsError;
use std::thread_local;
use crate::process::{run_command, CommandResult};
use std::cell::RefCell;
use std::thread_local;
// Thread-local storage for debug flag
thread_local! {
@@ -9,6 +9,7 @@ thread_local! {
}
/// Set the thread-local debug flag
#[allow(dead_code)]
pub fn set_thread_local_debug(debug: bool) {
DEBUG.with(|d| {
*d.borrow_mut() = debug;
@@ -17,9 +18,7 @@ pub fn set_thread_local_debug(debug: bool) {
/// Get the current thread-local debug flag
pub fn thread_local_debug() -> bool {
DEBUG.with(|d| {
*d.borrow()
})
DEBUG.with(|d| *d.borrow())
}
/// Execute an RFS command with the given arguments
@@ -33,30 +32,30 @@ pub fn thread_local_debug() -> bool {
/// * `Result<CommandResult, RfsError>` - Command result or error
pub fn execute_rfs_command(args: &[&str]) -> Result<CommandResult, RfsError> {
let debug = thread_local_debug();
// Construct the command string
let mut cmd = String::from("rfs");
for arg in args {
cmd.push(' ');
cmd.push_str(arg);
}
if debug {
println!("Executing RFS command: {}", cmd);
}
// Execute the command
let result = run_command(&cmd)
.map_err(|e| RfsError::CommandFailed(format!("Failed to execute RFS command: {}", e)))?;
if debug {
println!("RFS command result: {:?}", result);
}
// Check if the command was successful
if !result.success && !result.stderr.is_empty() {
return Err(RfsError::CommandFailed(result.stderr));
}
Ok(result)
}
}