...
This commit is contained in:
parent
c9b4010089
commit
bf5eb2f6fc
0
rhai_dir_test/base_file.txt
Normal file
0
rhai_dir_test/base_file.txt
Normal file
0
rhai_dir_test/tmp/test/sub_file.txt
Normal file
0
rhai_dir_test/tmp/test/sub_file.txt
Normal file
0
rhai_test_dir/copied_file.txt
Normal file
0
rhai_test_dir/copied_file.txt
Normal file
0
rhai_test_dir/test_file.txt
Normal file
0
rhai_test_dir/test_file.txt
Normal file
@ -19,10 +19,13 @@ let file_content = "This is a test file created by Rhai script.";
|
|||||||
println(`Creating file: ${test_file}`);
|
println(`Creating file: ${test_file}`);
|
||||||
// First ensure the directory exists
|
// First ensure the directory exists
|
||||||
run_command(`mkdir -p ${test_dir}`);
|
run_command(`mkdir -p ${test_dir}`);
|
||||||
// Then create the file using a different approach
|
// Then create the file using a simpler approach
|
||||||
// Use run_command with sh -c to properly handle shell features
|
// First touch the file
|
||||||
let write_cmd = `sh -c 'touch ${test_file} && echo "${file_content}" > ${test_file}'`;
|
let touch_cmd = `touch ${test_file}`;
|
||||||
let write_result = run_command(write_cmd);
|
run_command(touch_cmd);
|
||||||
|
// Then write to it with a separate command
|
||||||
|
let echo_cmd = `echo ${file_content} > ${test_file}`;
|
||||||
|
let write_result = run_command(echo_cmd);
|
||||||
println(`File creation result: ${write_result.success}`);
|
println(`File creation result: ${write_result.success}`);
|
||||||
|
|
||||||
// Wait a moment to ensure the file is created
|
// Wait a moment to ensure the file is created
|
||||||
|
84
rhaiexamples/05_directory_operations.rhai
Normal file
84
rhaiexamples/05_directory_operations.rhai
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// 05_directory_operations.rhai
|
||||||
|
// Demonstrates directory operations using SAL, including the new chdir function
|
||||||
|
|
||||||
|
// Create a test directory structure
|
||||||
|
let base_dir = "rhai_dir_test";
|
||||||
|
let sub_dir = base_dir + "/tmp/test";
|
||||||
|
|
||||||
|
println("Creating directory structure...");
|
||||||
|
let base_result = mkdir(base_dir+"/subdir");
|
||||||
|
println(`Base directory creation result: ${base_result}`);
|
||||||
|
|
||||||
|
let sub_result = mkdir(sub_dir);
|
||||||
|
println(`Subdirectory creation result: ${sub_result}`);
|
||||||
|
|
||||||
|
// Create a test file in the base directory
|
||||||
|
let base_file = base_dir + "/base_file.txt";
|
||||||
|
let base_content = "This is a file in the base directory.";
|
||||||
|
// First touch the file
|
||||||
|
run_command(`touch ${base_file}`);
|
||||||
|
// Then write to it with a separate command
|
||||||
|
run_command(`echo ${base_content} > ${base_file}`);
|
||||||
|
|
||||||
|
// Create a test file in the subdirectory
|
||||||
|
let sub_file = sub_dir + "/sub_file.txt";
|
||||||
|
let sub_content = "This is a file in the subdirectory.";
|
||||||
|
// First touch the file
|
||||||
|
run_command(`touch ${sub_file}`);
|
||||||
|
// Then write to it with a separate command
|
||||||
|
run_command(`echo ${sub_content} > ${sub_file}`);
|
||||||
|
|
||||||
|
// Get the current working directory before changing
|
||||||
|
let pwd_before = run_command("pwd");
|
||||||
|
println(`Current directory before chdir: ${pwd_before.stdout.trim()}`);
|
||||||
|
|
||||||
|
// Change to the base directory
|
||||||
|
println(`Changing directory to: ${base_dir}`);
|
||||||
|
let chdir_result = chdir(base_dir);
|
||||||
|
println(`Directory change result: ${chdir_result}`);
|
||||||
|
|
||||||
|
// Get the current working directory after changing
|
||||||
|
let pwd_after = run_command("pwd");
|
||||||
|
println(`Current directory after chdir: ${pwd_after.stdout.trim()}`);
|
||||||
|
|
||||||
|
// List files in the current directory (which should now be the base directory)
|
||||||
|
println("Files in the current directory:");
|
||||||
|
let files = find_files(".", "*");
|
||||||
|
println("Files found:");
|
||||||
|
for file in files {
|
||||||
|
println(`- ${file}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change to the subdirectory
|
||||||
|
println(`Changing directory to: subdir`);
|
||||||
|
let chdir_sub_result = chdir("subdir");
|
||||||
|
println(`Directory change result: ${chdir_sub_result}`);
|
||||||
|
|
||||||
|
// Get the current working directory after changing to subdirectory
|
||||||
|
let pwd_final = run_command("pwd");
|
||||||
|
println(`Current directory after second chdir: ${pwd_final.stdout.trim()}`);
|
||||||
|
|
||||||
|
// List files in the subdirectory
|
||||||
|
println("Files in the subdirectory:");
|
||||||
|
let subdir_files = find_files(".", "*");
|
||||||
|
println("Files found:");
|
||||||
|
for file in subdir_files {
|
||||||
|
println(`- ${file}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change back to the parent directory
|
||||||
|
println("Changing directory back to parent...");
|
||||||
|
let chdir_parent_result = chdir("..");
|
||||||
|
println(`Directory change result: ${chdir_parent_result}`);
|
||||||
|
|
||||||
|
// Clean up (uncomment to actually delete the files)
|
||||||
|
// println("Cleaning up...");
|
||||||
|
// Change back to the original directory first
|
||||||
|
// chdir(pwd_before.stdout.trim());
|
||||||
|
// delete(sub_file);
|
||||||
|
// delete(base_file);
|
||||||
|
// delete(sub_dir);
|
||||||
|
// delete(base_dir);
|
||||||
|
// println("Cleanup complete");
|
||||||
|
|
||||||
|
"Directory operations script completed successfully!"
|
@ -16,7 +16,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
.short("p")
|
.short("p")
|
||||||
.long("path")
|
.long("path")
|
||||||
.value_name("PATH")
|
.value_name("PATH")
|
||||||
.help("Path to directory containing Rhai scripts")
|
.help("Path to a Rhai script file or directory containing Rhai scripts")
|
||||||
.required(true)
|
.required(true)
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
|
@ -14,17 +14,17 @@ use std::process;
|
|||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `script_path` - Path to the directory containing Rhai scripts
|
/// * `script_path` - Path to a Rhai script file or directory containing Rhai scripts
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// Result indicating success or failure
|
/// Result indicating success or failure
|
||||||
pub fn run(script_path: &str) -> Result<(), Box<dyn Error>> {
|
pub fn run(script_path: &str) -> Result<(), Box<dyn Error>> {
|
||||||
let script_dir = Path::new(script_path);
|
let path = Path::new(script_path);
|
||||||
|
|
||||||
// Check if the directory exists
|
// Check if the path exists
|
||||||
if !script_dir.exists() || !script_dir.is_dir() {
|
if !path.exists() {
|
||||||
eprintln!("Error: '{}' is not a valid directory", script_path);
|
eprintln!("Error: '{}' does not exist", script_path);
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,25 +37,57 @@ pub fn run(script_path: &str) -> Result<(), Box<dyn Error>> {
|
|||||||
// Register all SAL modules with the engine
|
// Register all SAL modules with the engine
|
||||||
crate::rhai::register(&mut engine)?;
|
crate::rhai::register(&mut engine)?;
|
||||||
|
|
||||||
// Find all .rhai files in the directory
|
// Determine if the path is a file or directory
|
||||||
let mut script_files: Vec<PathBuf> = fs::read_dir(script_dir)?
|
let script_files: Vec<PathBuf> = if path.is_file() {
|
||||||
.filter_map(Result::ok)
|
// Check if it's a .rhai file
|
||||||
.filter(|entry| {
|
if path.extension().map_or(false, |ext| ext == "rhai") {
|
||||||
entry.path().is_file() &&
|
vec![path.to_path_buf()]
|
||||||
entry.path().extension().map_or(false, |ext| ext == "rhai")
|
} else {
|
||||||
})
|
eprintln!("Error: '{}' is not a Rhai script file", script_path);
|
||||||
.map(|entry| entry.path())
|
process::exit(1);
|
||||||
.collect();
|
}
|
||||||
|
} else if path.is_dir() {
|
||||||
|
// Find all .rhai files in the directory recursively
|
||||||
|
let mut files: Vec<PathBuf> = Vec::new();
|
||||||
|
|
||||||
|
// Helper function to recursively find .rhai files
|
||||||
|
fn find_rhai_files(dir: &Path, files: &mut Vec<PathBuf>) -> std::io::Result<()> {
|
||||||
|
if dir.is_dir() {
|
||||||
|
for entry in fs::read_dir(dir)? {
|
||||||
|
let entry = entry?;
|
||||||
|
let path = entry.path();
|
||||||
|
|
||||||
|
if path.is_dir() {
|
||||||
|
find_rhai_files(&path, files)?;
|
||||||
|
} else if path.is_file() &&
|
||||||
|
path.extension().map_or(false, |ext| ext == "rhai") {
|
||||||
|
files.push(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all .rhai files recursively
|
||||||
|
find_rhai_files(path, &mut files)?;
|
||||||
|
|
||||||
// Sort the script files by name
|
// Sort the script files by name
|
||||||
script_files.sort();
|
files.sort();
|
||||||
|
|
||||||
if script_files.is_empty() {
|
if files.is_empty() {
|
||||||
println!("No Rhai scripts found in '{}'", script_path);
|
println!("No Rhai scripts found in '{}'", script_path);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Found {} Rhai scripts to execute:", script_files.len());
|
files
|
||||||
|
} else {
|
||||||
|
eprintln!("Error: '{}' is neither a file nor a directory", script_path);
|
||||||
|
process::exit(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("Found {} Rhai script{} to execute:",
|
||||||
|
script_files.len(),
|
||||||
|
if script_files.len() == 1 { "" } else { "s" });
|
||||||
|
|
||||||
// Execute each script in sorted order
|
// Execute each script in sorted order
|
||||||
for script_file in script_files {
|
for script_file in script_files {
|
||||||
@ -74,7 +106,8 @@ pub fn run(script_path: &str) -> Result<(), Box<dyn Error>> {
|
|||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("Error executing script: {}", err);
|
eprintln!("Error executing script: {}", err);
|
||||||
// Continue with the next script instead of stopping
|
// Exit with error code when a script fails
|
||||||
|
process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
41
src/os/fs.rs
41
src/os/fs.rs
@ -20,6 +20,7 @@ pub enum FsError {
|
|||||||
NotAFile(String),
|
NotAFile(String),
|
||||||
UnknownFileType(String),
|
UnknownFileType(String),
|
||||||
MetadataError(io::Error),
|
MetadataError(io::Error),
|
||||||
|
ChangeDirFailed(io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement Display for FsError
|
// Implement Display for FsError
|
||||||
@ -38,6 +39,7 @@ impl fmt::Display for FsError {
|
|||||||
FsError::NotAFile(path) => write!(f, "Path '{}' is not a regular file", path),
|
FsError::NotAFile(path) => write!(f, "Path '{}' is not a regular file", path),
|
||||||
FsError::UnknownFileType(path) => write!(f, "Unknown file type at '{}'", path),
|
FsError::UnknownFileType(path) => write!(f, "Unknown file type at '{}'", path),
|
||||||
FsError::MetadataError(e) => write!(f, "Failed to get file metadata: {}", e),
|
FsError::MetadataError(e) => write!(f, "Failed to get file metadata: {}", e),
|
||||||
|
FsError::ChangeDirFailed(e) => write!(f, "Failed to change directory: {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,6 +54,7 @@ impl Error for FsError {
|
|||||||
FsError::CommandExecutionError(e) => Some(e),
|
FsError::CommandExecutionError(e) => Some(e),
|
||||||
FsError::InvalidGlobPattern(e) => Some(e),
|
FsError::InvalidGlobPattern(e) => Some(e),
|
||||||
FsError::MetadataError(e) => Some(e),
|
FsError::MetadataError(e) => Some(e),
|
||||||
|
FsError::ChangeDirFailed(e) => Some(e),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -578,3 +581,41 @@ pub fn rsync(src: &str, dest: &str) -> Result<String, FsError> {
|
|||||||
Err(e) => Err(FsError::CommandExecutionError(e)),
|
Err(e) => Err(FsError::CommandExecutionError(e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the current working directory.
|
||||||
|
*
|
||||||
|
* # Arguments
|
||||||
|
*
|
||||||
|
* * `path` - The path to change to
|
||||||
|
*
|
||||||
|
* # Returns
|
||||||
|
*
|
||||||
|
* * `Ok(String)` - A success message indicating the directory was changed
|
||||||
|
* * `Err(FsError)` - An error if the directory change failed
|
||||||
|
*
|
||||||
|
* # Examples
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* let result = chdir("/path/to/directory")?;
|
||||||
|
* println!("{}", result);
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
pub fn chdir(path: &str) -> Result<String, FsError> {
|
||||||
|
let path_obj = Path::new(path);
|
||||||
|
|
||||||
|
// Check if directory exists
|
||||||
|
if !path_obj.exists() {
|
||||||
|
return Err(FsError::DirectoryNotFound(path.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's a directory
|
||||||
|
if !path_obj.is_dir() {
|
||||||
|
return Err(FsError::NotADirectory(path.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change directory
|
||||||
|
std::env::set_current_dir(path_obj).map_err(FsError::ChangeDirFailed)?;
|
||||||
|
|
||||||
|
Ok(format!("Successfully changed directory to '{}'", path))
|
||||||
|
}
|
||||||
|
@ -30,6 +30,7 @@ pub fn register_os_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>>
|
|||||||
engine.register_fn("mkdir", mkdir);
|
engine.register_fn("mkdir", mkdir);
|
||||||
engine.register_fn("file_size", file_size);
|
engine.register_fn("file_size", file_size);
|
||||||
engine.register_fn("rsync", rsync);
|
engine.register_fn("rsync", rsync);
|
||||||
|
engine.register_fn("chdir", chdir);
|
||||||
|
|
||||||
// Register download functions
|
// Register download functions
|
||||||
engine.register_fn("download", download);
|
engine.register_fn("download", download);
|
||||||
@ -128,6 +129,13 @@ pub fn rsync(src: &str, dest: &str) -> Result<String, Box<EvalAltResult>> {
|
|||||||
os::rsync(src, dest).to_rhai_error()
|
os::rsync(src, dest).to_rhai_error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wrapper for os::chdir
|
||||||
|
///
|
||||||
|
/// Change the current working directory.
|
||||||
|
pub fn chdir(path: &str) -> Result<String, Box<EvalAltResult>> {
|
||||||
|
os::chdir(path).to_rhai_error()
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Download Function Wrappers
|
// Download Function Wrappers
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user