#[cfg_attr(test, allow(dead_code))]
#[cfg_attr(not(test), allow(dead_code))]
pub fn find_gui_command() -> Option<(std::path::PathBuf, Vec<String>)> {
use std::process::Command;
const EXPECTED_VERSION: &str = env!("CARGO_PKG_VERSION");
let check_version = |path: &std::path::Path| -> bool {
if let Ok(output) = Command::new(path)
.args(["gui-subprocess", "--version"])
.output()
{
if let Ok(version_str) = String::from_utf8(output.stdout) {
let version = version_str.split_whitespace().last().unwrap_or("");
return version.trim() == EXPECTED_VERSION;
}
}
false
};
#[cfg(all(feature = "gui", not(feature = "python")))]
{
if let Ok(exe_path) = std::env::current_exe() {
return Some((exe_path, vec!["gui-subprocess".to_string()]));
}
}
#[cfg(feature = "python")]
{
use pyo3::prelude::*;
use pyo3::types::PyModule;
if let Ok(package_dir) = Python::attach(|py| -> PyResult<String> {
let importlib = PyModule::import(py, "importlib.util")?;
let spec = importlib.call_method1("find_spec", ("rgrow",))?;
let origin = spec.getattr("origin")?;
if origin.is_none() {
return Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(
"Could not find rgrow package",
));
}
let origin_str = origin.extract::<String>()?;
let path = std::path::PathBuf::from(origin_str);
if let Some(parent) = path.parent() {
Ok(parent.to_string_lossy().to_string())
} else {
Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(
"Could not determine package directory",
))
}
}) {
let rgrow_exe = std::path::PathBuf::from(&package_dir).join("rgrow");
#[cfg(windows)]
let rgrow_exe = std::path::PathBuf::from(&package_dir).join("rgrow.exe");
if rgrow_exe.exists() && check_version(&rgrow_exe) {
return Some((rgrow_exe, vec!["gui-subprocess".to_string()]));
}
}
}
if let Ok(package_dir) = std::env::var("RGROW_PACKAGE_DIR") {
let rgrow_exe = std::path::PathBuf::from(&package_dir).join("rgrow");
#[cfg(windows)]
let rgrow_exe = std::path::PathBuf::from(&package_dir).join("rgrow.exe");
if rgrow_exe.exists() && check_version(&rgrow_exe) {
return Some((rgrow_exe, vec!["gui-subprocess".to_string()]));
}
}
if let Ok(path) = which::which("rgrow") {
if check_version(&path) {
return Some((path, vec!["gui-subprocess".to_string()]));
} else {
eprintln!(
"Warning: Found rgrow on PATH but version mismatch. Expected version {}",
env!("CARGO_PKG_VERSION")
);
}
}
if let Ok(exe_path) = std::env::current_exe() {
if let Some(exe_dir) = exe_path.parent() {
let rgrow_exe = exe_dir.join("rgrow");
#[cfg(windows)]
let rgrow_exe = exe_dir.join("rgrow.exe");
if rgrow_exe.exists() && check_version(&rgrow_exe) {
return Some((rgrow_exe, vec!["gui-subprocess".to_string()]));
}
}
}
if let Ok(path) = which::which("rgrow-gui") {
return Some((path, vec![]));
}
#[cfg(feature = "python")]
{
use pyo3::prelude::*;
use pyo3::types::PyModule;
if let Ok(package_dir) = Python::attach(|py| -> PyResult<String> {
let importlib = PyModule::import(py, "importlib.util")?;
let spec = importlib.call_method1("find_spec", ("rgrow",))?;
let origin = spec.getattr("origin")?;
if origin.is_none() {
return Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(
"Could not find rgrow package",
));
}
let origin_str = origin.extract::<String>()?;
let path = std::path::PathBuf::from(origin_str);
if let Some(parent) = path.parent() {
Ok(parent.to_string_lossy().to_string())
} else {
Err(PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(
"Could not determine package directory",
))
}
}) {
let gui_exe = std::path::PathBuf::from(&package_dir).join("rgrow-gui");
#[cfg(windows)]
let gui_exe = std::path::PathBuf::from(&package_dir).join("rgrow-gui.exe");
if gui_exe.exists() {
return Some((gui_exe, vec![]));
}
}
}
if let Ok(exe_path) = std::env::current_exe() {
if let Some(exe_dir) = exe_path.parent() {
let gui_exe = exe_dir.join("rgrow-gui");
#[cfg(windows)]
let gui_exe = exe_dir.join("rgrow-gui.exe");
if gui_exe.exists() {
return Some((gui_exe, vec![]));
}
}
}
None
}