Skip to content

Commit

Permalink
Added support for gitea (#674)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mik4sa committed Jan 5, 2021
1 parent edbee72 commit 64beae3
Show file tree
Hide file tree
Showing 24 changed files with 862 additions and 0 deletions.
12 changes: 12 additions & 0 deletions SourceLink.sln
Expand Up @@ -64,6 +64,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.SourceLink.Tools.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.SourceLink.Tools.UnitTests", "src\SourceLink.Tools.UnitTests\Microsoft.SourceLink.Tools.UnitTests.csproj", "{99D113A9-24EC-471D-9F74-D2AC2F16220B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.SourceLink.Gitea", "src\SourceLink.Gitea\Microsoft.SourceLink.Gitea.csproj", "{C16867BE-053E-4AD3-9867-3352658FC56C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.SourceLink.Gitea.UnitTests", "src\SourceLink.Gitea.UnitTests\Microsoft.SourceLink.Gitea.UnitTests.csproj", "{04C95AC8-E3A4-4A2B-94E6-4C62E910FD8A}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\SourceLink.Tools\Microsoft.SourceLink.Tools.projitems*{5df76cc2-5f0e-45a6-ad56-6bbbccbc1a78}*SharedItemsImports = 13
Expand Down Expand Up @@ -166,6 +170,14 @@ Global
{99D113A9-24EC-471D-9F74-D2AC2F16220B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{99D113A9-24EC-471D-9F74-D2AC2F16220B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{99D113A9-24EC-471D-9F74-D2AC2F16220B}.Release|Any CPU.Build.0 = Release|Any CPU
{C16867BE-053E-4AD3-9867-3352658FC56C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C16867BE-053E-4AD3-9867-3352658FC56C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C16867BE-053E-4AD3-9867-3352658FC56C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C16867BE-053E-4AD3-9867-3352658FC56C}.Release|Any CPU.Build.0 = Release|Any CPU
{04C95AC8-E3A4-4A2B-94E6-4C62E910FD8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{04C95AC8-E3A4-4A2B-94E6-4C62E910FD8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{04C95AC8-E3A4-4A2B-94E6-4C62E910FD8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{04C95AC8-E3A4-4A2B-94E6-4C62E910FD8A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
168 changes: 168 additions & 0 deletions src/SourceLink.Git.IntegrationTests/GiteaTests.cs
@@ -0,0 +1,168 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.IO;
using TestUtilities;

namespace Microsoft.SourceLink.IntegrationTests
{
public class GiteaTests : DotNetSdkTestBase
{
public GiteaTests()
: base("Microsoft.SourceLink.Gitea")
{
}

[ConditionalFact(typeof(DotNetSdkAvailable))]
public void FullValidation_Https()
{
// Test non-ascii characters and escapes in the URL.
// Escaped URI reserved characters should remain escaped, non-reserved characters unescaped in the results.
var repoUrl = "https://噸.com/test-org/test-%72epo\u1234%24%2572%2F";
var repoName = "test-repo\u1234%24%2572%2F";

var repo = GitUtilities.CreateGitRepositoryWithSingleCommit(ProjectDir.Path, new[] { ProjectFileName }, repoUrl);
var commitSha = repo.Head.Tip.Sha;

VerifyValues(
customProps: @"
<PropertyGroup>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
</PropertyGroup>
<ItemGroup>
<SourceLinkGiteaHost Include='噸.com'/>
</ItemGroup>
",
customTargets: "",
targets: new[]
{
"Build", "Pack"
},
expressions: new[]
{
"@(SourceRoot)",
"@(SourceRoot->'%(SourceLinkUrl)')",
"$(SourceLink)",
"$(PrivateRepositoryUrl)",
"$(RepositoryUrl)"
},
expectedResults: new[]
{
NuGetPackageFolders,
ProjectSourceRoot,
$"https://噸.com/test-org/{repoName}/raw/commit/{commitSha}/*",
s_relativeSourceLinkJsonPath,
$"https://噸.com/test-org/{repoName}",
$"https://噸.com/test-org/{repoName}"
});

AssertEx.AreEqual(
$@"{{""documents"":{{""{ProjectSourceRoot.Replace(@"\", @"\\")}*"":""https://噸.com/test-org/{repoName}/raw/commit/{commitSha}/*""}}}}",
File.ReadAllText(Path.Combine(ProjectDir.Path, s_relativeSourceLinkJsonPath)));

TestUtilities.ValidateAssemblyInformationalVersion(
Path.Combine(ProjectDir.Path, s_relativeOutputFilePath),
"1.0.0+" + commitSha);

TestUtilities.ValidateNuSpecRepository(
Path.Combine(ProjectDir.Path, s_relativePackagePath),
type: "git",
commit: commitSha,
url: $"https://噸.com/test-org/{repoName}");
}

[ConditionalFact(typeof(DotNetSdkAvailable))]
public void FullValidation_Ssh()
{
// Test non-ascii characters and escapes in the URL.
// Escaped URI reserved characters should remain escaped, non-reserved characters unescaped in the results.
var repoUrl = "test-user@噸.com:test-org/test-%72epo\u1234%24%2572%2F";
var repoName = "test-repo\u1234%24%2572%2F";

var repo = GitUtilities.CreateGitRepositoryWithSingleCommit(ProjectDir.Path, new[] { ProjectFileName }, repoUrl);
var commitSha = repo.Head.Tip.Sha;

VerifyValues(
customProps: @"
<PropertyGroup>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
</PropertyGroup>
<ItemGroup>
<SourceLinkGiteaHost Include='噸.com'/>
</ItemGroup>
",
customTargets: "",
targets: new[]
{
"Build", "Pack"
},
expressions: new[]
{
"@(SourceRoot)",
"@(SourceRoot->'%(SourceLinkUrl)')",
"$(SourceLink)",
"$(PrivateRepositoryUrl)",
"$(RepositoryUrl)"
},
expectedResults: new[]
{
NuGetPackageFolders,
ProjectSourceRoot,
$"https://噸.com/test-org/{repoName}/raw/commit/{commitSha}/*",
s_relativeSourceLinkJsonPath,
$"https://噸.com/test-org/{repoName}",
$"https://噸.com/test-org/{repoName}"
});

AssertEx.AreEqual(
$@"{{""documents"":{{""{ProjectSourceRoot.Replace(@"\", @"\\")}*"":""https://噸.com/test-org/{repoName}/raw/commit/{commitSha}/*""}}}}",
File.ReadAllText(Path.Combine(ProjectDir.Path, s_relativeSourceLinkJsonPath)));

TestUtilities.ValidateAssemblyInformationalVersion(
Path.Combine(ProjectDir.Path, s_relativeOutputFilePath),
"1.0.0+" + commitSha);

TestUtilities.ValidateNuSpecRepository(
Path.Combine(ProjectDir.Path, s_relativePackagePath),
type: "git",
commit: commitSha,
url: $"https://噸.com/test-org/{repoName}");
}


[ConditionalFact(typeof(DotNetSdkAvailable))]
public void ImplicitHost()
{
// Test non-ascii characters and escapes in the URL.
// Escaped URI reserved characters should remain escaped, non-reserved characters unescaped in the results.
var repoUrl = "http://噸.com/test-org/test-%72epo\u1234%24%2572%2F";
var repoName = "test-repo\u1234%24%2572%2F";

var repo = GitUtilities.CreateGitRepositoryWithSingleCommit(ProjectDir.Path, new[] { ProjectFileName }, repoUrl);
var commitSha = repo.Head.Tip.Sha;

VerifyValues(
customProps: @"
<PropertyGroup>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
</PropertyGroup>
",
customTargets: "",
targets: new[]
{
"Build", "Pack"
},
expressions: new[]
{
"@(SourceRoot->'%(SourceLinkUrl)')",
"$(PrivateRepositoryUrl)",
"$(RepositoryUrl)"
},
expectedResults: new[]
{
$"http://噸.com/test-org/{repoName}/raw/commit/{commitSha}/*",
$"http://噸.com/test-org/{repoName}",
$"http://噸.com/test-org/{repoName}"
});
}
}
}
55 changes: 55 additions & 0 deletions src/SourceLink.Gitea.UnitTests/GetSourceLinkUrlTests.cs
@@ -0,0 +1,55 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Build.Tasks.SourceControl;
using TestUtilities;
using Xunit;
using static TestUtilities.KeyValuePairUtils;

namespace Microsoft.SourceLink.Gitea.UnitTests
{
public class GetSourceLinkUrlTests
{
[Fact]
public void EmptyHosts()
{
var engine = new MockEngine();

var task = new GetSourceLinkUrl()
{
BuildEngine = engine,
SourceRoot = new MockItem("x", KVP("RepositoryUrl", "http://abc.com"), KVP("SourceControl", "git")),
};

bool result = task.Execute();

AssertEx.AssertEqualToleratingWhitespaceDifferences(
"ERROR : " + string.Format(CommonResources.AtLeastOneRepositoryHostIsRequired, "SourceLinkGiteaHost", "Gitea"), engine.Log);

Assert.False(result);
}

[Theory]
[InlineData("", "")]
[InlineData("", "/")]
[InlineData("/", "")]
[InlineData("/", "/")]
public void BuildSourceLinkUrl(string s1, string s2)
{
var engine = new MockEngine();

var task = new GetSourceLinkUrl()
{
BuildEngine = engine,
SourceRoot = new MockItem("/src/", KVP("RepositoryUrl", "http://subdomain.mygitea.com:100/a/b" + s1), KVP("SourceControl", "git"), KVP("RevisionId", "0123456789abcdefABCDEF000000000000000000")),
Hosts = new[]
{
new MockItem("mygitea.com", KVP("ContentUrl", "https://domain.com/x/y" + s2)),
}
};

bool result = task.Execute();
AssertEx.AssertEqualToleratingWhitespaceDifferences("", engine.Log);
AssertEx.AreEqual("https://domain.com/x/y/a/b/raw/commit/0123456789abcdefABCDEF000000000000000000/*", task.SourceLinkUrl);
Assert.True(result);
}
}
}
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472;net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SourceLink.Gitea\Microsoft.SourceLink.Gitea.csproj" />
<ProjectReference Include="..\TestUtilities\TestUtilities.csproj" />
</ItemGroup>
</Project>
50 changes: 50 additions & 0 deletions src/SourceLink.Gitea.UnitTests/TranslateRepositoryUrlsTests.cs
@@ -0,0 +1,50 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Linq;
using TestUtilities;
using Xunit;
using static TestUtilities.KeyValuePairUtils;

namespace Microsoft.SourceLink.Gitea.UnitTests
{
public class TranslateRepositoryUrlsTests
{
[Fact]
public void Translate()
{
var engine = new MockEngine();

var task = new TranslateRepositoryUrls()
{
BuildEngine = engine,
RepositoryUrl = "ssh://gitea.com/a/b",
IsSingleProvider = true,
SourceRoots = new[]
{
new MockItem("/1/", KVP("SourceControl", "git"), KVP("ScmRepositoryUrl", "ssh://gitea.com:22/a/b")),
new MockItem("/2/", KVP("SourceControl", "tfvc"), KVP("ScmRepositoryUrl", "ssh://gitea1.com/a/b")),
new MockItem("/2/", KVP("SourceControl", "git"), KVP("ScmRepositoryUrl", "ssh://gitea1.com/a/b")),
new MockItem("/2/", KVP("SourceControl", "tfvc"), KVP("ScmRepositoryUrl", "ssh://gitea2.com/a/b")),
},
Hosts = new[]
{
new MockItem("gitea1.com")
}
};

bool result = task.Execute();
AssertEx.AssertEqualToleratingWhitespaceDifferences("", engine.Log);

AssertEx.AreEqual("https://gitea.com/a/b", task.TranslatedRepositoryUrl);

AssertEx.Equal(new[]
{
"https://gitea.com/a/b",
"ssh://gitea1.com/a/b",
"https://gitea1.com/a/b",
"ssh://gitea2.com/a/b"
}, task.TranslatedSourceRoots?.Select(r => r.GetMetadata("ScmRepositoryUrl")));

Assert.True(result);
}
}
}
22 changes: 22 additions & 0 deletions src/SourceLink.Gitea/GetSourceLinkUrl.cs
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using Microsoft.Build.Framework;
using Microsoft.Build.Tasks.SourceControl;

namespace Microsoft.SourceLink.Gitea
{
/// <summary>
/// The task calculates SourceLink URL for a given SourceRoot.
/// If the SourceRoot is associated with a git repository with a recognized domain the <see cref="SourceLinkUrl"/>
/// output property is set to the content URL corresponding to the domain, otherwise it is set to string "N/A".
/// </summary>
public sealed class GetSourceLinkUrl : GetSourceLinkUrlGitTask
{
protected override string HostsItemGroupName => "SourceLinkGiteaHost";
protected override string ProviderDisplayName => "Gitea";

protected override string? BuildSourceLinkUrl(Uri contentUri, Uri gitUri, string relativeUrl, string revisionId, ITaskItem? hostItem)
=> UriUtilities.Combine(UriUtilities.Combine(contentUri.ToString(), relativeUrl), "raw/commit/" + revisionId + "/*");
}
}
33 changes: 33 additions & 0 deletions src/SourceLink.Gitea/Microsoft.SourceLink.Gitea.csproj
@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472;net5.0</TargetFrameworks>
<AutoGenerateAssemblyVersion>true</AutoGenerateAssemblyVersion>

<!-- Using an explicit nuspec file due to https://github.com/NuGet/Home/issues/6754 -->
<IsPackable>true</IsPackable>
<NuspecFile>$(MSBuildProjectName).nuspec</NuspecFile>
<NuspecBasePath>$(OutputPath)</NuspecBasePath>

<PackageDescription>Generates source link for Gitea repositories.</PackageDescription>
<PackageTags>MSBuild Tasks Gitea source link</PackageTags>
<DevelopmentDependency>true</DevelopmentDependency>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Common\NullableAttributes.cs" Link="Common\NullableAttributes.cs" />
<Compile Include="..\Common\Names.cs" Link="Common\Names.cs" />
<Compile Include="..\Common\GetSourceLinkUrlGitTask.cs" Link="Common\GetSourceLinkUrlGitTask.cs" />
<Compile Include="..\Common\TranslateRepositoryUrlGitTask.cs" Link="Common\TranslateRepositoryUrlGitTask.cs" />
<Compile Include="..\Common\UriUtilities.cs" Link="Common\UriUtilities.cs" />
<EmbeddedResource Include="..\Common\CommonResources.resx" Link="Common\CommonResources.resx">
<Namespace>Microsoft.Build.Tasks.SourceControl</Namespace>
<GenerateSource>true</GenerateSource>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="$(MicrosoftBuildVersion)" />
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="$(MicrosoftBuildTasksCore)" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="Microsoft.SourceLink.Gitea.UnitTests" />
</ItemGroup>
</Project>
17 changes: 17 additions & 0 deletions src/SourceLink.Gitea/Microsoft.SourceLink.Gitea.nuspec
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
$CommonMetadataElements$
<dependencies>
<dependency id="Microsoft.SourceLink.Common" version="$Version$" />
<dependency id="Microsoft.Build.Tasks.Git" version="$Version$" />
</dependencies>
</metadata>
<files>
$CommonFileElements$
<file src="**\Microsoft.SourceLink.Gitea.*" target="tools" />

<file src="$ProjectDirectory$\build\*.*" target="build" />
<file src="$ProjectDirectory$\buildMultiTargeting\*.*" target="buildMultiTargeting" />
</files>
</package>
10 changes: 10 additions & 0 deletions src/SourceLink.Gitea/TranslateRepositoryUrls.cs
@@ -0,0 +1,10 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.Build.Tasks.SourceControl;

namespace Microsoft.SourceLink.Gitea
{
public sealed class TranslateRepositoryUrls : TranslateRepositoryUrlsGitTask
{
}
}

0 comments on commit 64beae3

Please sign in to comment.