Skip to main content

git_worktree_manager/
repo_config.rs

1//! Repo-local `.cwconfig.json` loader.
2//!
3//! Walks up from `start` looking for the first `.cwconfig.json`. Returns the
4//! parsed JSON value alongside the path it was found at. Used by Phase 7.2's
5//! layered config resolution; not yet wired into config callers.
6
7use std::path::{Path, PathBuf};
8
9use crate::error::Result;
10
11pub struct RepoConfig {
12    pub path: PathBuf,
13    pub value: serde_json::Value,
14}
15
16/// Maximum directory levels to walk up when searching for `.cwconfig.json`.
17/// Prevents unbounded traversal on deep or unusual filesystem layouts.
18const MAX_ANCESTOR_DEPTH: usize = 20;
19
20pub fn find_repo_config(start: &Path) -> Option<RepoConfig> {
21    let mut cur = start.to_path_buf();
22    for _ in 0..MAX_ANCESTOR_DEPTH {
23        let candidate = cur.join(".cwconfig.json");
24        if candidate.exists() {
25            if let Ok(content) = std::fs::read_to_string(&candidate) {
26                if let Ok(value) = serde_json::from_str::<serde_json::Value>(&content) {
27                    return Some(RepoConfig {
28                        path: candidate,
29                        value,
30                    });
31                }
32            }
33        }
34        if !cur.pop() {
35            return None;
36        }
37    }
38    None
39}
40
41pub fn load_repo_config(start: &Path) -> Result<Option<serde_json::Value>> {
42    Ok(find_repo_config(start).map(|c| c.value))
43}