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;
|
2017-03-21 13:46:08 -05:00
|
|
|
|
using Microsoft.Build.Evaluation;
|
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
|
|
|
|
{
|
2017-04-12 16:03:45 -07:00
|
|
|
|
public string Configuration { get; private set; }
|
|
|
|
|
public string Framework { get; private set; }
|
|
|
|
|
public bool NoBuild { get; private set; }
|
|
|
|
|
public string Project { get; private set; }
|
|
|
|
|
public IReadOnlyCollection<string> Args { get; private set; }
|
2015-11-20 19:00:56 -08:00
|
|
|
|
|
2016-05-12 10:24:57 -05:00
|
|
|
|
private List<string> _args;
|
2017-03-21 13:46:08 -05:00
|
|
|
|
private bool ShouldBuild => !NoBuild;
|
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();
|
|
|
|
|
|
2017-03-21 13:46:08 -05:00
|
|
|
|
if (ShouldBuild)
|
|
|
|
|
{
|
|
|
|
|
EnsureProjectIsBuilt();
|
|
|
|
|
}
|
2016-10-27 18:46:43 -07:00
|
|
|
|
|
|
|
|
|
ICommand runCommand = GetRunCommand();
|
|
|
|
|
|
|
|
|
|
return runCommand
|
|
|
|
|
.Execute()
|
|
|
|
|
.ExitCode;
|
2016-05-12 10:24:57 -05:00
|
|
|
|
}
|
2015-11-20 19:00:56 -08:00
|
|
|
|
|
2017-04-12 16:03:45 -07:00
|
|
|
|
public RunCommand(string configuration,
|
|
|
|
|
string framework,
|
|
|
|
|
bool noBuild,
|
|
|
|
|
string project,
|
|
|
|
|
IReadOnlyCollection<string> args)
|
|
|
|
|
{
|
|
|
|
|
Configuration = configuration;
|
|
|
|
|
Framework = framework;
|
|
|
|
|
NoBuild = noBuild;
|
|
|
|
|
Project = project;
|
|
|
|
|
Args = args;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RunCommand MakeNewWithReplaced(string configuration = null,
|
|
|
|
|
string framework = null,
|
|
|
|
|
bool? noBuild = null,
|
|
|
|
|
string project = null,
|
|
|
|
|
IReadOnlyCollection<string> args = null)
|
|
|
|
|
{
|
|
|
|
|
return new RunCommand(
|
|
|
|
|
configuration ?? this.Configuration,
|
|
|
|
|
framework ?? this.Framework,
|
|
|
|
|
noBuild ?? this.NoBuild,
|
|
|
|
|
project ?? this.Project,
|
|
|
|
|
args ?? this.Args
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
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>();
|
2017-03-21 13:46:08 -05:00
|
|
|
|
|
|
|
|
|
buildArgs.Add(Project);
|
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
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();
|
2016-11-19 11:45:46 -08:00
|
|
|
|
throw new GracefulException(LocalizableStrings.RunCommandException);
|
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
|
|
|
|
{
|
2017-02-07 15:14:43 -08:00
|
|
|
|
var globalProperties = new Dictionary<string, string>
|
2015-11-23 19:58:11 -08:00
|
|
|
|
{
|
2017-02-07 15:14:43 -08:00
|
|
|
|
{ Constants.MSBuildExtensionsPath, AppContext.BaseDirectory }
|
2016-10-27 18:46:43 -07:00
|
|
|
|
};
|
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
|
|
|
|
{
|
2017-02-07 15:14:43 -08: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
|
|
|
|
{
|
2017-02-07 15:14:43 -08:00
|
|
|
|
globalProperties.Add("TargetFramework", Framework);
|
2015-11-20 19:00:56 -08:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-21 13:46:08 -05:00
|
|
|
|
Project project = new Project(Project, globalProperties, null);
|
2016-10-27 18:46:43 -07:00
|
|
|
|
|
2017-03-21 13:46:08 -05:00
|
|
|
|
string runProgram = project.GetPropertyValue("RunCommand");
|
2016-10-27 18:46:43 -07:00
|
|
|
|
if (string.IsNullOrEmpty(runProgram))
|
2016-04-25 13:53:02 -07:00
|
|
|
|
{
|
2017-03-21 13:46:08 -05:00
|
|
|
|
ThrowUnableToRunError(project);
|
2016-04-25 13:53:02 -07:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-21 13:46:08 -05:00
|
|
|
|
string runArguments = project.GetPropertyValue("RunArguments");
|
|
|
|
|
string runWorkingDirectory = project.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
|
|
|
|
|
2017-03-21 13:46:08 -05:00
|
|
|
|
private void ThrowUnableToRunError(Project project)
|
|
|
|
|
{
|
|
|
|
|
string targetFrameworks = project.GetPropertyValue("TargetFrameworks");
|
|
|
|
|
if (!string.IsNullOrEmpty(targetFrameworks))
|
|
|
|
|
{
|
|
|
|
|
string targetFramework = project.GetPropertyValue("TargetFramework");
|
|
|
|
|
if (string.IsNullOrEmpty(targetFramework))
|
|
|
|
|
{
|
|
|
|
|
var framework = "--framework";
|
|
|
|
|
|
|
|
|
|
throw new GracefulException(LocalizableStrings.RunCommandExceptionUnableToRunSpecifyFramework, framework);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string outputType = project.GetPropertyValue("OutputType");
|
|
|
|
|
|
|
|
|
|
throw new GracefulException(
|
|
|
|
|
string.Format(
|
|
|
|
|
LocalizableStrings.RunCommandExceptionUnableToRun,
|
|
|
|
|
"dotnet run",
|
|
|
|
|
"OutputType",
|
|
|
|
|
outputType));
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
private void Initialize()
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(Project))
|
2016-03-31 09:00:25 -07:00
|
|
|
|
{
|
2017-03-24 06:44:53 +01:00
|
|
|
|
Project = Directory.GetCurrentDirectory();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Directory.Exists(Project))
|
|
|
|
|
{
|
|
|
|
|
Project = FindSingleProjectInDirectory(Project);
|
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
|
|
|
|
}
|
|
|
|
|
}
|
2017-03-24 06:44:53 +01:00
|
|
|
|
|
|
|
|
|
private static string FindSingleProjectInDirectory(string directory)
|
|
|
|
|
{
|
|
|
|
|
string[] projectFiles = Directory.GetFiles(directory, "*.*proj");
|
|
|
|
|
|
|
|
|
|
if (projectFiles.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
var project = "--project";
|
|
|
|
|
|
|
|
|
|
throw new GracefulException(LocalizableStrings.RunCommandExceptionNoProjects, directory, project);
|
|
|
|
|
}
|
|
|
|
|
else if (projectFiles.Length > 1)
|
|
|
|
|
{
|
|
|
|
|
throw new GracefulException(LocalizableStrings.RunCommandExceptionMultipleProjects, directory);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return projectFiles[0];
|
|
|
|
|
}
|
2015-11-20 19:00:56 -08:00
|
|
|
|
}
|
|
|
|
|
}
|