use std::path::{Path, PathBuf};
#[must_use]
pub fn get_home_dir() -> PathBuf {
if let Ok(test_home) = std::env::var("DOTSTATE_TEST_HOME") {
return PathBuf::from(test_home);
}
dirs::home_dir().unwrap_or_else(|| PathBuf::from("/"))
}
#[must_use]
pub fn is_git_repo(path: &Path) -> bool {
if path.is_dir() {
path.join(".git").exists()
} else {
false
}
}
#[must_use]
pub fn is_safe_to_add(path: &Path, repo_path: &Path) -> (bool, Option<String>) {
let home_dir = get_home_dir();
if path == home_dir {
return (false, Some("Cannot add home folder".to_string()));
}
if path == Path::new("/") {
return (false, Some("Cannot add root folder".to_string()));
}
if path == repo_path {
return (
false,
Some("Cannot add storage repository folder".to_string()),
);
}
if repo_path.strip_prefix(path).is_ok() {
return (
false,
Some("Cannot add a parent folder of the storage repository".to_string()),
);
}
(true, None)
}
#[must_use]
pub fn get_config_dir() -> PathBuf {
if let Ok(test_config) = std::env::var("DOTSTATE_TEST_CONFIG_DIR") {
return PathBuf::from(test_config);
}
get_home_dir().join(".config").join("dotstate")
}
#[must_use]
pub fn get_config_path() -> PathBuf {
get_config_dir().join("config.toml")
}
#[must_use]
pub fn expand_path(path_str: &str) -> PathBuf {
let home_dir = get_home_dir();
if path_str.starts_with('/') {
PathBuf::from(path_str)
} else if let Some(stripped) = path_str.strip_prefix("~/") {
home_dir.join(stripped)
} else if path_str == "~" {
home_dir
} else {
home_dir.join(path_str)
}
}
#[allow(dead_code)]
#[must_use]
pub fn format_path_for_display(path: &Path) -> String {
let home_dir = get_home_dir();
if let Ok(relative) = path.strip_prefix(&home_dir) {
if relative.as_os_str().is_empty() {
"~".to_string()
} else {
format!("~/{}", relative.to_string_lossy())
}
} else {
path.to_string_lossy().to_string()
}
}
#[allow(dead_code)]
#[must_use]
pub fn is_dotfile(path: &Path) -> bool {
path.file_name()
.and_then(|n| n.to_str())
.is_some_and(|s| s.starts_with('.'))
}
pub fn get_repository_path() -> anyhow::Result<PathBuf> {
use crate::config::Config;
let config_path = get_config_path();
let config = Config::load_or_create(&config_path)
.map_err(|e| anyhow::anyhow!("Failed to load config: {e}"))?;
Ok(config.repo_path)
}