This commit is contained in:
parent
f0d7636cda
commit
0e7dba9466
120
src/os/fs.rs
120
src/os/fs.rs
@ -6,6 +6,8 @@ use std::path::Path;
|
|||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use libc;
|
use libc;
|
||||||
use dirs;
|
use dirs;
|
||||||
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
|
||||||
// Define a custom error type for file system operations
|
// Define a custom error type for file system operations
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -77,39 +79,14 @@ impl Error for FsError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#[cfg(not(target_os = "windows"))]
|
||||||
* Recursively copy a file or directory from source to destination.
|
fn set_executable(path: &Path) -> Result<(), io::Error> {
|
||||||
*
|
let mut perms = fs::metadata(path)?.permissions();
|
||||||
* # Arguments
|
perms.set_mode(0o755); // rwxr-xr-x
|
||||||
*
|
fs::set_permissions(path, perms)
|
||||||
* * `src` - The source path, which can include wildcards
|
}
|
||||||
* * `dest` - The destination path
|
|
||||||
*
|
fn copy_internal(src: &str, dest: &str, make_executable: bool) -> Result<String, FsError> {
|
||||||
* # 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> {
|
|
||||||
let dest_path = Path::new(dest);
|
let dest_path = Path::new(dest);
|
||||||
|
|
||||||
// Check if source path contains wildcards
|
// 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);
|
println!("Warning: Failed to copy {}: {}", path.display(), e);
|
||||||
} else {
|
} else {
|
||||||
success_count += 1;
|
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() {
|
} else if path.is_dir() {
|
||||||
// For directories, use platform-specific command
|
// 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() {
|
if dest_path.exists() && dest_path.is_dir() {
|
||||||
let file_name = src_path.file_name().unwrap_or_default();
|
let file_name = src_path.file_name().unwrap_or_default();
|
||||||
let new_dest_path = dest_path.join(file_name);
|
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!(
|
Ok(format!(
|
||||||
"Successfully copied file '{}' to '{}/{}'",
|
"Successfully copied file '{}' to '{}/{}'",
|
||||||
src,
|
src,
|
||||||
@ -235,6 +236,18 @@ pub fn copy(src: &str, dest: &str) -> Result<String, FsError> {
|
|||||||
} else {
|
} else {
|
||||||
// Otherwise copy file to the specified destination
|
// Otherwise copy file to the specified destination
|
||||||
fs::copy(src_path, dest_path).map_err(FsError::CopyFailed)?;
|
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))
|
Ok(format!("Successfully copied file '{}' to '{}'", src, dest))
|
||||||
}
|
}
|
||||||
} else if src_path.is_dir() {
|
} 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.
|
* 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")
|
.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 {
|
if let Ok(msg) = &result {
|
||||||
println!("{}", msg);
|
println!("{}", msg);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user