From 214ecfece0015f1c0a1850262e4a508815a0174b Mon Sep 17 00:00:00 2001 From: Sarah Oslund Date: Fri, 16 Oct 2020 09:36:44 -0700 Subject: [PATCH 1/2] Removing conflicting publish output dlls --- .../ResolvePublishOutputConflicts.cs | 55 ++++++++++ src/Tasks/Common/Resources/Strings.resx | 4 + src/Tasks/Common/Resources/xlf/Strings.cs.xlf | 5 + src/Tasks/Common/Resources/xlf/Strings.de.xlf | 5 + src/Tasks/Common/Resources/xlf/Strings.es.xlf | 5 + src/Tasks/Common/Resources/xlf/Strings.fr.xlf | 5 + src/Tasks/Common/Resources/xlf/Strings.it.xlf | 5 + src/Tasks/Common/Resources/xlf/Strings.ja.xlf | 5 + src/Tasks/Common/Resources/xlf/Strings.ko.xlf | 5 + src/Tasks/Common/Resources/xlf/Strings.pl.xlf | 5 + .../Common/Resources/xlf/Strings.pt-BR.xlf | 5 + src/Tasks/Common/Resources/xlf/Strings.ru.xlf | 5 + src/Tasks/Common/Resources/xlf/Strings.tr.xlf | 5 + .../Common/Resources/xlf/Strings.zh-Hans.xlf | 5 + .../Common/Resources/xlf/Strings.zh-Hant.xlf | 5 + .../CheckForDuplicateItemMetadata.cs | 37 +++++++ .../Microsoft.NET.ConflictResolution.targets | 22 ++++ .../targets/Microsoft.NET.Publish.targets | 24 ++++- ...ivenThatWeWantToPublishWithoutConflicts.cs | 101 ++++++++++++++++++ 19 files changed, 304 insertions(+), 4 deletions(-) create mode 100644 src/Tasks/Common/ConflictResolution/ResolvePublishOutputConflicts.cs create mode 100644 src/Tasks/Microsoft.NET.Build.Tasks/CheckForDuplicateItemMetadata.cs create mode 100644 src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishWithoutConflicts.cs diff --git a/src/Tasks/Common/ConflictResolution/ResolvePublishOutputConflicts.cs b/src/Tasks/Common/ConflictResolution/ResolvePublishOutputConflicts.cs new file mode 100644 index 000000000000..492878c422bf --- /dev/null +++ b/src/Tasks/Common/ConflictResolution/ResolvePublishOutputConflicts.cs @@ -0,0 +1,55 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Build.Framework; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.NET.Build.Tasks.ConflictResolution +{ + public class ResolveOverlappingItemGroupConflicts : TaskBase + { + [Required] + public ITaskItem[] ItemGroup1 { get; set; } + + [Required] + public ITaskItem[] ItemGroup2 { get; set; } + + public string[] PreferredPackages { get; set; } + + public ITaskItem[] PackageOverrides { get; set; } + + [Output] + public ITaskItem[] RemovedItemGroup1 { get; set; } + + [Output] + public ITaskItem[] RemovedItemGroup2 { get; set; } + + protected override void ExecuteCore() + { + var packageRanks = new PackageRank(PreferredPackages); + var packageOverrides = new PackageOverrideResolver(PackageOverrides); + var conflicts = new HashSet(); + + var conflictItemGroup1 = GetConflictTaskItems(ItemGroup1, ConflictItemType.CopyLocal); + var conflictItemGroup2 = GetConflictTaskItems(ItemGroup2, ConflictItemType.CopyLocal); + + using (var conflictResolver = new ConflictResolver(packageRanks, packageOverrides, Log)) + { + var allConflicts = conflictItemGroup1.Concat(conflictItemGroup2); + conflictResolver.ResolveConflicts(allConflicts, + ci => ItemUtilities.GetReferenceTargetPath(ci.OriginalItem), + (ConflictItem winner, ConflictItem loser) => { conflicts.Add(loser); }); + + var conflictItems = conflicts.Select(i => i.OriginalItem); + RemovedItemGroup1 = ItemGroup1.Intersect(conflictItems).ToArray(); + RemovedItemGroup2 = ItemGroup2.Intersect(conflictItems).ToArray(); + } + } + + private IEnumerable GetConflictTaskItems(ITaskItem[] items, ConflictItemType itemType) + { + return (items != null) ? items.Select(i => new ConflictItem(i, itemType)) : Enumerable.Empty(); + } + } +} diff --git a/src/Tasks/Common/Resources/Strings.resx b/src/Tasks/Common/Resources/Strings.resx index 78964c053e1f..fa2ba9285e12 100644 --- a/src/Tasks/Common/Resources/Strings.resx +++ b/src/Tasks/Common/Resources/Strings.resx @@ -694,4 +694,8 @@ The following are names of parameters or literal values and should not be transl NETSDK1147: The following workload packs were not installed: {0} {StrBegin="NETSDK1147: "} + + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + {StrBegin="NETSDK1148: "} + diff --git a/src/Tasks/Common/Resources/xlf/Strings.cs.xlf b/src/Tasks/Common/Resources/xlf/Strings.cs.xlf index 2305d7971c5e..7561f89b749a 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.cs.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.cs.xlf @@ -284,6 +284,11 @@ NETSDK1015: Token preprocesoru {0} získal více než jednu hodnotu. Volí se hodnota {1}. {StrBegin="NETSDK1015: "} + + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + {StrBegin="NETSDK1148: "} + NETSDK1110: More than one asset in the runtime pack has the same destination sub-path of '{0}'. Report this error to the .NET team here: https://aka.ms/dotnet-sdk-issue. NETSDK1110: Více než jeden prostředek v balíčku modulu runtime má stejnou cílovou dílčí cestu {0}. Tady můžete tuto chybu nahlásit týmu .NET: https://aka.ms/dotnet-sdk-issue. diff --git a/src/Tasks/Common/Resources/xlf/Strings.de.xlf b/src/Tasks/Common/Resources/xlf/Strings.de.xlf index f2d6e7c9a90d..e638f2f38a07 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.de.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.de.xlf @@ -284,6 +284,11 @@ NETSDK1015: Das Präprozessortoken "{0}" wurde mit mehreren Werten versehen. "{1}" wird als Wert ausgewählt. {StrBegin="NETSDK1015: "} + + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + {StrBegin="NETSDK1148: "} + NETSDK1110: More than one asset in the runtime pack has the same destination sub-path of '{0}'. Report this error to the .NET team here: https://aka.ms/dotnet-sdk-issue. NETSDK1110: Mehr als eine Ressource im Runtimepaket weist den gleichen Zielunterpfad "{0}" auf. Melden Sie diesen Fehler hier dem .NET-Team: https://aka.ms/dotnet-sdk-issue. diff --git a/src/Tasks/Common/Resources/xlf/Strings.es.xlf b/src/Tasks/Common/Resources/xlf/Strings.es.xlf index f5d6be3c81e6..bd4b0c72bae7 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.es.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.es.xlf @@ -284,6 +284,11 @@ NETSDK1015: Se han dado varios valores para el token de preprocesador "{0}". Se va a elegir "{1}" como valor. {StrBegin="NETSDK1015: "} + + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + {StrBegin="NETSDK1148: "} + NETSDK1110: More than one asset in the runtime pack has the same destination sub-path of '{0}'. Report this error to the .NET team here: https://aka.ms/dotnet-sdk-issue. NETSDK1110: Más de un recurso del paquete del entorno de ejecución tiene la misma subruta de acceso de destino de "{0}". Notifique este error al equipo de .NET aquí: https://aka.ms/dotnet-sdk-issue. diff --git a/src/Tasks/Common/Resources/xlf/Strings.fr.xlf b/src/Tasks/Common/Resources/xlf/Strings.fr.xlf index 3ee232186fea..a7eeb1dc99f6 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.fr.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.fr.xlf @@ -284,6 +284,11 @@ NETSDK1015: Le jeton de préprocesseur '{0}' a reçu plusieurs valeurs. La valeur choisie est '{1}'. {StrBegin="NETSDK1015: "} + + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + {StrBegin="NETSDK1148: "} + NETSDK1110: More than one asset in the runtime pack has the same destination sub-path of '{0}'. Report this error to the .NET team here: https://aka.ms/dotnet-sdk-issue. NETSDK1110: Plusieurs composants du pack de runtime ont le même sous-chemin de destination que '{0}'. Signalez cette erreur à l'équipe .NET ici : https://aka.ms/dotnet-sdk-issue. diff --git a/src/Tasks/Common/Resources/xlf/Strings.it.xlf b/src/Tasks/Common/Resources/xlf/Strings.it.xlf index 07feb3527f08..cc386df91e71 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.it.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.it.xlf @@ -284,6 +284,11 @@ NETSDK1015: al token di preprocessore '{0}' è stato assegnato più di un valore. Come valore verrà scelto '{1}'. {StrBegin="NETSDK1015: "} + + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + {StrBegin="NETSDK1148: "} + NETSDK1110: More than one asset in the runtime pack has the same destination sub-path of '{0}'. Report this error to the .NET team here: https://aka.ms/dotnet-sdk-issue. NETSDK1110: più di un asset nel pacchetto di runtime ha lo stesso percorso secondario di destinazione di '{0}'. Segnalare questo errore al team di .NET all'indirizzo: https://aka.ms/dotnet-sdk-issue. diff --git a/src/Tasks/Common/Resources/xlf/Strings.ja.xlf b/src/Tasks/Common/Resources/xlf/Strings.ja.xlf index ad9e6ada4e61..95937a32d5c6 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.ja.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.ja.xlf @@ -284,6 +284,11 @@ NETSDK1015: プリプロセッサ トークン '{0}' に複数の値が指定されています。値として '{1}' を選択します。 {StrBegin="NETSDK1015: "} + + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + {StrBegin="NETSDK1148: "} + NETSDK1110: More than one asset in the runtime pack has the same destination sub-path of '{0}'. Report this error to the .NET team here: https://aka.ms/dotnet-sdk-issue. NETSDK1110: ランタイム パック内の複数のアセットに同じターゲット サブパス '{0}' が指定されています。https://aka.ms/dotnet-sdk-issue で、このエラーを .NET チームに報告してください。 diff --git a/src/Tasks/Common/Resources/xlf/Strings.ko.xlf b/src/Tasks/Common/Resources/xlf/Strings.ko.xlf index 7e3e10f41c7d..4d8df355d617 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.ko.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.ko.xlf @@ -284,6 +284,11 @@ NETSDK1015: 전처리기 토큰 '{0}'의 값이 두 개 이상 지정되었습니다. '{1}'을(를) 값으로 선택합니다. {StrBegin="NETSDK1015: "} + + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + {StrBegin="NETSDK1148: "} + NETSDK1110: More than one asset in the runtime pack has the same destination sub-path of '{0}'. Report this error to the .NET team here: https://aka.ms/dotnet-sdk-issue. NETSDK1110: 런타임 팩에 있는 두 개 이상 자산에 동일한 대상 하위 경로인 '{0}'이(가) 있습니다. https://aka.ms/dotnet-sdk-issue에서 .NET 팀에 이 오류를 보고하세요. diff --git a/src/Tasks/Common/Resources/xlf/Strings.pl.xlf b/src/Tasks/Common/Resources/xlf/Strings.pl.xlf index c960e16bef1c..bba8c7fcc20c 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.pl.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.pl.xlf @@ -284,6 +284,11 @@ NETSDK1015: Dla tokenu preprocesora „{0}” podano więcej niż jedną wartość. Wybieranie elementu „{1}” jako wartości. {StrBegin="NETSDK1015: "} + + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + {StrBegin="NETSDK1148: "} + NETSDK1110: More than one asset in the runtime pack has the same destination sub-path of '{0}'. Report this error to the .NET team here: https://aka.ms/dotnet-sdk-issue. NETSDK1110: Więcej niż jeden zasób w pakiecie środowiska uruchomieniowego ma taką samą docelową ścieżkę podrzędną („{0}”). Zgłoś ten błąd zespołowi platformy .NET tutaj: https://aka.ms/dotnet-sdk-issue. diff --git a/src/Tasks/Common/Resources/xlf/Strings.pt-BR.xlf b/src/Tasks/Common/Resources/xlf/Strings.pt-BR.xlf index b5db7e49c683..50e19c2ee346 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.pt-BR.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.pt-BR.xlf @@ -284,6 +284,11 @@ NETSDK1015: O token de pré-processador '{0}' recebeu mais de um valor. Escolhendo '{1}' como o valor. {StrBegin="NETSDK1015: "} + + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + {StrBegin="NETSDK1148: "} + NETSDK1110: More than one asset in the runtime pack has the same destination sub-path of '{0}'. Report this error to the .NET team here: https://aka.ms/dotnet-sdk-issue. NETSDK1110: mais de um ativo no pacote de runtime tem o mesmo subcaminho de destino de '{0}'. Relate esse erro à equipe do .NET: https://aka.ms/dotnet-sdk-issue. diff --git a/src/Tasks/Common/Resources/xlf/Strings.ru.xlf b/src/Tasks/Common/Resources/xlf/Strings.ru.xlf index e137efa39ef9..e414ed72f628 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.ru.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.ru.xlf @@ -284,6 +284,11 @@ NETSDK1015: для маркера препроцессора "{0}" указано множество значений. В качестве значения будет использовано "{1}". {StrBegin="NETSDK1015: "} + + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + {StrBegin="NETSDK1148: "} + NETSDK1110: More than one asset in the runtime pack has the same destination sub-path of '{0}'. Report this error to the .NET team here: https://aka.ms/dotnet-sdk-issue. NETSDK1110: сразу несколько ресурсов в пакете среды выполнения имеют один и тот же конечный вложенный путь "{0}". Сообщите об этой ошибке группе разработчиков .NET по следующему адресу: https://aka.ms/dotnet-sdk-issue. diff --git a/src/Tasks/Common/Resources/xlf/Strings.tr.xlf b/src/Tasks/Common/Resources/xlf/Strings.tr.xlf index 7af6ae695f66..d1368e25caf0 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.tr.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.tr.xlf @@ -284,6 +284,11 @@ NETSDK1015: '{0}' ön işlemci belirtecine birden fazla değer verildi. Değer olarak '{1}' seçiliyor. {StrBegin="NETSDK1015: "} + + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + {StrBegin="NETSDK1148: "} + NETSDK1110: More than one asset in the runtime pack has the same destination sub-path of '{0}'. Report this error to the .NET team here: https://aka.ms/dotnet-sdk-issue. NETSDK1110: Çalışma zamanı paketindeki birden fazla varlık, aynı '{0}' hedef alt yoluna sahip. Bu hatayı https://aka.ms/dotnet-sdk-issue adresinden .NET ekibine bildirin. diff --git a/src/Tasks/Common/Resources/xlf/Strings.zh-Hans.xlf b/src/Tasks/Common/Resources/xlf/Strings.zh-Hans.xlf index 4cf1deb39da0..c59ae6e4157b 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.zh-Hans.xlf @@ -284,6 +284,11 @@ NETSDK1015: 已向预处理器标记“{0}”提供多个值。选择“{1}”作为值。 {StrBegin="NETSDK1015: "} + + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + {StrBegin="NETSDK1148: "} + NETSDK1110: More than one asset in the runtime pack has the same destination sub-path of '{0}'. Report this error to the .NET team here: https://aka.ms/dotnet-sdk-issue. NETSDK1110: 运行时包中的多个资产具有“{0}”的相同目标子路径。请在此处将此错误报告给 .NET 团队: https://aka.ms/dotnet-sdk-issue。 diff --git a/src/Tasks/Common/Resources/xlf/Strings.zh-Hant.xlf b/src/Tasks/Common/Resources/xlf/Strings.zh-Hant.xlf index c39d541dd143..a3b704d8ffda 100644 --- a/src/Tasks/Common/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/Tasks/Common/Resources/xlf/Strings.zh-Hant.xlf @@ -284,6 +284,11 @@ NETSDK1015: 已為前置處理器語彙基元 '{0}' 指定多個值。正在選擇 '{1}' 作為值。 {StrBegin="NETSDK1015: "} + + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + NETSDK1148: Found multiple publish output files with the same relative path: {0}. + {StrBegin="NETSDK1148: "} + NETSDK1110: More than one asset in the runtime pack has the same destination sub-path of '{0}'. Report this error to the .NET team here: https://aka.ms/dotnet-sdk-issue. NETSDK1110: 執行階段套件中有多項資產具有相同的目的地子路徑 '{0}'。請將此錯誤回報給 .NET 小組: https://aka.ms/dotnet-sdk-issue。 diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/CheckForDuplicateItemMetadata.cs b/src/Tasks/Microsoft.NET.Build.Tasks/CheckForDuplicateItemMetadata.cs new file mode 100644 index 000000000000..91d174c5241f --- /dev/null +++ b/src/Tasks/Microsoft.NET.Build.Tasks/CheckForDuplicateItemMetadata.cs @@ -0,0 +1,37 @@ +using Microsoft.Build.Framework; +using System.Linq; + +namespace Microsoft.NET.Build.Tasks +{ + public class CheckForDuplicateItemMetadata : TaskBase + { + [Required] + public ITaskItem[] Items { get; set; } + + [Required] + public string MetadataName { get; set; } + + [Output] + public ITaskItem[] DuplicateItems { get; set; } + + [Output] + public string[] DuplicatedMetadataValues { get; set; } + + [Output] + public bool DuplicatesExist { get; set; } + + protected override void ExecuteCore() + { + var groupings = Items.GroupBy(item => item.GetMetadata(MetadataName)) + .Where(g => g.Count() > 1) + .ToList(); + DuplicatesExist = groupings.Any(); + DuplicatedMetadataValues = groupings + .Select(g => g.Key) + .ToArray(); + DuplicateItems = groupings + .SelectMany(g => g) + .ToArray(); + } + } +} diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ConflictResolution.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ConflictResolution.targets index 9bcb1aef4c32..39b55c670011 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ConflictResolution.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ConflictResolution.targets @@ -15,6 +15,7 @@ Copyright (c) .NET Foundation. All rights reserved. + + + + + + + + + + + + diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets index 5be0d736b820..2f2f066d0981 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets @@ -134,7 +134,8 @@ Copyright (c) .NET Foundation. All rights reserved. + _CopyResolvedFilesToPublishAlways; + _HandleFileConflictsForPublish" /> @@ -565,7 +568,19 @@ Copyright (c) .NET Foundation. All rights reserved. %(Filename)%(Extension) PreserveNewest + + + + + + + + <_ResolvedCopyLocalPublishAssets Remove="@(_ResolvedCopyLocalPublishAssetsRemoved)"/> + + %(_ResolvedCopyLocalPublishAssets.DestinationSubDirectory)%(Filename)%(Extension) @@ -580,7 +595,7 @@ Copyright (c) .NET Foundation. All rights reserved. - + shims/%(_EmbeddedApphostPaths.ShimRuntimeIdentifier)/%(_EmbeddedApphostPaths.Filename)%(_EmbeddedApphostPaths.Extension) PreserveNewest @@ -701,7 +716,7 @@ Copyright (c) .NET Foundation. All rights reserved. <_ResolvedCopyLocalPublishAssets Include="@(ReferenceCopyLocalPaths)" Exclude="@(_ResolvedCopyLocalBuildAssets);@(RuntimePackAsset)" - Condition="'$(PublishReferencesDocumentationFiles)' == 'true' or '%(ReferenceCopyLocalPaths.Extension)' != '.xml'"> + Condition="('$(PublishReferencesDocumentationFiles)' == 'true' or '%(ReferenceCopyLocalPaths.Extension)' != '.xml') and '%(ReferenceCopyLocalPaths.Private)' != 'false'"> %(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension) @@ -980,6 +995,7 @@ Copyright (c) .NET Foundation. All rights reserved. ============================================================ --> diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishWithoutConflicts.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishWithoutConflicts.cs new file mode 100644 index 000000000000..1797a60ad017 --- /dev/null +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishWithoutConflicts.cs @@ -0,0 +1,101 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using FluentAssertions; +using Microsoft.NET.TestFramework; +using Microsoft.NET.TestFramework.Assertions; +using Microsoft.NET.TestFramework.Commands; +using Microsoft.NET.TestFramework.ProjectConstruction; +using Xunit; +using Xunit.Abstractions; +using System.IO; +using System.Linq; + +namespace Microsoft.NET.Publish.Tests +{ + public class GivenThatWeWantToPublishWithoutConflicts : SdkTest + { + public GivenThatWeWantToPublishWithoutConflicts(ITestOutputHelper log) : base(log) + { + } + + [WindowsOnlyFact] + public void It_solves_conflicts_between_package_and_implicit_references() + { + // Test case from https://github.com/dotnet/sdk/issues/3904. + // This dll is included in both the explicit package reference and Microsoft.NET.Build.Extensions. We prevent a double write in + // _ComputeResolvedCopyLocalPublishAssets by removing dlls duplicated between package references and implicitly expanded .NET references. + var reference = "System.Runtime.InteropServices.RuntimeInformation"; + var targetFramework = "net461"; + var testProject = new TestProject() + { + Name = "ConflictingFilePublish", + IsSdkProject = true, + TargetFrameworks = targetFramework + }; + testProject.PackageReferences.Add(new TestPackageReference(reference, "4.3.0")); + testProject.PackageReferences.Add(new TestPackageReference("Microsoft.AspNetCore", "2.1.4")); + var testAsset = _testAssetsManager.CreateTestProject(testProject, testProject.Name); + + var getValuesCommand = new GetValuesCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name), targetFramework, "ResolvedFileToPublish", GetValuesCommand.ValueType.Item) + { + DependsOnTargets = "Publish" + }; + + getValuesCommand + .Execute() + .Should() + .Pass(); + + var files = getValuesCommand.GetValues() + .Where(file => file.Contains(reference)); + files.Count().Should().Be(1); + // We should choose the file from system.runtime.interopservices.runtimeinformation package version + files.FirstOrDefault().Contains(@"system.runtime.interopservices.runtimeinformation\4.3.0").Should().BeTrue(); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void It_has_consistent_behavior_when_publishing_single_file(bool shouldPublishSingleFile) + { + var targetFramework = "netcoreapp3.1"; + var testProject = new TestProject() + { + Name = "DuplicateFiles", + TargetFrameworks = targetFramework, + IsSdkProject = true, + IsExe = true, + RuntimeIdentifier = "win-x64" + }; + // The Microsoft.TestPlatform.CLI package contains System.Runtime.CompilerServices.Unsafe.dll as content, which could cause a double write with the same dll originating from the + // runtime package. Without _HandleFileConflictsForPublish this would be caught when by the bundler when publishing single file, but a normal publish would succeed with double writes. + testProject.PackageReferences.Add(new TestPackageReference("Microsoft.TestPlatform.CLI", "16.5.0")); + + var testAsset = _testAssetsManager.CreateTestProject(testProject); + var getValuesCommand = new GetValuesCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name), targetFramework, "ResolvedFileToPublish", GetValuesCommand.ValueType.Item) + { + DependsOnTargets = "Publish" + }; + + if (shouldPublishSingleFile) { + getValuesCommand.Execute("/p:PublishSingleFile=true") + .Should() + .Pass(); + } + else + { + getValuesCommand.Execute() + .Should() + .Pass(); + + var duplicatedDll = "System.Runtime.CompilerServices.Unsafe.dll"; + var files = getValuesCommand.GetValues() + .Where(file => file.Contains(duplicatedDll)); + files.Count().Should().Be(1); + // We should choose the file from microsoft.netcore.app.runtime package over the Microsoft.TestPlatform.CLI package version + files.FirstOrDefault().Contains("microsoft.netcore.app.runtime").Should().BeTrue(); + } + } + } +} From 193ae79a98c10088daf4993838eb9f6046e0ca14 Mon Sep 17 00:00:00 2001 From: Sarah Oslund Date: Wed, 4 Nov 2020 08:14:10 -0800 Subject: [PATCH 2/2] PR feedback --- .../targets/Microsoft.NET.Publish.targets | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets index 2f2f066d0981..f7f256ea2dfd 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets @@ -570,6 +570,8 @@ Copyright (c) .NET Foundation. All rights reserved. +