diff --git a/src/Microsoft.DotNet.Cli.Utils/Command.cs b/src/Microsoft.DotNet.Cli.Utils/Command.cs
index 631c508db..083bd5139 100644
--- a/src/Microsoft.DotNet.Cli.Utils/Command.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/Command.cs
@@ -56,22 +56,20 @@ namespace Microsoft.DotNet.Cli.Utils
/// array will be present in the corresponding argument array
/// in the command's process.
///
- ///
- ///
- ///
- ///
public static Command Create(
string commandName,
IEnumerable args,
NuGetFramework framework = null,
string configuration = Constants.DefaultConfiguration,
- string outputPath = null)
+ string outputPath = null,
+ string applicationName = null)
{
var commandSpec = CommandResolver.TryResolveCommandSpec(commandName,
args,
framework,
configuration: configuration,
- outputPath: outputPath);
+ outputPath: outputPath,
+ applicationName: applicationName);
if (commandSpec == null)
{
diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/CommandResolverArguments.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/CommandResolverArguments.cs
index e43b377b5..dca62db0a 100644
--- a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/CommandResolverArguments.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/CommandResolverArguments.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Microsoft.DotNet.ProjectModel;
-using Microsoft.DotNet.ProjectModel.Graph;
+using System.Collections.Generic;
using NuGet.Frameworks;
namespace Microsoft.DotNet.Cli.Utils
@@ -26,5 +22,7 @@ namespace Microsoft.DotNet.Cli.Utils
public string BuildBasePath { get; set; }
public string DepsJsonFile { get; set; }
+
+ public string ApplicationName { get; set; }
}
}
diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/DefaultCommandResolverPolicy.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/DefaultCommandResolverPolicy.cs
index fbd093e6a..2eed9b0f6 100644
--- a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/DefaultCommandResolverPolicy.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/DefaultCommandResolverPolicy.cs
@@ -1,3 +1,4 @@
+using Microsoft.DotNet.Cli.Utils.CommandResolution;
using Microsoft.DotNet.PlatformAbstractions;
namespace Microsoft.DotNet.Cli.Utils
@@ -8,6 +9,7 @@ namespace Microsoft.DotNet.Cli.Utils
{
var environment = new EnvironmentProvider();
var packagedCommandSpecFactory = new PackagedCommandSpecFactory();
+ var publishedPathCommandSpecFactory = new PublishPathCommandSpecFactory();
var platformCommandSpecFactory = default(IPlatformCommandSpecFactory);
if (RuntimeEnvironment.OperatingSystemPlatform == Platform.Windows)
@@ -19,13 +21,18 @@ namespace Microsoft.DotNet.Cli.Utils
platformCommandSpecFactory = new GenericPlatformCommandSpecFactory();
}
- return CreateDefaultCommandResolver(environment, packagedCommandSpecFactory, platformCommandSpecFactory);
+ return CreateDefaultCommandResolver(
+ environment,
+ packagedCommandSpecFactory,
+ platformCommandSpecFactory,
+ publishedPathCommandSpecFactory);
}
public static CompositeCommandResolver CreateDefaultCommandResolver(
IEnvironmentProvider environment,
IPackagedCommandSpecFactory packagedCommandSpecFactory,
- IPlatformCommandSpecFactory platformCommandSpecFactory)
+ IPlatformCommandSpecFactory platformCommandSpecFactory,
+ IPublishedPathCommandSpecFactory publishedPathCommandSpecFactory)
{
var compositeCommandResolver = new CompositeCommandResolver();
@@ -33,8 +40,12 @@ namespace Microsoft.DotNet.Cli.Utils
compositeCommandResolver.AddCommandResolver(new RootedCommandResolver());
compositeCommandResolver.AddCommandResolver(new ProjectToolsCommandResolver(packagedCommandSpecFactory));
compositeCommandResolver.AddCommandResolver(new AppBaseDllCommandResolver());
- compositeCommandResolver.AddCommandResolver(new AppBaseCommandResolver(environment, platformCommandSpecFactory));
- compositeCommandResolver.AddCommandResolver(new PathCommandResolver(environment, platformCommandSpecFactory));
+ compositeCommandResolver.AddCommandResolver(
+ new AppBaseCommandResolver(environment, platformCommandSpecFactory));
+ compositeCommandResolver.AddCommandResolver(
+ new PathCommandResolver(environment, platformCommandSpecFactory));
+ compositeCommandResolver.AddCommandResolver(
+ new PublishedPathCommandResolver(environment, publishedPathCommandSpecFactory));
return compositeCommandResolver;
}
diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/IPackagedCommandSpecFactory.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/IPackagedCommandSpecFactory.cs
index 3c5316456..24e82fa6c 100644
--- a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/IPackagedCommandSpecFactory.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/IPackagedCommandSpecFactory.cs
@@ -1,10 +1,5 @@
-using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Graph;
-using Microsoft.DotNet.ProjectModel.Compilation;
namespace Microsoft.DotNet.Cli.Utils
{
diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/IPublishedPathCommandSpecFactory.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/IPublishedPathCommandSpecFactory.cs
new file mode 100644
index 000000000..f42cee7de
--- /dev/null
+++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/IPublishedPathCommandSpecFactory.cs
@@ -0,0 +1,17 @@
+// 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.Collections.Generic;
+
+namespace Microsoft.DotNet.Cli.Utils.CommandResolution
+{
+ public interface IPublishedPathCommandSpecFactory
+ {
+ CommandSpec CreateCommandSpecFromPublishFolder(
+ string commandPath,
+ IEnumerable commandArguments,
+ CommandResolutionStrategy commandResolutionStrategy,
+ string depsFilePath,
+ string runtimeConfigPath);
+ }
+}
diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/OutputPathCommandResolver.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/OutputPathCommandResolver.cs
index 231de29c2..036cbada8 100644
--- a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/OutputPathCommandResolver.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/OutputPathCommandResolver.cs
@@ -51,7 +51,9 @@ namespace Microsoft.DotNet.Cli.Utils
return null;
}
- var buildOutputPath = projectContext.GetOutputPaths(configuration, buildBasePath, outputPath).RuntimeFiles.BasePath;
+ var buildOutputPath =
+ projectContext.GetOutputPaths(configuration, buildBasePath, outputPath).CompilationOutputPath +
+ "publish";
if (! Directory.Exists(buildOutputPath))
{
diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/PublishPathCommandSpecFactory.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/PublishPathCommandSpecFactory.cs
new file mode 100644
index 000000000..2008404cf
--- /dev/null
+++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/PublishPathCommandSpecFactory.cs
@@ -0,0 +1,96 @@
+// 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;
+using System.Collections.Generic;
+using System.IO;
+using Microsoft.DotNet.ProjectModel;
+
+namespace Microsoft.DotNet.Cli.Utils.CommandResolution
+{
+ public class PublishPathCommandSpecFactory : IPublishedPathCommandSpecFactory
+ {
+ public CommandSpec CreateCommandSpecFromPublishFolder(
+ string commandPath,
+ IEnumerable commandArguments,
+ CommandResolutionStrategy commandResolutionStrategy,
+ string depsFilePath,
+ string runtimeConfigPath)
+ {
+ return CreateCommandSpecWrappingWithMuxerIfDll(
+ commandPath,
+ commandArguments,
+ depsFilePath,
+ commandResolutionStrategy,
+ runtimeConfigPath);
+ }
+
+ private CommandSpec CreateCommandSpecWrappingWithMuxerIfDll(
+ string commandPath,
+ IEnumerable commandArguments,
+ string depsFilePath,
+ CommandResolutionStrategy commandResolutionStrategy,
+ string runtimeConfigPath)
+ {
+ var commandExtension = Path.GetExtension(commandPath);
+
+ if (commandExtension == FileNameSuffixes.DotNet.DynamicLib)
+ {
+ return CreatePackageCommandSpecUsingMuxer(
+ commandPath,
+ commandArguments,
+ depsFilePath,
+ commandResolutionStrategy,
+ runtimeConfigPath);
+ }
+
+ return CreateCommandSpec(commandPath, commandArguments, commandResolutionStrategy);
+ }
+ private CommandSpec CreatePackageCommandSpecUsingMuxer(
+ string commandPath,
+ IEnumerable commandArguments,
+ string depsFilePath,
+ CommandResolutionStrategy commandResolutionStrategy,
+ string runtimeConfigPath)
+ {
+ var arguments = new List();
+
+ var muxer = new Muxer();
+
+ var host = muxer.MuxerPath;
+ if (host == null)
+ {
+ throw new Exception("Unable to locate dotnet multiplexer");
+ }
+
+ arguments.Add("exec");
+
+ if (runtimeConfigPath != null)
+ {
+ arguments.Add("--runtimeconfig");
+ arguments.Add(runtimeConfigPath);
+ }
+
+ if (depsFilePath != null)
+ {
+ arguments.Add("--depsfile");
+ arguments.Add(depsFilePath);
+ }
+
+ arguments.Add(commandPath);
+ arguments.AddRange(commandArguments);
+
+ return CreateCommandSpec(host, arguments, commandResolutionStrategy);
+ }
+
+ private CommandSpec CreateCommandSpec(
+ string commandPath,
+ IEnumerable commandArguments,
+ CommandResolutionStrategy commandResolutionStrategy)
+ {
+ var escapedArgs = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(commandArguments);
+
+ return new CommandSpec(commandPath, escapedArgs, commandResolutionStrategy);
+ }
+ }
+}
diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolution/PublishedPathCommandResolver.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/PublishedPathCommandResolver.cs
new file mode 100644
index 000000000..f9763ba9e
--- /dev/null
+++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolution/PublishedPathCommandResolver.cs
@@ -0,0 +1,73 @@
+// 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.IO;
+using Microsoft.DotNet.Cli.Utils.CommandResolution;
+
+namespace Microsoft.DotNet.Cli.Utils
+{
+ public class PublishedPathCommandResolver : ICommandResolver
+ {
+ private readonly IEnvironmentProvider _environment;
+ private readonly IPublishedPathCommandSpecFactory _commandSpecFactory;
+
+ public PublishedPathCommandResolver(
+ IEnvironmentProvider environment,
+ IPublishedPathCommandSpecFactory commandSpecFactory)
+ {
+ _environment = environment;
+ _commandSpecFactory = commandSpecFactory;
+ }
+
+ public CommandSpec Resolve(CommandResolverArguments commandResolverArguments)
+ {
+ var publishDirectory = commandResolverArguments.OutputPath;
+ var commandName = commandResolverArguments.CommandName;
+ var applicationName = commandResolverArguments.ApplicationName;
+
+ if (publishDirectory == null || commandName == null || applicationName == null)
+ {
+ return null;
+ }
+
+ var commandPath = ResolveCommandPath(publishDirectory, commandName);
+
+ if (commandPath == null)
+ {
+ return null;
+ }
+
+ var depsFilePath = Path.Combine(publishDirectory, $"{applicationName}.deps.json");
+ if (!File.Exists(depsFilePath))
+ {
+ Reporter.Verbose.WriteLine($"PublishedPathCommandResolver: {depsFilePath} does not exist");
+ return null;
+ }
+
+ var runtimeConfigPath = Path.Combine(publishDirectory, $"{applicationName}.runtimeconfig.json");
+ if (!File.Exists(runtimeConfigPath))
+ {
+ Reporter.Verbose.WriteLine($"projectdependenciescommandresolver: {runtimeConfigPath} does not exist");
+ return null;
+ }
+
+ return _commandSpecFactory.CreateCommandSpecFromPublishFolder(
+ commandPath,
+ commandResolverArguments.CommandArguments.OrEmptyIfNull(),
+ CommandResolutionStrategy.OutputPath,
+ depsFilePath,
+ runtimeConfigPath);
+ }
+
+ private string ResolveCommandPath(string publishDirectory, string commandName)
+ {
+ if (!Directory.Exists(publishDirectory))
+ {
+ Reporter.Verbose.WriteLine($"publishedpathresolver: {publishDirectory} does not exist");
+ return null;
+ }
+
+ return _environment.GetCommandPathFromRootPath(publishDirectory, commandName, ".dll");
+ }
+ }
+}
diff --git a/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs b/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs
index 35f2f3cd5..d929c8cad 100644
--- a/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/CommandResolver.cs
@@ -12,7 +12,8 @@ namespace Microsoft.DotNet.Cli.Utils
IEnumerable args,
NuGetFramework framework = null,
string configuration = Constants.DefaultConfiguration,
- string outputPath = null)
+ string outputPath = null,
+ string applicationName = null)
{
var commandResolverArgs = new CommandResolverArguments
{
@@ -21,7 +22,8 @@ namespace Microsoft.DotNet.Cli.Utils
Framework = framework,
ProjectDirectory = Directory.GetCurrentDirectory(),
Configuration = configuration,
- OutputPath = outputPath
+ OutputPath = outputPath,
+ ApplicationName = applicationName
};
var defaultCommandResolver = DefaultCommandResolverPolicy.Create();
diff --git a/src/Microsoft.DotNet.Cli.Utils/PublishedPathCommandFactory.cs b/src/Microsoft.DotNet.Cli.Utils/PublishedPathCommandFactory.cs
new file mode 100644
index 000000000..24fac7d35
--- /dev/null
+++ b/src/Microsoft.DotNet.Cli.Utils/PublishedPathCommandFactory.cs
@@ -0,0 +1,29 @@
+// 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.Collections.Generic;
+using NuGet.Frameworks;
+
+namespace Microsoft.DotNet.Cli.Utils
+{
+ public class PublishedPathCommandFactory : ICommandFactory
+ {
+ private readonly string _publishDirectory;
+ private readonly string _applicationName;
+
+ public PublishedPathCommandFactory(string publishDirectory, string applicationName)
+ {
+ _publishDirectory = publishDirectory;
+ _applicationName = applicationName;
+ }
+
+ public ICommand Create(
+ string commandName,
+ IEnumerable args,
+ NuGetFramework framework = null,
+ string configuration = Constants.DefaultConfiguration)
+ {
+ return Command.Create(commandName, args, framework, configuration, _publishDirectory, _applicationName);
+ }
+ }
+}
diff --git a/src/dotnet-test-console/AssemblyTestRunner.cs b/src/dotnet-test-console/AssemblyTestRunner.cs
index 62c0fdb57..fb25062b5 100644
--- a/src/dotnet-test-console/AssemblyTestRunner.cs
+++ b/src/dotnet-test-console/AssemblyTestRunner.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
+using System.IO;
using Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Tools.Test
@@ -17,8 +18,11 @@ namespace Microsoft.DotNet.Tools.Test
public int RunTests(DotnetTestParams dotnetTestParams)
{
- var commandFactory =
- new CommandFactory();
+ var assembly = new FileInfo(dotnetTestParams.ProjectOrAssemblyPath);
+ var publishDirectory = assembly.Directory.FullName;
+ var applicationName = Path.GetFileNameWithoutExtension(dotnetTestParams.ProjectOrAssemblyPath);
+
+ var commandFactory = new PublishedPathCommandFactory(publishDirectory, applicationName);
var assemblyUnderTest = dotnetTestParams.ProjectOrAssemblyPath;
diff --git a/test/dotnet-test.Tests/GivenThatWeWantToRunTestsInTheConsole.cs b/test/dotnet-test.Tests/GivenThatWeWantToRunTestsInTheConsole.cs
index fb0f0f3e6..f34a44f6e 100644
--- a/test/dotnet-test.Tests/GivenThatWeWantToRunTestsInTheConsole.cs
+++ b/test/dotnet-test.Tests/GivenThatWeWantToRunTestsInTheConsole.cs
@@ -100,11 +100,11 @@ namespace Microsoft.Dotnet.Tools.Test.Tests
[Fact]
public void It_runs_tests_for_an_assembly_passed_as_param()
{
- var buildCommand = new BuildCommand(_projectFilePath);
- var result = buildCommand.Execute();
+ var publishCommand = new PublishCommand(_projectFilePath);
+ var result = publishCommand.Execute();
result.Should().Pass();
- var assemblyUnderTestPath = Path.Combine(_defaultOutputPath, buildCommand.GetPortableOutputName());
+ var assemblyUnderTestPath = Path.Combine(publishCommand.GetOutputDirectory(true).FullName, publishCommand.GetPortableOutputName());
var testCommand = new DotnetTestCommand();
result = testCommand.Execute($"{assemblyUnderTestPath}");
diff --git a/test/dotnet-test.Tests/project.json b/test/dotnet-test.Tests/project.json
index 873f6a070..569e67db7 100644
--- a/test/dotnet-test.Tests/project.json
+++ b/test/dotnet-test.Tests/project.json
@@ -15,6 +15,9 @@
"Microsoft.DotNet.ProjectModel": {
"target": "project"
},
+ "Microsoft.DotNet.InternalAbstractions": {
+ "target": "project"
+ },
"System.Net.NameResolution": "4.0.0",
"System.Net.Sockets": "4.1.0",
"System.Runtime.Serialization.Primitives": "4.1.1",