mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-22 16:02:24 +00:00
85 lines
2.3 KiB
Rust
85 lines
2.3 KiB
Rust
use std::path::{Path, PathBuf};
|
|
use std::process::{Command, Stdio};
|
|
|
|
use anyhow::{Context as _, Result, bail};
|
|
|
|
pub fn launch(path: Option<&Path>) -> Result<()> {
|
|
let executable = find_executable()?;
|
|
let mut command = Command::new(&executable);
|
|
if let Some(path) = path {
|
|
command.arg("--open-path").arg(path);
|
|
}
|
|
|
|
// The CLI must not keep a caller's redirected pipes alive after it exits.
|
|
// The GUI owns its own logging and never needs this console's standard IO.
|
|
command
|
|
.stdin(Stdio::null())
|
|
.stdout(Stdio::null())
|
|
.stderr(Stdio::null())
|
|
.spawn()
|
|
.with_context(|| format!("launching {}", executable.display()))?;
|
|
Ok(())
|
|
}
|
|
|
|
/// The bundled `tty7-app` this CLI belongs to: `TTY7_APP`, then the file next
|
|
/// to this executable, then `PATH`. `gui` launches it; hook diagnosis needs the
|
|
/// same path because that is the executable a hook command names.
|
|
pub fn find_executable() -> Result<PathBuf> {
|
|
if let Some(explicit) = std::env::var_os("TTY7_APP") {
|
|
let path = PathBuf::from(explicit);
|
|
if path.is_file() {
|
|
return Ok(path);
|
|
}
|
|
bail!(
|
|
"TTY7_APP points to {}, but that file does not exist",
|
|
path.display()
|
|
);
|
|
}
|
|
|
|
let name = executable_name();
|
|
if let Ok(own) = std::env::current_exe()
|
|
&& let Some(dir) = own.parent()
|
|
{
|
|
let sibling = dir.join(name);
|
|
if sibling.is_file() {
|
|
return Ok(sibling);
|
|
}
|
|
}
|
|
|
|
if let Some(paths) = std::env::var_os("PATH") {
|
|
for dir in std::env::split_paths(&paths) {
|
|
let candidate = dir.join(name);
|
|
if candidate.is_file() {
|
|
return Ok(candidate);
|
|
}
|
|
}
|
|
}
|
|
|
|
bail!("could not find {name} next to this CLI or on PATH — install tty7-app, or set TTY7_APP")
|
|
}
|
|
|
|
fn executable_name() -> &'static str {
|
|
if cfg!(windows) {
|
|
"tty7-app.exe"
|
|
} else {
|
|
"tty7-app"
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn the_gui_executable_name_matches_the_platform() {
|
|
assert_eq!(
|
|
executable_name(),
|
|
if cfg!(windows) {
|
|
"tty7-app.exe"
|
|
} else {
|
|
"tty7-app"
|
|
}
|
|
);
|
|
}
|
|
}
|