Skip to main content

auths_cli/adapters/
git_config.rs

1use std::path::PathBuf;
2
3use auths_sdk::ports::git_config::{GitConfigError, GitConfigProvider};
4
5/// System adapter for git signing configuration.
6///
7/// Runs `git config <scope> <key> <value>` via `std::process::Command`.
8/// Construct with `SystemGitConfigProvider::global()` or
9/// `SystemGitConfigProvider::local(repo_path)`.
10///
11/// Usage:
12/// ```ignore
13/// let provider = SystemGitConfigProvider::global();
14/// provider.set("gpg.format", "ssh")?;
15/// ```
16pub struct SystemGitConfigProvider {
17    scope_flag: &'static str,
18    working_dir: Option<PathBuf>,
19}
20
21impl SystemGitConfigProvider {
22    /// Creates a provider that sets git config in global scope.
23    pub fn global() -> Self {
24        Self {
25            scope_flag: "--global",
26            working_dir: None,
27        }
28    }
29
30    /// Creates a provider that sets git config in local scope for the given repo.
31    ///
32    /// Args:
33    /// * `repo_path`: Path to the git repository to configure.
34    pub fn local(repo_path: PathBuf) -> Self {
35        Self {
36            scope_flag: "--local",
37            working_dir: Some(repo_path),
38        }
39    }
40}
41
42impl GitConfigProvider for SystemGitConfigProvider {
43    fn set(&self, key: &str, value: &str) -> Result<(), GitConfigError> {
44        let mut cmd = std::process::Command::new("git");
45        cmd.args(["config", self.scope_flag, key, value]);
46        if let Some(dir) = &self.working_dir {
47            cmd.current_dir(dir);
48        }
49        let status = cmd
50            .status()
51            .map_err(|e| GitConfigError::CommandFailed(format!("failed to run git config: {e}")))?;
52        if !status.success() {
53            return Err(GitConfigError::CommandFailed(format!(
54                "git config {} = {} failed",
55                key, value
56            )));
57        }
58        Ok(())
59    }
60}