Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions NGitLab.Mock/Clients/ContainerRegistryClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NGitLab.Mock.Internals;
using NGitLab.Models;
using ModelContainerRegistryTag = NGitLab.Models.ContainerRegistryTag;
using ModelContainerRepository = NGitLab.Models.ContainerRepository;

namespace NGitLab.Mock.Clients;

internal sealed class ContainerRegistryClient(ClientContext context, ProjectId projectId) : ClientBase(context), IContainerRegistryClient
{
public GitLabCollectionResponse<ModelContainerRepository> GetRepositoriesAsync(CancellationToken cancellationToken = default)
{
using (Context.BeginOperationScope())
{
var project = GetProject(projectId, ProjectPermission.View);
var result = project.ContainerRepositories
.Select(r => r.ToClientContainerRepository())
.ToList();
return GitLabCollectionResponse.Create(result);
}
}

public GitLabCollectionResponse<ModelContainerRegistryTag> GetTagsAsync(long repositoryId, CancellationToken cancellationToken = default)
{
using (Context.BeginOperationScope())
{
var project = GetProject(projectId, ProjectPermission.View);
var repo = project.ContainerRepositories.FirstOrDefault(r => r.Id == repositoryId)
?? throw GitLabException.NotFound();
var result = repo.Tags
.Select(t => t.ToClientContainerRegistryTag())
.ToList();
return GitLabCollectionResponse.Create(result);
}
}

public Task DeleteTagAsync(long repositoryId, string tagName, CancellationToken cancellationToken = default)
{
using (Context.BeginOperationScope())
{
var project = GetProject(projectId, ProjectPermission.Edit);
var repo = project.ContainerRepositories.FirstOrDefault(r => r.Id == repositoryId)
?? throw GitLabException.NotFound();
repo.Tags.RemoveAll(t => string.Equals(t.Name, tagName, System.StringComparison.Ordinal));
return Task.CompletedTask;
}
}

public Task DeleteRepositoryAsync(long repositoryId, CancellationToken cancellationToken = default)
{
using (Context.BeginOperationScope())
{
var project = GetProject(projectId, ProjectPermission.Edit);
var repo = project.ContainerRepositories.FirstOrDefault(r => r.Id == repositoryId)
?? throw GitLabException.NotFound();
project.ContainerRepositories.Remove(repo);
return Task.CompletedTask;
}
}
}
2 changes: 2 additions & 0 deletions NGitLab.Mock/Clients/GitLabClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,6 @@ public IPipelineScheduleClient GetPipelineSchedules(ProjectId projectId)
public IGroupHooksClient GetGroupHooksClient(GroupId groupId) => new GroupHooksClient(Context, groupId);

public IProjectJobTokenScopeClient GetProjectJobTokenScopeClient(ProjectId projectId) => new ProjectJobTokenScopeClient(Context, projectId);

public IContainerRegistryClient GetContainerRegistry(ProjectId projectId) => new ContainerRegistryClient(Context, projectId);
}
21 changes: 21 additions & 0 deletions NGitLab.Mock/Config/GitLabContainerRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Collections.Generic;

namespace NGitLab.Mock.Config;

/// <summary>
/// Describe a container repository in a GitLab project
/// </summary>
public class GitLabContainerRepository : GitLabObject
{
public string Name { get; set; }

public List<string> Tags { get; } = [];
}

public class GitLabContainerRepositoriesCollection : GitLabCollection<GitLabContainerRepository>
{
internal GitLabContainerRepositoriesCollection(GitLabProject parent)
: base(parent)
{
}
}
47 changes: 47 additions & 0 deletions NGitLab.Mock/Config/GitLabHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,33 @@ public static GitLabProject WithRelease(this GitLabProject project, string autho
});
}

/// <summary>
/// Add a container repository in project
/// </summary>
/// <param name="project">Project.</param>
/// <param name="name">Repository name.</param>
/// <param name="tags">Tag names.</param>
public static GitLabProject WithContainerRepository(this GitLabProject project, string name, IEnumerable<string>? tags = null)
{
return Configure(project, _ =>
{
var repo = new GitLabContainerRepository
{
Name = name ?? throw new ArgumentNullException(nameof(name)),
};

if (tags != null)
{
foreach (var tag in tags)
{
repo.Tags.Add(tag);
}
}

project.ContainerRepositories.Add(repo);
});
}

/// <summary>
/// Add label in issue (create it if not exists)
/// </summary>
Expand Down Expand Up @@ -1314,6 +1341,11 @@ private static void CreateProject(GitLabServer server, GitLabProject project)
CreatePipeline(server, prj, pipeline, aliases);
}

foreach (var containerRepository in project.ContainerRepositories)
{
CreateContainerRepository(prj, containerRepository);
}

if (!string.IsNullOrEmpty(project.ClonePath))
{
var folderPath = Path.GetDirectoryName(Path.GetFullPath(project.ClonePath));
Expand Down Expand Up @@ -1357,6 +1389,21 @@ private static void CreateRelease(GitLabServer server, Project project, GitLabRe
project.Releases.Add(release);
}

private static void CreateContainerRepository(Project project, GitLabContainerRepository containerRepository)
{
var repo = new ContainerRepository
{
Name = containerRepository.Name,
};

foreach (var tag in containerRepository.Tags)
{
repo.Tags.Add(new ContainerRegistryTagEntry { Name = tag, });
}

project.ContainerRepositories.Add(repo);
}

private static Commit CreateCommit(GitLabServer server, Project prj, GitLabCommit commit)
{
var username = commit.User ?? commit.Parent.Parent.DefaultUser ?? throw new InvalidOperationException("Default user is required when author not set");
Expand Down
3 changes: 3 additions & 0 deletions NGitLab.Mock/Config/GitLabProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public GitLabProject()
Milestones = new GitLabMilestonesCollection(this);
Pipelines = new GitLabPipelinesCollection(this);
Releases = new GitLabReleaseInfoCollection(this);
ContainerRepositories = new GitLabContainerRepositoriesCollection(this);
}

/// <summary>
Expand Down Expand Up @@ -64,6 +65,8 @@ public GitLabProject()
public GitLabPipelinesCollection Pipelines { get; }

public GitLabReleaseInfoCollection Releases { get; }

public GitLabContainerRepositoriesCollection ContainerRepositories { get; }
}

public class GitLabProjectsCollection : GitLabCollection<GitLabProject, GitLabConfig>
Expand Down
16 changes: 16 additions & 0 deletions NGitLab.Mock/ContainerRegistryTagEntry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using NGitLab.Models;

namespace NGitLab.Mock;

public sealed class ContainerRegistryTagEntry
{
public string Name { get; set; }

public Models.ContainerRegistryTag ToClientContainerRegistryTag()
{
return new Models.ContainerRegistryTag
{
Name = Name,
};
}
}
27 changes: 27 additions & 0 deletions NGitLab.Mock/ContainerRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using NGitLab.Models;

namespace NGitLab.Mock;

public sealed class ContainerRepository : GitLabObject
{
public new Project Parent => (Project)base.Parent;

public long Id { get; set; }

public string Name { get; set; }

public List<ContainerRegistryTagEntry> Tags { get; } = [];

public Models.ContainerRepository ToClientContainerRepository()
{
return new Models.ContainerRepository
{
Id = Id,
Name = Name,
ProjectId = Parent?.Id ?? 0,
TagsCount = Tags.Count,
};
}
}
9 changes: 9 additions & 0 deletions NGitLab.Mock/ContainerRepositoryCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace NGitLab.Mock;

public sealed class ContainerRepositoryCollection : Collection<ContainerRepository>
{
public ContainerRepositoryCollection(GitLabObject parent)
: base(parent)
{
}
}
3 changes: 3 additions & 0 deletions NGitLab.Mock/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public Project(string name, string path)
CommitStatuses = new CommitStatusCollection(this);
Releases = new ReleaseCollection(this);
ProtectedBranches = new ProtectedBranchCollection(this);
ContainerRepositories = new ContainerRepositoryCollection(this);
ApprovalsBeforeMerge = 0;
}

Expand Down Expand Up @@ -163,6 +164,8 @@ public string[] Tags

public ProtectedBranchCollection ProtectedBranches { get; }

public ContainerRepositoryCollection ContainerRepositories { get; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add the possibility to set it in the GitLabHelpers (to construct GitLabConfig), thus, to be able to use the mocked client.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed ^^


public string RunnersToken { get; internal set; }

public SquashOption SquashOption { get; set; }
Expand Down
27 changes: 27 additions & 0 deletions NGitLab.Mock/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1381,3 +1381,30 @@ static NGitLab.Mock.TemporaryDirectory.DeleteDirectory(string path) -> void
static NGitLab.Mock.TemporaryDirectory.DeleteFile(string path) -> void
static NGitLab.Mock.UserRef.implicit operator NGitLab.Mock.UserRef(NGitLab.Mock.User user) -> NGitLab.Mock.UserRef
virtual NGitLab.Mock.Collection<T>.Add(T item) -> void

NGitLab.Mock.ContainerRepository
NGitLab.Mock.ContainerRepository.ContainerRepository() -> void
NGitLab.Mock.ContainerRepository.Id.get -> long
NGitLab.Mock.ContainerRepository.Id.set -> void
NGitLab.Mock.ContainerRepository.Name.get -> string
NGitLab.Mock.ContainerRepository.Name.set -> void
NGitLab.Mock.ContainerRepository.Parent.get -> NGitLab.Mock.Project
NGitLab.Mock.ContainerRepository.Tags.get -> System.Collections.Generic.List<NGitLab.Mock.ContainerRegistryTagEntry>
NGitLab.Mock.ContainerRepository.ToClientContainerRepository() -> NGitLab.Models.ContainerRepository
NGitLab.Mock.ContainerRegistryTagEntry
NGitLab.Mock.ContainerRegistryTagEntry.ContainerRegistryTagEntry() -> void
NGitLab.Mock.ContainerRegistryTagEntry.Name.get -> string
NGitLab.Mock.ContainerRegistryTagEntry.Name.set -> void
NGitLab.Mock.ContainerRegistryTagEntry.ToClientContainerRegistryTag() -> NGitLab.Models.ContainerRegistryTag
NGitLab.Mock.ContainerRepositoryCollection
NGitLab.Mock.ContainerRepositoryCollection.ContainerRepositoryCollection(NGitLab.Mock.GitLabObject parent) -> void
NGitLab.Mock.Project.ContainerRepositories.get -> NGitLab.Mock.ContainerRepositoryCollection

NGitLab.Mock.Config.GitLabContainerRepository
NGitLab.Mock.Config.GitLabContainerRepository.GitLabContainerRepository() -> void
NGitLab.Mock.Config.GitLabContainerRepository.Name.get -> string
NGitLab.Mock.Config.GitLabContainerRepository.Name.set -> void
NGitLab.Mock.Config.GitLabContainerRepository.Tags.get -> System.Collections.Generic.List<string>
NGitLab.Mock.Config.GitLabContainerRepositoriesCollection
NGitLab.Mock.Config.GitLabProject.ContainerRepositories.get -> NGitLab.Mock.Config.GitLabContainerRepositoriesCollection
static NGitLab.Mock.Config.GitLabHelpers.WithContainerRepository(this NGitLab.Mock.Config.GitLabProject project, string name, System.Collections.Generic.IEnumerable<string> tags = null) -> NGitLab.Mock.Config.GitLabProject
3 changes: 3 additions & 0 deletions NGitLab/GitLabClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,7 @@ public IGroupHooksClient GetGroupHooksClient(GroupId groupId)

public IProjectJobTokenScopeClient GetProjectJobTokenScopeClient(ProjectId projectId)
=> new ProjectJobTokenScopeClient(_api, projectId);

public IContainerRegistryClient GetContainerRegistry(ProjectId projectId)
=> new ContainerRegistryClient(_api, projectId);
}
28 changes: 28 additions & 0 deletions NGitLab/IContainerRegistryClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Threading;
using System.Threading.Tasks;
using NGitLab.Models;

namespace NGitLab;

public interface IContainerRegistryClient
{
/// <summary>
/// Returns all container repositories for the project.
/// </summary>
GitLabCollectionResponse<ContainerRepository> GetRepositoriesAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Returns all tags for the given repository.
/// </summary>
GitLabCollectionResponse<ContainerRegistryTag> GetTagsAsync(long repositoryId, CancellationToken cancellationToken = default);

/// <summary>
/// Deletes a single tag from a repository.
/// </summary>
Task DeleteTagAsync(long repositoryId, string tagName, CancellationToken cancellationToken = default);

/// <summary>
/// Deletes a repository and all its tags.
/// </summary>
Task DeleteRepositoryAsync(long repositoryId, CancellationToken cancellationToken = default);
}
2 changes: 2 additions & 0 deletions NGitLab/IGitLabClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,6 @@ public interface IGitLabClient
IGroupHooksClient GetGroupHooksClient(GroupId groupId);

IProjectJobTokenScopeClient GetProjectJobTokenScopeClient(ProjectId projectId);

IContainerRegistryClient GetContainerRegistry(ProjectId projectId);
}
30 changes: 30 additions & 0 deletions NGitLab/Impl/ContainerRegistryClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Threading;
using System.Threading.Tasks;
using NGitLab.Extensions;
using NGitLab.Models;

namespace NGitLab.Impl;

public class ContainerRegistryClient : IContainerRegistryClient
{
private readonly API _api;
private readonly string _projectId;

public ContainerRegistryClient(API api, ProjectId projectId)
{
_api = api;
_projectId = projectId.ValueAsUriParameter();
}

public GitLabCollectionResponse<ContainerRepository> GetRepositoriesAsync(CancellationToken cancellationToken = default)
=> _api.Get().GetAllAsync<ContainerRepository>($"/projects/{_projectId}/registry/repositories");

public GitLabCollectionResponse<ContainerRegistryTag> GetTagsAsync(long repositoryId, CancellationToken cancellationToken = default)
=> _api.Get().GetAllAsync<ContainerRegistryTag>($"/projects/{_projectId}/registry/repositories/{repositoryId.ToStringInvariant()}/tags");

public Task DeleteTagAsync(long repositoryId, string tagName, CancellationToken cancellationToken = default)
=> _api.Delete().ExecuteAsync($"/projects/{_projectId}/registry/repositories/{repositoryId.ToStringInvariant()}/tags/{tagName}", cancellationToken);

public Task DeleteRepositoryAsync(long repositoryId, CancellationToken cancellationToken = default)
=> _api.Delete().ExecuteAsync($"/projects/{_projectId}/registry/repositories/{repositoryId.ToStringInvariant()}", cancellationToken);
}
31 changes: 31 additions & 0 deletions NGitLab/Models/ContainerRegistryTag.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Text.Json.Serialization;

namespace NGitLab.Models;

public class ContainerRegistryTag
{
[JsonPropertyName("name")]
public string Name { get; set; }

[JsonPropertyName("path")]
public string Path { get; set; }

[JsonPropertyName("location")]
public string Location { get; set; }

[JsonPropertyName("revision")]
public string Revision { get; set; }

[JsonPropertyName("short_revision")]
public string ShortRevision { get; set; }

[JsonPropertyName("digest")]
public string Digest { get; set; }

[JsonPropertyName("created_at")]
public DateTime CreatedAt { get; set; }

[JsonPropertyName("total_size")]
public long TotalSize { get; set; }
}
Loading
Loading