feat: Improve package management and testing
- 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:
@@ -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(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user