Switched to using a FallbackPackagePathResolver to find the tool dll, because now with Fallback folders, we can have the tool dll in the fallback folder but its assets file in the user nuget cache. This happens because Nuget never writes to the fallback folder, including the tool's assets file that it generates during restore.

This commit is contained in:
Livar Cunha 2017-03-23 22:20:47 -07:00
parent b2ac1cf8df
commit 10e743e8e5
10 changed files with 182 additions and 19 deletions

View file

@ -0,0 +1,15 @@
// 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 System;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello Fallback folder World!");
}
}
}

View file

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), testAsset.props))\testAsset.props" />
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<AssemblyName>dotnet-fallbackfoldertool</AssemblyName>
<OutputType>Exe</OutputType>
<VersionSuffix></VersionSuffix>
<RuntimeFrameworkVersion>$(CLI_SharedFrameworkVersion)</RuntimeFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<BuiltProjectOutputGroupOutput Include="$(ProjectRuntimeConfigFilePath)">
<FinalOutputPath>$(ProjectRuntimeConfigFilePath)</FinalOutputPath>
</BuiltProjectOutputGroupOutput>
</ItemGroup>
</Project>

View file

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), testAsset.props))\testAsset.props" />
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<OutputType>Exe</OutputType>
<RuntimeFrameworkVersion>$(CLI_SharedFrameworkVersion)</RuntimeFrameworkVersion>
<DotnetCliToolTargetFramework>netcoreapp2.0</DotnetCliToolTargetFramework>
</PropertyGroup>
<ItemGroup>
<DotNetCliToolReference Include="dotnet-fallbackfoldertool" Version="1.0.0" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="test-packages" value="../../../artifacts/testpackages" />
</packageSources>
</configuration>

View file

@ -0,0 +1,15 @@
// 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 System;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

View file

@ -127,6 +127,15 @@
<VersionSuffix></VersionSuffix>
<Clean>True</Clean>
</BaseTestPackageProject>
<BaseTestPackageProject Include="TestAssets/TestPackages/dotnet-fallbackfoldertool">
<Name>dotnet-fallbackfoldertool</Name>
<ProjectName>dotnet-fallbackfoldertool.csproj</ProjectName>
<IsTool>True</IsTool>
<IsApplicable>True</IsApplicable>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
<Clean>True</Clean>
</BaseTestPackageProject>
<BaseTestPackageProject Include="TestAssets/TestPackages/dotnet-prefercliruntime">
<Name>dotnet-prefercliruntime</Name>
<ProjectName>dotnet-prefercliruntime.csproj</ProjectName>

View file

@ -18,5 +18,14 @@ namespace Microsoft.DotNet.Cli.Utils
string depsFilePath,
string runtimeConfigPath);
CommandSpec CreateCommandSpecFromLibrary(
LockFileTargetLibrary toolLibrary,
string commandName,
IEnumerable<string> commandArguments,
IEnumerable<string> allowedExtensions,
IEnumerable<string> packageFolders,
CommandResolutionStrategy commandResolutionStrategy,
string depsFilePath,
string runtimeConfigPath);
}
}

View file

@ -31,6 +31,27 @@ namespace Microsoft.DotNet.Cli.Utils
CommandResolutionStrategy commandResolutionStrategy,
string depsFilePath,
string runtimeConfigPath)
{
return CreateCommandSpecFromLibrary(
toolLibrary,
commandName,
commandArguments,
allowedExtensions,
new List<string> { nugetPackagesRoot },
commandResolutionStrategy,
depsFilePath,
runtimeConfigPath);
}
public CommandSpec CreateCommandSpecFromLibrary(
LockFileTargetLibrary toolLibrary,
string commandName,
IEnumerable<string> commandArguments,
IEnumerable<string> allowedExtensions,
IEnumerable<string> packageFolders,
CommandResolutionStrategy commandResolutionStrategy,
string depsFilePath,
string runtimeConfigPath)
{
Reporter.Verbose.WriteLine(string.Format(
LocalizableStrings.AttemptingToFindCommand,
@ -51,7 +72,7 @@ namespace Microsoft.DotNet.Cli.Utils
return null;
}
var commandPath = GetCommandFilePath(nugetPackagesRoot, toolLibrary, toolAssembly);
var commandPath = GetCommandFilePath(packageFolders, toolLibrary, toolAssembly);
if (!File.Exists(commandPath))
{
@ -68,17 +89,22 @@ namespace Microsoft.DotNet.Cli.Utils
commandArguments,
depsFilePath,
commandResolutionStrategy,
nugetPackagesRoot,
packageFolders,
runtimeConfigPath);
}
private string GetCommandFilePath(
string nugetPackagesRoot,
IEnumerable<string> packageFolders,
LockFileTargetLibrary toolLibrary,
LockFileItem runtimeAssembly)
{
var packageDirectory = new VersionFolderPathResolver(nugetPackagesRoot)
.GetInstallPath(toolLibrary.Name, toolLibrary.Version);
var packageFoldersCount = packageFolders.Count();
var userPackageFolder = packageFoldersCount == 1 ? string.Empty : packageFolders.First();
var fallbackPackageFolders = packageFoldersCount > 1 ? packageFolders.Skip(1) : packageFolders;
var packageDirectory = new FallbackPackagePathResolver(userPackageFolder, fallbackPackageFolders)
.GetPackageDirectory(toolLibrary.Name, toolLibrary.Version);
var filePath = Path.Combine(
packageDirectory,
@ -92,7 +118,7 @@ namespace Microsoft.DotNet.Cli.Utils
IEnumerable<string> commandArguments,
string depsFilePath,
CommandResolutionStrategy commandResolutionStrategy,
string nugetPackagesRoot,
IEnumerable<string> packageFolders,
string runtimeConfigPath)
{
var commandExtension = Path.GetExtension(commandPath);
@ -104,7 +130,7 @@ namespace Microsoft.DotNet.Cli.Utils
commandArguments,
depsFilePath,
commandResolutionStrategy,
nugetPackagesRoot,
packageFolders,
runtimeConfigPath);
}
@ -116,7 +142,7 @@ namespace Microsoft.DotNet.Cli.Utils
IEnumerable<string> commandArguments,
string depsFilePath,
CommandResolutionStrategy commandResolutionStrategy,
string nugetPackagesRoot,
IEnumerable<string> packageFolders,
string runtimeConfigPath)
{
var host = string.Empty;
@ -144,8 +170,11 @@ namespace Microsoft.DotNet.Cli.Utils
arguments.Add(depsFilePath);
}
arguments.Add("--additionalprobingpath");
arguments.Add(nugetPackagesRoot);
foreach (var packageFolder in packageFolders)
{
arguments.Add("--additionalprobingpath");
arguments.Add(packageFolder);
}
if(_addAdditionalArguments != null)
{

View file

@ -136,12 +136,10 @@ namespace Microsoft.DotNet.Cli.Utils
var toolPackageFramework = project.DotnetCliToolTargetFramework;
string nugetPackagesRoot;
var toolLockFile = GetToolLockFile(
toolLibraryRange,
toolPackageFramework,
possiblePackageRoots,
out nugetPackagesRoot);
possiblePackageRoots);
if (toolLockFile == null)
{
@ -174,7 +172,8 @@ namespace Microsoft.DotNet.Cli.Utils
toolLockFile,
depsFileRoot);
var normalizedNugetPackagesRoot = PathUtility.EnsureNoTrailingDirectorySeparator(nugetPackagesRoot);
var packageFolders = toolLockFile.PackageFolders.Select(p =>
PathUtility.EnsureNoTrailingDirectorySeparator(p.Path));
Reporter.Verbose.WriteLine(string.Format(
LocalizableStrings.AttemptingToCreateCommandSpec,
@ -185,7 +184,7 @@ namespace Microsoft.DotNet.Cli.Utils
commandName,
args,
_allowedCommandExtensions,
normalizedNugetPackagesRoot,
packageFolders,
s_commandResolutionStrategy,
depsFilePath,
null);
@ -215,19 +214,16 @@ namespace Microsoft.DotNet.Cli.Utils
private LockFile GetToolLockFile(
SingleProjectInfo toolLibrary,
NuGetFramework framework,
IEnumerable<string> possibleNugetPackagesRoot,
out string nugetPackagesRoot)
IEnumerable<string> possibleNugetPackagesRoot)
{
foreach (var packagesRoot in possibleNugetPackagesRoot)
{
if (TryGetToolLockFile(toolLibrary, framework, packagesRoot, out LockFile lockFile))
{
nugetPackagesRoot = packagesRoot;
return lockFile;
}
}
nugetPackagesRoot = null;
return null;
}

View file

@ -335,6 +335,59 @@ namespace Microsoft.DotNet.Tests
result.Args.Should().NotContain("--fx-version");
}
[Fact]
public void ItFindsToolsLocatedInTheNuGetFallbackFolder()
{
var projectToolsCommandResolver = SetupProjectToolsCommandResolver();
var testInstance = TestAssets.Get("AppWithFallbackFolderToolDependency")
.CreateInstance()
.WithSourceFiles();
var testProjectDirectory = testInstance.Root.FullName;
var fallbackFolder = Path.Combine(testProjectDirectory, "fallbackFolder");
PopulateFallbackFolder(testProjectDirectory, fallbackFolder);
var nugetConfig = testInstance.Root.GetFile("NuGet.Config").FullName;
File.WriteAllText(
nugetConfig,
$@"<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
<fallbackPackageFolders>
<add key=""MachineWide"" value=""{fallbackFolder}""/>
</fallbackPackageFolders>
</configuration>
");
new RestoreCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute($"--configfile {nugetConfig}")
.Should()
.Pass();
var commandResolverArguments = new CommandResolverArguments()
{
CommandName = "dotnet-fallbackfoldertool",
CommandArguments = null,
ProjectDirectory = testProjectDirectory
};
var result = projectToolsCommandResolver.Resolve(commandResolverArguments);
result.Should().NotBeNull();
}
private void PopulateFallbackFolder(string testProjectDirectory, string fallbackFolder)
{
new RestoreCommand()
.WithWorkingDirectory(testProjectDirectory)
.Execute($"--packages {fallbackFolder}")
.Should()
.Pass();
Directory.Delete(Path.Combine(fallbackFolder, ".tools"), true);
}
private ProjectToolsCommandResolver SetupProjectToolsCommandResolver()
{
Environment.SetEnvironmentVariable(