diff --git a/eng/Versions.props b/eng/Versions.props index 5d72a67a..2cac8039 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -21,6 +21,7 @@ 1.8.1 4.5.0 4.7.2 + 1.5.25 0.27.0-preview-0119 diff --git a/src/Common/CommonResources.resx b/src/Common/CommonResources.resx index 876d8353..f1f53245 100644 --- a/src/Common/CommonResources.resx +++ b/src/Common/CommonResources.resx @@ -141,4 +141,10 @@ Unable to determine repository url, the source code won't be available via source link. + + No well-formed host URIs specified: {0}. + + + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + \ No newline at end of file diff --git a/src/Common/GetSourceLinkUrlGitTask.cs b/src/Common/GetSourceLinkUrlGitTask.cs index 6b6863ed..254b97c7 100644 --- a/src/Common/GetSourceLinkUrlGitTask.cs +++ b/src/Common/GetSourceLinkUrlGitTask.cs @@ -18,7 +18,9 @@ public abstract class GetSourceLinkUrlGitTask : Task protected const string NotApplicableValue = "N/A"; private const string ContentUrlMetadataName = "ContentUrl"; - [Required, NotNull] + /// + /// Optional, but null is elimated when the task starts executing. + /// public ITaskItem? SourceRoot { get; set; } /// @@ -65,6 +67,12 @@ public override bool Execute() private void ExecuteImpl() { + // Avoid errors when no SourceRoot is specified, _InitializeXyzGitSourceLinkUrl target will simply not update any SourceRoots. + if (SourceRoot == null) + { + return; + } + // skip SourceRoot that already has SourceLinkUrl set, or its SourceControl is not "git": if (!string.IsNullOrEmpty(SourceRoot.GetMetadata(Names.SourceRoot.SourceLinkUrl)) || !string.Equals(SourceRoot.GetMetadata(Names.SourceRoot.SourceControl), SourceControlName, StringComparison.OrdinalIgnoreCase)) diff --git a/src/Common/TranslateRepositoryUrlGitTask.cs b/src/Common/TranslateRepositoryUrlGitTask.cs index f09822ef..fd7208df 100644 --- a/src/Common/TranslateRepositoryUrlGitTask.cs +++ b/src/Common/TranslateRepositoryUrlGitTask.cs @@ -43,9 +43,13 @@ public override bool Execute() private void ExecuteImpl() { + // Assign translated roots even when the task fails (or no Hosts were specified) to avoid cascading errors. + TranslatedSourceRoots = SourceRoots; + var hostUris = GetHostUris().ToArray(); if (hostUris.Length == 0) { + Log.LogMessage(CommonResources.NoWellFormedHostUrisSpecified, "'" + string.Join("','", (Hosts ?? Array.Empty()).Select(h => h.ItemSpec)) + "'"); return; } @@ -78,8 +82,6 @@ static bool isMatchingHostUri(Uri hostUri, Uri uri) return; } - TranslatedSourceRoots = SourceRoots; - if (TranslatedSourceRoots != null) { foreach (var sourceRoot in TranslatedSourceRoots) @@ -120,6 +122,10 @@ private IEnumerable GetHostUris() { yield return hostUri; } + else + { + Log.LogWarning(CommonResources.IgnoringInvalidHostName, item.ItemSpec); + } } } diff --git a/src/Common/xlf/CommonResources.cs.xlf b/src/Common/xlf/CommonResources.cs.xlf index 65706134..a3eb22bc 100644 --- a/src/Common/xlf/CommonResources.cs.xlf +++ b/src/Common/xlf/CommonResources.cs.xlf @@ -7,11 +7,21 @@ Skupina položek {0} je prázdná. Kvůli generování zdrojového odkazu se vyžaduje alespoň jeden hostitel úložiště {1}. + + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + + Item '{0}' of item group '{1}' must specify metadata '{2}' Položka {0} ve skupině položek {1} musí uvádět metadata {2}. + + No well-formed host URIs specified: {0}. + No well-formed host URIs specified: {0}. + + Unable to determine repository url, the source code won't be available via source link. Nejde určit adresu URL úložiště. Zdrojový kód nebude k dispozici přes odkaz na zdroj. diff --git a/src/Common/xlf/CommonResources.de.xlf b/src/Common/xlf/CommonResources.de.xlf index fb8a5d97..9df3d513 100644 --- a/src/Common/xlf/CommonResources.de.xlf +++ b/src/Common/xlf/CommonResources.de.xlf @@ -7,11 +7,21 @@ Die Elementgruppe "{0}" ist leer. Mindestens ein {1}-Repositoryhost wird benötigt, um SourceLink zu generieren. + + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + + Item '{0}' of item group '{1}' must specify metadata '{2}' Das Element "{0}" der Elementgruppe "{1}" muss die Metadaten "{2}" angeben. + + No well-formed host URIs specified: {0}. + No well-formed host URIs specified: {0}. + + Unable to determine repository url, the source code won't be available via source link. Die URL für das Repository konnte nicht ermittelt werden. Daher ist der Quellcode nicht über die Quellverknüpfung verfügbar. diff --git a/src/Common/xlf/CommonResources.es.xlf b/src/Common/xlf/CommonResources.es.xlf index 6c77c859..e154cc16 100644 --- a/src/Common/xlf/CommonResources.es.xlf +++ b/src/Common/xlf/CommonResources.es.xlf @@ -7,11 +7,21 @@ El grupo de elementos {0} está vacío. Se requiere al menos un repositorio {1} a fin de generar SourceLink. + + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + + Item '{0}' of item group '{1}' must specify metadata '{2}' El elemento "{0}" del grupo de elementos "{1}" debe especificar los metadatos "{2}" + + No well-formed host URIs specified: {0}. + No well-formed host URIs specified: {0}. + + Unable to determine repository url, the source code won't be available via source link. No se puede determinar la URL del repositorio, el código fuente no estará disponible a través del vínculo de origen. diff --git a/src/Common/xlf/CommonResources.fr.xlf b/src/Common/xlf/CommonResources.fr.xlf index 2253dbd5..a2185a45 100644 --- a/src/Common/xlf/CommonResources.fr.xlf +++ b/src/Common/xlf/CommonResources.fr.xlf @@ -7,11 +7,21 @@ 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. + + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + + Item '{0}' of item group '{1}' must specify metadata '{2}' L'élément '{0}' du groupe d'éléments '{1}' doit spécifier les métadonnées '{2}' + + No well-formed host URIs specified: {0}. + No well-formed host URIs specified: {0}. + + Unable to determine repository url, the source code won't be available via source link. Impossible de déterminer l'URL du dépôt, le code source n'est pas disponible via Source Link. diff --git a/src/Common/xlf/CommonResources.it.xlf b/src/Common/xlf/CommonResources.it.xlf index 222ef236..9e7ce4de 100644 --- a/src/Common/xlf/CommonResources.it.xlf +++ b/src/Common/xlf/CommonResources.it.xlf @@ -7,11 +7,21 @@ Il gruppo di elementi {0} è vuoto. Per generare SourceLink, è necessario almeno un host di repository di {1}. + + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + + Item '{0}' of item group '{1}' must specify metadata '{2}' L'elemento '{0}' del gruppo di elementi '{1}' deve specificare i metadati '{2}' + + No well-formed host URIs specified: {0}. + No well-formed host URIs specified: {0}. + + Unable to determine repository url, the source code won't be available via source link. Non è possibile determinare l'URL del repository. Il codice sorgente non sarà disponibile tramite il collegamento all'origine. diff --git a/src/Common/xlf/CommonResources.ja.xlf b/src/Common/xlf/CommonResources.ja.xlf index 9457924d..df31abb0 100644 --- a/src/Common/xlf/CommonResources.ja.xlf +++ b/src/Common/xlf/CommonResources.ja.xlf @@ -7,11 +7,21 @@ {0} 項目グループが空です。SourceLink を生成するには、少なくとも 1 つの {1} リポジトリ ホストが必要です。 + + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + + Item '{0}' of item group '{1}' must specify metadata '{2}' 項目グループ '{1}' の項目 '{0}' には、メタデータ '{2}' を指定する必要があります + + No well-formed host URIs specified: {0}. + No well-formed host URIs specified: {0}. + + Unable to determine repository url, the source code won't be available via source link. リポジトリのURLを特定できません。ソース リンクを使用してソース コードを利用できません。 diff --git a/src/Common/xlf/CommonResources.ko.xlf b/src/Common/xlf/CommonResources.ko.xlf index 178cd0af..b40a1967 100644 --- a/src/Common/xlf/CommonResources.ko.xlf +++ b/src/Common/xlf/CommonResources.ko.xlf @@ -7,11 +7,21 @@ {0} 항목 그룹이 비어 있습니다. SourceLink를 생성하려면 {1} 리포지토리 호스트가 하나 이상 필요합니다. + + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + + Item '{0}' of item group '{1}' must specify metadata '{2}' 항목 그룹 '{1}'의 '{0}' 항목은 '{2}' 메타데이터를 지정해야 합니다. + + No well-formed host URIs specified: {0}. + No well-formed host URIs specified: {0}. + + Unable to determine repository url, the source code won't be available via source link. 리포지토리 URL을 확인할 수 없으며, 소스 링크를 통해 소스 코드를 사용할 수 없습니다. diff --git a/src/Common/xlf/CommonResources.pl.xlf b/src/Common/xlf/CommonResources.pl.xlf index e3021dcf..5dba2ad2 100644 --- a/src/Common/xlf/CommonResources.pl.xlf +++ b/src/Common/xlf/CommonResources.pl.xlf @@ -7,11 +7,21 @@ Grupa elementów {0} jest pusta. Wymagany jest co najmniej jeden host repozytorium {1} w celu wygenerowania elementu SourceLink. + + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + + Item '{0}' of item group '{1}' must specify metadata '{2}' Element „{0}” grupy elementów „{1}” musi określać metadane „{2}”. + + No well-formed host URIs specified: {0}. + No well-formed host URIs specified: {0}. + + Unable to determine repository url, the source code won't be available via source link. Nie można określić adresu URL repozytorium, kod źródłowy nie będzie dostępny za pośrednictwem linku do źródła. diff --git a/src/Common/xlf/CommonResources.pt-BR.xlf b/src/Common/xlf/CommonResources.pt-BR.xlf index 2692726c..28f05777 100644 --- a/src/Common/xlf/CommonResources.pt-BR.xlf +++ b/src/Common/xlf/CommonResources.pt-BR.xlf @@ -7,11 +7,21 @@ O grupo de itens {0} está vazio. Pelo menos um host de repositório {1} é necessário para gerar o SourceLink. + + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + + Item '{0}' of item group '{1}' must specify metadata '{2}' Item '{0}' do grupo de item '{1}' deve especificar metadados '{2}' + + No well-formed host URIs specified: {0}. + No well-formed host URIs specified: {0}. + + Unable to determine repository url, the source code won't be available via source link. Não é possível determinar a URL do repositório, o código-fonte não estará disponível através do source link. diff --git a/src/Common/xlf/CommonResources.ru.xlf b/src/Common/xlf/CommonResources.ru.xlf index 30bec787..66b3482f 100644 --- a/src/Common/xlf/CommonResources.ru.xlf +++ b/src/Common/xlf/CommonResources.ru.xlf @@ -7,11 +7,21 @@ Группа элементов {0} пуста. Для создания SourceLink нужно указать хотя бы один хост репозитория {1}. + + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + + Item '{0}' of item group '{1}' must specify metadata '{2}' Необходимо указать метаданные '{2}' для элемента '{0}' в группе элементов '{1}' + + No well-formed host URIs specified: {0}. + No well-formed host URIs specified: {0}. + + Unable to determine repository url, the source code won't be available via source link. Не удается определить URL-адрес репозитория, исходный код не будет доступен по исходной ссылке. diff --git a/src/Common/xlf/CommonResources.tr.xlf b/src/Common/xlf/CommonResources.tr.xlf index 89a36224..7b7964b9 100644 --- a/src/Common/xlf/CommonResources.tr.xlf +++ b/src/Common/xlf/CommonResources.tr.xlf @@ -7,11 +7,21 @@ {0} öğe grubu boş. SourceLink oluşturmak için en az bir {1} depo konağı gereklidir. + + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + + Item '{0}' of item group '{1}' must specify metadata '{2}' '{1}' öğe grubunun '{0}' öğesi, '{2}' meta verilerini belirtmelidir + + No well-formed host URIs specified: {0}. + No well-formed host URIs specified: {0}. + + Unable to determine repository url, the source code won't be available via source link. Depo URL'si belirlenemiyor. Kaynak kod, kaynak bağlantısı aracılığıyla kullanılamayacak. diff --git a/src/Common/xlf/CommonResources.zh-Hans.xlf b/src/Common/xlf/CommonResources.zh-Hans.xlf index 4508d81a..335b4e9e 100644 --- a/src/Common/xlf/CommonResources.zh-Hans.xlf +++ b/src/Common/xlf/CommonResources.zh-Hans.xlf @@ -7,11 +7,21 @@ {0} 项目组为空。至少需要一个 {1} 存储库主机才能生成 SourceLink。 + + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + + Item '{0}' of item group '{1}' must specify metadata '{2}' 项组 "{1}" 的项 "{0}" 必须指定元数据 "{2}" + + No well-formed host URIs specified: {0}. + No well-formed host URIs specified: {0}. + + Unable to determine repository url, the source code won't be available via source link. 无法确定仓库 URL,源代码将无法通过源链接获得。 diff --git a/src/Common/xlf/CommonResources.zh-Hant.xlf b/src/Common/xlf/CommonResources.zh-Hant.xlf index 3b87d6af..33c7f9c4 100644 --- a/src/Common/xlf/CommonResources.zh-Hant.xlf +++ b/src/Common/xlf/CommonResources.zh-Hant.xlf @@ -7,11 +7,21 @@ {0} 項目群組是空的。至少需要一個 {1} 存放庫主機,才可產生 SourceLink。 + + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + Ignoring invalid host name: '{0}' -- expected 'domain[:port]'. + + Item '{0}' of item group '{1}' must specify metadata '{2}' 項目群組 '{1}' 的項目 '{0}' 必須指定中繼資料 '{2}' + + No well-formed host URIs specified: {0}. + No well-formed host URIs specified: {0}. + + Unable to determine repository url, the source code won't be available via source link. 無法判斷存放庫 URL,無法透過來源連結取得原始程式碼。 diff --git a/src/Microsoft.Build.Tasks.Git/RepositoryTask.cs b/src/Microsoft.Build.Tasks.Git/RepositoryTask.cs index 10f453c3..16e9382e 100644 --- a/src/Microsoft.Build.Tasks.Git/RepositoryTask.cs +++ b/src/Microsoft.Build.Tasks.Git/RepositoryTask.cs @@ -29,6 +29,11 @@ public abstract class RepositoryTask : Task static RepositoryTask() => AssemblyResolver.Initialize(); #endif + /// + /// True to report a warning when the repository can't be located. + /// + public bool NoWarnOnMissingRepository { get; set; } + public sealed override bool Execute() { #if NET461 @@ -98,7 +103,11 @@ private void ExecuteImpl() if (!GitRepository.TryFindRepository(initialPath, out var location)) { - Log.LogWarning(Resources.UnableToLocateRepository, initialPath); + if (!NoWarnOnMissingRepository) + { + Log.LogWarning(Resources.UnableToLocateRepository, initialPath); + } + return null; } @@ -120,7 +129,11 @@ private void ExecuteImpl() if (repository?.WorkingDirectory == null) { - Log.LogWarning(Resources.UnableToLocateRepository, initialPath); + if (!NoWarnOnMissingRepository) + { + Log.LogWarning(Resources.UnableToLocateRepository, initialPath); + } + repository = null; } diff --git a/src/Microsoft.Build.Tasks.Git/build/Microsoft.Build.Tasks.Git.targets b/src/Microsoft.Build.Tasks.Git/build/Microsoft.Build.Tasks.Git.targets index 1e26dec0..12fec562 100644 --- a/src/Microsoft.Build.Tasks.Git/build/Microsoft.Build.Tasks.Git.targets +++ b/src/Microsoft.Build.Tasks.Git/build/Microsoft.Build.Tasks.Git.targets @@ -17,16 +17,18 @@ --> local - + - + ConfigurationScope="$(GitRepositoryConfigurationScope)" + NoWarnOnMissingRepository="$(PkgMicrosoft_Build_Tasks_Git.Equals(''))"> + @@ -37,7 +39,7 @@ git - + + diff --git a/src/SourceLink.Git.IntegrationTests/AzureReposAndGitHubTests.cs b/src/SourceLink.Git.IntegrationTests/CloudHostedProvidersTests.cs similarity index 78% rename from src/SourceLink.Git.IntegrationTests/AzureReposAndGitHubTests.cs rename to src/SourceLink.Git.IntegrationTests/CloudHostedProvidersTests.cs index fb043223..c485eef9 100644 --- a/src/SourceLink.Git.IntegrationTests/AzureReposAndGitHubTests.cs +++ b/src/SourceLink.Git.IntegrationTests/CloudHostedProvidersTests.cs @@ -2,20 +2,77 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the License.txt file in the project root for more information. +using System; using System.IO; -using Microsoft.SourceLink.Common; using TestUtilities; using Xunit; namespace Microsoft.SourceLink.IntegrationTests { - public class AzureReposAndGitHubTests : DotNetSdkTestBase + /// + /// Tests projects with all providers that have cloud-hosted repos. + /// These providers are included in the SDK. + /// + public class CloudHostedProvidersTests : DotNetSdkTestBase { - public AzureReposAndGitHubTests() - : base("Microsoft.SourceLink.AzureRepos.Git", "Microsoft.SourceLink.GitHub") + public CloudHostedProvidersTests() + : base("Microsoft.SourceLink.AzureRepos.Git", + "Microsoft.SourceLink.GitHub", + "Microsoft.SourceLink.GitLab", + "Microsoft.SourceLink.Bitbucket.Git") { } + [ConditionalFact(typeof(DotNetSdkAvailable))] + public void NoRepository_Warnings() + { + VerifyValues( + customProps: "", + customTargets: "", + targets: new[] + { + "Build" + }, + expressions: new[] + { + "@(SourceRoot)", + }, + expectedResults: new[] + { + NuGetPackageFolders + }, + expectedWarnings: new[] + { + string.Format(Build.Tasks.Git.Resources.UnableToLocateRepository, ProjectDir.Path), + string.Format(Common.Resources.SourceControlInformationIsNotAvailableGeneratedSourceLinkEmpty), + }); + } + + [ConditionalFact(typeof(DotNetSdkAvailable))] + public void NoRepository_NoWarnings() + { + VerifyValues( + customProps: """ + + + + + """, + customTargets: "", + targets: new[] + { + "Build" + }, + expressions: new[] + { + "@(SourceRoot)", + }, + expectedResults: new[] + { + NuGetPackageFolders + }); + } + [ConditionalFact(typeof(DotNetSdkAvailable))] public void CustomTranslation() { @@ -202,7 +259,7 @@ public void Host_Unknown() }, expectedWarnings: new[] { - string.Format(Resources.SourceControlInformationIsNotAvailableGeneratedSourceLinkEmpty) + string.Format(Common.Resources.SourceControlInformationIsNotAvailableGeneratedSourceLinkEmpty) }); } } diff --git a/src/SourceLink.Git.IntegrationTests/GitHubTests.cs b/src/SourceLink.Git.IntegrationTests/GitHubTests.cs index 81cd9714..9f88ce41 100644 --- a/src/SourceLink.Git.IntegrationTests/GitHubTests.cs +++ b/src/SourceLink.Git.IntegrationTests/GitHubTests.cs @@ -2,16 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the License.txt file in the project root for more information. -using System; using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Reflection; -using System.Xml.Linq; using LibGit2Sharp; using Microsoft.Build.Tasks.Git; using TestUtilities; -using Xunit; namespace Microsoft.SourceLink.IntegrationTests { diff --git a/src/SourceLink.GitLab/build/Microsoft.SourceLink.GitLab.props b/src/SourceLink.GitLab/build/Microsoft.SourceLink.GitLab.props new file mode 100644 index 00000000..8484b2d1 --- /dev/null +++ b/src/SourceLink.GitLab/build/Microsoft.SourceLink.GitLab.props @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/SourceLink.GitLab/buildMultiTargeting/Microsoft.SourceLink.GitLab.props b/src/SourceLink.GitLab/buildMultiTargeting/Microsoft.SourceLink.GitLab.props new file mode 100644 index 00000000..afadd0e1 --- /dev/null +++ b/src/SourceLink.GitLab/buildMultiTargeting/Microsoft.SourceLink.GitLab.props @@ -0,0 +1,5 @@ + + + + + diff --git a/src/TestUtilities/TestUtilities.csproj b/src/TestUtilities/TestUtilities.csproj index bdaaf251..090276bb 100644 --- a/src/TestUtilities/TestUtilities.csproj +++ b/src/TestUtilities/TestUtilities.csproj @@ -12,6 +12,7 @@ +