2026-03-26 23:39:31 -06:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
|
2026-03-28 12:26:45 -06:00
|
|
|
/// Resolve the project root at runtime.
|
|
|
|
|
///
|
|
|
|
|
/// Dev layout: <root>/src-tauri/target/debug/<bin> → walk up 4 levels
|
|
|
|
|
/// Packaged: use TAURI_RESOURCE_DIR env var set by the Tauri runtime,
|
|
|
|
|
/// falling back to a sibling `resources/` directory next to the exe.
|
2026-03-26 23:39:31 -06:00
|
|
|
pub fn project_root() -> PathBuf {
|
2026-03-28 12:26:45 -06:00
|
|
|
// Tauri sets this env var when running packaged; prefer it.
|
|
|
|
|
if let Ok(res) = std::env::var("TAURI_RESOURCE_DIR") {
|
|
|
|
|
return PathBuf::from(res);
|
|
|
|
|
}
|
2026-03-26 23:39:31 -06:00
|
|
|
let exe = std::env::current_exe().expect("Failed to get executable path");
|
2026-03-28 12:26:45 -06:00
|
|
|
// Dev: exe is at <root>/src-tauri/target/debug/<bin>, walk up 4 levels.
|
|
|
|
|
if let Some(root) = exe
|
|
|
|
|
.parent() // debug/
|
|
|
|
|
.and_then(|p| p.parent()) // target/
|
|
|
|
|
.and_then(|p| p.parent()) // src-tauri/
|
|
|
|
|
.and_then(|p| p.parent()) // project root
|
|
|
|
|
{
|
|
|
|
|
if root.join("backend").exists() {
|
|
|
|
|
return root.to_path_buf();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Packaged fallback: resources/ lives next to the exe.
|
2026-03-26 23:39:31 -06:00
|
|
|
exe.parent()
|
2026-03-28 12:26:45 -06:00
|
|
|
.map(|p| p.join("resources"))
|
|
|
|
|
.unwrap_or_else(|| PathBuf::from("resources"))
|
2026-03-26 23:39:31 -06:00
|
|
|
}
|
|
|
|
|
|
2026-03-28 12:26:45 -06:00
|
|
|
/// Absolute path to the bundled Python interpreter.
|
|
|
|
|
/// Tries .venv312 first (new), falls back to .venv (legacy).
|
2026-03-26 23:39:31 -06:00
|
|
|
pub fn python_exe() -> PathBuf {
|
2026-03-28 12:26:45 -06:00
|
|
|
let root = project_root();
|
|
|
|
|
// Packaged layout: resources/python/bin/python3
|
|
|
|
|
let bundled = root.join("python").join("bin").join("python3");
|
|
|
|
|
if bundled.exists() {
|
|
|
|
|
return bundled;
|
|
|
|
|
}
|
|
|
|
|
// Dev: prefer .venv312 (Python 3.12), fall back to .venv
|
|
|
|
|
let venv312 = root.join(".venv312").join("bin").join("python3.12");
|
|
|
|
|
if venv312.exists() {
|
|
|
|
|
return venv312;
|
|
|
|
|
}
|
|
|
|
|
root.join(".venv").join("bin").join("python3")
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 23:39:31 -06:00
|
|
|
/// Absolute path to a script in the backend directory.
|
|
|
|
|
pub fn backend_script(name: &str) -> PathBuf {
|
|
|
|
|
project_root().join("backend").join(name)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Absolute path to a script at the project root.
|
|
|
|
|
pub fn root_script(name: &str) -> PathBuf {
|
|
|
|
|
project_root().join(name)
|
|
|
|
|
}
|