Fixing ProjectDependenciesCommandFactory to resolve tools
if the package name is different from the dll name Addresses #2592
This commit is contained in:
parent
3d8cbba932
commit
1aac8fb643
12 changed files with 231 additions and 21 deletions
12
TestAssets/TestPackages/ToolWithOutputName/Program.cs
Normal file
12
TestAssets/TestPackages/ToolWithOutputName/Program.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace ConsoleApplication
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Tool with output name!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
TestAssets/TestPackages/ToolWithOutputName/project.json
Normal file
17
TestAssets/TestPackages/ToolWithOutputName/project.json
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0",
|
||||||
|
"compilationOptions": {
|
||||||
|
"outputName": "dotnet-tool-with-output-name",
|
||||||
|
"emitEntryPoint": true
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"netcoreapp1.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"type": "platform",
|
||||||
|
"version": "1.0.0-rc2-*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace ConsoleApplication
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
Console.WriteLine("App with a dependency on a tool whose package name is different from the dll name!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
"compilationOptions": {
|
||||||
|
"emitEntryPoint": true
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"version": "1.0.0-rc2-*",
|
||||||
|
"type": "platform"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"netcoreapp1.0": { }
|
||||||
|
},
|
||||||
|
|
||||||
|
"tools": {
|
||||||
|
"ToolWithOutputName": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"target": "package"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace ConsoleApplication
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Contains a dependency on a tool whose package name is different from the dll name.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"compilationOptions": {
|
||||||
|
"emitEntryPoint": true
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ToolWithOutputName": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"target": "package"
|
||||||
|
},
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"version": "1.0.0-rc2-*",
|
||||||
|
"type": "platform"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"netcoreapp1.0": { }
|
||||||
|
},
|
||||||
|
"tools": {
|
||||||
|
"dotnet-dependency-tool-invoker": {
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
"imports": [
|
||||||
|
"dnxcore50",
|
||||||
|
"portable-net45+win8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
{
|
{
|
||||||
"compilationOptions": {
|
"compilationOptions": {
|
||||||
"outputName": "MyApp",
|
"outputName": "MyApp",
|
||||||
"emitEntryPoint": true,
|
"emitEntryPoint": true
|
||||||
"preserveCompilationContext": true
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.NETCore.App": "1.0.0-rc2-*"
|
"Microsoft.NETCore.App": "1.0.0-rc2-*"
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace Microsoft.DotNet.Cli.Build
|
||||||
Name = "dotnet-dependency-tool-invoker",
|
Name = "dotnet-dependency-tool-invoker",
|
||||||
IsTool = true,
|
IsTool = true,
|
||||||
Path = "TestAssets/TestPackages/dotnet-dependency-tool-invoker",
|
Path = "TestAssets/TestPackages/dotnet-dependency-tool-invoker",
|
||||||
IsApplicable = CurrentPlatform.IsWindows,
|
IsApplicable = true,
|
||||||
VersionSuffix = s_testPackageBuildVersionSuffix,
|
VersionSuffix = s_testPackageBuildVersionSuffix,
|
||||||
Clean = true,
|
Clean = true,
|
||||||
Frameworks = new [] { "netcoreapp1.0" }
|
Frameworks = new [] { "netcoreapp1.0" }
|
||||||
|
@ -107,6 +107,16 @@ namespace Microsoft.DotNet.Cli.Build
|
||||||
Frameworks = new [] { "netcoreapp1.0" }
|
Frameworks = new [] { "netcoreapp1.0" }
|
||||||
},
|
},
|
||||||
new TestPackageProject()
|
new TestPackageProject()
|
||||||
|
{
|
||||||
|
Name = "ToolWithOutputName",
|
||||||
|
IsTool = true,
|
||||||
|
Path = "TestAssets/TestPackages/ToolWithOutputName",
|
||||||
|
IsApplicable = true,
|
||||||
|
VersionSuffix = string.Empty,
|
||||||
|
Clean = true,
|
||||||
|
Frameworks = new [] { "netcoreapp1.0" }
|
||||||
|
},
|
||||||
|
new TestPackageProject()
|
||||||
{
|
{
|
||||||
Name = "Microsoft.DotNet.Cli.Utils",
|
Name = "Microsoft.DotNet.Cli.Utils",
|
||||||
IsTool = true,
|
IsTool = true,
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
{
|
{
|
||||||
public class ProjectDependenciesCommandResolver : ICommandResolver
|
public class ProjectDependenciesCommandResolver : ICommandResolver
|
||||||
{
|
{
|
||||||
private static readonly CommandResolutionStrategy s_commandResolutionStrategy =
|
private static readonly CommandResolutionStrategy s_commandResolutionStrategy =
|
||||||
CommandResolutionStrategy.ProjectDependenciesPackage;
|
CommandResolutionStrategy.ProjectDependenciesPackage;
|
||||||
|
|
||||||
private readonly IEnvironmentProvider _environment;
|
private readonly IEnvironmentProvider _environment;
|
||||||
|
@ -78,7 +78,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
var depsFilePath =
|
var depsFilePath =
|
||||||
projectContext.GetOutputPaths(configuration, buildBasePath, outputPath).RuntimeFiles.DepsJson;
|
projectContext.GetOutputPaths(configuration, buildBasePath, outputPath).RuntimeFiles.DepsJson;
|
||||||
|
|
||||||
var runtimeConfigPath =
|
var runtimeConfigPath =
|
||||||
projectContext.GetOutputPaths(configuration, buildBasePath, outputPath).RuntimeFiles.RuntimeConfigJson;
|
projectContext.GetOutputPaths(configuration, buildBasePath, outputPath).RuntimeFiles.RuntimeConfigJson;
|
||||||
|
|
||||||
var toolLibrary = GetToolLibraryForContext(projectContext, commandName);
|
var toolLibrary = GetToolLibraryForContext(projectContext, commandName);
|
||||||
|
@ -97,12 +97,18 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
private LockFileTargetLibrary GetToolLibraryForContext(
|
private LockFileTargetLibrary GetToolLibraryForContext(
|
||||||
ProjectContext projectContext, string commandName)
|
ProjectContext projectContext, string commandName)
|
||||||
{
|
{
|
||||||
var toolLibrary = projectContext.LockFile.Targets
|
var toolLibraries = projectContext.LockFile.Targets
|
||||||
.FirstOrDefault(t => t.TargetFramework.GetShortFolderName()
|
.FirstOrDefault(t => t.TargetFramework.GetShortFolderName()
|
||||||
.Equals(projectContext.TargetFramework.GetShortFolderName()))
|
.Equals(projectContext.TargetFramework.GetShortFolderName()))
|
||||||
?.Libraries.FirstOrDefault(l => l.Name == commandName);
|
?.Libraries.Where(l => l.Name == commandName ||
|
||||||
|
l.RuntimeAssemblies.Any(r => Path.GetFileNameWithoutExtension(r.Path) == commandName)).ToList();
|
||||||
|
|
||||||
return toolLibrary;
|
if (toolLibraries?.Count() > 1)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Ambiguous command name: {commandName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return toolLibraries?.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProjectContext GetProjectContextFromDirectory(string directory, NuGetFramework framework)
|
private ProjectContext GetProjectContextFromDirectory(string directory, NuGetFramework framework)
|
||||||
|
@ -120,8 +126,8 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProjectContext.Create(
|
return ProjectContext.Create(
|
||||||
projectRootPath,
|
projectRootPath,
|
||||||
framework,
|
framework,
|
||||||
PlatformServices.Default.Runtime.GetAllCandidateRuntimeIdentifiers());
|
PlatformServices.Default.Runtime.GetAllCandidateRuntimeIdentifiers());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,8 @@ namespace Microsoft.DotNet.Cli.Utils.Tests
|
||||||
{
|
{
|
||||||
public class GivenAProjectDependenciesCommandFactory : TestBase
|
public class GivenAProjectDependenciesCommandFactory : TestBase
|
||||||
{
|
{
|
||||||
private static readonly NuGetFramework s_desktopTestFramework = FrameworkConstants.CommonFrameworks.Net451;
|
private static readonly NuGetFramework s_desktopTestFramework = FrameworkConstants.CommonFrameworks.Net451;
|
||||||
|
|
||||||
[WindowsOnlyFact]
|
[WindowsOnlyFact]
|
||||||
public void It_resolves_desktop_apps_defaulting_to_Debug_Configuration()
|
public void It_resolves_desktop_apps_defaulting_to_Debug_Configuration()
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests
|
||||||
.WithLockFiles();
|
.WithLockFiles();
|
||||||
|
|
||||||
var buildCommand = new BuildCommand(
|
var buildCommand = new BuildCommand(
|
||||||
Path.Combine(testInstance.TestRoot, "project.json"),
|
Path.Combine(testInstance.TestRoot, "project.json"),
|
||||||
configuration: configuration)
|
configuration: configuration)
|
||||||
.ExecuteWithCapturedOutput()
|
.ExecuteWithCapturedOutput()
|
||||||
.Should()
|
.Should()
|
||||||
|
@ -65,7 +65,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests
|
||||||
.WithLockFiles();
|
.WithLockFiles();
|
||||||
|
|
||||||
var buildCommand = new BuildCommand(
|
var buildCommand = new BuildCommand(
|
||||||
Path.Combine(testInstance.TestRoot, "project.json"),
|
Path.Combine(testInstance.TestRoot, "project.json"),
|
||||||
configuration: configuration)
|
configuration: configuration)
|
||||||
.ExecuteWithCapturedOutput()
|
.ExecuteWithCapturedOutput()
|
||||||
.Should()
|
.Should()
|
||||||
|
@ -96,7 +96,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests
|
||||||
.WithLockFiles();
|
.WithLockFiles();
|
||||||
|
|
||||||
var buildCommand = new BuildCommand(
|
var buildCommand = new BuildCommand(
|
||||||
Path.Combine(testInstance.TestRoot, "project.json"),
|
Path.Combine(testInstance.TestRoot, "project.json"),
|
||||||
configuration: configuration)
|
configuration: configuration)
|
||||||
.ExecuteWithCapturedOutput()
|
.ExecuteWithCapturedOutput()
|
||||||
.Should()
|
.Should()
|
||||||
|
@ -127,7 +127,7 @@ namespace Microsoft.DotNet.Cli.Utils.Tests
|
||||||
.WithLockFiles();
|
.WithLockFiles();
|
||||||
|
|
||||||
var buildCommand = new BuildCommand(
|
var buildCommand = new BuildCommand(
|
||||||
Path.Combine(testInstance.TestRoot, "project.json"),
|
Path.Combine(testInstance.TestRoot, "project.json"),
|
||||||
configuration: configuration)
|
configuration: configuration)
|
||||||
.ExecuteWithCapturedOutput()
|
.ExecuteWithCapturedOutput()
|
||||||
.Should()
|
.Should()
|
||||||
|
@ -147,5 +147,36 @@ namespace Microsoft.DotNet.Cli.Utils.Tests
|
||||||
command.CommandName.Should().Contain(Path.Combine(testInstance.TestRoot, "bin", configuration));
|
command.CommandName.Should().Contain(Path.Combine(testInstance.TestRoot, "bin", configuration));
|
||||||
Path.GetFileName(command.CommandName).Should().Be("dotnet-desktop-and-portable.exe");
|
Path.GetFileName(command.CommandName).Should().Be("dotnet-desktop-and-portable.exe");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_resolves_tools_whose_package_name_is_different_than_dll_name()
|
||||||
|
{
|
||||||
|
var configuration = "Debug";
|
||||||
|
|
||||||
|
var testAssetManager = new TestAssetsManager(Path.Combine(RepoRoot, "TestAssets", "TestProjects"));
|
||||||
|
var testInstance = testAssetManager.CreateTestInstance("AppWithDirectDependencyWithOutputName")
|
||||||
|
.WithLockFiles();
|
||||||
|
|
||||||
|
var buildCommand = new BuildCommand(
|
||||||
|
Path.Combine(testInstance.TestRoot, "project.json"),
|
||||||
|
configuration: configuration)
|
||||||
|
.ExecuteWithCapturedOutput()
|
||||||
|
.Should()
|
||||||
|
.Pass();
|
||||||
|
|
||||||
|
var context = ProjectContext.Create(testInstance.TestRoot, FrameworkConstants.CommonFrameworks.NetCoreApp10);
|
||||||
|
|
||||||
|
var factory = new ProjectDependenciesCommandFactory(
|
||||||
|
FrameworkConstants.CommonFrameworks.NetCoreApp10,
|
||||||
|
configuration,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
testInstance.TestRoot);
|
||||||
|
|
||||||
|
var command = factory.Create("dotnet-tool-with-output-name", null);
|
||||||
|
|
||||||
|
command.CommandArgs.Should().Contain(
|
||||||
|
Path.Combine("ToolWithOutputName", "1.0.0", "lib", "netcoreapp1.0", "dotnet-tool-with-output-name.dll"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,43 @@ namespace Microsoft.DotNet.Tests
|
||||||
result.Should().Pass();
|
result.Should().Pass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CanInvokeToolWhosePackageNameIsDifferentFromDllName()
|
||||||
|
{
|
||||||
|
var appDirectory = Path.Combine(_testProjectsRoot, "AppWithDependencyOnToolWithOutputName");
|
||||||
|
|
||||||
|
new BuildCommand(Path.Combine(appDirectory, "project.json"))
|
||||||
|
.Execute()
|
||||||
|
.Should()
|
||||||
|
.Pass();
|
||||||
|
|
||||||
|
CommandResult result = new GenericCommand("tool-with-output-name") { WorkingDirectory = appDirectory }
|
||||||
|
.ExecuteWithCapturedOutput();
|
||||||
|
|
||||||
|
result.Should().HaveStdOutContaining("Tool with output name!");
|
||||||
|
result.Should().NotHaveStdErr();
|
||||||
|
result.Should().Pass();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CanInvokeToolFromDirectDependenciesIfPackageNameDifferentFromToolName()
|
||||||
|
{
|
||||||
|
var appDirectory = Path.Combine(_testProjectsRoot, "AppWithDirectDependencyWithOutputName");
|
||||||
|
const string framework = ".NETCoreApp,Version=v1.0";
|
||||||
|
|
||||||
|
new BuildCommand(Path.Combine(appDirectory, "project.json"))
|
||||||
|
.Execute()
|
||||||
|
.Should()
|
||||||
|
.Pass();
|
||||||
|
|
||||||
|
CommandResult result = new DependencyToolInvokerCommand { WorkingDirectory = appDirectory }
|
||||||
|
.ExecuteWithCapturedOutput("tool-with-output-name", framework, string.Empty);
|
||||||
|
|
||||||
|
result.Should().HaveStdOutContaining("Tool with output name!");
|
||||||
|
result.Should().NotHaveStdErr();
|
||||||
|
result.Should().Pass();
|
||||||
|
}
|
||||||
|
|
||||||
// need conditional theories so we can skip on non-Windows
|
// need conditional theories so we can skip on non-Windows
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData("DependencyToolArguments")]
|
[MemberData("DependencyToolArguments")]
|
||||||
|
@ -62,7 +99,7 @@ namespace Microsoft.DotNet.Tests
|
||||||
.Pass();
|
.Pass();
|
||||||
|
|
||||||
CommandResult result = new DependencyToolInvokerCommand { WorkingDirectory = appDirectory }
|
CommandResult result = new DependencyToolInvokerCommand { WorkingDirectory = appDirectory }
|
||||||
.ExecuteWithCapturedOutput(framework, args);
|
.ExecuteWithCapturedOutput("desktop-and-portable", framework, args);
|
||||||
|
|
||||||
result.Should().HaveStdOutContaining(framework);
|
result.Should().HaveStdOutContaining(framework);
|
||||||
result.Should().HaveStdOutContaining(args);
|
result.Should().HaveStdOutContaining(args);
|
||||||
|
@ -163,6 +200,29 @@ namespace Microsoft.DotNet.Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GenericCommand : TestCommand
|
||||||
|
{
|
||||||
|
private readonly string _commandName;
|
||||||
|
|
||||||
|
public GenericCommand(string commandName)
|
||||||
|
: base("dotnet")
|
||||||
|
{
|
||||||
|
_commandName = commandName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override CommandResult Execute(string args = "")
|
||||||
|
{
|
||||||
|
args = $"{_commandName} {args}";
|
||||||
|
return base.Execute(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override CommandResult ExecuteWithCapturedOutput(string args = "")
|
||||||
|
{
|
||||||
|
args = $"{_commandName} {args}";
|
||||||
|
return base.ExecuteWithCapturedOutput(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class DependencyContextTestCommand : TestCommand
|
class DependencyContextTestCommand : TestCommand
|
||||||
{
|
{
|
||||||
public DependencyContextTestCommand()
|
public DependencyContextTestCommand()
|
||||||
|
@ -190,15 +250,15 @@ namespace Microsoft.DotNet.Tests
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandResult Execute(string framework, string additionalArgs)
|
public CommandResult Execute(string commandName, string framework, string additionalArgs)
|
||||||
{
|
{
|
||||||
var args = $"dependency-tool-invoker desktop-and-portable --framework {framework} {additionalArgs}";
|
var args = $"dependency-tool-invoker {commandName} --framework {framework} {additionalArgs}";
|
||||||
return base.Execute(args);
|
return base.Execute(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandResult ExecuteWithCapturedOutput(string framework, string additionalArgs)
|
public CommandResult ExecuteWithCapturedOutput(string commandName, string framework, string additionalArgs)
|
||||||
{
|
{
|
||||||
var args = $"dependency-tool-invoker desktop-and-portable --framework {framework} {additionalArgs}";
|
var args = $"dependency-tool-invoker {commandName} --framework {framework} {additionalArgs}";
|
||||||
return base.ExecuteWithCapturedOutput(args);
|
return base.ExecuteWithCapturedOutput(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"content": [
|
"content": [
|
||||||
|
"../../TestAssets/TestProjects/AppWithDependencyOnToolWithOutputName/**/*",
|
||||||
"../../TestAssets/TestProjects/AppWithDirectAndToolDependency/**/*",
|
"../../TestAssets/TestProjects/AppWithDirectAndToolDependency/**/*",
|
||||||
"../../TestAssets/TestProjects/AppWithDirectDependency/**/*",
|
"../../TestAssets/TestProjects/AppWithDirectDependency/**/*",
|
||||||
|
"../../TestAssets/TestProjects/AppWithDirectDependencyWithOutputName/**/*",
|
||||||
"../../TestAssets/TestProjects/AppWithToolDependency/**/*",
|
"../../TestAssets/TestProjects/AppWithToolDependency/**/*",
|
||||||
"../../TestAssets/TestProjects/DependencyContextFromTool/**/*",
|
"../../TestAssets/TestProjects/DependencyContextFromTool/**/*",
|
||||||
"../../TestAssets/DesktopTestProjects/AppWithDirectDependencyDesktopAndPortable/**/*"
|
"../../TestAssets/DesktopTestProjects/AppWithDirectDependencyDesktopAndPortable/**/*"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue