Skip to content

Commit 81f7761

Browse files
authored
Added Git checkout option for GitRepoClone (#414)
* Updated Functional Tests Signed-off-by: Rakesh <[email protected]> * Added Git Checkout * Update Docs * commit changes * commit changes * commit changes * Rename Commit * Commit changes --------- Signed-off-by: Rakesh <[email protected]>
1 parent 8fc3478 commit 81f7761

File tree

3 files changed

+156
-0
lines changed

3 files changed

+156
-0
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
namespace VirtualClient.Dependencies
5+
{
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Diagnostics;
9+
using System.Linq;
10+
using System.Threading;
11+
using System.Threading.Tasks;
12+
using Microsoft.Extensions.DependencyInjection;
13+
using Moq;
14+
using NUnit.Framework;
15+
using VirtualClient.Common;
16+
using VirtualClient.Common.Telemetry;
17+
18+
[TestFixture]
19+
[Category("Unit")]
20+
public class GitRepoCloneTests
21+
{
22+
private MockFixture mockFixture;
23+
24+
[Test]
25+
public async Task GitRepoCloneRunsTheExpectedCommand()
26+
{
27+
this.mockFixture = new MockFixture();
28+
this.mockFixture.File.Reset();
29+
this.mockFixture.Setup(PlatformID.Unix);
30+
this.mockFixture.File.Setup(f => f.Exists(It.IsAny<string>()))
31+
.Returns(true);
32+
this.mockFixture.Parameters = new Dictionary<string, IConvertible>()
33+
{
34+
{ nameof(GitRepoClone.PackageName), "coremark" },
35+
{ nameof(GitRepoClone.RepoUri), "https://github.com/eembc/coremark.git" }
36+
};
37+
38+
ProcessStartInfo expectedInfo = new ProcessStartInfo();
39+
List<string> expectedCommands = new List<string>()
40+
{
41+
$@"git clone {this.mockFixture.Parameters[$"{nameof(GitRepoClone.RepoUri)}"]} {this.mockFixture.GetPackagePath()}/{this.mockFixture.Parameters[$"{nameof(GitRepoClone.PackageName)}"]}"
42+
};
43+
44+
int commandExecuted = 0;
45+
this.mockFixture.ProcessManager.OnCreateProcess = (exe, arguments, workingDir) =>
46+
{
47+
if (expectedCommands.Any(c => c == $"{exe} {arguments}"))
48+
{
49+
commandExecuted++;
50+
}
51+
52+
IProcessProxy process = new InMemoryProcess()
53+
{
54+
ExitCode = 0,
55+
OnStart = () => true,
56+
OnHasExited = () => true
57+
};
58+
return process;
59+
};
60+
61+
using (TestGitRepoClone installation = new TestGitRepoClone(this.mockFixture.Dependencies, this.mockFixture.Parameters))
62+
{
63+
await installation.ExecuteAsync(CancellationToken.None).ConfigureAwait(false);
64+
}
65+
66+
Assert.AreEqual(1, commandExecuted);
67+
}
68+
69+
[Test]
70+
public async Task GitRepoCloneRunsTheExpectedCommandWithCheckout()
71+
{
72+
this.mockFixture = new MockFixture();
73+
this.mockFixture.Setup(PlatformID.Unix);
74+
this.mockFixture.File.Reset();
75+
this.mockFixture.File.Setup(f => f.Exists(It.IsAny<string>()))
76+
.Returns(true);
77+
78+
// The parameter Commit can be a branch-name, tag or a commit id.
79+
this.mockFixture.Parameters = new Dictionary<string, IConvertible>()
80+
{
81+
{ nameof(GitRepoClone.PackageName), "coremark" },
82+
{ nameof(GitRepoClone.RepoUri), "https://github.com/eembc/coremark.git" },
83+
{ nameof(GitRepoClone.Commit), "Checkout-string" }
84+
};
85+
86+
ProcessStartInfo expectedInfo = new ProcessStartInfo();
87+
List<string> expectedCommands = new List<string>()
88+
{
89+
$@"git clone {this.mockFixture.Parameters[$"{nameof(GitRepoClone.RepoUri)}"]} {this.mockFixture.GetPackagePath()}/{this.mockFixture.Parameters[$"{nameof(GitRepoClone.PackageName)}"]}",
90+
$@"git -C {this.mockFixture.GetPackagePath()}/{this.mockFixture.Parameters[$"{nameof(GitRepoClone.PackageName)}"]} checkout {this.mockFixture.Parameters[$"{nameof(GitRepoClone.Commit)}"]}",
91+
};
92+
93+
int commandExecuted = 0;
94+
this.mockFixture.ProcessManager.OnCreateProcess = (exe, arguments, workingDir) =>
95+
{
96+
if (expectedCommands.Any(c => c == $"{exe} {arguments}"))
97+
{
98+
commandExecuted++;
99+
}
100+
101+
IProcessProxy process = new InMemoryProcess()
102+
{
103+
ExitCode = 0,
104+
OnStart = () => true,
105+
OnHasExited = () => true
106+
};
107+
return process;
108+
};
109+
110+
using (TestGitRepoClone installation = new TestGitRepoClone(this.mockFixture.Dependencies, this.mockFixture.Parameters))
111+
{
112+
await installation.ExecuteAsync(CancellationToken.None).ConfigureAwait(false);
113+
}
114+
115+
Assert.AreEqual(2, commandExecuted);
116+
}
117+
118+
private class TestGitRepoClone : GitRepoClone
119+
{
120+
public TestGitRepoClone(IServiceCollection dependencies, IDictionary<string, IConvertible> parameters)
121+
: base(dependencies, parameters)
122+
{
123+
}
124+
125+
public new Task ExecuteAsync(EventContext context, CancellationToken cancellationToken)
126+
{
127+
return base.ExecuteAsync(context, cancellationToken);
128+
}
129+
}
130+
}
131+
}

src/VirtualClient/VirtualClient.Dependencies/Packaging/GitRepoClone.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace VirtualClient.Dependencies
55
{
66
using System;
77
using System.Collections.Generic;
8+
using System.CommandLine;
89
using System.Threading;
910
using System.Threading.Tasks;
1011
using Microsoft.Extensions.DependencyInjection;
@@ -47,13 +48,30 @@ public Uri RepoUri
4748
}
4849
}
4950

51+
/// <summary>
52+
/// Parameter to checkout to a specific branch, commit or tag in the repository
53+
/// </summary>
54+
public string Commit
55+
{
56+
get
57+
{
58+
return this.Parameters.GetValue<string>(nameof(GitRepoClone.Commit), string.Empty);
59+
}
60+
61+
set
62+
{
63+
this.Parameters[nameof(GitRepoClone.Commit)] = value;
64+
}
65+
}
66+
5067
/// <summary>
5168
/// Executes the git clone operation.
5269
/// </summary>
5370
protected override async Task ExecuteAsync(EventContext telemetryContext, CancellationToken cancellationToken)
5471
{
5572
telemetryContext.AddContext("repoUri", this.RepoUri);
5673
telemetryContext.AddContext("packagesDirectory", this.PlatformSpecifics.PackagesDirectory);
74+
telemetryContext.AddContext("Commit", this.Commit);
5775

5876
ISystemManagement systemManagement = this.Dependencies.GetService<ISystemManagement>();
5977
ProcessManager processManager = systemManagement.ProcessManager;
@@ -100,6 +118,11 @@ await systemManagement.PackageManager.RegisterPackageAsync(
100118
await systemManagement.PackageManager.RegisterPackageAsync(package, cancellationToken)
101119
.ConfigureAwait(false);
102120
}
121+
122+
if (!string.IsNullOrEmpty(this.Commit))
123+
{
124+
await this.ExecuteCommandAsync("git", $"-C {cloneDirectory} checkout {this.Commit}", this.PlatformSpecifics.PackagesDirectory, telemetryContext, cancellationToken);
125+
}
103126
}
104127
}
105128
}

website/docs/dependencies/0040-install-git-repo.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ The following section describes the parameters used by the individual component
2121
|---------------|--------------|-----------------------------------------------------------------------------------------------------------------|
2222
| PackageName | Yes | The logical name of the that will be registered with the Virtual Client runtime to represent the packages directory into which the repo was cloned. Other profile components can use this name to reference/discover the repo and its location. |
2323
| RepoUri | Yes | The full URI to the Git repository to download/clone into the packages directory. |
24+
| Commit | No | The branch-name or commit-hash or tag to checkout to a specific branch, commit, tag in the repository. |
2425
| Scenario | No | A name/identifier for the specific component in the profile. This is used for telemetry purposes only with components in dependency sections of the profile (i.e. cannot be used with --scenarios option on the command line). |
2526

2627

@@ -36,6 +37,7 @@ In this example, VC clones https://github.com/eembc/coremark.git into the runtim
3637
"Type": "GitRepoClone",
3738
"Parameters": {
3839
"RepoUri": "https://github.com/eembc/coremark.git",
40+
"Commit": "v1.01"
3941
"PackageName": "coremark"
4042
}
4143
}

0 commit comments

Comments
 (0)