Skip to main content

auths_cli/adapters/
doctor_fixes.rs

1//! Fix implementations for CLI-only diagnostic checks.
2
3use std::path::PathBuf;
4
5use auths_sdk::ports::diagnostics::{CheckResult, DiagnosticError, DiagnosticFix};
6/// Sets the 5 git signing config keys for auths.
7///
8/// Unsafe fix — may overwrite existing non-auths git signing config,
9/// so it requires user confirmation in interactive mode.
10pub struct GitSigningConfigFix {
11    sign_binary_path: PathBuf,
12    key_alias: String,
13}
14
15impl GitSigningConfigFix {
16    pub fn new(sign_binary_path: PathBuf, key_alias: String) -> Self {
17        Self {
18            sign_binary_path,
19            key_alias,
20        }
21    }
22}
23
24impl DiagnosticFix for GitSigningConfigFix {
25    fn name(&self) -> &str {
26        "Configure git signing"
27    }
28
29    fn is_safe(&self) -> bool {
30        false
31    }
32
33    fn can_fix(&self, check: &CheckResult) -> bool {
34        check.name == "Git signing config" && !check.passed
35    }
36
37    fn apply(&self) -> Result<String, DiagnosticError> {
38        let auths_sign_str = self
39            .sign_binary_path
40            .to_str()
41            .ok_or_else(|| DiagnosticError::ExecutionFailed("auths-sign path not UTF-8".into()))?;
42        let signing_key = format!("auths:{}", self.key_alias);
43
44        let configs: &[(&str, &str)] = &[
45            ("gpg.format", "ssh"),
46            ("gpg.ssh.program", auths_sign_str),
47            ("user.signingkey", &signing_key),
48            ("commit.gpgsign", "true"),
49            ("tag.gpgsign", "true"),
50        ];
51
52        for (key, val) in configs {
53            set_git_config_value(key, val)?;
54        }
55
56        Ok("Set 5 git signing config keys (gpg.format, gpg.ssh.program, user.signingkey, commit.gpgsign, tag.gpgsign)".to_string())
57    }
58}
59
60fn set_git_config_value(key: &str, value: &str) -> Result<(), DiagnosticError> {
61    let status = crate::subprocess::git_command(&["config", "--global", key, value])
62        .status()
63        .map_err(|e| DiagnosticError::ExecutionFailed(format!("git config: {e}")))?;
64    if !status.success() {
65        return Err(DiagnosticError::ExecutionFailed(format!(
66            "git config --global {key} {value} failed"
67        )));
68    }
69    Ok(())
70}