From 93bb565b655080a6f5a5fbf222fdb63da09a61c7 Mon Sep 17 00:00:00 2001 From: Kai Leonhardt <8343141+Mik4sa@users.noreply.github.com> Date: Wed, 18 Nov 2020 13:42:15 +0100 Subject: [PATCH] Added support for gitea --- SourceLink.sln | 12 ++ .../GiteaTests.cs | 168 ++++++++++++++++++ .../GetSourceLinkUrlTests.cs | 55 ++++++ ...icrosoft.SourceLink.Gitea.UnitTests.csproj | 9 + .../TranslateRepositoryUrlsTests.cs | 50 ++++++ src/SourceLink.Gitea/GetSourceLinkUrl.cs | 22 +++ .../Microsoft.SourceLink.Gitea.csproj | 33 ++++ .../Microsoft.SourceLink.Gitea.nuspec | 17 ++ .../TranslateRepositoryUrls.cs | 10 ++ .../build/Microsoft.SourceLink.Gitea.targets | 66 +++++++ .../Microsoft.SourceLink.Gitea.targets | 4 + src/SourceLink.Gitea/xlf/Resources.cs.xlf | 32 ++++ src/SourceLink.Gitea/xlf/Resources.de.xlf | 32 ++++ src/SourceLink.Gitea/xlf/Resources.es.xlf | 32 ++++ src/SourceLink.Gitea/xlf/Resources.fr.xlf | 32 ++++ src/SourceLink.Gitea/xlf/Resources.it.xlf | 32 ++++ src/SourceLink.Gitea/xlf/Resources.ja.xlf | 32 ++++ src/SourceLink.Gitea/xlf/Resources.ko.xlf | 32 ++++ src/SourceLink.Gitea/xlf/Resources.pl.xlf | 32 ++++ src/SourceLink.Gitea/xlf/Resources.pt-BR.xlf | 32 ++++ src/SourceLink.Gitea/xlf/Resources.ru.xlf | 32 ++++ src/SourceLink.Gitea/xlf/Resources.tr.xlf | 32 ++++ .../xlf/Resources.zh-Hans.xlf | 32 ++++ .../xlf/Resources.zh-Hant.xlf | 32 ++++ 24 files changed, 862 insertions(+) create mode 100644 src/SourceLink.Git.IntegrationTests/GiteaTests.cs create mode 100644 src/SourceLink.Gitea.UnitTests/GetSourceLinkUrlTests.cs create mode 100644 src/SourceLink.Gitea.UnitTests/Microsoft.SourceLink.Gitea.UnitTests.csproj create mode 100644 src/SourceLink.Gitea.UnitTests/TranslateRepositoryUrlsTests.cs create mode 100644 src/SourceLink.Gitea/GetSourceLinkUrl.cs create mode 100644 src/SourceLink.Gitea/Microsoft.SourceLink.Gitea.csproj create mode 100644 src/SourceLink.Gitea/Microsoft.SourceLink.Gitea.nuspec create mode 100644 src/SourceLink.Gitea/TranslateRepositoryUrls.cs create mode 100644 src/SourceLink.Gitea/build/Microsoft.SourceLink.Gitea.targets create mode 100644 src/SourceLink.Gitea/buildMultiTargeting/Microsoft.SourceLink.Gitea.targets create mode 100644 src/SourceLink.Gitea/xlf/Resources.cs.xlf create mode 100644 src/SourceLink.Gitea/xlf/Resources.de.xlf create mode 100644 src/SourceLink.Gitea/xlf/Resources.es.xlf create mode 100644 src/SourceLink.Gitea/xlf/Resources.fr.xlf create mode 100644 src/SourceLink.Gitea/xlf/Resources.it.xlf create mode 100644 src/SourceLink.Gitea/xlf/Resources.ja.xlf create mode 100644 src/SourceLink.Gitea/xlf/Resources.ko.xlf create mode 100644 src/SourceLink.Gitea/xlf/Resources.pl.xlf create mode 100644 src/SourceLink.Gitea/xlf/Resources.pt-BR.xlf create mode 100644 src/SourceLink.Gitea/xlf/Resources.ru.xlf create mode 100644 src/SourceLink.Gitea/xlf/Resources.tr.xlf create mode 100644 src/SourceLink.Gitea/xlf/Resources.zh-Hans.xlf create mode 100644 src/SourceLink.Gitea/xlf/Resources.zh-Hant.xlf diff --git a/SourceLink.sln b/SourceLink.sln index 39b64cbd..49104dbd 100644 --- a/SourceLink.sln +++ b/SourceLink.sln @@ -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 @@ -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 diff --git a/src/SourceLink.Git.IntegrationTests/GiteaTests.cs b/src/SourceLink.Git.IntegrationTests/GiteaTests.cs new file mode 100644 index 00000000..d0c06e9c --- /dev/null +++ b/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: @" + + true + + + + +", + 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: @" + + true + + + + +", + 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: @" + + true + +", + 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}" + }); + } + } +} diff --git a/src/SourceLink.Gitea.UnitTests/GetSourceLinkUrlTests.cs b/src/SourceLink.Gitea.UnitTests/GetSourceLinkUrlTests.cs new file mode 100644 index 00000000..06e75407 --- /dev/null +++ b/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); + } + } +} diff --git a/src/SourceLink.Gitea.UnitTests/Microsoft.SourceLink.Gitea.UnitTests.csproj b/src/SourceLink.Gitea.UnitTests/Microsoft.SourceLink.Gitea.UnitTests.csproj new file mode 100644 index 00000000..12bdc2d6 --- /dev/null +++ b/src/SourceLink.Gitea.UnitTests/Microsoft.SourceLink.Gitea.UnitTests.csproj @@ -0,0 +1,9 @@ + + + net472;net5.0 + + + + + + diff --git a/src/SourceLink.Gitea.UnitTests/TranslateRepositoryUrlsTests.cs b/src/SourceLink.Gitea.UnitTests/TranslateRepositoryUrlsTests.cs new file mode 100644 index 00000000..3949583d --- /dev/null +++ b/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); + } + } +} diff --git a/src/SourceLink.Gitea/GetSourceLinkUrl.cs b/src/SourceLink.Gitea/GetSourceLinkUrl.cs new file mode 100644 index 00000000..5d5526e7 --- /dev/null +++ b/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 +{ + /// + /// The task calculates SourceLink URL for a given SourceRoot. + /// If the SourceRoot is associated with a git repository with a recognized domain the + /// output property is set to the content URL corresponding to the domain, otherwise it is set to string "N/A". + /// + 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 + "/*"); + } +} diff --git a/src/SourceLink.Gitea/Microsoft.SourceLink.Gitea.csproj b/src/SourceLink.Gitea/Microsoft.SourceLink.Gitea.csproj new file mode 100644 index 00000000..b5bbc93d --- /dev/null +++ b/src/SourceLink.Gitea/Microsoft.SourceLink.Gitea.csproj @@ -0,0 +1,33 @@ + + + net472;net5.0 + true + + + true + $(MSBuildProjectName).nuspec + $(OutputPath) + + Generates source link for Gitea repositories. + MSBuild Tasks Gitea source link + true + + + + + + + + + Microsoft.Build.Tasks.SourceControl + true + + + + + + + + + + diff --git a/src/SourceLink.Gitea/Microsoft.SourceLink.Gitea.nuspec b/src/SourceLink.Gitea/Microsoft.SourceLink.Gitea.nuspec new file mode 100644 index 00000000..a4c7ff74 --- /dev/null +++ b/src/SourceLink.Gitea/Microsoft.SourceLink.Gitea.nuspec @@ -0,0 +1,17 @@ + + + + $CommonMetadataElements$ + + + + + + + $CommonFileElements$ + + + + + + \ No newline at end of file diff --git a/src/SourceLink.Gitea/TranslateRepositoryUrls.cs b/src/SourceLink.Gitea/TranslateRepositoryUrls.cs new file mode 100644 index 00000000..1bc949a7 --- /dev/null +++ b/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 + { + } +} diff --git a/src/SourceLink.Gitea/build/Microsoft.SourceLink.Gitea.targets b/src/SourceLink.Gitea/build/Microsoft.SourceLink.Gitea.targets new file mode 100644 index 00000000..5b6765e5 --- /dev/null +++ b/src/SourceLink.Gitea/build/Microsoft.SourceLink.Gitea.targets @@ -0,0 +1,66 @@ + + + + <_SourceLinkGiteaAssemblyFile Condition="'$(MSBuildRuntimeType)' != 'Core'">$(MSBuildThisFileDirectory)..\tools\net472\Microsoft.SourceLink.Gitea.dll + <_SourceLinkGiteaAssemblyFile Condition="'$(MSBuildRuntimeType)' == 'Core'">$(MSBuildThisFileDirectory)..\tools\net5.0\Microsoft.SourceLink.Gitea.dll + + + + + + + $(SourceLinkUrlInitializerTargets);_InitializeGiteaSourceLinkUrl + $(SourceControlManagerUrlTranslationTargets);TranslateGiteaUrlsInSourceControlInformation + + + + + + + + + + + + + + + + + + + <_TranslatedSourceRoot Remove="@(_TranslatedSourceRoot)"/> + + + + + + + + + + + + + + diff --git a/src/SourceLink.Gitea/buildMultiTargeting/Microsoft.SourceLink.Gitea.targets b/src/SourceLink.Gitea/buildMultiTargeting/Microsoft.SourceLink.Gitea.targets new file mode 100644 index 00000000..84afbc37 --- /dev/null +++ b/src/SourceLink.Gitea/buildMultiTargeting/Microsoft.SourceLink.Gitea.targets @@ -0,0 +1,4 @@ + + + + diff --git a/src/SourceLink.Gitea/xlf/Resources.cs.xlf b/src/SourceLink.Gitea/xlf/Resources.cs.xlf new file mode 100644 index 00000000..0e6540e3 --- /dev/null +++ b/src/SourceLink.Gitea/xlf/Resources.cs.xlf @@ -0,0 +1,32 @@ + + + + + + {0} item group is empty. At least one {1} repository host is required in order to generate SourceLink. + Skupina položek {0} je prázdná. Kvůli generování zdrojového odkazu se vyžaduje alespoň jeden hostitel úložiště {1}. + + + + {0} specifies an invalid URL: '{1}' + {0} určuje neplatnou adresu URL: {1}. + + + + The value of {0} with identity '{1}' is invalid: '{2}'" + Hodnota {0} s identitou {1} je neplatná: {2}" + + + + The value of {0} with identity '{1}' is not a valid commit hash: '{2}'" + Hodnota {0} s identitou {1} není platná hodnota hash potvrzení: {2}" + + + + The value passed to task parameter {0} is not a valid host name: '{1}' + Hodnota předaná parametru úlohy {0} není platný název hostitele: {1}. + + + + + \ No newline at end of file diff --git a/src/SourceLink.Gitea/xlf/Resources.de.xlf b/src/SourceLink.Gitea/xlf/Resources.de.xlf new file mode 100644 index 00000000..dcc9a38f --- /dev/null +++ b/src/SourceLink.Gitea/xlf/Resources.de.xlf @@ -0,0 +1,32 @@ + + + + + + {0} item group is empty. At least one {1} repository host is required in order to generate SourceLink. + Die Elementgruppe "{0}" ist leer. Mindestens ein {1}-Repositoryhost wird benötigt, um SourceLink zu generieren. + + + + {0} specifies an invalid URL: '{1}' + "{0}" gibt eine ungültige URL an: {1} + + + + The value of {0} with identity '{1}' is invalid: '{2}'" + Der Wert von "{0}" mit der Identität "{1}" ist ungültig: "{2}" + + + + The value of {0} with identity '{1}' is not a valid commit hash: '{2}'" + Der Wert von "{0}" mit der Identität "{1}" ist kein gültiger Commithash: "{2}" + + + + The value passed to task parameter {0} is not a valid host name: '{1}' + Der an den Taskparameter "{0}" übergebene Wert ist kein gültiger Hostname: "{1}" + + + + + \ No newline at end of file diff --git a/src/SourceLink.Gitea/xlf/Resources.es.xlf b/src/SourceLink.Gitea/xlf/Resources.es.xlf new file mode 100644 index 00000000..17b78f7c --- /dev/null +++ b/src/SourceLink.Gitea/xlf/Resources.es.xlf @@ -0,0 +1,32 @@ + + + + + + {0} item group is empty. At least one {1} repository host is required in order to generate SourceLink. + El grupo de elementos {0} está vacío. Se requiere al menos un repositorio {1} a fin de generar SourceLink. + + + + {0} specifies an invalid URL: '{1}' + {0} especifica una dirección URL no válida: "{1}" + + + + The value of {0} with identity '{1}' is invalid: '{2}'" + El valor de {0} con identidad '{1}' no es válido '{2}'" + + + + The value of {0} with identity '{1}' is not a valid commit hash: '{2}'" + El valor de {0} con identidad '{1}' no es un hash de confirmación válido '{2}'" + + + + The value passed to task parameter {0} is not a valid host name: '{1}' + El valor pasado al parámetro de tarea {0} no es un nombre de host válido: "{1}" + + + + + \ No newline at end of file diff --git a/src/SourceLink.Gitea/xlf/Resources.fr.xlf b/src/SourceLink.Gitea/xlf/Resources.fr.xlf new file mode 100644 index 00000000..21751341 --- /dev/null +++ b/src/SourceLink.Gitea/xlf/Resources.fr.xlf @@ -0,0 +1,32 @@ + + + + + + {0} item group is empty. At least one {1} repository host is required in order to generate SourceLink. + Le groupe d'éléments {0} est vide. Au moins un hôte de dépôt {1} est nécessaire pour générer SourceLink. + + + + {0} specifies an invalid URL: '{1}' + {0} spécifie une URL non valide : '{1}' + + + + The value of {0} with identity '{1}' is invalid: '{2}'" + La valeur de {0} avec l'identité '{1}' n'est pas valide : '{2}'" + + + + The value of {0} with identity '{1}' is not a valid commit hash: '{2}'" + La valeur de {0} avec l'identité '{1}' n'est pas un hachage de validation valide : '{2}'" + + + + The value passed to task parameter {0} is not a valid host name: '{1}' + La valeur passée au paramètre de tâche {0} n'est pas un nom d'hôte valide : '{1}' + + + + + \ No newline at end of file diff --git a/src/SourceLink.Gitea/xlf/Resources.it.xlf b/src/SourceLink.Gitea/xlf/Resources.it.xlf new file mode 100644 index 00000000..f6f3cb05 --- /dev/null +++ b/src/SourceLink.Gitea/xlf/Resources.it.xlf @@ -0,0 +1,32 @@ + + + + + + {0} item group is empty. At least one {1} repository host is required in order to generate SourceLink. + Il gruppo di elementi {0} è vuoto. Per generare SourceLink, è necessario almeno un host di repository di {1}. + + + + {0} specifies an invalid URL: '{1}' + {0} specifica un URL non valido: '{1}' + + + + The value of {0} with identity '{1}' is invalid: '{2}'" + Il valore di {0} con identità '{1}' non è valido: '{2}'" + + + + The value of {0} with identity '{1}' is not a valid commit hash: '{2}'" + Il valore di {0} con identità '{1}' non è un hash commit valido: '{2}'" + + + + The value passed to task parameter {0} is not a valid host name: '{1}' + Il valore passato al parametro {0} dell'attività non è un nome host valido: '{1}' + + + + + \ No newline at end of file diff --git a/src/SourceLink.Gitea/xlf/Resources.ja.xlf b/src/SourceLink.Gitea/xlf/Resources.ja.xlf new file mode 100644 index 00000000..98145efd --- /dev/null +++ b/src/SourceLink.Gitea/xlf/Resources.ja.xlf @@ -0,0 +1,32 @@ + + + + + + {0} item group is empty. At least one {1} repository host is required in order to generate SourceLink. + {0} 項目グループが空です。SourceLink を生成するには、少なくとも 1 つの {1} リポジトリ ホストが必要です。 + + + + {0} specifies an invalid URL: '{1}' + {0} は無効な URL を指定しています: '{1}' + + + + The value of {0} with identity '{1}' is invalid: '{2}'" + ID '{1}' の {0} の値は無効です: '{2}'" + + + + The value of {0} with identity '{1}' is not a valid commit hash: '{2}'" + ID '{1}' の {0} の値は有効なコミット ハッシュではありません: '{2}'" + + + + The value passed to task parameter {0} is not a valid host name: '{1}' + タスク パラメーター {0} に渡された値は有効なホスト名ではありません: '{1}' + + + + + \ No newline at end of file diff --git a/src/SourceLink.Gitea/xlf/Resources.ko.xlf b/src/SourceLink.Gitea/xlf/Resources.ko.xlf new file mode 100644 index 00000000..ce5571ba --- /dev/null +++ b/src/SourceLink.Gitea/xlf/Resources.ko.xlf @@ -0,0 +1,32 @@ + + + + + + {0} item group is empty. At least one {1} repository host is required in order to generate SourceLink. + {0} 항목 그룹이 비어 있습니다. SourceLink를 생성하려면 {1} 리포지토리 호스트가 하나 이상 필요합니다. + + + + {0} specifies an invalid URL: '{1}' + {0}이(가) 잘못된 URL을 지정합니다. '{1}' + + + + The value of {0} with identity '{1}' is invalid: '{2}'" + ID가 '{1}'인 {0}의 값이 잘못되었습니다. '{2}'" + + + + The value of {0} with identity '{1}' is not a valid commit hash: '{2}'" + ID가 '{1}'인 {0}의 값이 유효한 커밋 해시가 아닙니다. '{2}'" + + + + The value passed to task parameter {0} is not a valid host name: '{1}' + 작업 매개 변수 {0}에 전달되는 값이 유효한 호스트 이름이 아닙니다. '{1}' + + + + + \ No newline at end of file diff --git a/src/SourceLink.Gitea/xlf/Resources.pl.xlf b/src/SourceLink.Gitea/xlf/Resources.pl.xlf new file mode 100644 index 00000000..5f2e9268 --- /dev/null +++ b/src/SourceLink.Gitea/xlf/Resources.pl.xlf @@ -0,0 +1,32 @@ + + + + + + {0} item group is empty. At least one {1} repository host is required in order to generate SourceLink. + Grupa elementów {0} jest pusta. Wymagany jest co najmniej jeden host repozytorium {1} w celu wygenerowania elementu SourceLink. + + + + {0} specifies an invalid URL: '{1}' + Element {0} określa nieprawidłowy adres URL: „{1}” + + + + The value of {0} with identity '{1}' is invalid: '{2}'" + Wartość elementu {0} z tożsamością „{1}” jest nieprawidłowa: „{2}”" + + + + The value of {0} with identity '{1}' is not a valid commit hash: '{2}'" + Wartość elementu {0} z tożsamością „{1}” nie jest prawidłowym skrótem zatwierdzenia: „{2}”" + + + + The value passed to task parameter {0} is not a valid host name: '{1}' + Wartość przekazana do parametru zadania {0} nie jest prawidłową nazwą hosta: „{1}” + + + + + \ No newline at end of file diff --git a/src/SourceLink.Gitea/xlf/Resources.pt-BR.xlf b/src/SourceLink.Gitea/xlf/Resources.pt-BR.xlf new file mode 100644 index 00000000..4a461578 --- /dev/null +++ b/src/SourceLink.Gitea/xlf/Resources.pt-BR.xlf @@ -0,0 +1,32 @@ + + + + + + {0} item group is empty. At least one {1} repository host is required in order to generate SourceLink. + O grupo de itens {0} está vazio. Pelo menos um host de repositório {1} é necessário para gerar o SourceLink. + + + + {0} specifies an invalid URL: '{1}' + {0} especifica uma URL inválida: '{1}' + + + + The value of {0} with identity '{1}' is invalid: '{2}'" + O valor de {0} com a identidade '{1}' é inválido: '{2}'" + + + + The value of {0} with identity '{1}' is not a valid commit hash: '{2}'" + O valor de {0} com a identidade '{1}' não é um hash de confirmação válido: '{2}'" + + + + The value passed to task parameter {0} is not a valid host name: '{1}' + O valor passado para o parâmetro de tarefa {0} não é um nome de host válido: '{1}' + + + + + \ No newline at end of file diff --git a/src/SourceLink.Gitea/xlf/Resources.ru.xlf b/src/SourceLink.Gitea/xlf/Resources.ru.xlf new file mode 100644 index 00000000..8683b5a7 --- /dev/null +++ b/src/SourceLink.Gitea/xlf/Resources.ru.xlf @@ -0,0 +1,32 @@ + + + + + + {0} item group is empty. At least one {1} repository host is required in order to generate SourceLink. + Группа элементов {0} пуста. Для создания SourceLink нужно указать хотя бы один хост репозитория {1}. + + + + {0} specifies an invalid URL: '{1}' + В {0} указан недопустимый URL-адрес: "{1}" + + + + The value of {0} with identity '{1}' is invalid: '{2}'" + Значение {0} с идентификатором "{1}" недопустимо: "{2}" + + + + The value of {0} with identity '{1}' is not a valid commit hash: '{2}'" + Значение {0} с идентификатором "{1}" не является допустимым хэш-кодом фиксации: "{2}" + + + + The value passed to task parameter {0} is not a valid host name: '{1}' + Значение, передаваемое параметру задачи {0}, не является допустимым именем узла: "{1}" + + + + + \ No newline at end of file diff --git a/src/SourceLink.Gitea/xlf/Resources.tr.xlf b/src/SourceLink.Gitea/xlf/Resources.tr.xlf new file mode 100644 index 00000000..cb9305b8 --- /dev/null +++ b/src/SourceLink.Gitea/xlf/Resources.tr.xlf @@ -0,0 +1,32 @@ + + + + + + {0} item group is empty. At least one {1} repository host is required in order to generate SourceLink. + {0} öğe grubu boş. SourceLink oluşturmak için en az bir {1} depo konağı gereklidir. + + + + {0} specifies an invalid URL: '{1}' + {0} geçersiz bir URL belirtiyor: '{1}' + + + + The value of {0} with identity '{1}' is invalid: '{2}'" + '{1}' kimliğine sahip {0} değeri geçersiz: '{2}'" + + + + The value of {0} with identity '{1}' is not a valid commit hash: '{2}'" + '{1}' kimliğine sahip {0} değeri geçerli bir işleme karması değil: '{2}'" + + + + The value passed to task parameter {0} is not a valid host name: '{1}' + {0} görev parametresine geçirilen değer geçerli bir konak adı değil: '{1}' + + + + + \ No newline at end of file diff --git a/src/SourceLink.Gitea/xlf/Resources.zh-Hans.xlf b/src/SourceLink.Gitea/xlf/Resources.zh-Hans.xlf new file mode 100644 index 00000000..e4a4010d --- /dev/null +++ b/src/SourceLink.Gitea/xlf/Resources.zh-Hans.xlf @@ -0,0 +1,32 @@ + + + + + + {0} item group is empty. At least one {1} repository host is required in order to generate SourceLink. + {0} 项目组为空。至少需要一个 {1} 存储库主机才能生成 SourceLink。 + + + + {0} specifies an invalid URL: '{1}' + {0} 指定无效的 URL:“{1}” + + + + The value of {0} with identity '{1}' is invalid: '{2}'" + 带有 '{1}' 标识的 {0} 的值无效: '{2}'" + + + + The value of {0} with identity '{1}' is not a valid commit hash: '{2}'" + 带有 '{1}' 标识的 {0} 的值不是有效的提交哈希: '{2}'" + + + + The value passed to task parameter {0} is not a valid host name: '{1}' + 传递给任务参数 {0} 的值不是有效的主机名:“{1}” + + + + + \ No newline at end of file diff --git a/src/SourceLink.Gitea/xlf/Resources.zh-Hant.xlf b/src/SourceLink.Gitea/xlf/Resources.zh-Hant.xlf new file mode 100644 index 00000000..ab6c29b8 --- /dev/null +++ b/src/SourceLink.Gitea/xlf/Resources.zh-Hant.xlf @@ -0,0 +1,32 @@ + + + + + + {0} item group is empty. At least one {1} repository host is required in order to generate SourceLink. + {0} 項目群組是空的。至少需要一個 {1} 存放庫主機,才可產生 SourceLink。 + + + + {0} specifies an invalid URL: '{1}' + {0} 指定的 URL 無效: '{1}' + + + + The value of {0} with identity '{1}' is invalid: '{2}'" + 識別為 {1} 之 {0} 的值無效: '{2}'" + + + + The value of {0} with identity '{1}' is not a valid commit hash: '{2}'" + 識別為 {1} 之 {0} 的值不是有效的認可雜湊: '{2}'" + + + + The value passed to task parameter {0} is not a valid host name: '{1}' + 傳遞給工作參數 {0} 的值並非有效的主機名稱: '{1}' + + + + + \ No newline at end of file