Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ public async Task ExecuteAsync(IComponentProviderContext context)
{
var components = context.ComponentReferences.Where(x => x.Provider == _name && x.IsEnabled);

var refs = await FetchRefsAsync(context.CancellationToken);
var refs = await FetchRefsAsync(context);

var tasks = components
.Select(x => ProcessComponentAsync(x, refs, context.Logger, context.CancellationToken))
.Select(x => ProcessComponentAsync(x, refs, context))
.ToArray();

List<string>? errors = null;
Expand All @@ -82,18 +82,20 @@ public async Task ExecuteAsync(IComponentProviderContext context)
}

private async Task<IReadOnlyDictionary<string, string>> FetchRefsAsync(
CancellationToken cancellationToken)
IComponentProviderContext context)
{
var directory =
new DirectoryInfo(Path.Combine(_cloneDirectory.FullName, "__refs"));
var refs = new Dictionary<string, string>();

string gitUrl = GitUrl.Create(_repositoryUrl, context.Parameter);

var sparseConfig =
new GitSparseCheckoutConfiguration(_repositoryUrl, directory.FullName, _arguments);
await _git.SparseCheckoutAsync(sparseConfig, cancellationToken);
new GitSparseCheckoutConfiguration(gitUrl, directory.FullName, _arguments);
await _git.SparseCheckoutAsync(sparseConfig, context.CancellationToken);

var showRefConfig = new GitShowRefsConfiguration(directory.FullName, _arguments);
var refsOutput = await _git.ShowRefsAsync(showRefConfig, cancellationToken);
var refsOutput = await _git.ShowRefsAsync(showRefConfig, context.CancellationToken);

foreach (var line in refsOutput.Split('\n'))
{
Expand All @@ -115,8 +117,7 @@ private async Task<IReadOnlyDictionary<string, string>> FetchRefsAsync(
private async Task<ComponentOrError?> ProcessComponentAsync(
ComponentReferenceDefinition definition,
IReadOnlyDictionary<string, string> refs,
IConsoleLogger logger,
CancellationToken cancellationToken)
IComponentProviderContext context)
{
var version = definition.Version ?? "latest";
var componentName = definition.ComponentName;
Expand All @@ -129,13 +130,15 @@ private async Task<IReadOnlyDictionary<string, string>> FetchRefsAsync(
directory.EnsureFolder();

var cloneArgument = _arguments.ToList();

string gitUrl = GitUrl.Create(_repositoryUrl, context.Parameter);

var cloneConfiguration = new GitCloneConfiguration(
_repositoryUrl,
gitUrl,
directory.FullName,
cloneArgument.ToArray());

await _git.CloneAsync(cloneConfiguration, cancellationToken);
await _git.CloneAsync(cloneConfiguration, context.CancellationToken);

if (version is not "latest")
{
Expand All @@ -147,7 +150,7 @@ private async Task<IReadOnlyDictionary<string, string>> FetchRefsAsync(

await _git.CheckoutAsync(
new GitCheckoutConfiguration(directory.FullName, hash, cloneArgument.ToArray()),
cancellationToken);
context.CancellationToken);
}

var pathToComponent = Path
Expand All @@ -159,7 +162,7 @@ await _git.CheckoutAsync(
$"Could not find component {componentName} ({version}) in git repository");
}

logger.FoundComponent(componentName, version);
context.Logger.FoundComponent(componentName, version);

var json = JsonSchema.FromFile(pathToComponent);
var component =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Confix.Tool.Common.Pipelines;

namespace Confix.Tool.Entities.Components.Git;

public static class GitUrl
{
public static string Create(string repositoryUrl, IParameterCollection parameters)
{
parameters.TryGet(GitUsernameOptions.Instance, out string? username);
parameters.TryGet(GitTokenOptions.Instance, out string? token);

if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(token))
{
if (repositoryUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
{
var uri = new Uri(repositoryUrl);
var builder = new UriBuilder(uri)
{
UserName = username,
Password = token
};
return builder.Uri.ToString();
}
}

return repositoryUrl;
}
}
15 changes: 15 additions & 0 deletions src/Confix.Tool/src/Confix.Library/Options/GitTokenOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.CommandLine;

namespace Confix.Tool;

internal sealed class GitTokenOptions : Option<string>
{
public static GitTokenOptions Instance { get; } = new();

private GitTokenOptions()
: base("--git-token")
{
Arity = ArgumentArity.ZeroOrOne;
Description = "The token used for git authentication.";
}
}
15 changes: 15 additions & 0 deletions src/Confix.Tool/src/Confix.Library/Options/GitUsernameOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.CommandLine;

namespace Confix.Tool;

internal sealed class GitUsernameOptions : Option<string>
{
public static GitUsernameOptions Instance { get; } = new();

private GitUsernameOptions()
: base("--git-username")
{
Arity = ArgumentArity.ZeroOrOne;
Description = "The username used for git authentication.";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Confix.Tool;
using Confix.Tool.Common.Pipelines;
using Confix.Tool.Entities.Components.Git;
using Moq;

public class GitUrlTests
{
[Theory]
[InlineData("https://github.com/org/repo.git", "user", "token", "https://user:token@github.com/org/repo.git")]
[InlineData("https://github.com/org/repo.git", null, null, "https://github.com/org/repo.git")]
[InlineData("https://github.com/org/repo.git", "", "", "https://github.com/org/repo.git")]
[InlineData("http://github.com/org/repo.git", "user", "token", "http://github.com/org/repo.git")]
[InlineData("https://github.com/org/repo.git", "user", null, "https://github.com/org/repo.git")]
[InlineData("https://github.com/org/repo.git", null, "token", "https://github.com/org/repo.git")]
public void GitUrl_Create_WorksAsExpected(string url, object username, object token, string expected)
{
// Arrange
var parameters = new Mock<IParameterCollection>();
parameters.Setup(p => p.TryGet(It.IsAny<GitUsernameOptions>(), out username)).Returns(true);
parameters.Setup(p => p.TryGet(It.IsAny<GitTokenOptions>(), out token)).Returns(true);

// Act
var result = GitUrl.Create(url, parameters.Object);

// Assert
Assert.Equal(expected, result);
}
}
Loading