diff --git a/TestAssets/DesktopTestProjects/LibraryWithDirectDependencyDesktopAndPortable/.noautobuild b/TestAssets/DesktopTestProjects/LibraryWithDirectDependencyDesktopAndPortable/.noautobuild new file mode 100644 index 000000000..e69de29bb diff --git a/TestAssets/DesktopTestProjects/LibraryWithDirectDependencyDesktopAndPortable/Program.cs b/TestAssets/DesktopTestProjects/LibraryWithDirectDependencyDesktopAndPortable/Program.cs new file mode 100644 index 000000000..51233cffa --- /dev/null +++ b/TestAssets/DesktopTestProjects/LibraryWithDirectDependencyDesktopAndPortable/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace ConsoleApplication +{ + public class Program + { + public static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + } + } +} diff --git a/TestAssets/DesktopTestProjects/LibraryWithDirectDependencyDesktopAndPortable/project.json b/TestAssets/DesktopTestProjects/LibraryWithDirectDependencyDesktopAndPortable/project.json new file mode 100644 index 000000000..fd28441ac --- /dev/null +++ b/TestAssets/DesktopTestProjects/LibraryWithDirectDependencyDesktopAndPortable/project.json @@ -0,0 +1,31 @@ +{ + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": false + }, + "dependencies": { + "dotnet-desktop-and-portable": "1.0.0-*" + }, + "frameworks": { + "netstandard1.5": { + "dependencies": { + "NETStandard.Library": "1.5.0-rc2-24027" + }, + "imports": [ + "portable-net45+win8", + "dnxcore50", + "netcoreapp1.0" + ] + }, + "net451": {} + }, + "tools": { + "dotnet-dependency-tool-invoker": { + "version": "1.0.0-*", + "imports": [ + "dnxcore50", + "portable-net45+win8" + ] + } + } +} diff --git a/TestAssets/TestPackages/dotnet-dependency-tool-invoker/Program.cs b/TestAssets/TestPackages/dotnet-dependency-tool-invoker/Program.cs index 8ba883d6e..53e103eaa 100644 --- a/TestAssets/TestPackages/dotnet-dependency-tool-invoker/Program.cs +++ b/TestAssets/TestPackages/dotnet-dependency-tool-invoker/Program.cs @@ -9,7 +9,7 @@ namespace Microsoft.DotNet.Tools.DependencyInvoker { public class Program { - public static void Main(string[] args) + public static int Main(string[] args) { DebugHelper.HandleDebugSwitch(ref args); @@ -21,7 +21,7 @@ namespace Microsoft.DotNet.Tools.DependencyInvoker { Console.WriteLine("A command name must be provided"); - return; + return 1; } var projectContexts = @@ -59,8 +59,10 @@ namespace Microsoft.DotNet.Tools.DependencyInvoker catch (CommandUnknownException) { Console.WriteLine($"Command not found"); + return 1; } } + return 0; } private static IEnumerable CreateProjectContexts(string projectPath = null) diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/OutputPathCommandResolver.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/OutputPathCommandResolver.cs index a8d5b2333..231de29c2 100644 --- a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/OutputPathCommandResolver.cs +++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/OutputPathCommandResolver.cs @@ -53,6 +53,12 @@ namespace Microsoft.DotNet.Cli.Utils var buildOutputPath = projectContext.GetOutputPaths(configuration, buildBasePath, outputPath).RuntimeFiles.BasePath; + if (! Directory.Exists(buildOutputPath)) + { + Reporter.Verbose.WriteLine($"outputpathresolver: {buildOutputPath} does not exist"); + return null; + } + return _environment.GetCommandPathFromRootPath(buildOutputPath, commandName); } diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ProjectDependenciesCommandResolver.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ProjectDependenciesCommandResolver.cs index 63b094661..60bb1a87b 100644 --- a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ProjectDependenciesCommandResolver.cs +++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/ProjectDependenciesCommandResolver.cs @@ -78,9 +78,21 @@ namespace Microsoft.DotNet.Cli.Utils var depsFilePath = projectContext.GetOutputPaths(configuration, buildBasePath, outputPath).RuntimeFiles.DepsJson; + if (! File.Exists(depsFilePath)) + { + Reporter.Verbose.WriteLine($"projectdependenciescommandresolver: {depsFilePath} does not exist"); + return null; + } + var runtimeConfigPath = projectContext.GetOutputPaths(configuration, buildBasePath, outputPath).RuntimeFiles.RuntimeConfigJson; + if (! File.Exists(runtimeConfigPath)) + { + Reporter.Verbose.WriteLine($"projectdependenciescommandresolver: {runtimeConfigPath} does not exist"); + return null; + } + var toolLibrary = GetToolLibraryForContext(projectContext, commandName); return _packagedCommandSpecFactory.CreateCommandSpecFromLibrary( diff --git a/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectDependencyCommandResolver.cs b/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectDependencyCommandResolver.cs index e9ba22554..29a31653c 100644 --- a/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectDependencyCommandResolver.cs +++ b/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectDependencyCommandResolver.cs @@ -179,9 +179,10 @@ namespace Microsoft.DotNet.Cli.Utils.Tests } [Fact] - public void It_sets_depsfile_based_on_output_path_when_returning_a_commandspec() + public void It_sets_depsfile_in_output_path_in_commandspec() { var projectDependenciesCommandResolver = SetupProjectDependenciesCommandResolver(); + var outputDir = Path.Combine(AppContext.BaseDirectory, "outdir"); var commandResolverArguments = new CommandResolverArguments { @@ -190,16 +191,22 @@ namespace Microsoft.DotNet.Cli.Utils.Tests ProjectDirectory = s_liveProjectDirectory, Configuration = "Debug", Framework = FrameworkConstants.CommonFrameworks.NetCoreApp10, - OutputPath = AppContext.BaseDirectory + OutputPath = outputDir }; + var buildCommand = new BuildCommand( + Path.Combine(s_liveProjectDirectory, "project.json"), + output: outputDir, + framework: FrameworkConstants.CommonFrameworks.NetCoreApp10.ToString()) + .Execute().Should().Pass(); + var projectContext = ProjectContext.Create( s_liveProjectDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10, RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers()); var depsFilePath = - projectContext.GetOutputPaths("Debug", outputPath: AppContext.BaseDirectory).RuntimeFiles.DepsJson; + projectContext.GetOutputPaths("Debug", outputPath: outputDir).RuntimeFiles.DepsJson; var result = projectDependenciesCommandResolver.Resolve(commandResolverArguments); @@ -208,9 +215,10 @@ namespace Microsoft.DotNet.Cli.Utils.Tests } [Fact] - public void It_sets_depsfile_based_on_build_base_path_when_returning_a_commandspec() + public void It_sets_depsfile_in_build_base_path_in_commandspec() { var projectDependenciesCommandResolver = SetupProjectDependenciesCommandResolver(); + var buildBasePath = Path.Combine(AppContext.BaseDirectory, "basedir"); var commandResolverArguments = new CommandResolverArguments { @@ -219,16 +227,22 @@ namespace Microsoft.DotNet.Cli.Utils.Tests ProjectDirectory = s_liveProjectDirectory, Configuration = "Debug", Framework = FrameworkConstants.CommonFrameworks.NetCoreApp10, - BuildBasePath = AppContext.BaseDirectory + BuildBasePath = buildBasePath }; + var buildCommand = new BuildCommand( + Path.Combine(s_liveProjectDirectory, "project.json"), + buildBasePath: buildBasePath, + framework: FrameworkConstants.CommonFrameworks.NetCoreApp10.ToString()) + .Execute().Should().Pass(); + var projectContext = ProjectContext.Create( s_liveProjectDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10, RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers()); var depsFilePath = - projectContext.GetOutputPaths("Debug", AppContext.BaseDirectory).RuntimeFiles.DepsJson; + projectContext.GetOutputPaths("Debug", buildBasePath).RuntimeFiles.DepsJson; var result = projectDependenciesCommandResolver.Resolve(commandResolverArguments); diff --git a/test/dotnet.Tests/PackagedCommandTests.cs b/test/dotnet.Tests/PackagedCommandTests.cs index e17e6f7a2..c514fb0a8 100644 --- a/test/dotnet.Tests/PackagedCommandTests.cs +++ b/test/dotnet.Tests/PackagedCommandTests.cs @@ -18,6 +18,34 @@ namespace Microsoft.DotNet.Tests private readonly string _testProjectsRoot; private readonly string _desktopTestProjectsRoot; + public static IEnumerable DependencyToolArguments + { + get + { + var rid = RuntimeEnvironmentRidExtensions.GetLegacyRestoreRuntimeIdentifier(); + var projectOutputPath = $"AppWithDirectDependencyDesktopAndPortable\\bin\\Debug\\net451\\{rid}\\dotnet-desktop-and-portable.exe"; + return new[] + { + new object[] { ".NETCoreApp,Version=v1.0", "CoreFX", "lib\\netcoreapp1.0\\dotnet-desktop-and-portable.dll", true }, + new object[] { ".NETFramework,Version=v4.5.1", "NetFX", projectOutputPath, true } + }; + } + } + + public static IEnumerable LibraryDependencyToolArguments + { + get + { + var rid = RuntimeEnvironmentRidExtensions.GetLegacyRestoreRuntimeIdentifier(); + var projectOutputPath = $"LibraryWithDirectDependencyDesktopAndPortable\\bin\\Debug\\net451\\dotnet-desktop-and-portable.exe"; + return new[] + { + new object[] { ".NETStandard,Version=v1.5", "CoreFX", "lib\\netstandard1.5\\dotnet-desktop-and-portable.dll", true }, + new object[] { ".NETFramework,Version=v4.5.1", "NetFX", projectOutputPath, true } + }; + } + } + public PackagedCommandTests() { _testProjectsRoot = Path.Combine(AppContext.BaseDirectory, "TestAssets", "TestProjects"); @@ -39,7 +67,7 @@ namespace Microsoft.DotNet.Tests CommandResult result = new PortableCommand { WorkingDirectory = appDirectory } .ExecuteWithCapturedOutput(); - result.Should().HaveStdOut("Hello Portable World!" + Environment.NewLine); + result.Should().HaveStdOutContaining("Hello Portable World!" + Environment.NewLine); result.Should().NotHaveStdErr(); result.Should().Pass(); } @@ -84,9 +112,9 @@ namespace Microsoft.DotNet.Tests // need conditional theories so we can skip on non-Windows [Theory] [MemberData("DependencyToolArguments")] - public void TestFrameworkSpecificDependencyToolsCanBeInvoked(string framework, string args, string expectedDependencyToolPath) + public void TestFrameworkSpecificDependencyToolsCanBeInvoked(string framework, string args, string expectedDependencyToolPath, bool windowsOnly) { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && windowsOnly) { return; } @@ -108,6 +136,29 @@ namespace Microsoft.DotNet.Tests result.Should().Pass(); } + [Theory] + [MemberData("LibraryDependencyToolArguments")] + public void TestFrameworkSpecificLibraryDependencyToolsCannotBeInvoked(string framework, string args, string expectedDependencyToolPath, bool windowsOnly) + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && windowsOnly) + { + return; + } + + var appDirectory = Path.Combine(_desktopTestProjectsRoot, "LibraryWithDirectDependencyDesktopAndPortable"); + + new BuildCommand(Path.Combine(appDirectory, "project.json")) + .Execute() + .Should() + .Pass(); + + CommandResult result = new DependencyToolInvokerCommand { WorkingDirectory = appDirectory } + .ExecuteWithCapturedOutput("desktop-and-portable", framework, args); + + result.Should().HaveStdOutContaining("Command not found"); + result.Should().Fail(); + } + [Fact] public void ToolsCanAccessDependencyContextProperly() { @@ -119,20 +170,6 @@ namespace Microsoft.DotNet.Tests result.Should().Pass(); } - public static IEnumerable DependencyToolArguments - { - get - { - var rid = RuntimeEnvironmentRidExtensions.GetLegacyRestoreRuntimeIdentifier(); - var projectOutputPath = $"AppWithDirectDependencyDesktopAndPortable\\bin\\Debug\\net451\\{rid}\\dotnet-desktop-and-portable.exe"; - return new[] - { - new object[] { ".NETCoreApp,Version=v1.0", "CoreFX", "lib\\netcoreapp1.0\\dotnet-desktop-and-portable.dll" }, - new object[] { ".NETFramework,Version=v4.5.1", "NetFX", projectOutputPath } - }; - } - } - [Fact] public void TestProjectDependencyIsNotAvailableThroughDriver() { diff --git a/test/dotnet.Tests/project.json b/test/dotnet.Tests/project.json index f5205ee3d..7d784e3ed 100644 --- a/test/dotnet.Tests/project.json +++ b/test/dotnet.Tests/project.json @@ -36,7 +36,8 @@ "../../TestAssets/TestProjects/AppWithDirectDependencyWithOutputName/**/*", "../../TestAssets/TestProjects/AppWithToolDependency/**/*", "../../TestAssets/TestProjects/DependencyContextFromTool/**/*", - "../../TestAssets/DesktopTestProjects/AppWithDirectDependencyDesktopAndPortable/**/*" + "../../TestAssets/DesktopTestProjects/AppWithDirectDependencyDesktopAndPortable/**/*", + "../../TestAssets/DesktopTestProjects/LibraryWithDirectDependencyDesktopAndPortable/**/*" ], "testRunner": "xunit" }