Skip to main content

chore_cli/
path_resolver.rs

1/* src/path_resolver.rs */
2
3use std::path::{Path, PathBuf};
4
5/// Find the project root directory based on various heuristics
6pub fn find_project_root(start_dir: &Path) -> PathBuf {
7    // Priority 1: Look for chore.toml or .chore.toml
8    if let Some(config_dir) = find_config_directory(start_dir) {
9        return config_dir;
10    }
11
12    // Priority 2: Look for .git directory
13    if let Some(git_root) = find_git_root(start_dir) {
14        return git_root;
15    }
16
17    // Priority 3: Look for Cargo.toml
18    if let Some(cargo_root) = find_cargo_root(start_dir) {
19        return cargo_root;
20    }
21
22    // Priority 4: Use current working directory
23    start_dir.to_path_buf()
24}
25
26/// Find directory containing chore.toml or .chore.toml
27fn find_config_directory(start_dir: &Path) -> Option<PathBuf> {
28    let mut current = start_dir.to_path_buf();
29
30    loop {
31        if current.join("chore.toml").exists() || current.join(".chore.toml").exists() {
32            return Some(current);
33        }
34
35        if !current.pop() {
36            break;
37        }
38    }
39
40    None
41}
42
43/// Find Git repository root
44fn find_git_root(start_dir: &Path) -> Option<PathBuf> {
45    let mut current = start_dir.to_path_buf();
46
47    loop {
48        if current.join(".git").exists() {
49            return Some(current);
50        }
51
52        if !current.pop() {
53            break;
54        }
55    }
56
57    None
58}
59
60/// Find Cargo project root
61fn find_cargo_root(start_dir: &Path) -> Option<PathBuf> {
62    let mut current = start_dir.to_path_buf();
63
64    loop {
65        if current.join("Cargo.toml").exists() {
66            return Some(current);
67        }
68
69        if !current.pop() {
70            break;
71        }
72    }
73
74    None
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    #[test]
82    fn test_find_project_root() {
83        // Test with current directory (should find the Cargo.toml)
84        let current_dir = std::env::current_dir().unwrap();
85        let root = find_project_root(&current_dir);
86
87        // Should find Cargo.toml in project root
88        assert!(root.join("Cargo.toml").exists());
89    }
90}