greentic_config/
paths.rs

1use std::path::{Path, PathBuf};
2
3#[derive(Debug, Clone)]
4pub struct DefaultPaths {
5    pub root: PathBuf,
6    pub state_dir: PathBuf,
7    pub cache_dir: PathBuf,
8    pub logs_dir: PathBuf,
9}
10
11impl DefaultPaths {
12    pub fn from_root(root: &Path) -> Self {
13        let state_dir = root.join(".greentic");
14        let cache_dir = state_dir.join("cache");
15        let logs_dir = state_dir.join("logs");
16        Self {
17            root: root.to_path_buf(),
18            state_dir,
19            cache_dir,
20            logs_dir,
21        }
22    }
23}
24
25pub fn discover_project_root(start: &Path) -> Option<PathBuf> {
26    for ancestor in start.ancestors() {
27        let greentic_dir = ancestor.join(".greentic");
28        if greentic_dir.is_dir() {
29            return Some(ancestor.to_path_buf());
30        }
31        let git_dir = ancestor.join(".git");
32        if git_dir.is_dir() {
33            return Some(ancestor.to_path_buf());
34        }
35        let cargo = ancestor.join("Cargo.toml");
36        if cargo.is_file() {
37            return Some(ancestor.to_path_buf());
38        }
39    }
40    None
41}
42
43pub fn absolute_path(path: &Path) -> anyhow::Result<PathBuf> {
44    if path.is_absolute() {
45        return Ok(path.to_path_buf());
46    }
47    let cwd = std::env::current_dir()?;
48    Ok(cwd.join(path))
49}