chore_cli/
path_resolver.rs1use std::path::{Path, PathBuf};
4
5pub fn find_project_root(start_dir: &Path) -> PathBuf {
7 if let Some(config_dir) = find_config_directory(start_dir) {
9 return config_dir;
10 }
11
12 if let Some(git_root) = find_git_root(start_dir) {
14 return git_root;
15 }
16
17 if let Some(cargo_root) = find_cargo_root(start_dir) {
19 return cargo_root;
20 }
21
22 start_dir.to_path_buf()
24}
25
26fn 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
43fn 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
60fn 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 let current_dir = std::env::current_dir().unwrap();
85 let root = find_project_root(¤t_dir);
86
87 assert!(root.join("Cargo.toml").exists());
89 }
90}