From 8b13b3e5797dbe37444f99991100da0eb5c1b7a6 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 5 May 2017 13:13:18 -0700 Subject: [PATCH 1/2] Fall back to tools restored for .NET Core 1.x if they haven't been restored for .NET Core 2.0 --- .../ProjectToolsCommandResolver.cs | 26 ++++++++- test/dotnet.Tests/PackagedCommandTests.cs | 55 ++++++++++++++++++- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ProjectToolsCommandResolver.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ProjectToolsCommandResolver.cs index 7cd9a6113..8f952c950 100644 --- a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ProjectToolsCommandResolver.cs +++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ProjectToolsCommandResolver.cs @@ -141,9 +141,33 @@ namespace Microsoft.DotNet.Cli.Utils toolPackageFramework, possiblePackageRoots); + + // NuGet restore in Visual Studio may restore for netcoreapp1.0. So if that happens, fall back to + // looking for a netcoreapp1.0 or netcoreapp1.1 tool restore. if (toolLockFile == null) { - return null; + if (toolPackageFramework.Framework == FrameworkConstants.FrameworkIdentifiers.NetCoreApp && + toolPackageFramework.Version >= new Version(2, 0, 0)) + { + foreach (var fallbackFramework in new [] { "netcoreapp1.1", "netcoreapp1.0"}) + { + toolPackageFramework = NuGetFramework.Parse(fallbackFramework); + toolLockFile = GetToolLockFile( + toolLibraryRange, + toolPackageFramework, + possiblePackageRoots); + + if (toolLockFile != null) + { + break; + } + } + } + + if (toolLockFile == null) + { + return null; + } } Reporter.Verbose.WriteLine(string.Format( diff --git a/test/dotnet.Tests/PackagedCommandTests.cs b/test/dotnet.Tests/PackagedCommandTests.cs index bb75131d5..d5c83d97a 100644 --- a/test/dotnet.Tests/PackagedCommandTests.cs +++ b/test/dotnet.Tests/PackagedCommandTests.cs @@ -16,6 +16,7 @@ using Xunit.Abstractions; using Microsoft.Build.Construction; using System.Linq; using Microsoft.Build.Evaluation; +using System.Xml.Linq; namespace Microsoft.DotNet.Tests { @@ -161,10 +162,62 @@ namespace Microsoft.DotNet.Tests .Execute(toolPrefersCLIRuntime ? "portable-v1-prefercli" : "portable-v1"); result.Should().Pass() - .And.HaveStdOutContaining("I'm running on shared framework version 1.1.1!"); + .And.HaveStdOutContaining("I'm running on shared framework version 1.1.1!"); } + [RequiresSpecificFrameworkFact("netcoreapp1.1")] + public void IfAToolHasNotBeenRestoredForNetCoreApp2_0ItFallsBackToNetCoreApp1_x() + { + string toolName = "dotnet-portable-v1"; + + var toolFolder = Path.Combine(new RepoDirectoriesProvider().NugetPackages, + ".tools", + toolName); + + // Other tests may have restored the tool for netcoreapp2.0, so delete its tools folder + if (Directory.Exists(toolFolder)) + { + Directory.Delete(toolFolder, true); + } + + var testInstance = TestAssets.Get("AppWithToolDependency") + .CreateInstance() + .WithSourceFiles() + .WithNuGetConfig(new RepoDirectoriesProvider().TestPackages); + + testInstance = testInstance.WithProjectChanges(project => + { + var ns = project.Root.Name.Namespace; + + // Remove reference to tool that won't restore on 1.x + project.Descendants(ns + "DotNetCliToolReference") + .Where(tr => tr.Attribute("Include").Value == "dotnet-PreferCliRuntime") + .Remove(); + + var toolReference = project.Descendants(ns + "DotNetCliToolReference") + .Where(tr => tr.Attribute("Include").Value == "dotnet-portable") + .Single(); + + toolReference.Attribute("Include").Value = toolName; + + // Restore tools for .NET Core 1.1 + project.Root.Element(ns + "PropertyGroup") + .Add(new XElement(ns + "DotnetCliToolTargetFramework", "netcoreapp1.1")); + + }); + + testInstance = testInstance.WithRestoreFiles(); + + var result = + new DotnetCommand(DotnetUnderTest.WithBackwardsCompatibleRuntimes) + .WithWorkingDirectory(testInstance.Root) + .Execute("portable-v1"); + + result.Should().Pass() + .And.HaveStdOutContaining("I'm running on shared framework version 1.1.1!"); + } + [Fact] public void CanInvokeToolWhosePackageNameIsDifferentFromDllName() { From 10dd67baa8853d0a01e229f685e85f4d4f71fab1 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 5 May 2017 14:23:33 -0700 Subject: [PATCH 2/2] Clean up tool restore framework fallback logic so there aren't multiple call sites to GetToolLockFile --- .../ProjectToolsCommandResolver.cs | 61 +++++++++---------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ProjectToolsCommandResolver.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ProjectToolsCommandResolver.cs index 8f952c950..a75472142 100644 --- a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ProjectToolsCommandResolver.cs +++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ProjectToolsCommandResolver.cs @@ -134,40 +134,39 @@ namespace Microsoft.DotNet.Cli.Utils ProjectToolsCommandResolverName, string.Join(Environment.NewLine, possiblePackageRoots.Select((p) => $"- {p}")))); - var toolPackageFramework = project.DotnetCliToolTargetFramework; - - var toolLockFile = GetToolLockFile( - toolLibraryRange, - toolPackageFramework, - possiblePackageRoots); - + List toolFrameworksToCheck = new List(); + toolFrameworksToCheck.Add(project.DotnetCliToolTargetFramework); // NuGet restore in Visual Studio may restore for netcoreapp1.0. So if that happens, fall back to // looking for a netcoreapp1.0 or netcoreapp1.1 tool restore. + if (project.DotnetCliToolTargetFramework.Framework == FrameworkConstants.FrameworkIdentifiers.NetCoreApp && + project.DotnetCliToolTargetFramework.Version >= new Version(2, 0, 0)) + { + toolFrameworksToCheck.Add(NuGetFramework.Parse("netcoreapp1.1")); + toolFrameworksToCheck.Add(NuGetFramework.Parse("netcoreapp1.0")); + } + + + LockFile toolLockFile = null; + NuGetFramework toolTargetFramework = null; ; + + foreach (var toolFramework in toolFrameworksToCheck) + { + toolLockFile = GetToolLockFile( + toolLibraryRange, + toolFramework, + possiblePackageRoots); + + if (toolLockFile != null) + { + toolTargetFramework = toolFramework; + break; + } + } + if (toolLockFile == null) { - if (toolPackageFramework.Framework == FrameworkConstants.FrameworkIdentifiers.NetCoreApp && - toolPackageFramework.Version >= new Version(2, 0, 0)) - { - foreach (var fallbackFramework in new [] { "netcoreapp1.1", "netcoreapp1.0"}) - { - toolPackageFramework = NuGetFramework.Parse(fallbackFramework); - toolLockFile = GetToolLockFile( - toolLibraryRange, - toolPackageFramework, - possiblePackageRoots); - - if (toolLockFile != null) - { - break; - } - } - } - - if (toolLockFile == null) - { - return null; - } + return null; } Reporter.Verbose.WriteLine(string.Format( @@ -176,7 +175,7 @@ namespace Microsoft.DotNet.Cli.Utils toolLockFile.Path)); var toolLibrary = toolLockFile.Targets - .FirstOrDefault(t => toolPackageFramework == t.TargetFramework) + .FirstOrDefault(t => toolTargetFramework == t.TargetFramework) ?.Libraries.FirstOrDefault( l => StringComparer.OrdinalIgnoreCase.Equals(l.Name, toolLibraryRange.Name)); if (toolLibrary == null) @@ -192,7 +191,7 @@ namespace Microsoft.DotNet.Cli.Utils var depsFilePath = GetToolDepsFilePath( toolLibraryRange, - toolPackageFramework, + toolTargetFramework, toolLockFile, depsFileRoot, project.ToolDepsJsonGeneratorProject);