...
Some checks are pending
Rhai Tests / Run Rhai Tests (push) Waiting to run

This commit is contained in:
kristof 2025-06-15 22:15:44 +02:00
parent f0d7636cda
commit 0e7dba9466

View File

@ -6,6 +6,8 @@ use std::path::Path;
use std::process::Command;
use libc;
use dirs;
#[cfg(not(target_os = "windows"))]
use std::os::unix::fs::PermissionsExt;
// Define a custom error type for file system operations
#[derive(Debug)]
@ -77,39 +79,14 @@ impl Error for FsError {
}
}
/**
* Recursively copy a file or directory from source to destination.
*
* # Arguments
*
* * `src` - The source path, which can include wildcards
* * `dest` - The destination path
*
* # Returns
*
* * `Ok(String)` - A success message indicating what was copied
* * `Err(FsError)` - An error if the copy operation failed
*
* # Examples
*
* ```no_run
* use sal::os::copy;
*
* fn main() -> Result<(), Box<dyn std::error::Error>> {
* // Copy a single file
* let result = copy("file.txt", "backup/file.txt")?;
*
* // Copy multiple files using wildcards
* let result = copy("*.txt", "backup/")?;
*
* // Copy a directory recursively
* let result = copy("src_dir", "dest_dir")?;
*
* Ok(())
* }
* ```
*/
pub fn copy(src: &str, dest: &str) -> Result<String, FsError> {
#[cfg(not(target_os = "windows"))]
fn set_executable(path: &Path) -> Result<(), io::Error> {
let mut perms = fs::metadata(path)?.permissions();
perms.set_mode(0o755); // rwxr-xr-x
fs::set_permissions(path, perms)
}
fn copy_internal(src: &str, dest: &str, make_executable: bool) -> Result<String, FsError> {
let dest_path = Path::new(dest);
// Check if source path contains wildcards
@ -155,6 +132,18 @@ pub fn copy(src: &str, dest: &str) -> Result<String, FsError> {
println!("Warning: Failed to copy {}: {}", path.display(), e);
} else {
success_count += 1;
if make_executable {
#[cfg(not(target_os = "windows"))]
{
if let Err(e) = set_executable(&target_path) {
println!(
"Warning: Failed to make {} executable: {}",
target_path.display(),
e
);
}
}
}
}
} else if path.is_dir() {
// For directories, use platform-specific command
@ -225,7 +214,19 @@ pub fn copy(src: &str, dest: &str) -> Result<String, FsError> {
if dest_path.exists() && dest_path.is_dir() {
let file_name = src_path.file_name().unwrap_or_default();
let new_dest_path = dest_path.join(file_name);
fs::copy(src_path, new_dest_path).map_err(FsError::CopyFailed)?;
fs::copy(src_path, &new_dest_path).map_err(FsError::CopyFailed)?;
if make_executable {
#[cfg(not(target_os = "windows"))]
{
if let Err(e) = set_executable(&new_dest_path) {
println!(
"Warning: Failed to make {} executable: {}",
new_dest_path.display(),
e
);
}
}
}
Ok(format!(
"Successfully copied file '{}' to '{}/{}'",
src,
@ -235,6 +236,18 @@ pub fn copy(src: &str, dest: &str) -> Result<String, FsError> {
} else {
// Otherwise copy file to the specified destination
fs::copy(src_path, dest_path).map_err(FsError::CopyFailed)?;
if make_executable {
#[cfg(not(target_os = "windows"))]
{
if let Err(e) = set_executable(dest_path) {
println!(
"Warning: Failed to make {} executable: {}",
dest_path.display(),
e
);
}
}
}
Ok(format!("Successfully copied file '{}' to '{}'", src, dest))
}
} else if src_path.is_dir() {
@ -269,6 +282,43 @@ pub fn copy(src: &str, dest: &str) -> Result<String, FsError> {
}
}
}
/**
* Recursively copy a file or directory from source to destination.
*
* # Arguments
*
* * `src` - The source path, which can include wildcards
* * `dest` - The destination path
*
* # Returns
*
* * `Ok(String)` - A success message indicating what was copied
* * `Err(FsError)` - An error if the copy operation failed
*
* # Examples
*
* ```no_run
* use sal::os::copy;
*
* fn main() -> Result<(), Box<dyn std::error::Error>> {
* // Copy a single file
* let result = copy("file.txt", "backup/file.txt")?;
*
* // Copy multiple files using wildcards
* let result = copy("*.txt", "backup/")?;
*
* // Copy a directory recursively
* let result = copy("src_dir", "dest_dir")?;
*
* Ok(())
* }
* ```
*/
pub fn copy(src: &str, dest: &str) -> Result<String, FsError> {
copy_internal(src, dest, false)
}
/**
* Copy a binary to the correct location based on OS and user privileges.
*
@ -302,7 +352,7 @@ pub fn copy_bin(src: &str) -> Result<String, FsError> {
.join("hero/bin")
};
let result = copy(src, dest_path.to_str().unwrap());
let result = copy_internal(src, dest_path.to_str().unwrap(), true);
if let Ok(msg) = &result {
println!("{}", msg);
}