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
43 changes: 43 additions & 0 deletions NGitLab.Mock.Tests/ProjectsMockTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,49 @@ public void Test_project_can_be_cloned_by_default()
Assert.IsTrue(Directory.Exists(tempDir.GetFullPath(".git")));
}

[Test]
public void Test_project_with_submodules()
{
using var tempDir = TemporaryDirectory.Create();
using var server = new GitLabConfig()
.WithUser("Test", isDefault: true)
.WithProject("ModuleA", configure: x => x.WithCommit(configure: c => c.WithFile("A.txt")))
.WithProject("ModuleB", configure: x => x.WithCommit(configure: c => c.WithFile("B.txt")))
.WithProject("Test", clonePath: tempDir.FullPath, configure: x =>
x.WithCommit("Init", configure: c
=> c.WithSubModule("ModuleA")
.WithSubModule("ModuleB")))
.BuildServer();

Assert.IsTrue(Directory.Exists(tempDir.GetFullPath(".git")));
Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleA/.git")));
Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleA/A.txt")));
Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/.git")));
Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/B.txt")));
}

[Test]
public void Test_project_with_nested_submodules()
{
using var tempDir = TemporaryDirectory.Create();
using var server = new GitLabConfig()
.WithUser("Test", isDefault: true)
.WithProject("ModuleA", configure: x => x.WithCommit(configure: c => c.WithFile("A.txt")))
.WithProject("ModuleB", configure: x => x.WithCommit(configure: c
=> c.WithFile("B.txt")
.WithSubModule("ModuleA")))
.WithProject("Test", clonePath: tempDir.FullPath, configure: x =>
x.WithCommit(configure: c
=> c.WithSubModule("ModuleB")))
.BuildServer();

Assert.IsTrue(Directory.Exists(tempDir.GetFullPath(".git")));
Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/.git")));
Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/B.txt")));
Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/ModuleA/.git")));
Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/ModuleA/A.txt")));
}

[Test]
public void Test_projects_created_url_ends_with_namespace_and_name()
{
Expand Down
5 changes: 5 additions & 0 deletions NGitLab.Mock/Config/GitLabCommit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ public class GitLabCommit : GitLabObject<GitLabProject>
/// </summary>
public IList<GitLabFileDescriptor> Files { get; } = new List<GitLabFileDescriptor>();

/// <summary>
/// Submodules added at this commit
/// </summary>
public IList<GitLabSubModuleDescriptor> SubModules { get; } = new List<GitLabSubModuleDescriptor>();

public IList<string> Tags { get; } = new List<string>();

/// <summary>
Expand Down
63 changes: 59 additions & 4 deletions NGitLab.Mock/Config/GitLabHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,20 @@ public static GitLabCommit WithFile(this GitLabCommit commit, string relativePat
});
}

/// <summary>
/// Add a submodule in commit
/// </summary>
public static GitLabCommit WithSubModule(this GitLabCommit commit, string projectName)
{
return Configure(commit, _ =>
{
commit.SubModules.Add(new GitLabSubModuleDescriptor
{
ProjectName = projectName,
});
});
}

/// <summary>
/// Add an issue description in project
/// </summary>
Expand Down Expand Up @@ -1234,7 +1248,7 @@ private static void CreateProject(GitLabServer server, GitLabProject project)
StartInfo = new ProcessStartInfo
{
FileName = "git",
Arguments = $"clone {project.CloneParameters} \"{prj.SshUrl}\" \"{Path.GetFileName(project.ClonePath)}\"",
Arguments = $"-c protocol.file.allow=always clone {project.CloneParameters} \"{prj.SshUrl}\" \"{Path.GetFileName(project.ClonePath)}\" --recursive",
RedirectStandardError = true,
UseShellExecute = false,
WorkingDirectory = folderPath,
Expand Down Expand Up @@ -1283,9 +1297,12 @@ private static Commit CreateCommit(GitLabServer server, Project prj, GitLabCommi
prj.Repository.CreateBranch(commit.SourceBranch);

var files = commit.Files.Count == 0
? new[] { File.CreateFromText("test.txt", Guid.NewGuid().ToString()) }
: commit.Files.Select(x => File.CreateFromText(x.Path, x.Content ?? string.Empty));
cmt = prj.Repository.Commit(user, commit.Message ?? Guid.NewGuid().ToString("D"), commit.SourceBranch, files);
? new List<File>() { File.CreateFromText("test.txt", Guid.NewGuid().ToString()) }
: commit.Files.Select(x => File.CreateFromText(x.Path, x.Content ?? string.Empty)).ToList();

var submodules = CreateSubModules(server, prj, commit);

cmt = prj.Repository.Commit(user, commit.Message ?? Guid.NewGuid().ToString("D"), commit.SourceBranch, files, submodules);
}
else
{
Expand All @@ -1302,6 +1319,44 @@ private static Commit CreateCommit(GitLabServer server, Project prj, GitLabCommi
return cmt;
}

private static IEnumerable<string> CreateSubModules(GitLabServer server, Project prj, GitLabCommit commit)
{
List<string> submodules = new();
foreach (var submodule in commit.SubModules)
{
var subModuleProject = server.AllProjects.FirstOrDefault(x =>
x.Name.Equals(submodule.ProjectName, StringComparison.OrdinalIgnoreCase));
if (subModuleProject is null)
{
throw new GitLabException($"Project {submodule.ProjectName} can't be found.");
}

if (!subModuleProject.Repository.GetCommits().Any())
{
throw new GitLabException("Project added as a module must have least one commit.");
}

using var process = Process.Start(
new ProcessStartInfo("git", $"-c protocol.file.allow=always submodule add \"{subModuleProject.SshUrl}\" \"{subModuleProject.Name}\"")
{
RedirectStandardError = true,
UseShellExecute = false,
WorkingDirectory = prj.Repository.FullPath,
});

process.WaitForExit();
if (process.ExitCode != 0)
{
var error = process.StandardError.ReadToEnd();
throw new GitLabException($"Cannot add submodule: {error}");
}

submodules.Add(subModuleProject.Name);
}

return submodules;
}

private static void CreateLabel(Group group, GitLabLabel label)
{
group.Labels.Add(new Label
Expand Down
13 changes: 13 additions & 0 deletions NGitLab.Mock/Config/GitLabSubModuleDescriptor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace NGitLab.Mock.Config
{
/// <summary>
/// Describe a sub module in project repository
/// </summary>
public class GitLabSubModuleDescriptor
{
/// <summary>
/// Project's ID added as a submodule
/// </summary>
public string ProjectName { get; init; }
}
}
7 changes: 7 additions & 0 deletions NGitLab.Mock/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ NGitLab.Mock.Config.GitLabCommit.DeleteSourceBranch.get -> bool
NGitLab.Mock.Config.GitLabCommit.DeleteSourceBranch.set -> void
NGitLab.Mock.Config.GitLabCommit.FromBranch.get -> string
NGitLab.Mock.Config.GitLabCommit.FromBranch.set -> void
NGitLab.Mock.Config.GitLabCommit.SubModules.get -> System.Collections.Generic.IList<NGitLab.Mock.Config.GitLabSubModuleDescriptor>
NGitLab.Mock.Config.GitLabConfig.DefaultBranch.get -> string
NGitLab.Mock.Config.GitLabConfig.DefaultBranch.set -> void
NGitLab.Mock.Config.GitLabConfig.DefaultUser.get -> string
Expand Down Expand Up @@ -210,6 +211,10 @@ NGitLab.Mock.Config.GitLabReleaseInfo.ReleasedAt.set -> void
NGitLab.Mock.Config.GitLabReleaseInfo.TagName.get -> string
NGitLab.Mock.Config.GitLabReleaseInfo.TagName.set -> void
NGitLab.Mock.Config.GitLabReleaseInfoCollection
NGitLab.Mock.Config.GitLabSubModuleDescriptor
NGitLab.Mock.Config.GitLabSubModuleDescriptor.GitLabSubModuleDescriptor() -> void
NGitLab.Mock.Config.GitLabSubModuleDescriptor.ProjectName.get -> string
NGitLab.Mock.Config.GitLabSubModuleDescriptor.ProjectName.init -> void
NGitLab.Mock.EffectivePermissions
NGitLab.Mock.EffectivePermissions.GetAccessLevel(NGitLab.Mock.User user) -> NGitLab.Models.AccessLevel?
NGitLab.Mock.EffectivePermissions.GetEffectivePermission(NGitLab.Mock.User user) -> NGitLab.Mock.EffectiveUserPermission
Expand Down Expand Up @@ -956,6 +961,7 @@ NGitLab.Mock.Repository.Checkout(string committishOrBranchNameSpec) -> void
NGitLab.Mock.Repository.CherryPick(NGitLab.Models.CommitCherryPick commitCherryPick) -> LibGit2Sharp.Commit
NGitLab.Mock.Repository.Commit(NGitLab.Mock.User user, string message) -> LibGit2Sharp.Commit
NGitLab.Mock.Repository.Commit(NGitLab.Mock.User user, string message, string targetBranch, System.Collections.Generic.IEnumerable<NGitLab.Mock.File> files) -> LibGit2Sharp.Commit
NGitLab.Mock.Repository.Commit(NGitLab.Mock.User user, string message, string targetBranch, System.Collections.Generic.IEnumerable<NGitLab.Mock.File> files, System.Collections.Generic.IEnumerable<string> submodules) -> LibGit2Sharp.Commit
NGitLab.Mock.Repository.Commit(NGitLab.Mock.User user, string message, System.Collections.Generic.IEnumerable<NGitLab.Mock.File> files) -> LibGit2Sharp.Commit
NGitLab.Mock.Repository.Commit(NGitLab.Models.CommitCreate commitCreate) -> LibGit2Sharp.Commit
NGitLab.Mock.Repository.CreateAndCheckoutBranch(string branchName) -> LibGit2Sharp.Branch
Expand Down Expand Up @@ -1230,6 +1236,7 @@ static NGitLab.Mock.Config.GitLabHelpers.WithMilestone(this NGitLab.Mock.Config.
static NGitLab.Mock.Config.GitLabHelpers.WithPipeline(this NGitLab.Mock.Config.GitLabProject project, string ref, System.Action<NGitLab.Mock.Config.GitLabPipeline> configure) -> NGitLab.Mock.Config.GitLabProject
static NGitLab.Mock.Config.GitLabHelpers.WithProject(this NGitLab.Mock.Config.GitLabConfig config, string name = null, int id = 0, string namespace = null, string description = null, string defaultBranch = null, NGitLab.Models.VisibilityLevel visibility = NGitLab.Models.VisibilityLevel.Internal, bool initialCommit = false, bool addDefaultUserAsMaintainer = false, string clonePath = null, string cloneParameters = null, System.Action<NGitLab.Mock.Config.GitLabProject> configure = null) -> NGitLab.Mock.Config.GitLabConfig
static NGitLab.Mock.Config.GitLabHelpers.WithRelease(this NGitLab.Mock.Config.GitLabProject project, string author, string tagName, System.DateTime? createdAt = null, System.DateTime? releasedAt = null) -> NGitLab.Mock.Config.GitLabProject
static NGitLab.Mock.Config.GitLabHelpers.WithSubModule(this NGitLab.Mock.Config.GitLabCommit commit, string projectName) -> NGitLab.Mock.Config.GitLabCommit
static NGitLab.Mock.Config.GitLabHelpers.WithSystemComment(this NGitLab.Mock.Config.GitLabIssue issue, string message = null, string innerHtml = null, int id = 0, string author = null, System.DateTime? createdAt = null, System.DateTime? updatedAt = null) -> NGitLab.Mock.Config.GitLabIssue
static NGitLab.Mock.Config.GitLabHelpers.WithSystemComment(this NGitLab.Mock.Config.GitLabMergeRequest mergeRequest, string message = null, string innerHtml = null, int id = 0, string author = null, System.DateTime? createdAt = null, System.DateTime? updatedAt = null) -> NGitLab.Mock.Config.GitLabMergeRequest
static NGitLab.Mock.Config.GitLabHelpers.WithUser(this NGitLab.Mock.Config.GitLabConfig config, string username, string name = null, string email = null, string avatarUrl = null, bool isAdmin = false, bool isDefault = false, System.Action<NGitLab.Mock.Config.GitLabUser> configure = null) -> NGitLab.Mock.Config.GitLabConfig
Expand Down
12 changes: 11 additions & 1 deletion NGitLab.Mock/Repository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public IReadOnlyCollection<Branch> GetAllBranches()

public Commit Commit(User user, string message)
{
return Commit(user, message, targetBranch: null, new[] { File.CreateFromText("test.txt", Guid.NewGuid().ToString()) });
return Commit(user, message, targetBranch: null, new[] { File.CreateFromText("test.txt", Guid.NewGuid().ToString()) }, Enumerable.Empty<string>());
}

public Commit Commit(User user, string message, IEnumerable<File> files)
Expand All @@ -166,6 +166,11 @@ public Commit Commit(User user, string message, IEnumerable<File> files)
}

public Commit Commit(User user, string message, string targetBranch, IEnumerable<File> files)
{
return Commit(user, message, targetBranch, files, Enumerable.Empty<string>());
}

public Commit Commit(User user, string message, string targetBranch, IEnumerable<File> files, IEnumerable<string> submodules)
{
var repository = GetGitRepository();
if (targetBranch != null)
Expand All @@ -181,6 +186,11 @@ public Commit Commit(User user, string message, string targetBranch, IEnumerable
repository.Index.Add(file.Path);
}

foreach (var submodule in submodules)
{
repository.Index.Add(submodule);
}

repository.Index.Write();

var author = new Signature(user.UserName, user.Email, DateTimeOffset.UtcNow);
Expand Down