Skip to main content

rippy_cli/config/
sources.rs

1use std::path::{Path, PathBuf};
2
3use super::loader::home_dir;
4
5/// Walk up from `start` looking for `.rippy` or `.dippy` config files.
6pub fn find_project_config(start: &Path) -> Option<PathBuf> {
7    let mut dir = start;
8    loop {
9        let toml = dir.join(".rippy.toml");
10        if toml.is_file() {
11            return Some(toml);
12        }
13        let rippy = dir.join(".rippy");
14        if rippy.is_file() {
15            return Some(rippy);
16        }
17        let dippy = dir.join(".dippy");
18        if dippy.is_file() {
19            return Some(dippy);
20        }
21        dir = dir.parent()?;
22    }
23}
24
25/// A config source with its tier label and optional file path.
26#[derive(Debug, Clone, serde::Serialize)]
27pub struct ConfigSourceInfo {
28    pub tier: &'static str,
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub path: Option<PathBuf>,
31}
32
33/// Enumerate the config sources that would be loaded for a given cwd.
34///
35/// Returns `(tier, path)` tuples in load order: stdlib → global → project/override.
36pub fn enumerate_config_sources(
37    cwd: &Path,
38    config_override: Option<&Path>,
39) -> Vec<ConfigSourceInfo> {
40    let mut sources = vec![ConfigSourceInfo {
41        tier: "stdlib",
42        path: None,
43    }];
44
45    if let Some(home) = home_dir() {
46        for candidate in [
47            home.join(".rippy/config.toml"),
48            home.join(".rippy/config"),
49            home.join(".dippy/config"),
50        ] {
51            if candidate.is_file() {
52                sources.push(ConfigSourceInfo {
53                    tier: "global",
54                    path: Some(candidate),
55                });
56                break;
57            }
58        }
59    }
60
61    if let Some(override_path) = config_override {
62        sources.push(ConfigSourceInfo {
63            tier: "override",
64            path: Some(override_path.to_owned()),
65        });
66    } else if let Some(project) = find_project_config(cwd) {
67        sources.push(ConfigSourceInfo {
68            tier: "project",
69            path: Some(project),
70        });
71    }
72
73    sources
74}