diff --git a/crates/goose-cli/src/commands/tui.rs b/crates/goose-cli/src/commands/tui.rs index a0ebc3311c5b..3b49a633f032 100644 --- a/crates/goose-cli/src/commands/tui.rs +++ b/crates/goose-cli/src/commands/tui.rs @@ -14,6 +14,10 @@ enum TuiSource { fn find_local_script() -> Option { let exe = std::env::current_exe().ok()?; + find_local_script_from(&exe) +} + +fn find_local_script_from(exe: &Path) -> Option { let exe_dir = exe.parent().unwrap_or_else(|| Path::new(".")); let mut dir = Some(exe_dir.to_path_buf()); @@ -27,13 +31,6 @@ fn find_local_script() -> Option { } } - if let Ok(cwd) = std::env::current_dir() { - let candidate = cwd.join(TUI_REL_PATH); - if candidate.is_file() { - return Some(candidate); - } - } - None } @@ -97,3 +94,34 @@ pub fn handle_tui(args: Vec) -> Result<()> { Ok(()) } } + +#[cfg(test)] +mod tests { + use super::*; + use std::fs; + + #[test] + fn find_local_script_ignores_unrelated_directories() { + let temp_dir = tempfile::tempdir().expect("create temp dir"); + let executable = temp_dir.path().join("install/bin/goose"); + let planted_script = temp_dir.path().join("checkout").join(TUI_REL_PATH); + fs::create_dir_all(planted_script.parent().unwrap()).expect("create script directory"); + fs::write(&planted_script, "process.exit(0)\n").expect("write planted script"); + + assert_eq!(find_local_script_from(&executable), None); + } + + #[test] + fn find_local_script_accepts_executable_ancestor() { + let temp_dir = tempfile::tempdir().expect("create temp dir"); + let executable = temp_dir.path().join("target/debug/goose"); + let bundled_script = temp_dir.path().join(TUI_REL_PATH); + fs::create_dir_all(bundled_script.parent().unwrap()).expect("create script directory"); + fs::write(&bundled_script, "process.exit(0)\n").expect("write bundled script"); + + assert_eq!( + find_local_script_from(&executable).as_deref(), + Some(bundled_script.as_path()) + ); + } +}