Skip to content

Commit 17ff6eb

Browse files
committed
Fixes handling of local and network paths in remote URL (#1150)
1 parent 0647320 commit 17ff6eb

4 files changed

Lines changed: 81 additions & 192 deletions

File tree

src/Microsoft.Build.Tasks.Git.UnitTests/GitDataTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public void MinimalGitData()
5454
Assert.Equal("1111111111111111111111111111111111111111", repository.GetHeadCommitSha());
5555

5656
var warnings = new List<(string, object?[])>();
57-
var sourceRoots = GitOperations.GetSourceRoots(repository, remoteName: null, warnOnMissingCommit: true, (message, args) => warnings.Add((message, args)));
57+
var sourceRoots = GitOperations.GetSourceRoots(repository, remoteName: null, warnOnMissingCommitOrUnsupportedUri: true, (message, args) => warnings.Add((message, args)));
5858
AssertEx.Equal(new[]
5959
{
6060
$@"'{repoDir.Path}{s}' SourceControl='git' RevisionId='1111111111111111111111111111111111111111' ScmRepositoryUrl='https://github.com/test-org/test-repo'",

src/Microsoft.Build.Tasks.Git.UnitTests/GitOperationsTests.cs

Lines changed: 38 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -192,147 +192,33 @@ public void GetRepositoryUrl_InsteadOf()
192192
Assert.Empty(warnings);
193193
}
194194

195-
/// <summary>
196-
/// Test scenario where a local repository is cloned from another local repository that was cloned from a remote repository.
197-
/// </summary>
198195
[Theory]
199-
[InlineData(true)]
200-
[InlineData(false)]
201-
public void GetRepositoryUrl_Local(bool useFileUrl)
196+
[InlineData("local")]
197+
[InlineData("file")]
198+
[InlineData("xyz://a/b")]
199+
public void GetRepositoryUrl_UnsupportedUrl(string kind)
202200
{
203201
using var temp = new TempRoot();
204202

205203
var dir = temp.CreateDirectory();
206-
var mainWorkingDir = dir.CreateDirectory("x \u1234");
207-
var mainGitDir = mainWorkingDir.CreateDirectory(".git");
208-
mainGitDir.CreateFile("HEAD");
209-
mainGitDir.CreateFile("config").WriteAllText(@"[remote ""origin""] url = https://github.com/repo");
204+
var originRepoPath = dir.CreateDirectory("x \u1234").Path;
210205

211-
var repo = CreateRepository(config: new GitConfig(ImmutableDictionary.CreateRange(new[]
212-
{
213-
KVP(new GitVariableName("remote", "origin", "url"),
214-
ImmutableArray.Create(useFileUrl ? new Uri(mainWorkingDir.Path).AbsolutePath : mainWorkingDir.Path)),
215-
})));
216-
217-
var warnings = new List<(string, object?[])>();
218-
Assert.Equal("https://github.com/repo", GitOperations.GetRepositoryUrl(repo, remoteName: null, logWarning: (message, args) => warnings.Add((message, args))));
219-
Assert.Empty(warnings);
220-
}
221-
222-
/// <summary>
223-
/// Test scenario where a local repository is cloned from another local repository that was cloned from a remote repository.
224-
/// With custom remote name.
225-
/// </summary>
226-
[Fact]
227-
public void GetRepositoryUrl_Local_CustomRemoteName()
228-
{
229-
using var temp = new TempRoot();
230-
231-
var mainWorkingDir = temp.CreateDirectory();
232-
var mainGitDir = mainWorkingDir.CreateDirectory(".git");
233-
mainGitDir.CreateFile("HEAD");
234-
mainGitDir.CreateFile("config").WriteAllText(@"[remote ""origin""] url = https://github.com/repo");
235-
236-
var repo = CreateRepository(config: new GitConfig(ImmutableDictionary.CreateRange(new[]
237-
{
238-
KVP(new GitVariableName("remote", "origin", "url"), ImmutableArray.Create(mainWorkingDir.Path)),
239-
})));
240-
241-
var warnings = new List<(string, object?[])>();
242-
Assert.Equal("https://github.com/repo", GitOperations.GetRepositoryUrl(repo, remoteName: "myremote", logWarning: (message, args) => warnings.Add((message, args))));
243-
AssertEx.Equal(new[] { string.Format(Resources.RepositoryDoesNotHaveSpecifiedRemote, repo.WorkingDirectory, "myremote", "origin") }, warnings.Select(TestUtilities.InspectDiagnostic));
244-
}
245-
246-
/// <summary>
247-
/// Test scenario where a local repository is cloned from another local repository that does not have remote URL specified.
248-
/// </summary>
249-
[Fact]
250-
public void GetRepositoryUrl_Local_NoRemoteOriginUrl()
251-
{
252-
using var temp = new TempRoot();
253-
254-
var mainWorkingDir = temp.CreateDirectory();
255-
var mainGitDir = mainWorkingDir.CreateDirectory(".git");
256-
mainGitDir.CreateFile("HEAD");
257-
258-
var repo = CreateRepository(config: new GitConfig(ImmutableDictionary.CreateRange(new[]
206+
var url = kind switch
259207
{
260-
KVP(new GitVariableName("remote", "origin", "url"), ImmutableArray.Create(mainWorkingDir.Path)),
261-
})));
262-
263-
var warnings = new List<(string, object?[])>();
264-
Assert.Equal(new Uri(mainWorkingDir.Path).AbsoluteUri, GitOperations.GetRepositoryUrl(repo, remoteName: null, logWarning: (message, args) => warnings.Add((message, args))));
265-
AssertEx.Equal(new[] { string.Format(Resources.RepositoryHasNoRemote, mainWorkingDir.Path) }, warnings.Select(TestUtilities.InspectDiagnostic));
266-
}
267-
268-
/// <summary>
269-
/// Test scenario where a local repository is cloned from another local repository that does not have a working directory.
270-
/// </summary>
271-
[Fact]
272-
public void GetRepositoryUrl_Local_NoWorkingDirectory()
273-
{
274-
using var temp = new TempRoot();
275-
276-
var dir = temp.CreateDirectory();
277-
278-
var gitDir1 = dir.CreateDirectory("1");
279-
gitDir1.CreateFile("HEAD");
280-
gitDir1.CreateFile("config").WriteAllText(@"[remote ""origin""] url = https://github.com/repo");
281-
282-
var gitDir2 = dir.CreateDirectory("2");
283-
gitDir2.CreateFile("HEAD");
284-
gitDir2.CreateFile("config").WriteAllText(@"[remote ""origin""] url = ../1");
285-
286-
var repo = CreateRepository(config: new GitConfig(ImmutableDictionary.CreateRange(new[]
287-
{
288-
KVP(new GitVariableName("remote", "origin", "url"), ImmutableArray.Create(gitDir2.Path)),
289-
})));
290-
291-
var warnings = new List<(string, object?[])>();
292-
Assert.Null(GitOperations.GetRepositoryUrl(repo, remoteName: null, logWarning: (message, args) => warnings.Add((message, args))));
293-
AssertEx.Equal(new[] { string.Format(Resources.UnableToLocateRepository, gitDir2.Path) }, warnings.Select(TestUtilities.InspectDiagnostic));
294-
}
295-
296-
/// <summary>
297-
/// Test scenario where a local repository is cloned from another local repository that was cloned from a remote repository.
298-
/// </summary>
299-
[Fact]
300-
public void GetRepositoryUrl_Local_BadRepo()
301-
{
302-
using var temp = new TempRoot();
303-
304-
var mainWorkingDir = temp.CreateDirectory();
305-
var mainGitDir = mainWorkingDir.CreateDirectory(".git");
306-
307-
var repo = CreateRepository(config: new GitConfig(ImmutableDictionary.CreateRange(new[]
308-
{
309-
KVP(new GitVariableName("remote", "origin", "url"), ImmutableArray.Create(mainWorkingDir.Path)),
310-
})));
311-
312-
var warnings = new List<(string, object?[])>();
313-
Assert.Equal(new Uri(mainWorkingDir.Path).AbsoluteUri, GitOperations.GetRepositoryUrl(repo, remoteName: null, logWarning: (message, args) => warnings.Add((message, args))));
314-
AssertEx.Equal(new[] { string.Format(Resources.RepositoryHasNoRemote, mainWorkingDir.Path) }, warnings.Select(TestUtilities.InspectDiagnostic));
315-
}
316-
317-
[Fact]
318-
public void GetRepositoryUrl_LocalRecursion()
319-
{
320-
using var temp = new TempRoot();
321-
322-
var mainWorkingDir = temp.CreateDirectory();
323-
var mainGitDir = mainWorkingDir.CreateDirectory(".git");
324-
mainGitDir.CreateFile("HEAD");
325-
mainGitDir.CreateFile("config").WriteAllText($@"[remote ""origin""] url = {mainWorkingDir.Path.Replace('\\', '/')}");
208+
"local" => originRepoPath,
209+
"file" => new Uri(originRepoPath).AbsolutePath,
210+
_ => kind
211+
};
326212

327213
var repo = CreateRepository(config: new GitConfig(ImmutableDictionary.CreateRange(new[]
328214
{
329-
KVP(new GitVariableName("remote", "origin", "url"),
330-
ImmutableArray.Create(mainWorkingDir.Path)),
215+
KVP(new GitVariableName("remote", "origin", "url"), ImmutableArray.Create(url)),
331216
})));
332217

333218
var warnings = new List<(string, object?[])>();
334-
Assert.Equal(new Uri(mainWorkingDir.Path).AbsoluteUri, GitOperations.GetRepositoryUrl(repo, remoteName: null, logWarning: (message, args) => warnings.Add((message, args))));
335-
AssertEx.Equal(new[] { string.Format(Resources.RepositoryUrlEvaluationExceededMaximumAllowedDepth, "10") }, warnings.Select(TestUtilities.InspectDiagnostic));
219+
var uri = GitOperations.GetRepositoryUrl(repo, remoteName: null, warnOnMissingOrUnsupportedRemote: true, logWarning: (message, args) => warnings.Add((message, args)));
220+
Assert.Null(uri);
221+
AssertEx.Equal(new[] { string.Format(Resources.InvalidRepositoryRemoteUrl, "origin", url) }, warnings.Select(TestUtilities.InspectDiagnostic));
336222
}
337223

338224
[Theory]
@@ -468,7 +354,7 @@ public void GetSourceRoots_RepoWithCommits_WithoutUrl()
468354
commitSha: "0000000000000000000000000000000000000000");
469355

470356
var warnings = new List<(string, object?[])>();
471-
var items = GitOperations.GetSourceRoots(repo, remoteName: null, warnOnMissingCommit: true, (message, args) => warnings.Add((message, args)));
357+
var items = GitOperations.GetSourceRoots(repo, remoteName: null, warnOnMissingCommitOrUnsupportedUri: true, (message, args) => warnings.Add((message, args)));
472358

473359
AssertEx.Equal(new[]
474360
{
@@ -487,7 +373,7 @@ public void GetSourceRoots_RepoWithCommits_WithUrl()
487373
("remote.origin.url", "https://github.com/abc")));
488374

489375
var warnings = new List<(string, object?[])>();
490-
var items = GitOperations.GetSourceRoots(repo, remoteName: null, warnOnMissingCommit: true, (message, args) => warnings.Add((message, args)));
376+
var items = GitOperations.GetSourceRoots(repo, remoteName: null, warnOnMissingCommitOrUnsupportedUri: true, (message, args) => warnings.Add((message, args)));
491377

492378
AssertEx.Equal(new[]
493379
{
@@ -517,7 +403,7 @@ public void GetSourceRoots_RepoWithoutCommitsWithSubmodules()
517403
CreateSubmodule("sub6", "sub/6", "", "6666666666666666666666666666666666666666")));
518404

519405
var warnings = new List<(string, object?[])>();
520-
var items = GitOperations.GetSourceRoots(repo, remoteName: null, warnOnMissingCommit: false, (message, args) => warnings.Add((message, args)));
406+
var items = GitOperations.GetSourceRoots(repo, remoteName: null, warnOnMissingCommitOrUnsupportedUri: false, (message, args) => warnings.Add((message, args)));
521407

522408
// Module without a configuration entry is not initialized.
523409
// URLs listed in .submodules are ignored (they are used by git submodule initialize to generate URLs stored in config).
@@ -567,8 +453,9 @@ public void GetSourceRoots_RepoWithCommitsWithSubmodules(bool warnOnMissingCommi
567453
}
568454
}
569455

570-
[Fact]
571-
public void GetSourceRoots_RelativeSubmodulePath()
456+
[Theory]
457+
[CombinatorialData]
458+
public void GetSourceRoots_RelativeSubmodulePath(bool warnOnMissingCommitOrUnsupportedUri)
572459
{
573460
using var temp = new TempRoot();
574461

@@ -586,20 +473,32 @@ public void GetSourceRoots_RelativeSubmodulePath()
586473
workingDir: repoDir.Path,
587474
commitSha: "0000000000000000000000000000000000000000",
588475
config: CreateConfig(
589-
("submodule.1.url", "../1")),
476+
("submodule.1.url", "../1"),
477+
("submodule.2.url", "xyz://a/b")),
590478
submodules: ImmutableArray.Create(
591-
CreateSubmodule("1", "sub/1", "---", "1111111111111111111111111111111111111111", containingRepositoryWorkingDir: repoDir.Path)));
479+
CreateSubmodule("1", "sub/1", "---", "1111111111111111111111111111111111111111", containingRepositoryWorkingDir: repoDir.Path),
480+
CreateSubmodule("2", "sub/2", "---", "2222222222222222222222222222222222222222", containingRepositoryWorkingDir: repoDir.Path)));
592481

593482
var warnings = new List<(string, object?[])>();
594-
var items = GitOperations.GetSourceRoots(repo, remoteName: null, warnOnMissingCommit: false, (message, args) => warnings.Add((message, args)));
483+
var items = GitOperations.GetSourceRoots(repo, remoteName: null, warnOnMissingCommitOrUnsupportedUri, (message, args) => warnings.Add((message, args)));
595484

596485
AssertEx.Equal(new[]
597486
{
598-
$@"'{repoDir.Path}{s}' SourceControl='git' RevisionId='0000000000000000000000000000000000000000'",
599-
$@"'{repoDir.Path}{s}sub{s}1{s}' SourceControl='git' RevisionId='1111111111111111111111111111111111111111' NestedRoot='sub/1/' ContainingRoot='{repoDir.Path}{s}' ScmRepositoryUrl='https://github.com/repo1'",
487+
$@"'{repoDir.Path}{s}' SourceControl='git' RevisionId='0000000000000000000000000000000000000000'"
600488
}, items.Select(TestUtilities.InspectSourceRoot));
601489

602-
Assert.Empty(warnings);
490+
if (warnOnMissingCommitOrUnsupportedUri)
491+
{
492+
AssertEx.Equal(new[]
493+
{
494+
string.Format(Resources.SourceCodeWontBeAvailableViaSourceLink, string.Format(Resources.InvalidSubmoduleUrl, "1", "../1")),
495+
string.Format(Resources.SourceCodeWontBeAvailableViaSourceLink, string.Format(Resources.InvalidSubmoduleUrl, "2", "xyz://a/b"))
496+
}, warnings.Select(TestUtilities.InspectDiagnostic));
497+
}
498+
else
499+
{
500+
Assert.Empty(warnings);
501+
}
603502
}
604503

605504
private static GitOperations.DirectoryNode CreateNode(string name, string? submoduleWorkingDirectory, List<GitOperations.DirectoryNode>? children = null)

0 commit comments

Comments
 (0)