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 ;
using System.Runtime.InteropServices ;
using Microsoft.DotNet.Cli.Utils ;
2015-11-27 16:19:54 -08:00
using Microsoft.DotNet.ProjectModel ;
2015-11-20 19:00:56 -08:00
using NuGet.Frameworks ;
namespace Microsoft.DotNet.Tools.Run
{
public class RunCommand
{
public string Framework = null ;
public string Configuration = null ;
public bool PreserveTemporary = false ;
public string Project = null ;
public IReadOnlyList < string > Args = null ;
ProjectContext _context ;
List < string > _args ;
public int Start ( )
{
2015-11-23 16:31:27 -08:00
if ( IsInteractive ( ) )
2015-11-20 19:00:56 -08:00
{
return RunInteractive ( Project ) ;
}
else
{
return RunExecutable ( ) ;
}
}
2015-11-23 16:31:27 -08:00
private bool IsInteractive ( )
2015-11-20 19:00:56 -08:00
{
if ( ! string . IsNullOrEmpty ( Project ) )
{
2015-11-23 16:31:27 -08:00
if ( File . Exists ( Project ) & & ( Path . GetExtension ( Project ) . ToLowerInvariant ( ) = = ".csx" ) )
2015-11-20 19:00:56 -08:00
{
2015-11-23 16:31:27 -08:00
return true ;
2015-11-20 19:00:56 -08:00
}
}
2015-11-23 16:31:27 -08:00
return false ;
}
private void CalculateDefaultsForNonAssigned ( )
{
2015-11-23 19:58:11 -08:00
if ( string . IsNullOrWhiteSpace ( Project ) )
{
Project = Directory . GetCurrentDirectory ( ) ;
}
2015-11-20 19:00:56 -08:00
if ( string . IsNullOrWhiteSpace ( Configuration ) )
{
Configuration = Constants . DefaultConfiguration ;
}
var contexts = ProjectContext . CreateContextForEachFramework ( Project ) ;
if ( Framework = = null )
{
_context = contexts . First ( ) ;
}
else
{
var fx = NuGetFramework . Parse ( Framework ) ;
_context = contexts . FirstOrDefault ( c = > c . TargetFramework . Equals ( fx ) ) ;
}
if ( Args = = null )
{
_args = new List < string > ( ) ;
}
else
{
_args = new List < string > ( Args ) ;
}
}
private int RunExecutable ( )
{
2015-11-23 19:58:11 -08:00
CalculateDefaultsForNonAssigned ( ) ;
2015-12-13 22:07:32 -08:00
// Create a temporary directory under the project root
// REVIEW: MAX_PATH?
var tempDir = Path . Combine ( _context . ProjectDirectory , "bin" , ".dotnetrun" , Guid . NewGuid ( ) . ToString ( "N" ) ) ;
2015-11-20 19:00:56 -08:00
// Compile to that directory
var result = Command . Create ( $"dotnet-compile" , $"--output \" { tempDir } \ " --temp-output \"{tempDir}\" --framework \"{_context.TargetFramework}\" --configuration \"{Configuration}\" {_context.ProjectFile.ProjectDirectory}" )
. ForwardStdOut ( onlyIfVerbose : true )
. ForwardStdErr ( )
. Execute ( ) ;
if ( result . ExitCode ! = 0 )
{
return result . ExitCode ;
}
// Now launch the output and give it the results
var outputName = Path . Combine ( tempDir , _context . ProjectFile . Name + Constants . ExeSuffix ) ;
if ( ! RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
{
if ( _context . TargetFramework . IsDesktop ( ) )
{
// Run mono if we're running a desktop target on non windows
_args . Insert ( 0 , outputName + ".exe" ) ;
if ( string . Equals ( Configuration , "Debug" , StringComparison . OrdinalIgnoreCase ) )
{
// If we're compiling for the debug configuration then add the --debug flag
// other options may be passed using the MONO_OPTIONS env var
_args . Insert ( 0 , "--debug" ) ;
}
outputName = "mono" ;
}
}
// Locate the runtime
string runtime = Environment . GetEnvironmentVariable ( "DOTNET_HOME" ) ;
if ( string . IsNullOrEmpty ( runtime ) )
{
// Use the runtime deployed with the tools, if present
var candidate = Path . Combine ( AppContext . BaseDirectory , ".." , "runtime" ) ;
if ( File . Exists ( Path . Combine ( candidate , Constants . LibCoreClrName ) ) )
{
runtime = Path . GetFullPath ( candidate ) ;
}
}
result = Command . Create ( outputName , string . Join ( " " , _args ) )
. ForwardStdOut ( )
. ForwardStdErr ( )
. EnvironmentVariable ( "DOTNET_HOME" , runtime )
. Execute ( ) ;
2015-12-13 22:07:32 -08:00
2015-11-20 19:00:56 -08:00
// Clean up
if ( ! PreserveTemporary )
{
Directory . Delete ( tempDir , recursive : true ) ;
}
return result . ExitCode ;
}
private static int RunInteractive ( string scriptName )
{
var command = Command . Create ( $"dotnet-repl-csi" , scriptName )
. ForwardStdOut ( )
. ForwardStdErr ( ) ;
var result = command . Execute ( ) ;
return result . ExitCode ;
}
}
}