diff --git a/TestAssets/TestPackages/dotnet-prefercliruntime/Program.cs b/TestAssets/TestPackages/dotnet-prefercliruntime/Program.cs new file mode 100644 index 000000000..c011575f6 --- /dev/null +++ b/TestAssets/TestPackages/dotnet-prefercliruntime/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace ConsoleApplication +{ + public class Program + { + public static void Main(string[] args) + { + Console.WriteLine("Hello I prefer the cli runtime World!"); + } + } +} diff --git a/TestAssets/TestPackages/dotnet-prefercliruntime/dotnet-prefercliruntime.csproj b/TestAssets/TestPackages/dotnet-prefercliruntime/dotnet-prefercliruntime.csproj new file mode 100644 index 000000000..ff1b4d25a --- /dev/null +++ b/TestAssets/TestPackages/dotnet-prefercliruntime/dotnet-prefercliruntime.csproj @@ -0,0 +1,42 @@ + + + + + netcoreapp1.0 + Exe + + + + + + + + + true + lib\$(TargetFramework) + + + true + \prefercliruntime + + + + + + 1.0.0-alpha-20161104-2 + All + + + + + + 1.1.0 + + + + + $(DefineConstants);RELEASE + + + + diff --git a/TestAssets/TestPackages/dotnet-prefercliruntime/prefercliruntime b/TestAssets/TestPackages/dotnet-prefercliruntime/prefercliruntime new file mode 100644 index 000000000..e69de29bb diff --git a/TestAssets/TestProjects/MSBuildTestApp/MSBuildTestApp.csproj b/TestAssets/TestProjects/MSBuildTestApp/MSBuildTestApp.csproj index 43b4a62b3..1f1078e54 100644 --- a/TestAssets/TestProjects/MSBuildTestApp/MSBuildTestApp.csproj +++ b/TestAssets/TestProjects/MSBuildTestApp/MSBuildTestApp.csproj @@ -25,6 +25,9 @@ 1.0.0 + + 1.0.0 + diff --git a/build/test/TestPackageProjects.targets b/build/test/TestPackageProjects.targets index b588be798..0860e224c 100644 --- a/build/test/TestPackageProjects.targets +++ b/build/test/TestPackageProjects.targets @@ -155,6 +155,16 @@ True netcoreapp1.0 + + dotnet-prefercliruntime + dotnet-prefercliruntime.csproj + True + True + 1.0.0 + + True + netcoreapp1.0 + dotnet-tool-with-output-name ToolWithOutputName.csproj diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/DefaultCommandResolverPolicy.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/DefaultCommandResolverPolicy.cs index ddc3b0a66..afb15dd64 100644 --- a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/DefaultCommandResolverPolicy.cs +++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/DefaultCommandResolverPolicy.cs @@ -12,7 +12,7 @@ namespace Microsoft.DotNet.Cli.Utils public static CompositeCommandResolver Create() { var environment = new EnvironmentProvider(); - var packagedCommandSpecFactory = new PackagedCommandSpecFactory(); + var packagedCommandSpecFactory = new PackagedCommandSpecFactoryWithCliRuntime(); var publishedPathCommandSpecFactory = new PublishPathCommandSpecFactory(); var platformCommandSpecFactory = default(IPlatformCommandSpecFactory); diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/PackagedCommandSpecFactory.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/PackagedCommandSpecFactory.cs index 18aefdebf..827877880 100644 --- a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/PackagedCommandSpecFactory.cs +++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/PackagedCommandSpecFactory.cs @@ -10,6 +10,13 @@ namespace Microsoft.DotNet.Cli.Utils { public class PackagedCommandSpecFactory : IPackagedCommandSpecFactory { + private Action> _addAdditionalArguments; + + internal PackagedCommandSpecFactory(Action> addAdditionalArguments = null) + { + _addAdditionalArguments = addAdditionalArguments; + } + public CommandSpec CreateCommandSpecFromLibrary( LockFileTargetLibrary toolLibrary, string commandName, @@ -120,6 +127,11 @@ namespace Microsoft.DotNet.Cli.Utils arguments.Add("--additionalprobingpath"); arguments.Add(nugetPackagesRoot); + if(_addAdditionalArguments != null) + { + _addAdditionalArguments(commandPath, arguments); + } + arguments.Add(commandPath); arguments.AddRange(commandArguments); diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/PackagedCommandSpecFactoryWithCliRuntime.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/PackagedCommandSpecFactoryWithCliRuntime.cs new file mode 100644 index 000000000..c4d15c958 --- /dev/null +++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/PackagedCommandSpecFactoryWithCliRuntime.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.DotNet.Tools.Common; +using NuGet.Packaging; +using NuGet.ProjectModel; + +namespace Microsoft.DotNet.Cli.Utils +{ + public class PackagedCommandSpecFactoryWithCliRuntime : PackagedCommandSpecFactory + { + public PackagedCommandSpecFactoryWithCliRuntime() : base(AddAditionalParameters) + { + } + + private static void AddAditionalParameters(string commandPath, IList arguments) + { + if(PrefersCliRuntime(commandPath)) + { + arguments.Add("--fx-version"); + arguments.Add(new Muxer().SharedFxVersion); + } + } + + private static bool PrefersCliRuntime(string commandPath) + { + var libTFMPackageDirectory = Path.GetDirectoryName(commandPath); + var packageDirectory = Path.Combine(libTFMPackageDirectory, "..", ".."); + var preferCliRuntimePath = Path.Combine(packageDirectory, "prefercliruntime"); + + Reporter.Verbose.WriteLine( + $"packagedcommandspecfactory: Looking for prefercliruntime file at `{preferCliRuntimePath}`"); + + return File.Exists(preferCliRuntimePath); + } + } +} diff --git a/src/Microsoft.DotNet.Cli.Utils/Muxer.cs b/src/Microsoft.DotNet.Cli.Utils/Muxer.cs index a2387c1ba..283f09770 100644 --- a/src/Microsoft.DotNet.Cli.Utils/Muxer.cs +++ b/src/Microsoft.DotNet.Cli.Utils/Muxer.cs @@ -11,6 +11,14 @@ namespace Microsoft.DotNet.Cli.Utils private string _muxerPath; + internal string SharedFxVersion + { + get + { + return new DirectoryInfo(Path.GetDirectoryName(GetDataFromAppDomain("FX_DEPS_FILE"))).Name; + } + } + public string MuxerPath { get diff --git a/test/EndToEnd/GivenDotNetUsesMSBuild.cs b/test/EndToEnd/GivenDotNetUsesMSBuild.cs index ea35b68b3..44389f598 100644 --- a/test/EndToEnd/GivenDotNetUsesMSBuild.cs +++ b/test/EndToEnd/GivenDotNetUsesMSBuild.cs @@ -69,6 +69,25 @@ namespace Microsoft.DotNet.Tests.EndToEnd .HaveStdOutContaining("Hello Portable World!");; } + [Fact] + public void ItCanRunToolsThatPrefersTheCliRuntime() + { + var testInstance = TestAssets.Get("MSBuildTestApp") + .CreateInstance() + .WithSourceFiles() + .WithRestoreFiles(); + + var testProjectDirectory = testInstance.Root; + + new DotnetCommand() + .WithWorkingDirectory(testInstance.Root) + .ExecuteWithCapturedOutput("prefercliruntime") + .Should() + .Pass() + .And + .HaveStdOutContaining("Hello I prefer the cli runtime World!");; + } + [Fact] public void ItCanRunAToolThatInvokesADependencyToolInACSProj() { diff --git a/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectToolsCommandResolver.cs b/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectToolsCommandResolver.cs index e5bd91ee1..9804ce7f2 100644 --- a/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectToolsCommandResolver.cs +++ b/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectToolsCommandResolver.cs @@ -17,7 +17,8 @@ namespace Microsoft.DotNet.Tests { public class GivenAProjectToolsCommandResolver : TestBase { - private static readonly NuGetFramework s_toolPackageFramework = FrameworkConstants.CommonFrameworks.NetCoreApp10; + private static readonly NuGetFramework s_toolPackageFramework = + FrameworkConstants.CommonFrameworks.NetCoreApp10; private const string TestProjectName = "AppWithToolDependency"; @@ -260,16 +261,64 @@ namespace Microsoft.DotNet.Tests File.Delete(depsJsonFile); } - private ProjectToolsCommandResolver SetupProjectToolsCommandResolver( - IPackagedCommandSpecFactory packagedCommandSpecFactory = null) + [Fact] + public void It_adds_fx_version_as_a_param_when_the_tool_has_the_prefercliruntime_file() + { + var projectToolsCommandResolver = SetupProjectToolsCommandResolver(); + + var testInstance = TestAssetsManager + .CreateTestInstance("MSBuildTestApp") + .WithNuGetMSBuildFiles() + .WithLockFiles(); + + var commandResolverArguments = new CommandResolverArguments() + { + CommandName = "dotnet-prefercliruntime", + CommandArguments = null, + ProjectDirectory = testInstance.Path + }; + + var result = projectToolsCommandResolver.Resolve(commandResolverArguments); + + result.Should().NotBeNull(); + + result.Args.Should().Contain("-fx-version 1.0.1"); + } + + [Fact] + public void It_does_not_add_fx_version_as_a_param_when_the_tool_does_not_have_the_prefercliruntime_file() + { + var projectToolsCommandResolver = SetupProjectToolsCommandResolver(); + + var testInstance = TestAssetsManager + .CreateTestInstance(TestProjectName) + .WithNuGetMSBuildFiles() + .WithLockFiles(); + + var commandResolverArguments = new CommandResolverArguments() + { + CommandName = "dotnet-portable", + CommandArguments = null, + ProjectDirectory = testInstance.Path + }; + + var result = projectToolsCommandResolver.Resolve(commandResolverArguments); + + result.Should().NotBeNull(); + + result.Args.Should().NotContain("-fx-version"); + } + + private ProjectToolsCommandResolver SetupProjectToolsCommandResolver() { Environment.SetEnvironmentVariable( Constants.MSBUILD_EXE_PATH, Path.Combine(new RepoDirectoriesProvider().Stage2Sdk, "MSBuild.dll")); - packagedCommandSpecFactory = packagedCommandSpecFactory ?? new PackagedCommandSpecFactory(); + var packagedCommandSpecFactory = new PackagedCommandSpecFactoryWithCliRuntime(); - var projectToolsCommandResolver = new ProjectToolsCommandResolver(packagedCommandSpecFactory, new EnvironmentProvider()); + var projectToolsCommandResolver = + new ProjectToolsCommandResolver(packagedCommandSpecFactory, new EnvironmentProvider()); return projectToolsCommandResolver; }