summaryrefslogtreecommitdiff
path: root/src/marlin.core/functional/IGitClient.cs
blob: 04dc12a7f66fb479a4a03c259bae8a2b236cde55 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
namespace marlin.core.functional;

using System.Diagnostics;

public interface IGitClient
{
    Task<Dictionary<string, string>> GetRemoteRefs(string remote);
}

public class GitBinaryClient : IGitClient
{
    public virtual async Task<Dictionary<string, string>> GetRemoteRefs(string remote)
    {
        var psi = this.CreateProcess(remote);
        var proc = Process.Start(psi)!;
        
        string stdout = await proc.StandardOutput.ReadToEndAsync();
        await proc.WaitForExitAsync();

        return ParseOutput(stdout);
    }
    
    private Dictionary<string, string> ParseOutput(string stdout)
    {
        return stdout
            .Split("\n", StringSplitOptions.RemoveEmptyEntries)
            .Select(x => x.Split('\t'))
            .ToDictionary(k => k[1], k => k[0]);
    }

    protected virtual ProcessStartInfo CreateProcess(string remote)
    {
        var psi = new ProcessStartInfo("git", $"ls-remote --heads --tags {remote}")
        {
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            UseShellExecute = false,
            CreateNoWindow = true,
            Environment = { ["GIT_TERMINAL_PROMPT"] = "0" }
        };

        return psi;
    }

    /*private async Task SshAuth(string privateKeyPem)
    {
        string keyPath = Path.Combine(Path.GetTempPath(), $"key_{Guid.NewGuid():N}");
        await File.WriteAllTextAsync(keyPath, privateKeyPem);
        File.SetUnixFileMode(keyPath, UnixFileMode.UserRead | UnixFileMode.UserWrite);

        try
        {
            psi.Environment["GIT_SSH_COMMAND"] =
                $"ssh -i {keyPath} -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new";
            // run ls-remote against the ssh:// or git@ URL
        }
        finally
        {
            File.Delete(keyPath);
        }
    }

    private async Task BasicAuth(string accessToken)
    {
        psi.Environment["GIT_CONFIG_COUNT"] = "1";
        psi.Environment["GIT_CONFIG_KEY_0"] = "http.extraheader";
        psi.Environment["GIT_CONFIG_VALUE_0"] =
            $"AUTHORIZATION: basic {Convert.ToBase64String(Encoding.UTF8.GetBytes($"x-access-token:{accessToken}"))}";

    }*/
}