2015-11-20 19:00:56 -08:00
|
|
|
|
// 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 System.Linq;
|
2016-10-27 18:46:43 -07:00
|
|
|
|
using Microsoft.Build.Execution;
|
2015-11-20 19:00:56 -08:00
|
|
|
|
using Microsoft.DotNet.Cli.Utils;
|
2016-10-27 18:46:43 -07:00
|
|
|
|
using Microsoft.DotNet.Tools.MSBuild;
|
2015-11-20 19:00:56 -08:00
|
|
|
|
|
|
|
|
|
namespace Microsoft.DotNet.Tools.Run
|
|
|
|
|
{
|
2016-01-30 21:47:50 -08:00
|
|
|
|
public partial class RunCommand
|
2015-11-20 19:00:56 -08:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
public string Configuration { get; set; }
|
|
|
|
|
public string Framework { get; set; }
|
|
|
|
|
public string Project { get; set; }
|
|
|
|
|
public IReadOnlyList<string> Args { get; set; }
|
2015-11-20 19:00:56 -08:00
|
|
|
|
|
2016-05-12 10:24:57 -05:00
|
|
|
|
private List<string> _args;
|
2016-04-25 13:53:02 -07:00
|
|
|
|
|
2016-05-12 10:24:57 -05:00
|
|
|
|
public RunCommand()
|
|
|
|
|
{
|
|
|
|
|
}
|
2016-04-25 13:53:02 -07:00
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
public int Start()
|
2016-05-12 10:24:57 -05:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
Initialize();
|
|
|
|
|
|
|
|
|
|
EnsureProjectIsBuilt();
|
|
|
|
|
|
|
|
|
|
ICommand runCommand = GetRunCommand();
|
|
|
|
|
|
|
|
|
|
return runCommand
|
|
|
|
|
.Execute()
|
|
|
|
|
.ExitCode;
|
2016-05-12 10:24:57 -05:00
|
|
|
|
}
|
2015-11-20 19:00:56 -08:00
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
private void EnsureProjectIsBuilt()
|
2015-11-20 19:00:56 -08:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
List<string> buildArgs = new List<string>();
|
|
|
|
|
|
|
|
|
|
buildArgs.Add(Project);
|
|
|
|
|
|
|
|
|
|
buildArgs.Add("/nologo");
|
|
|
|
|
buildArgs.Add("/verbosity:quiet");
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(Configuration))
|
2015-11-20 19:00:56 -08:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
buildArgs.Add($"/p:Configuration={Configuration}");
|
2015-11-20 19:00:56 -08:00
|
|
|
|
}
|
2016-10-27 18:46:43 -07:00
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(Framework))
|
2015-11-20 19:00:56 -08:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
buildArgs.Add($"/p:TargetFramework={Framework}");
|
2015-11-20 19:00:56 -08:00
|
|
|
|
}
|
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
var buildResult = new MSBuildForwardingApp(buildArgs).Execute();
|
|
|
|
|
|
|
|
|
|
if (buildResult != 0)
|
2015-11-20 19:00:56 -08:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
Reporter.Error.WriteLine();
|
|
|
|
|
throw new GracefulException("The build failed. Please fix the build errors and run again.");
|
2015-11-20 19:00:56 -08:00
|
|
|
|
}
|
2015-11-23 16:31:27 -08:00
|
|
|
|
}
|
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
private ICommand GetRunCommand()
|
2015-11-23 16:31:27 -08:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
Dictionary<string, string> globalProperties = new Dictionary<string, string>()
|
2015-11-23 19:58:11 -08:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
{ "MSBuildExtensionsPath", AppContext.BaseDirectory }
|
|
|
|
|
};
|
2015-11-20 19:00:56 -08:00
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
if (!string.IsNullOrWhiteSpace(Configuration))
|
2015-11-20 19:00:56 -08:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
globalProperties.Add("Configuration", Configuration);
|
2015-11-20 19:00:56 -08:00
|
|
|
|
}
|
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
if (!string.IsNullOrWhiteSpace(Framework))
|
2015-11-20 19:00:56 -08:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
globalProperties.Add("TargetFramework", Framework);
|
2015-11-20 19:00:56 -08:00
|
|
|
|
}
|
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
ProjectInstance projectInstance = new ProjectInstance(Project, globalProperties, null);
|
|
|
|
|
|
|
|
|
|
string runProgram = projectInstance.GetPropertyValue("RunCommand");
|
|
|
|
|
if (string.IsNullOrEmpty(runProgram))
|
2016-04-25 13:53:02 -07:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
string outputType = projectInstance.GetPropertyValue("OutputType");
|
|
|
|
|
|
|
|
|
|
throw new GracefulException(string.Join(Environment.NewLine,
|
|
|
|
|
"Unable to run your project.",
|
|
|
|
|
"Please ensure you have a runnable project type and ensure 'dotnet run' supports this project.",
|
|
|
|
|
$"The current OutputType is '{outputType}'."));
|
2016-04-25 13:53:02 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
string runArguments = projectInstance.GetPropertyValue("RunArguments");
|
|
|
|
|
string runWorkingDirectory = projectInstance.GetPropertyValue("RunWorkingDirectory");
|
2016-04-25 13:53:02 -07:00
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
string fullArguments = runArguments;
|
|
|
|
|
if (_args.Any())
|
2015-11-20 19:00:56 -08:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
fullArguments += " " + ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(_args);
|
2015-11-20 19:00:56 -08:00
|
|
|
|
}
|
2016-04-22 15:01:56 -07:00
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
CommandSpec commandSpec = new CommandSpec(runProgram, fullArguments, CommandResolutionStrategy.None);
|
2015-11-23 19:58:11 -08:00
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
return Command.Create(commandSpec)
|
|
|
|
|
.WorkingDirectory(runWorkingDirectory);
|
|
|
|
|
}
|
2015-11-20 19:00:56 -08:00
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
private void Initialize()
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(Project))
|
2016-03-31 09:00:25 -07:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
string directory = Directory.GetCurrentDirectory();
|
|
|
|
|
string[] projectFiles = Directory.GetFiles(directory, "*.*proj");
|
2016-07-26 13:20:23 -05:00
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
if (projectFiles.Length == 0)
|
2016-07-26 13:20:23 -05:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
throw new InvalidOperationException(
|
|
|
|
|
$"Couldn't find a project to run. Ensure a project exists in {directory}." + Environment.NewLine +
|
|
|
|
|
"Or pass the path to the project using --project");
|
2016-07-26 13:20:23 -05:00
|
|
|
|
}
|
2016-10-27 18:46:43 -07:00
|
|
|
|
else if (projectFiles.Length > 1)
|
2015-11-20 19:00:56 -08:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
throw new InvalidOperationException(
|
|
|
|
|
$"Specify which project file to use because this '{directory}' contains more than one project file.");
|
2015-11-20 19:00:56 -08:00
|
|
|
|
}
|
2016-10-27 18:46:43 -07:00
|
|
|
|
|
|
|
|
|
Project = projectFiles[0];
|
2015-11-20 19:00:56 -08:00
|
|
|
|
}
|
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
if (Args == null)
|
2016-03-15 11:50:14 -07:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
_args = new List<string>();
|
2016-03-15 11:50:14 -07:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
_args = new List<string>(Args);
|
2016-05-12 10:24:57 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2015-11-20 19:00:56 -08:00
|
|
|
|
}
|
|
|
|
|
}
|