From fc3f6f31c3ffa454eee8d9fabf5b9b9726e3ba92 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 24 Apr 2020 12:37:39 -0700 Subject: [PATCH] Fix NullReferenceException in dotnet store --- .../TargetManifests/PrunePackages.xml | 36 +++++++++++++++++++ .../FilterResolvedFiles.cs | 2 +- .../ProjectContext.cs | 7 +++- ...atWeWantToStoreAProjectWithDependencies.cs | 35 ++++++++++++++++++ 4 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 src/Assets/TestProjects/TargetManifests/PrunePackages.xml diff --git a/src/Assets/TestProjects/TargetManifests/PrunePackages.xml b/src/Assets/TestProjects/TargetManifests/PrunePackages.xml new file mode 100644 index 000000000000..d2841578b96f --- /dev/null +++ b/src/Assets/TestProjects/TargetManifests/PrunePackages.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(PackagesToPrune);@(PackageToPrune) + + + \ No newline at end of file diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/FilterResolvedFiles.cs b/src/Tasks/Microsoft.NET.Build.Tasks/FilterResolvedFiles.cs index 47c19f336ee7..e386a40dd910 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/FilterResolvedFiles.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/FilterResolvedFiles.cs @@ -69,7 +69,7 @@ protected override void ExecuteCore() var pkgName = packageItem.ItemSpec; if (!string.IsNullOrEmpty(pkgName)) { - packageClosure.UnionWith(projectContext.GetTransitiveList(pkgName)); + packageClosure.UnionWith(projectContext.GetTransitiveList(pkgName, ignoreIfNotFound: true)); } } diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/ProjectContext.cs b/src/Tasks/Microsoft.NET.Build.Tasks/ProjectContext.cs index 93541ac5674e..7db21df9c4a3 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/ProjectContext.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/ProjectContext.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using Microsoft.Build.Framework; +using Microsoft.DotNet.PlatformAbstractions; using NuGet.Packaging.Core; using NuGet.ProjectModel; using System; @@ -145,9 +146,13 @@ public IEnumerable GetRuntimeLibraries(IEnumerable GetTransitiveList(string package) + internal IEnumerable GetTransitiveList(string package, bool ignoreIfNotFound = false) { LockFileTargetLibrary platformLibrary = _lockFileTarget.GetLibrary(package); + if (platformLibrary == null && ignoreIfNotFound) + { + return Enumerable.Empty(); + } IEnumerable runtimeLibraries = _lockFileTarget.Libraries; Dictionary libraryLookup = runtimeLibraries.ToDictionary(e => e.Name, StringComparer.OrdinalIgnoreCase); diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToStoreAProjectWithDependencies.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToStoreAProjectWithDependencies.cs index 0b2137897fa7..e0577c39cda2 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToStoreAProjectWithDependencies.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToStoreAProjectWithDependencies.cs @@ -340,6 +340,41 @@ public void It_stores_when_targeting_netcoreapp3(bool isExe) }); } + [CoreMSBuildOnlyFact] + public void DotnetStoreWithPrunedPackages() + { + const string TargetFramework = "netcoreapp3.1"; + + TestAsset targetManifestsAsset = _testAssetsManager + .CopyTestAsset("TargetManifests") + .WithSource(); + + var outputFolder = Path.Combine(targetManifestsAsset.TestRoot, "o"); + var workingDir = Path.Combine(targetManifestsAsset.TestRoot, "w"); + + var composeStore = new ComposeStoreCommand(Log, targetManifestsAsset.TestRoot, "PrunePackages.xml") + .Execute( + $"/p:TargetFramework={TargetFramework}", + $"/p:RuntimeIdentifier={EnvironmentInfo.GetCompatibleRid(TargetFramework)}", + $"/p:ComposeDir={outputFolder}", + $"/p:ComposeWorkingDir={workingDir}", + "/p:PreserveComposeWorkingDir=true", + "/p:DoNotDecorateComposeDir=true", + "/p:CreateProfilingSymbols=false" + ); + + composeStore.Should().Pass(); + + new DirectoryInfo(outputFolder).GetDirectories() + .Select(d => d.Name) + .Should().BeEquivalentTo( + "fluentassertions", + "newtonsoft.json", + "system.configuration.configurationmanager", + "system.security.cryptography.protecteddata"); + + } + private static HashSet ParseStoreArtifacts(string path) { return new HashSet(