diff --git a/src/Common/GetSourceLinkUrlGitTask.cs b/src/Common/GetSourceLinkUrlGitTask.cs index ee476428..72a9b5f4 100644 --- a/src/Common/GetSourceLinkUrlGitTask.cs +++ b/src/Common/GetSourceLinkUrlGitTask.cs @@ -103,7 +103,7 @@ private void ExecuteImpl() return; } - bool IsHexDigit(char c) + static bool IsHexDigit(char c) => c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F'; string revisionId = SourceRoot.GetMetadata(Names.SourceRoot.RevisionId); @@ -149,8 +149,8 @@ public UrlMapping(string host, ITaskItem hostItem, int port, Uri contentUri, boo private IEnumerable GetUrlMappings(Uri gitUri) { - bool isValidContentUri(Uri uri) - => uri.Query == "" && uri.UserInfo == ""; + static bool isValidContentUri(Uri uri) + => uri.GetHost() != "" && uri.Query == "" && uri.UserInfo == ""; if (Hosts != null) { @@ -186,7 +186,16 @@ bool isValidContentUri(Uri uri) { if (Uri.TryCreate(RepositoryUrl, UriKind.Absolute, out var uri)) { - yield return new UrlMapping(uri.GetHost(), hostItem: null, uri.GetExplicitPort(), GetDefaultContentUriFromRepositoryUri(uri), hasDefaultContentUri: true); + // If the URL is a local path the host will be empty. + var host = uri.GetHost(); + if (host != "") + { + yield return new UrlMapping(host, hostItem: null, uri.GetExplicitPort(), GetDefaultContentUriFromRepositoryUri(uri), hasDefaultContentUri: true); + } + else + { + Log.LogError(CommonResources.ValuePassedToTaskParameterNotValidHostUri, nameof(RepositoryUrl), RepositoryUrl); + } } else { diff --git a/src/Microsoft.Build.Tasks.Git/GitOperations.cs b/src/Microsoft.Build.Tasks.Git/GitOperations.cs index 6726a911..4bb58dba 100644 --- a/src/Microsoft.Build.Tasks.Git/GitOperations.cs +++ b/src/Microsoft.Build.Tasks.Git/GitOperations.cs @@ -15,7 +15,9 @@ internal static class GitOperations { private const string SourceControlName = "git"; private const string RemoteSectionName = "remote"; + private const string RemoteOriginName = "origin"; private const string UrlSectionName = "url"; + private const string UrlVariableName = "url"; public static string GetRepositoryUrl(GitRepository repository, string remoteName, Action logWarning = null) { @@ -23,7 +25,7 @@ public static string GetRepositoryUrl(GitRepository repository, string remoteNam string remoteUrl = null; if (!string.IsNullOrEmpty(remoteName)) { - remoteUrl = repository.Config.GetVariableValue(RemoteSectionName, remoteName, "url"); + remoteUrl = repository.Config.GetVariableValue(RemoteSectionName, remoteName, UrlVariableName); if (remoteUrl == null) { unknownRemoteName = remoteName; @@ -52,15 +54,15 @@ public static string GetRepositoryUrl(GitRepository repository, string remoteNam private static bool TryGetRemote(GitConfig config, out string remoteName, out string remoteUrl) { - remoteName = "origin"; - remoteUrl = config.GetVariableValue(RemoteSectionName, remoteName, "url"); + remoteName = RemoteOriginName; + remoteUrl = config.GetVariableValue(RemoteSectionName, remoteName, UrlVariableName); if (remoteUrl != null) { return true; } var remoteVariable = config.Variables. - Where(kvp => kvp.Key.SectionNameEquals(RemoteSectionName)). + Where(kvp => kvp.Key.SectionNameEquals(RemoteSectionName) && kvp.Key.VariableNameEquals(UrlVariableName)). OrderBy(kvp => kvp.Key.SubsectionName, GitVariableName.SubsectionNameComparer). FirstOrDefault(); diff --git a/src/Microsoft.Build.Tasks.Git/RepositoryTask.cs b/src/Microsoft.Build.Tasks.Git/RepositoryTask.cs index bbcd75f6..fc6ad8ca 100644 --- a/src/Microsoft.Build.Tasks.Git/RepositoryTask.cs +++ b/src/Microsoft.Build.Tasks.Git/RepositoryTask.cs @@ -94,8 +94,7 @@ private GitRepository GetOrCreateRepositoryInstance() var initialPath = GetInitialPath(); - GitRepositoryLocation location; - if (!GitRepository.TryFindRepository(initialPath, out location)) + if (!GitRepository.TryFindRepository(initialPath, out var location)) { Log.LogWarning(Resources.UnableToLocateRepository, initialPath); return null; diff --git a/src/SourceLink.Common.UnitTests/GetSourceLinkUrlTests.cs b/src/SourceLink.Common.UnitTests/GetSourceLinkUrlTests.cs index 98913b6c..96a7dfc5 100644 --- a/src/SourceLink.Common.UnitTests/GetSourceLinkUrlTests.cs +++ b/src/SourceLink.Common.UnitTests/GetSourceLinkUrlTests.cs @@ -14,6 +14,7 @@ public class GetSourceLinkUrlTests [InlineData("contoso.com/a?x=2")] [InlineData("contoso.com/x")] [InlineData("a@contoso.com")] + [InlineData("file:///D:/contoso")] [InlineData("http://contoso.com")] [InlineData("http://contoso.com/a")] [InlineData("http://a@contoso.com")] @@ -60,6 +61,28 @@ public void ImplicitHost_Errors(string repositoryUrl) Assert.False(result); } + [Theory] + [InlineData("file:///D:/a/b")] + public void ImplicitHost_Local(string repositoryUrl) + { + var engine = new MockEngine(); + + var task = new MockGetSourceLinkUrlGitTask() + { + BuildEngine = engine, + SourceRoot = new MockItem("x", KVP("RepositoryUrl", "http://abc.com"), KVP("SourceControl", "git")), + RepositoryUrl = repositoryUrl, + IsSingleProvider = true, + }; + + bool result = task.Execute(); + + AssertEx.AssertEqualToleratingWhitespaceDifferences( + "ERROR : " + string.Format(CommonResources.ValuePassedToTaskParameterNotValidHostUri, "RepositoryUrl", repositoryUrl), engine.Log); + + Assert.False(result); + } + [Theory] [InlineData("contoso.com")] [InlineData("contoso.com/a")]