use anyhow::Result;
use std::path::PathBuf;
use std::process::Command;
pub struct SupervisorPaths;
impl SupervisorPaths {
pub fn data_dir() -> Result<PathBuf> {
let home = get_home_directory();
Ok(PathBuf::from(home).join(".local/share/geist-supervisor"))
}
pub fn backups_dir() -> Result<PathBuf> {
Ok(Self::data_dir()?.join("backups"))
}
pub fn config_dir() -> Result<PathBuf> {
Ok(Self::data_dir()?.join("config"))
}
pub fn logs_dir() -> Result<PathBuf> {
Ok(Self::data_dir()?.join("logs"))
}
pub fn ota_metadata_path() -> Result<PathBuf> {
Ok(Self::data_dir()?.join("ota_metadata.json"))
}
pub fn ensure_directories() -> Result<()> {
let dirs = [
Self::data_dir()?,
Self::backups_dir()?,
Self::config_dir()?,
Self::logs_dir()?,
];
for dir in &dirs {
if !dir.exists() {
std::fs::create_dir_all(dir).map_err(|e| {
anyhow::anyhow!("Failed to create directory {}: {}", dir.display(), e)
})?;
}
}
Ok(())
}
}
pub fn get_home_directory() -> String {
if let Ok(home) = std::env::var("HOME") {
if !home.is_empty() {
return home;
}
}
if let Ok(output) = Command::new("whoami").output() {
if output.status.success() {
let username = String::from_utf8_lossy(&output.stdout).trim().to_string();
if !username.is_empty() && username != "root" {
return format!("/home/{}", username);
}
}
}
if let Ok(user) = std::env::var("USER") {
let username = user.split_whitespace().next().unwrap_or("").to_string();
if !username.is_empty() && username != "root" {
return format!("/home/{}", username);
}
}
if let Ok(logname) = std::env::var("LOGNAME") {
let username = logname.split_whitespace().next().unwrap_or("").to_string();
if !username.is_empty() && username != "root" {
return format!("/home/{}", username);
}
}
"/tmp".to_string()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_path_construction() {
let data_dir = SupervisorPaths::data_dir().unwrap();
assert!(data_dir
.to_string_lossy()
.contains(".local/share/geist-supervisor"));
let backups_dir = SupervisorPaths::backups_dir().unwrap();
assert!(backups_dir.to_string_lossy().contains("backups"));
}
#[test]
fn test_ensure_directories() {
let result = SupervisorPaths::ensure_directories();
let _ = result;
}
#[test]
fn test_get_home_dir() {
let home = get_home_directory();
assert!(!home.is_empty());
}
}