use std::path::PathBuf;
pub const CODECORA_HOME_ENV: &str = "CODECORA_HOME";
pub fn codecora_home() -> PathBuf {
if let Ok(home) = std::env::var(CODECORA_HOME_ENV) {
PathBuf::from(home)
} else {
dirs::home_dir()
.expect("Cannot determine home directory. Set CODECORA_HOME or HOME.")
.join(".codecora")
}
}
pub fn product_data_dir(product: &str) -> PathBuf {
codecora_home().join(product)
}
pub fn cora_data_dir() -> PathBuf {
product_data_dir("cora-code")
}
pub fn graph_db_path() -> PathBuf {
let dir = cora_data_dir();
let new_db = dir.join("cora.db");
if !new_db.exists() {
let old_db = dir.join("graph.db");
if old_db.exists() {
if let Err(e) = std::fs::rename(&old_db, &new_db) {
eprintln!("warning: failed to migrate graph.db → cora.db: {e}");
return old_db;
}
}
}
new_db
}
pub fn ensure_data_dir() -> anyhow::Result<PathBuf> {
let dir = cora_data_dir();
std::fs::create_dir_all(&dir)?;
Ok(dir)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_codecora_home_returns_path() {
let path = codecora_home();
assert!(path.ends_with(".codecora"));
}
#[test]
fn test_product_data_dir() {
let path = product_data_dir("cora-code");
assert!(path.ends_with(".codecora/cora-code"));
}
#[test]
fn test_graph_db_path() {
let path = graph_db_path();
assert!(
path.ends_with(".codecora/cora-code/cora.db")
|| path.ends_with(".codecora/cora-code/graph.db"),
"graph_db_path should end with cora.db (or graph.db on migration failure), got: {path:?}"
);
}
#[test]
fn test_cora_data_dir() {
let path = cora_data_dir();
assert!(path.ends_with(".codecora/cora-code"));
let s = path.to_string_lossy();
assert!(!s.ends_with('/'));
}
#[test]
fn test_env_override() {
unsafe {
std::env::set_var(CODECORA_HOME_ENV, "/tmp/test-codecora");
}
let path = codecora_home();
assert_eq!(path, PathBuf::from("/tmp/test-codecora"));
unsafe {
std::env::remove_var(CODECORA_HOME_ENV);
}
}
}