...
This commit is contained in:
		
							
								
								
									
										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}`); | ||||
| // First ensure the directory exists | ||||
| run_command(`mkdir -p ${test_dir}`); | ||||
| // Then create the file using a different approach | ||||
| // Use run_command with sh -c to properly handle shell features | ||||
| let write_cmd = `sh -c 'touch ${test_file} && echo "${file_content}" > ${test_file}'`; | ||||
| let write_result = run_command(write_cmd); | ||||
| // Then create the file using a simpler approach | ||||
| // First touch the file | ||||
| let touch_cmd = `touch ${test_file}`; | ||||
| 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}`); | ||||
|  | ||||
| // 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") | ||||
|                 .long("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) | ||||
|                 .takes_value(true), | ||||
|         ) | ||||
|   | ||||
| @@ -14,17 +14,17 @@ use std::process; | ||||
| /// | ||||
| /// # Arguments | ||||
| /// | ||||
| /// * `script_path` - Path to the directory containing Rhai scripts | ||||
| /// * `script_path` - Path to a Rhai script file or directory containing Rhai scripts | ||||
| /// | ||||
| /// # Returns | ||||
| /// | ||||
| /// Result indicating success or failure | ||||
| 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 | ||||
|     if !script_dir.exists() || !script_dir.is_dir() { | ||||
|         eprintln!("Error: '{}' is not a valid directory", script_path); | ||||
|     // Check if the path exists | ||||
|     if !path.exists() { | ||||
|         eprintln!("Error: '{}' does not exist", script_path); | ||||
|         process::exit(1); | ||||
|     } | ||||
|  | ||||
| @@ -37,25 +37,57 @@ pub fn run(script_path: &str) -> Result<(), Box<dyn Error>> { | ||||
|     // Register all SAL modules with the engine | ||||
|     crate::rhai::register(&mut engine)?; | ||||
|  | ||||
|     // Find all .rhai files in the directory | ||||
|     let mut script_files: Vec<PathBuf> = fs::read_dir(script_dir)? | ||||
|         .filter_map(Result::ok) | ||||
|         .filter(|entry| { | ||||
|             entry.path().is_file() && | ||||
|             entry.path().extension().map_or(false, |ext| ext == "rhai") | ||||
|         }) | ||||
|         .map(|entry| entry.path()) | ||||
|         .collect(); | ||||
|     // Determine if the path is a file or directory | ||||
|     let script_files: Vec<PathBuf> = if path.is_file() { | ||||
|         // Check if it's a .rhai file | ||||
|         if path.extension().map_or(false, |ext| ext == "rhai") { | ||||
|             vec![path.to_path_buf()] | ||||
|         } else { | ||||
|             eprintln!("Error: '{}' is not a Rhai script file", script_path); | ||||
|             process::exit(1); | ||||
|         } | ||||
|     } 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 | ||||
|         files.sort(); | ||||
|          | ||||
|         if files.is_empty() { | ||||
|             println!("No Rhai scripts found in '{}'", script_path); | ||||
|             return Ok(()); | ||||
|         } | ||||
|          | ||||
|         files | ||||
|     } else { | ||||
|         eprintln!("Error: '{}' is neither a file nor a directory", script_path); | ||||
|         process::exit(1); | ||||
|     }; | ||||
|  | ||||
|     // Sort the script files by name | ||||
|     script_files.sort(); | ||||
|  | ||||
|     if script_files.is_empty() { | ||||
|         println!("No Rhai scripts found in '{}'", script_path); | ||||
|         return Ok(()); | ||||
|     } | ||||
|  | ||||
|     println!("Found {} Rhai scripts to execute:", script_files.len()); | ||||
|     println!("Found {} Rhai script{} to execute:", | ||||
|              script_files.len(), | ||||
|              if script_files.len() == 1 { "" } else { "s" }); | ||||
|      | ||||
|     // Execute each script in sorted order | ||||
|     for script_file in script_files { | ||||
| @@ -74,7 +106,8 @@ pub fn run(script_path: &str) -> Result<(), Box<dyn Error>> { | ||||
|             }, | ||||
|             Err(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), | ||||
|     UnknownFileType(String), | ||||
|     MetadataError(io::Error), | ||||
|     ChangeDirFailed(io::Error), | ||||
| } | ||||
|  | ||||
| // 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::UnknownFileType(path) => write!(f, "Unknown file type at '{}'", path), | ||||
|             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::InvalidGlobPattern(e) => Some(e), | ||||
|             FsError::MetadataError(e) => Some(e), | ||||
|             FsError::ChangeDirFailed(e) => Some(e), | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| @@ -578,3 +581,41 @@ pub fn rsync(src: &str, dest: &str) -> Result<String, FsError> { | ||||
|         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("file_size", file_size); | ||||
|     engine.register_fn("rsync", rsync); | ||||
|     engine.register_fn("chdir", chdir); | ||||
|      | ||||
|     // Register download functions | ||||
|     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() | ||||
| } | ||||
|  | ||||
| /// 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 | ||||
| // | ||||
|   | ||||
		Reference in New Issue
	
	Block a user