Skip to content

Commit

Permalink
Add cloning from Azure DevOps provider
Browse files Browse the repository at this point in the history
  • Loading branch information
Scepheo committed May 7, 2019
1 parent 56fa087 commit 1c190a6
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 22 deletions.
118 changes: 118 additions & 0 deletions src/GitMan/Clients/AzureClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace GitMan.Clients
{
internal class AzureClient
{
private readonly AzureClientConfig _config;

public AzureClient(AzureClientConfig config)
{
_config = config;
}

private HttpClient GetClient()
{
var client = new HttpClient();

var acceptHeader = new MediaTypeWithQualityHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(acceptHeader);

var patBytes = Encoding.ASCII.GetBytes(":" + _config.PersonalAccessToken);
var authParameter = Convert.ToBase64String(patBytes);
var authHeader = new AuthenticationHeaderValue("Basic", authParameter);
client.DefaultRequestHeaders.Authorization = authHeader;

client.Timeout = TimeSpan.FromSeconds(30);

return client;
}

private string MakeParameterString(KeyValuePair<string, string> parameter)
{
var safeKey = Uri.EscapeUriString(parameter.Key);
var safeValue = Uri.EscapeUriString(parameter.Value);
var parameterString = $"{safeKey}={safeValue}";
return parameterString;
}

private string MakeQuery(Dictionary<string, string> queryParams)
{
var pairs = queryParams.Select(MakeParameterString);
var query = string.Join('&', pairs);
return query;
}

private Uri BuildUri(string path)
{
var emptyQueryParams = new Dictionary<string, string>();
var uri = BuildUri(path, emptyQueryParams);
return uri;
}

private Uri BuildUri(string path, Dictionary<string, string> queryParams)
{
var organization = Uri.EscapeUriString(_config.Organization);
var project = Uri.EscapeUriString(_config.Project);
var fullPath = $"{organization}/{project}/_apis/{path}";

queryParams["api-version"] = "5.0";
var query = MakeQuery(queryParams);

var builder = new UriBuilder
{
Host = "dev.azure.com",
Scheme = "https",
Query = query,
Path = fullPath
};

var uriString = builder.ToString();
var uri = new Uri(uriString);
return uri;
}

private JsonDocument GetResponse(string path)
{
var uri = BuildUri(path);

using (var client = GetClient())
{
using (var response = client.GetAsync(uri).Result)
{
var json = response.Content.ReadAsStringAsync().Result;
var document = JsonDocument.Parse(json);
return document;
}
}
}

public AzureRepository[] GetRepositories()
{
var document = GetResponse("git/repositories");
var repositories = document.RootElement.GetProperty("value");

var count = repositories.GetArrayLength();
var azureRepos = new AzureRepository[count];
var index = 0;

foreach (var repository in repositories.EnumerateArray())
{
var name = repository.GetProperty("name").GetString();
var remoteUrl = repository.GetProperty("remoteUrl").GetString();
var azureRepo = new AzureRepository(name, remoteUrl);
azureRepos[index] = azureRepo;
index++;
}

return azureRepos;
}
}
}
9 changes: 9 additions & 0 deletions src/GitMan/Clients/AzureClientConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace GitMan.Clients
{
internal class AzureClientConfig
{
public string Organization { get; set; }
public string Project { get; set; }
public string PersonalAccessToken { get; set; }
}
}
14 changes: 14 additions & 0 deletions src/GitMan/Clients/AzureRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace GitMan.Clients
{
public class AzureRepository
{
public string Name { get; }
public string RemoteUrl { get; }

public AzureRepository(string name, string remoteUrl)
{
Name = name;
RemoteUrl = remoteUrl;
}
}
}
12 changes: 12 additions & 0 deletions src/GitMan/Config/AzureProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Collections.Generic;

namespace GitMan.Config
{
internal class AzureProvider
{
public string Organization { get; set; }
public string Project { get; set; }
public string PersonalAccessToken { get; set; }
public Dictionary<string, string> DefaultConfig { get; set; } = new Dictionary<string, string>();
}
}
16 changes: 9 additions & 7 deletions src/GitMan/Settings.cs → src/GitMan/Config/Settings.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
using System;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Text.Json.Serialization;

namespace GitMan
namespace GitMan.Config
{
internal class Settings
{
public string RepositoryFolder { get; set; }

public string VsCodePath { get; set; }

public string GitBashPath { get; set; }
public AzureProvider[] AzureProviders { get; set; }

private static Settings CreateDefault()
{
var userProfile = Environment.GetEnvironmentVariable("USERPROFILE");
var repositoryFolder = Path.Combine(userProfile, "./Source/Repos");
var vsCodePath = Path.Combine(userProfile, "./AppData/Local/Programs/Microsoft VS Code/Code.exe");
const string gitBashPath = "C:/Program Files/Git/git-bash.exe";
var azureProviders = Array.Empty<AzureProvider>();

var settings = new Settings
{
RepositoryFolder = repositoryFolder,
VsCodePath = vsCodePath,
GitBashPath = gitBashPath,
AzureProviders = azureProviders,
};

return settings;
Expand All @@ -36,19 +37,20 @@ public static Settings Load()
if (File.Exists("config.json"))
{
var json = File.ReadAllText("config.json");
settings = JsonSerializer.Parse<Settings>(json);
settings = JsonConvert.DeserializeObject<Settings>(json);
}
else
{
settings = CreateDefault();
settings.Save();
}

return settings;
}

public void Save()
{
var json = JsonSerializer.ToString(this);
var json = JsonConvert.SerializeObject(this);
File.WriteAllText("config.json", json);
}
}
Expand Down
Loading

0 comments on commit 1c190a6

Please sign in to comment.