diff --git a/crates/tui/src/eval.rs b/crates/tui/src/eval.rs index cdec123d..d3651613 100644 --- a/crates/tui/src/eval.rs +++ b/crates/tui/src/eval.rs @@ -14,12 +14,14 @@ use std::path::{Path, PathBuf}; use std::time::{Duration, Instant}; use tempfile::TempDir; +#[cfg(test)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum EvalShellPlatform { Windows, Unix, } +#[cfg(test)] #[derive(Debug, Clone, PartialEq, Eq)] struct EvalShellInvocation { program: &'static str, @@ -27,6 +29,7 @@ struct EvalShellInvocation { raw_payload_on_windows: bool, } +#[cfg(test)] fn eval_shell_invocation_for_platform( command: &str, platform: EvalShellPlatform, diff --git a/crates/tui/src/main.rs b/crates/tui/src/main.rs index 36d84c6e..1a8b5600 100644 --- a/crates/tui/src/main.rs +++ b/crates/tui/src/main.rs @@ -63,9 +63,9 @@ mod schema_migration; mod seam_manager; #[allow(dead_code)] mod session_failure_classifier; -mod shell_dispatcher; mod session_manager; mod settings; +mod shell_dispatcher; mod skill_state; mod skills; mod snapshot; diff --git a/crates/tui/src/sandbox/mod.rs b/crates/tui/src/sandbox/mod.rs index 6ed82bc6..76af2012 100644 --- a/crates/tui/src/sandbox/mod.rs +++ b/crates/tui/src/sandbox/mod.rs @@ -868,4 +868,3 @@ mod tests { } } } -} diff --git a/crates/tui/src/shell_dispatcher.rs b/crates/tui/src/shell_dispatcher.rs index bb2c6d6b..95d3d0c4 100644 --- a/crates/tui/src/shell_dispatcher.rs +++ b/crates/tui/src/shell_dispatcher.rs @@ -28,6 +28,7 @@ static LOG_MUTEX: Mutex<()> = Mutex::new(()); // --------------------------------------------------------------------------- /// The concrete shell that the dispatcher will use. +#[allow(dead_code)] #[derive(Debug, Clone, PartialEq, Eq)] pub enum ShellKind { /// PowerShell 7+ (`pwsh.exe`). @@ -104,6 +105,7 @@ pub struct ShellDispatcher { kind: ShellKind, } +#[allow(dead_code)] impl ShellDispatcher { /// Detect the user's shell from the environment. /// @@ -159,13 +161,10 @@ impl ShellDispatcher { // `detect()` which calls `log_startup()` which also acquires the mutex. let kind = global_dispatcher().kind(); let _lock = LOG_MUTEX.lock(); - let line = format!( - "[{}] exec via {kind:?}: {command}\n", now_iso() - ); + let line = format!("[{}] exec via {kind:?}: {command}\n", now_iso()); Self::append_log(path, &line) } - /// The detected shell kind. pub fn kind(&self) -> &ShellKind { &self.kind @@ -233,9 +232,7 @@ impl ShellDispatcher { let _lock = LOG_MUTEX.lock(); if let Ok(path) = std::env::var("SHELL_DISPATCHER_LOG") { let kind = self.kind(); - let line = format!( - "[{}] exec via {kind:?}: {shell_command}\n", now_iso() - ); + let line = format!("[{}] exec via {kind:?}: {shell_command}\n", now_iso()); let _ = Self::append_log(&path, &line); } } @@ -318,7 +315,9 @@ impl ShellDispatcher { r"C:\Program Files\PowerShell\7", r"C:\Windows\System32\WindowsPowerShell\v1.0", ]; - known_dirs.iter().any(|dir| std::path::Path::new(dir).join(name).is_file()) + known_dirs + .iter() + .any(|dir| std::path::Path::new(dir).join(name).is_file()) } fn binary_on_path(name: &str) -> bool { @@ -336,7 +335,9 @@ impl ShellDispatcher { // -- Helpers --------------------------------------------------------------- fn now_iso() -> String { - chrono::Utc::now().format("%Y-%m-%dT%H:%M:%S%.3f").to_string() + chrono::Utc::now() + .format("%Y-%m-%dT%H:%M:%S%.3f") + .to_string() } /// Global dispatcher instance, detected once at startup. @@ -384,7 +385,9 @@ mod tests { #[test] fn powershell_build_command_includes_no_profile_and_command_flags() { - let dispatcher = ShellDispatcher { kind: ShellKind::Pwsh }; + let dispatcher = ShellDispatcher { + kind: ShellKind::Pwsh, + }; let cmd = dispatcher.build_command("echo hello"); let args: Vec<&str> = cmd.get_args().map(|a| a.to_str().unwrap()).collect(); assert!(args.contains(&"-NoProfile")); @@ -394,7 +397,9 @@ mod tests { #[test] fn cmd_build_command_uses_c_flag() { - let dispatcher = ShellDispatcher { kind: ShellKind::Cmd }; + let dispatcher = ShellDispatcher { + kind: ShellKind::Cmd, + }; let cmd = dispatcher.build_command("echo hello"); let args: Vec<&str> = cmd.get_args().map(|a| a.to_str().unwrap()).collect(); assert!(args.contains(&"/C")); @@ -403,7 +408,9 @@ mod tests { #[test] fn sh_build_command_uses_dash_c() { - let dispatcher = ShellDispatcher { kind: ShellKind::Sh }; + let dispatcher = ShellDispatcher { + kind: ShellKind::Sh, + }; let cmd = dispatcher.build_command("echo hello"); let args: Vec<&str> = cmd.get_args().map(|a| a.to_str().unwrap()).collect(); assert!(args.contains(&"-c")); @@ -412,7 +419,9 @@ mod tests { #[test] fn build_direct_preserves_args() { - let dispatcher = ShellDispatcher { kind: ShellKind::Cmd }; + let dispatcher = ShellDispatcher { + kind: ShellKind::Cmd, + }; let args = vec!["-m".to_string(), "commit message".to_string()]; let cmd = dispatcher.build_direct("git", &args); let cmd_args: Vec<&str> = cmd.get_args().map(|a| a.to_str().unwrap()).collect(); @@ -439,7 +448,9 @@ mod tests { #[test] fn build_command_quotes_spaces_for_cmd() { - let dispatcher = ShellDispatcher { kind: ShellKind::Cmd }; + let dispatcher = ShellDispatcher { + kind: ShellKind::Cmd, + }; let cmd = dispatcher.build_command("git commit -m \"msg with spaces\""); let args: Vec<&str> = cmd.get_args().map(|a| a.to_str().unwrap()).collect(); assert_eq!(args.len(), 2); @@ -450,7 +461,9 @@ mod tests { #[test] fn build_command_quotes_spaces_for_pwsh() { - let dispatcher = ShellDispatcher { kind: ShellKind::Pwsh }; + let dispatcher = ShellDispatcher { + kind: ShellKind::Pwsh, + }; let cmd = dispatcher.build_command("git commit -m \"msg with spaces\""); let args: Vec<&str> = cmd.get_args().map(|a| a.to_str().unwrap()).collect(); assert_eq!(args.len(), 3); @@ -461,7 +474,9 @@ mod tests { #[test] fn build_direct_handles_empty_args() { - let dispatcher = ShellDispatcher { kind: ShellKind::Sh }; + let dispatcher = ShellDispatcher { + kind: ShellKind::Sh, + }; let cmd = dispatcher.build_direct("echo", &[]); let args: Vec<&str> = cmd.get_args().map(|a| a.to_str().unwrap()).collect(); assert!(args.is_empty()); @@ -499,4 +514,4 @@ mod tests { assert_eq!(kind.binary(), "/bin/zsh"); assert_eq!(kind.command_flag(), "-c"); } -} \ No newline at end of file +} diff --git a/crates/tui/src/tools/shell.rs b/crates/tui/src/tools/shell.rs index 1975595e..31f09f1b 100644 --- a/crates/tui/src/tools/shell.rs +++ b/crates/tui/src/tools/shell.rs @@ -850,7 +850,11 @@ impl ShellManager { // success/failure/timeout (issue #1690). let _ = crossterm::terminal::disable_raw_mode(); struct SyncRawModeGuard; - impl Drop for SyncRawModeGuard { fn drop(&mut self) { let _ = crossterm::terminal::enable_raw_mode(); } } + impl Drop for SyncRawModeGuard { + fn drop(&mut self) { + let _ = crossterm::terminal::enable_raw_mode(); + } + } let _guard = SyncRawModeGuard; let mut child = cmd @@ -990,7 +994,11 @@ impl ShellManager { // Disable raw mode before spawn; restore on drop (issue #1690). let _ = crossterm::terminal::disable_raw_mode(); struct InteractiveRawModeGuard; - impl Drop for InteractiveRawModeGuard { fn drop(&mut self) { let _ = crossterm::terminal::enable_raw_mode(); } } + impl Drop for InteractiveRawModeGuard { + fn drop(&mut self) { + let _ = crossterm::terminal::enable_raw_mode(); + } + } let _guard = InteractiveRawModeGuard; child_env::apply_to_command(&mut cmd, child_env::string_map_env(&exec_env.env)); @@ -2810,4 +2818,4 @@ impl ToolSpec for NoteTool { } #[cfg(test)] -mod tests; \ No newline at end of file +mod tests; diff --git a/crates/tui/tests/eval_harness.rs b/crates/tui/tests/eval_harness.rs index 8fb7485a..00a5d26b 100644 --- a/crates/tui/tests/eval_harness.rs +++ b/crates/tui/tests/eval_harness.rs @@ -4,6 +4,8 @@ use std::fs; #[path = "../src/eval.rs"] mod eval; +#[path = "../src/shell_dispatcher.rs"] +mod shell_dispatcher; use eval::{EvalHarness, EvalHarnessConfig, ScenarioStepKind}; use tempfile::tempdir;