diff --git a/src/SourceLink.GitLab.UnitTests/GetSourceLinkUrlTests.cs b/src/SourceLink.GitLab.UnitTests/GetSourceLinkUrlTests.cs index e412a6b8..1ef882ed 100644 --- a/src/SourceLink.GitLab.UnitTests/GetSourceLinkUrlTests.cs +++ b/src/SourceLink.GitLab.UnitTests/GetSourceLinkUrlTests.cs @@ -30,11 +30,15 @@ public void EmptyHosts() } [Theory] - [InlineData("", "")] - [InlineData("", "/")] - [InlineData("/", "")] - [InlineData("/", "/")] - public void BuildSourceLinkUrl(string s1, string s2) + [InlineData("", "", null)] + [InlineData("", "/", null)] + [InlineData("/", "", null)] + [InlineData("/", "/", null)] + [InlineData("", "", "12.0")] + [InlineData("", "/", "12.0")] + [InlineData("/", "", "12.0")] + [InlineData("/", "/", "12.0")] + public void BuildSourceLinkUrl(string s1, string s2, string version) { var engine = new MockEngine(); @@ -44,7 +48,33 @@ public void BuildSourceLinkUrl(string s1, string s2) SourceRoot = new MockItem("/src/", KVP("RepositoryUrl", "http://subdomain.mygitlab.com:100/a/b" + s1), KVP("SourceControl", "git"), KVP("RevisionId", "0123456789abcdefABCDEF000000000000000000")), Hosts = new[] { - new MockItem("mygitlab.com", KVP("ContentUrl", "https://domain.com/x/y" + s2)), + version == null + ? new MockItem("mygitlab.com", KVP("ContentUrl", "https://domain.com/x/y" + s2)) + : new MockItem("mygitlab.com", KVP("ContentUrl", "https://domain.com/x/y" + s2), KVP("Version", version)), + } + }; + + bool result = task.Execute(); + AssertEx.AssertEqualToleratingWhitespaceDifferences("", engine.Log); + AssertEx.AreEqual("https://domain.com/x/y/a/b/-/raw/0123456789abcdefABCDEF000000000000000000/*", task.SourceLinkUrl); + Assert.True(result); + } + + [Theory] + [InlineData("", "/", "11.0")] + [InlineData("/", "", "11.0")] + [InlineData("/", "/", "11.0")] + public void BuildSourceLinkUrl_DeprecatedVersion(string s1, string s2, string version) + { + var engine = new MockEngine(); + + var task = new GetSourceLinkUrl() + { + BuildEngine = engine, + SourceRoot = new MockItem("/src/", KVP("RepositoryUrl", "http://subdomain.mygitlab.com:100/a/b" + s1), KVP("SourceControl", "git"), KVP("RevisionId", "0123456789abcdefABCDEF000000000000000000")), + Hosts = new[] + { + new MockItem("mygitlab.com", KVP("ContentUrl", "https://domain.com/x/y" + s2), KVP("Version", version)), } }; diff --git a/src/SourceLink.GitLab/GetSourceLinkUrl.cs b/src/SourceLink.GitLab/GetSourceLinkUrl.cs index 5c2f6d5a..33325efe 100644 --- a/src/SourceLink.GitLab/GetSourceLinkUrl.cs +++ b/src/SourceLink.GitLab/GetSourceLinkUrl.cs @@ -18,7 +18,33 @@ public sealed class GetSourceLinkUrl : GetSourceLinkUrlGitTask protected override string HostsItemGroupName => "SourceLinkGitLabHost"; protected override string ProviderDisplayName => "GitLab"; + private const string VersionMetadataName = "Version"; + + // see https://gitlab.com/gitlab-org/gitlab/-/issues/28848 + private static readonly Version s_versionWithNewUrlFormat = new Version(12, 0); + protected override string? BuildSourceLinkUrl(Uri contentUri, Uri gitUri, string relativeUrl, string revisionId, ITaskItem? hostItem) - => UriUtilities.Combine(UriUtilities.Combine(contentUri.ToString(), relativeUrl), "raw/" + revisionId + "/*"); + { + var path = GetVersion(hostItem) >= s_versionWithNewUrlFormat + ? "-/raw/" + revisionId + "/*" + : "raw/" + revisionId + "/*"; + return UriUtilities.Combine(UriUtilities.Combine(contentUri.ToString(), relativeUrl), path); + } + + private Version GetVersion(ITaskItem? hostItem) + { + var versionAsString = hostItem?.GetMetadata(VersionMetadataName); + if (!NullableString.IsNullOrEmpty(versionAsString)) + { + if (Version.TryParse(versionAsString, out var version)) + { + return version; + } + + Log.LogError(CommonResources.ItemOfItemGroupMustSpecifyMetadata, hostItem!.ItemSpec, HostsItemGroupName, VersionMetadataName); + } + + return s_versionWithNewUrlFormat; + } } }