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 ( ) ;
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
}
2016-10-27 18:46:43 -07:00
ProjectInstance projectInstance = new ProjectInstance ( Project , globalProperties , null ) ;
2017-02-07 15:14:43 -08:00
string runProgram = projectInstance . GetPropertyValue ( "RunCommand" ) ;
2016-10-27 18:46:43 -07:00
if ( string . IsNullOrEmpty ( runProgram ) )
2016-04-25 13:53:02 -07:00
{
2017-02-07 15:14:43 -08:00
string outputType = projectInstance . GetPropertyValue ( "OutputType" ) ;
throw new GracefulException (
string . Format (
LocalizableStrings . RunCommandExceptionUnableToRun ,
"dotnet run" ,
"OutputType" ,
outputType ) ) ;
2016-04-25 13:53:02 -07:00
}
2017-02-07 15:14:43 -08: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
{
2017-02-07 15:14:43 -08:00
var project = "--project" ;
2016-10-27 18:46:43 -07:00
throw new InvalidOperationException (
2017-02-07 15:14:43 -08:00
$"Couldn\'t find a project to run. Ensure a project exists in {directory}, or pass the path to the project using {project}" )
. DisplayAsError ( ) ;
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 (
2017-02-07 15:14:43 -08:00
$"Specify which project file to use because {directory} contains more than one project file." )
. DisplayAsError ( ) ;
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
}
}