diff --git a/iceoryx2-cli/iox2/Cargo.toml b/iceoryx2-cli/iox2/Cargo.toml index 7e630195c..a945b2bf1 100644 --- a/iceoryx2-cli/iox2/Cargo.toml +++ b/iceoryx2-cli/iox2/Cargo.toml @@ -15,3 +15,4 @@ human-panic = "1.2.3" better-panic = "0.3.0" clap = { version = "4.4.18", features = ["derive"] } colored = "2.0" +thiserror = "1.0.56" diff --git a/iceoryx2-cli/iox2/src/cli.rs b/iceoryx2-cli/iox2/src/cli.rs index 14ce10000..d891eb0e4 100644 --- a/iceoryx2-cli/iox2/src/cli.rs +++ b/iceoryx2-cli/iox2/src/cli.rs @@ -16,6 +16,9 @@ pub struct Cli { #[arg(short, long, help = "Run development commands")] pub dev: bool, + + #[arg(hide = true, required = false)] + pub external_command: Vec, } fn help_template() -> &'static str { diff --git a/iceoryx2-cli/iox2/src/commands.rs b/iceoryx2-cli/iox2/src/commands.rs index 5bea9544e..7ca1c4d7f 100644 --- a/iceoryx2-cli/iox2/src/commands.rs +++ b/iceoryx2-cli/iox2/src/commands.rs @@ -2,6 +2,23 @@ use colored::*; use std::env; use std::fs; use std::path::PathBuf; +use std::process::{Command, Stdio}; +use thiserror::Error; + +#[derive(Clone, Debug)] +struct CommandInfo { + name: String, + path: PathBuf, + is_development: bool, +} + +#[derive(Error, Debug)] +pub enum ExecutionError { + #[error("Command not found: {0}")] + NotFound(String), + #[error("Execution failed: {0}")] + Failed(String), +} pub fn list() { println!("Installed Commands:"); @@ -11,20 +28,13 @@ pub fn list() { " {}", format!( "{}{}", + if command.is_development { "(dev) " } else { "" }, command.name.bold(), - if command.is_development { " (dev)" } else { "" } ) ); } } -#[derive(Clone, Debug)] -struct CommandInfo { - name: String, - path: PathBuf, - is_development: bool, -} - fn find() -> Vec { let development_commands = find_command_binaries_in_development_dirs(); let installed_commands = find_command_binaries_in_system_path(); @@ -107,3 +117,44 @@ fn is_valid_command_binary(path: &PathBuf) -> bool { .starts_with("iox2-") && path.extension().is_none() // Exclude files with extensions (e.g. '.d') } + +pub fn execute_external_command( + command_name: &str, + args: &[String], + dev_flag_present: bool, +) -> Result<(), ExecutionError> { + let available_commands = find(); + if let Some(command_info) = available_commands.into_iter().find(|c| { + &c.name == command_name + && if dev_flag_present { + c.is_development == true + } else { + if c.is_development { + println!( + "Development version of {} found but --dev flag is not set.", + command_name + ) + } + false + } + }) { + execute(&command_info, Some(args)) + } else { + Err(ExecutionError::NotFound(command_name.to_string())) + } +} + +fn execute(command_info: &CommandInfo, args: Option<&[String]>) -> Result<(), ExecutionError> { + let mut command = Command::new(&command_info.path); + command.stdout(Stdio::inherit()).stderr(Stdio::inherit()); + if let Some(arguments) = args { + command.args(arguments); + } + match command.status() { + Ok(_) => Ok(()), + Err(e) => Err(ExecutionError::Failed(format!( + "Failed to execute command: {}", + e + ))), + } +} diff --git a/iceoryx2-cli/iox2/src/main.rs b/iceoryx2-cli/iox2/src/main.rs index 44cfcd1b2..43bc1c5ab 100644 --- a/iceoryx2-cli/iox2/src/main.rs +++ b/iceoryx2-cli/iox2/src/main.rs @@ -27,5 +27,20 @@ fn main() { if cli.list { commands::list(); + } else if !cli.external_command.is_empty() { + let command_name = &cli.external_command[0]; + let command_args = &cli.external_command[1..]; + match commands::execute_external_command(command_name, command_args, cli.dev) { + Ok(()) => { + // Command executed successfully, nothing to do + } + Err(commands::ExecutionError::NotFound(_)) => { + // Command not found, print help + println!("Command not found. See all installed commands with --list."); + } + Err(commands::ExecutionError::Failed(_)) => { + println!("Command found but execution failed ..."); + } + } } }