From af2e8ba51ebcb59d526ce8a74447e0f88d7baa80 Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Tue, 3 Mar 2026 08:31:37 +0000 Subject: [PATCH] fixes PR006 --- crates/tools/prometeu-cli/src/main.rs | 66 +++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/crates/tools/prometeu-cli/src/main.rs b/crates/tools/prometeu-cli/src/main.rs index bbd42e7a..0fce6e0c 100644 --- a/crates/tools/prometeu-cli/src/main.rs +++ b/crates/tools/prometeu-cli/src/main.rs @@ -1,7 +1,7 @@ use clap::{Parser, Subcommand}; use std::env; use std::path::{Path, PathBuf}; -use std::process::Command; +use std::process::{Command, ExitStatus}; /// PROMETEU Dispatcher (CLI). /// @@ -158,9 +158,13 @@ fn execute_bin(bin_path: &Path, args: &[&str]) { .status(); match status { - Ok(status) => { - std::process::exit(status.code().unwrap_or(0)); - } + Ok(status) => match child_exit_code(status) { + Ok(code) => std::process::exit(code), + Err(message) => { + eprintln!("Error: {} ({})", message, bin_path.display()); + std::process::exit(1); + } + }, Err(e) => { eprintln!("Error executing {}: {}", bin_path.display(), e); std::process::exit(1); @@ -172,3 +176,57 @@ fn not_implemented(cmd: &str, _bin_name: &str) { eprintln!("prometeu: command '{}' is not yet available in this distribution", cmd); std::process::exit(1); } + +fn child_exit_code(status: ExitStatus) -> Result { + status.code().ok_or("child process terminated without a numeric exit code") +} + +#[cfg(test)] +mod tests { + use super::child_exit_code; + use std::process::ExitStatus; + + #[test] + fn child_exit_code_preserves_zero() { + let status = exit_status_with_code(0); + assert_eq!(child_exit_code(status), Ok(0)); + } + + #[test] + fn child_exit_code_preserves_non_zero_one() { + let status = exit_status_with_code(1); + assert_eq!(child_exit_code(status), Ok(1)); + } + + #[test] + fn child_exit_code_preserves_non_zero_other() { + let status = exit_status_with_code(42); + assert_eq!(child_exit_code(status), Ok(42)); + } + + #[cfg(unix)] + #[test] + fn child_exit_code_rejects_status_without_numeric_code() { + use std::os::unix::process::ExitStatusExt; + + let status = ExitStatus::from_raw(9); + assert_eq!( + child_exit_code(status), + Err("child process terminated without a numeric exit code") + ); + } + + #[cfg(unix)] + fn exit_status_with_code(code: i32) -> ExitStatus { + use std::os::unix::process::ExitStatusExt; + + ExitStatus::from_raw(code << 8) + } + + #[cfg(windows)] + fn exit_status_with_code(code: i32) -> ExitStatus { + use std::os::windows::process::ExitStatusExt; + + ExitStatus::from_raw(code as u32) + } +}