Skip to main content

auths_cli/adapters/
git_index.rs

1use std::path::{Path, PathBuf};
2
3use auths_sdk::ports::git::{IndexError, RepoIndex};
4
5/// System adapter for staging paths into a repository index.
6///
7/// Runs `git add -- <path>` / `git ls-files --error-unmatch -- <path>` via
8/// `std::process::Command`, rooted at the repository working directory.
9///
10/// Usage:
11/// ```ignore
12/// let index = SystemRepoIndex::at(repo_root.clone());
13/// index.stage(&repo_root.join(".auths/roots"))?;
14/// ```
15pub struct SystemRepoIndex {
16    working_dir: PathBuf,
17}
18
19impl SystemRepoIndex {
20    /// Creates an index adapter rooted at the given repository.
21    ///
22    /// Args:
23    /// * `working_dir`: Path to the git repository to operate in.
24    pub fn at(working_dir: PathBuf) -> Self {
25        Self { working_dir }
26    }
27}
28
29impl RepoIndex for SystemRepoIndex {
30    fn stage(&self, path: &Path) -> Result<(), IndexError> {
31        let path_str = path.to_string_lossy().to_string();
32        let output = crate::subprocess::git_command(&["add", "--", &path_str])
33            .current_dir(&self.working_dir)
34            .output()
35            .map_err(|e| IndexError::Stage {
36                path: path_str.clone(),
37                message: e.to_string(),
38            })?;
39
40        if output.status.success() {
41            return Ok(());
42        }
43        Err(IndexError::Stage {
44            path: path_str,
45            message: String::from_utf8_lossy(&output.stderr).trim().to_string(),
46        })
47    }
48
49    fn is_tracked(&self, path: &Path) -> bool {
50        let path_str = path.to_string_lossy().to_string();
51        crate::subprocess::git_command(&["ls-files", "--error-unmatch", "--", &path_str])
52            .current_dir(&self.working_dir)
53            .output()
54            .map(|out| out.status.success())
55            .unwrap_or(false)
56    }
57}