using ClaudeDo.Data.Environment; using ClaudeDo.Installer.Core; using ClaudeDo.Installer.Core.Interfaces; using ClaudeDo.Installer.Localization; namespace ClaudeDo.Installer.Checks; /// Trivial to fix after the fact (git config --global), and the Claude help-me button can resolve it — a warning, not a blocker. public sealed class GitIdentityCheck : IEnvironmentCheck { public const string CheckId = "git-identity"; private readonly IProcessRunner _processRunner; private readonly string? _pathOverride; private readonly string? _pathExtOverride; public GitIdentityCheck(IProcessRunner processRunner, string? pathOverride = null, string? pathExtOverride = null) { _processRunner = processRunner; _pathOverride = pathOverride; _pathExtOverride = pathExtOverride; } public string Id => CheckId; public CheckSeverity Severity => CheckSeverity.Warning; public async Task RunAsync(InstallContext ctx, CancellationToken ct) { var loc = TrExtension.Localizer; var resolved = ExecutableResolver.Resolve("git", _pathOverride, _pathExtOverride); if (resolved is null) { return CheckResult.Unknown(Id, Severity, "checks.gitIdentity.title", loc?["checks.gitIdentity.notFound"] ?? "git was not found — identity could not be checked."); } var name = await ReadConfigAsync(resolved, "user.name", ct); var email = await ReadConfigAsync(resolved, "user.email", ct); var hasName = !string.IsNullOrWhiteSpace(name); var hasEmail = !string.IsNullOrWhiteSpace(email); if (hasName && hasEmail) { return CheckResult.Ok(Id, Severity, "checks.gitIdentity.title", $"{name} <{email}>"); } var missing = (hasName, hasEmail) switch { (false, false) => "user.name, user.email", (false, true) => "user.name", _ => "user.email", }; return CheckResult.Fail(Id, Severity, "checks.gitIdentity.title", loc?.Get("checks.gitIdentity.missing", missing) ?? $"Missing git identity: {missing}.", "checks.gitIdentity.hint"); } private async Task ReadConfigAsync(ResolvedExecutable resolved, string key, CancellationToken ct) { var (fileName, arguments) = ProcessCommand.For(resolved, "config", "--get", key); var (_, output) = await _processRunner.RunAsync(fileName, arguments, null, ct); return output.Trim(); } }