Merge pull request #6138 from livarcocc/tool_fallback_folder
Switched to using a FallbackPackagePathResolver to find the tool dll
This commit is contained in:
commit
e09c33400c
11 changed files with 242 additions and 19 deletions
15
TestAssets/TestPackages/dotnet-fallbackfoldertool/Program.cs
Normal file
15
TestAssets/TestPackages/dotnet-fallbackfoldertool/Program.cs
Normal 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!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>
|
|
@ -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>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<add key="test-packages" value="../../../artifacts/testpackages" />
|
||||||
|
</packageSources>
|
||||||
|
</configuration>
|
|
@ -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!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -127,6 +127,15 @@
|
||||||
<VersionSuffix></VersionSuffix>
|
<VersionSuffix></VersionSuffix>
|
||||||
<Clean>True</Clean>
|
<Clean>True</Clean>
|
||||||
</BaseTestPackageProject>
|
</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">
|
<BaseTestPackageProject Include="TestAssets/TestPackages/dotnet-prefercliruntime">
|
||||||
<Name>dotnet-prefercliruntime</Name>
|
<Name>dotnet-prefercliruntime</Name>
|
||||||
<ProjectName>dotnet-prefercliruntime.csproj</ProjectName>
|
<ProjectName>dotnet-prefercliruntime.csproj</ProjectName>
|
||||||
|
|
|
@ -18,5 +18,14 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
string depsFilePath,
|
string depsFilePath,
|
||||||
string runtimeConfigPath);
|
string runtimeConfigPath);
|
||||||
|
|
||||||
|
CommandSpec CreateCommandSpecFromLibrary(
|
||||||
|
LockFileTargetLibrary toolLibrary,
|
||||||
|
string commandName,
|
||||||
|
IEnumerable<string> commandArguments,
|
||||||
|
IEnumerable<string> allowedExtensions,
|
||||||
|
IEnumerable<string> packageFolders,
|
||||||
|
CommandResolutionStrategy commandResolutionStrategy,
|
||||||
|
string depsFilePath,
|
||||||
|
string runtimeConfigPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,27 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
CommandResolutionStrategy commandResolutionStrategy,
|
CommandResolutionStrategy commandResolutionStrategy,
|
||||||
string depsFilePath,
|
string depsFilePath,
|
||||||
string runtimeConfigPath)
|
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(
|
Reporter.Verbose.WriteLine(string.Format(
|
||||||
LocalizableStrings.AttemptingToFindCommand,
|
LocalizableStrings.AttemptingToFindCommand,
|
||||||
|
@ -51,7 +72,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var commandPath = GetCommandFilePath(nugetPackagesRoot, toolLibrary, toolAssembly);
|
var commandPath = GetCommandFilePath(packageFolders, toolLibrary, toolAssembly);
|
||||||
|
|
||||||
if (!File.Exists(commandPath))
|
if (!File.Exists(commandPath))
|
||||||
{
|
{
|
||||||
|
@ -68,17 +89,28 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
commandArguments,
|
commandArguments,
|
||||||
depsFilePath,
|
depsFilePath,
|
||||||
commandResolutionStrategy,
|
commandResolutionStrategy,
|
||||||
nugetPackagesRoot,
|
packageFolders,
|
||||||
runtimeConfigPath);
|
runtimeConfigPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetCommandFilePath(
|
private string GetCommandFilePath(
|
||||||
string nugetPackagesRoot,
|
IEnumerable<string> packageFolders,
|
||||||
LockFileTargetLibrary toolLibrary,
|
LockFileTargetLibrary toolLibrary,
|
||||||
LockFileItem runtimeAssembly)
|
LockFileItem runtimeAssembly)
|
||||||
{
|
{
|
||||||
var packageDirectory = new VersionFolderPathResolver(nugetPackagesRoot)
|
var packageFoldersCount = packageFolders.Count();
|
||||||
.GetInstallPath(toolLibrary.Name, toolLibrary.Version);
|
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);
|
||||||
|
|
||||||
|
if (packageDirectory == null)
|
||||||
|
{
|
||||||
|
throw new GracefulException(string.Format(
|
||||||
|
LocalizableStrings.CommandAssembliesNotFound,
|
||||||
|
toolLibrary.Name));
|
||||||
|
}
|
||||||
|
|
||||||
var filePath = Path.Combine(
|
var filePath = Path.Combine(
|
||||||
packageDirectory,
|
packageDirectory,
|
||||||
|
@ -92,7 +124,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
IEnumerable<string> commandArguments,
|
IEnumerable<string> commandArguments,
|
||||||
string depsFilePath,
|
string depsFilePath,
|
||||||
CommandResolutionStrategy commandResolutionStrategy,
|
CommandResolutionStrategy commandResolutionStrategy,
|
||||||
string nugetPackagesRoot,
|
IEnumerable<string> packageFolders,
|
||||||
string runtimeConfigPath)
|
string runtimeConfigPath)
|
||||||
{
|
{
|
||||||
var commandExtension = Path.GetExtension(commandPath);
|
var commandExtension = Path.GetExtension(commandPath);
|
||||||
|
@ -104,7 +136,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
commandArguments,
|
commandArguments,
|
||||||
depsFilePath,
|
depsFilePath,
|
||||||
commandResolutionStrategy,
|
commandResolutionStrategy,
|
||||||
nugetPackagesRoot,
|
packageFolders,
|
||||||
runtimeConfigPath);
|
runtimeConfigPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +148,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
IEnumerable<string> commandArguments,
|
IEnumerable<string> commandArguments,
|
||||||
string depsFilePath,
|
string depsFilePath,
|
||||||
CommandResolutionStrategy commandResolutionStrategy,
|
CommandResolutionStrategy commandResolutionStrategy,
|
||||||
string nugetPackagesRoot,
|
IEnumerable<string> packageFolders,
|
||||||
string runtimeConfigPath)
|
string runtimeConfigPath)
|
||||||
{
|
{
|
||||||
var host = string.Empty;
|
var host = string.Empty;
|
||||||
|
@ -144,8 +176,11 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
arguments.Add(depsFilePath);
|
arguments.Add(depsFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
arguments.Add("--additionalprobingpath");
|
foreach (var packageFolder in packageFolders)
|
||||||
arguments.Add(nugetPackagesRoot);
|
{
|
||||||
|
arguments.Add("--additionalprobingpath");
|
||||||
|
arguments.Add(packageFolder);
|
||||||
|
}
|
||||||
|
|
||||||
if(_addAdditionalArguments != null)
|
if(_addAdditionalArguments != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -136,12 +136,10 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
|
|
||||||
var toolPackageFramework = project.DotnetCliToolTargetFramework;
|
var toolPackageFramework = project.DotnetCliToolTargetFramework;
|
||||||
|
|
||||||
string nugetPackagesRoot;
|
|
||||||
var toolLockFile = GetToolLockFile(
|
var toolLockFile = GetToolLockFile(
|
||||||
toolLibraryRange,
|
toolLibraryRange,
|
||||||
toolPackageFramework,
|
toolPackageFramework,
|
||||||
possiblePackageRoots,
|
possiblePackageRoots);
|
||||||
out nugetPackagesRoot);
|
|
||||||
|
|
||||||
if (toolLockFile == null)
|
if (toolLockFile == null)
|
||||||
{
|
{
|
||||||
|
@ -174,7 +172,8 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
toolLockFile,
|
toolLockFile,
|
||||||
depsFileRoot);
|
depsFileRoot);
|
||||||
|
|
||||||
var normalizedNugetPackagesRoot = PathUtility.EnsureNoTrailingDirectorySeparator(nugetPackagesRoot);
|
var packageFolders = toolLockFile.PackageFolders.Select(p =>
|
||||||
|
PathUtility.EnsureNoTrailingDirectorySeparator(p.Path));
|
||||||
|
|
||||||
Reporter.Verbose.WriteLine(string.Format(
|
Reporter.Verbose.WriteLine(string.Format(
|
||||||
LocalizableStrings.AttemptingToCreateCommandSpec,
|
LocalizableStrings.AttemptingToCreateCommandSpec,
|
||||||
|
@ -185,7 +184,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
commandName,
|
commandName,
|
||||||
args,
|
args,
|
||||||
_allowedCommandExtensions,
|
_allowedCommandExtensions,
|
||||||
normalizedNugetPackagesRoot,
|
packageFolders,
|
||||||
s_commandResolutionStrategy,
|
s_commandResolutionStrategy,
|
||||||
depsFilePath,
|
depsFilePath,
|
||||||
null);
|
null);
|
||||||
|
@ -215,19 +214,16 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
private LockFile GetToolLockFile(
|
private LockFile GetToolLockFile(
|
||||||
SingleProjectInfo toolLibrary,
|
SingleProjectInfo toolLibrary,
|
||||||
NuGetFramework framework,
|
NuGetFramework framework,
|
||||||
IEnumerable<string> possibleNugetPackagesRoot,
|
IEnumerable<string> possibleNugetPackagesRoot)
|
||||||
out string nugetPackagesRoot)
|
|
||||||
{
|
{
|
||||||
foreach (var packagesRoot in possibleNugetPackagesRoot)
|
foreach (var packagesRoot in possibleNugetPackagesRoot)
|
||||||
{
|
{
|
||||||
if (TryGetToolLockFile(toolLibrary, framework, packagesRoot, out LockFile lockFile))
|
if (TryGetToolLockFile(toolLibrary, framework, packagesRoot, out LockFile lockFile))
|
||||||
{
|
{
|
||||||
nugetPackagesRoot = packagesRoot;
|
|
||||||
return lockFile;
|
return lockFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nugetPackagesRoot = null;
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,8 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
|
|
||||||
public const string NoExecutableFoundMatchingCommand = "No executable found matching command \"{0}\"";
|
public const string NoExecutableFoundMatchingCommand = "No executable found matching command \"{0}\"";
|
||||||
|
|
||||||
|
public const string CommandAssembliesNotFound = "The command executable for \"{0}\" was not found. The project may not have been restored or restore failed - run `dotnet restore`";
|
||||||
|
|
||||||
public const string WaitingForDebuggerToAttach = "Waiting for debugger to attach. Press ENTER to continue";
|
public const string WaitingForDebuggerToAttach = "Waiting for debugger to attach. Press ENTER to continue";
|
||||||
|
|
||||||
public const string ProcessId = "Process ID: {0}";
|
public const string ProcessId = "Process ID: {0}";
|
||||||
|
|
|
@ -335,6 +335,111 @@ namespace Microsoft.DotNet.Tests
|
||||||
result.Args.Should().NotContain("--fx-version");
|
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 = UseNuGetConfigWithFallbackFolder(testInstance, fallbackFolder);
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
var commandPath = result.Args.Trim('"');
|
||||||
|
commandPath.Should().Contain(Path.Combine(
|
||||||
|
fallbackFolder,
|
||||||
|
"dotnet-fallbackfoldertool",
|
||||||
|
"1.0.0",
|
||||||
|
"lib",
|
||||||
|
"netcoreapp2.0",
|
||||||
|
"dotnet-fallbackfoldertool.dll"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ItXXXWhenTheToolDllIsNotFound()
|
||||||
|
{
|
||||||
|
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 = UseNuGetConfigWithFallbackFolder(testInstance, fallbackFolder);
|
||||||
|
|
||||||
|
new RestoreCommand()
|
||||||
|
.WithWorkingDirectory(testProjectDirectory)
|
||||||
|
.Execute($"--configfile {nugetConfig}")
|
||||||
|
.Should()
|
||||||
|
.Pass();
|
||||||
|
|
||||||
|
Directory.Delete(Path.Combine(fallbackFolder, "dotnet-fallbackfoldertool"), true);
|
||||||
|
|
||||||
|
var commandResolverArguments = new CommandResolverArguments()
|
||||||
|
{
|
||||||
|
CommandName = "dotnet-fallbackfoldertool",
|
||||||
|
CommandArguments = null,
|
||||||
|
ProjectDirectory = testProjectDirectory
|
||||||
|
};
|
||||||
|
|
||||||
|
Action action = () => projectToolsCommandResolver.Resolve(commandResolverArguments);
|
||||||
|
|
||||||
|
action.ShouldThrow<GracefulException>().WithMessage(
|
||||||
|
"The command executable for \"dotnet-fallbackfoldertool\" was not found. The project may not have been restored or restore failed - run `dotnet restore`");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopulateFallbackFolder(string testProjectDirectory, string fallbackFolder)
|
||||||
|
{
|
||||||
|
new RestoreCommand()
|
||||||
|
.WithWorkingDirectory(testProjectDirectory)
|
||||||
|
.Execute($"--packages {fallbackFolder}")
|
||||||
|
.Should()
|
||||||
|
.Pass();
|
||||||
|
|
||||||
|
Directory.Delete(Path.Combine(fallbackFolder, ".tools"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string UseNuGetConfigWithFallbackFolder(TestAssetInstance testInstance, string 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>
|
||||||
|
");
|
||||||
|
|
||||||
|
return nugetConfig;
|
||||||
|
}
|
||||||
|
|
||||||
private ProjectToolsCommandResolver SetupProjectToolsCommandResolver()
|
private ProjectToolsCommandResolver SetupProjectToolsCommandResolver()
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable(
|
Environment.SetEnvironmentVariable(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue