2015-10-30 15:40:13 -07:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
2015-11-01 02:30:34 -08:00
|
|
|
|
using System.Runtime.InteropServices;
|
2015-10-30 15:40:13 -07:00
|
|
|
|
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
|
|
|
|
using Microsoft.DotNet.Cli.Utils;
|
|
|
|
|
using Microsoft.Extensions.ProjectModel;
|
|
|
|
|
using NuGet.Frameworks;
|
|
|
|
|
|
2015-11-01 02:46:05 -08:00
|
|
|
|
namespace Microsoft.DotNet.Tools.Run
|
2015-10-30 15:40:13 -07:00
|
|
|
|
{
|
|
|
|
|
public class Program
|
|
|
|
|
{
|
|
|
|
|
public static int Main(string[] args)
|
|
|
|
|
{
|
|
|
|
|
DebugHelper.HandleDebugSwitch(ref args);
|
|
|
|
|
|
|
|
|
|
var app = new CommandLineApplication(throwOnUnexpectedArg: false);
|
|
|
|
|
app.Name = "dotnet run";
|
|
|
|
|
app.FullName = ".NET Executor";
|
|
|
|
|
app.Description = "Runner for the .NET Platform";
|
|
|
|
|
app.HelpOption("-h|--help");
|
|
|
|
|
|
|
|
|
|
var framework = app.Option("-f|--framework <FRAMEWORK>", "Compile a specific framework", CommandOptionType.MultipleValue);
|
|
|
|
|
var configuration = app.Option("-c|--configuration <CONFIGURATION>", "Configuration under which to build", CommandOptionType.SingleValue);
|
2015-11-01 16:21:10 -08:00
|
|
|
|
var preserveTemporaryOutput = app.Option("-t|--preserve-temporary", "Keep the output's temporary directory around", CommandOptionType.NoValue);
|
2015-10-30 10:34:02 -07:00
|
|
|
|
var project = app.Argument("<PROJECT>", "The project to run, defaults to the current directory. Can be a path to a project.json or a project directory");
|
2015-10-30 15:40:13 -07:00
|
|
|
|
|
|
|
|
|
app.OnExecute(() =>
|
|
|
|
|
{
|
|
|
|
|
// Locate the project and get the name and full path
|
2015-10-30 10:34:02 -07:00
|
|
|
|
var path = project.Value;
|
|
|
|
|
if (!string.IsNullOrEmpty(path))
|
2015-10-30 15:40:13 -07:00
|
|
|
|
{
|
2015-10-30 10:34:02 -07:00
|
|
|
|
if (File.Exists(path) && (Path.GetExtension(path) == ".csx"))
|
|
|
|
|
{
|
|
|
|
|
return RunInteractive(path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
path = Directory.GetCurrentDirectory();
|
2015-10-30 15:40:13 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var contexts = ProjectContext.CreateContextForEachFramework(path);
|
2015-10-30 10:34:02 -07:00
|
|
|
|
ProjectContext context;
|
2015-10-30 15:40:13 -07:00
|
|
|
|
if (!framework.HasValue())
|
|
|
|
|
{
|
2015-10-30 10:34:02 -07:00
|
|
|
|
context = contexts.First();
|
2015-10-30 15:40:13 -07:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-10-30 10:34:02 -07:00
|
|
|
|
var fx = NuGetFramework.Parse(framework.Value());
|
|
|
|
|
context = contexts.FirstOrDefault(c => c.TargetFramework.Equals(fx));
|
2015-10-30 15:40:13 -07:00
|
|
|
|
}
|
2015-10-30 10:34:02 -07:00
|
|
|
|
return Run(context, configuration.Value() ?? Constants.DefaultConfiguration, app.RemainingArguments, preserveTemporaryOutput.HasValue());
|
2015-10-30 15:40:13 -07:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return app.Execute(args);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG
|
|
|
|
|
Console.Error.WriteLine(ex);
|
|
|
|
|
#else
|
|
|
|
|
Console.Error.WriteLine(ex.Message);
|
|
|
|
|
#endif
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-01 02:30:34 -08:00
|
|
|
|
private static int Run(ProjectContext context, string configuration, List<string> remainingArguments, bool preserveTemporaryOutput)
|
2015-10-30 15:40:13 -07:00
|
|
|
|
{
|
|
|
|
|
// Create a temporary directory
|
|
|
|
|
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"));
|
|
|
|
|
|
|
|
|
|
// Compile to that directory
|
2015-11-03 00:01:04 -08:00
|
|
|
|
var result = Command.Create($"dotnet-compile", $"--output \"{tempDir}\" --temp-output \"{tempDir}\" --framework \"{context.TargetFramework}\" --configuration \"{configuration}\" {context.ProjectFile.ProjectDirectory}")
|
2015-11-01 16:21:10 -08:00
|
|
|
|
.ForwardStdOut(onlyIfVerbose: true)
|
2015-10-30 15:40:13 -07:00
|
|
|
|
.ForwardStdErr()
|
|
|
|
|
.Execute();
|
2015-11-01 01:44:53 -07:00
|
|
|
|
|
2015-10-30 15:40:13 -07:00
|
|
|
|
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);
|
2015-11-01 02:30:34 -08:00
|
|
|
|
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
|
|
|
{
|
|
|
|
|
if (context.TargetFramework.IsDesktop())
|
|
|
|
|
{
|
|
|
|
|
// Run mono if we're running a desktop target on non windows
|
|
|
|
|
remainingArguments.Insert(0, outputName + ".exe");
|
2015-11-01 20:41:58 -08:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
remainingArguments.Insert(0, "--debug");
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-01 02:30:34 -08:00
|
|
|
|
outputName = "mono";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-30 15:40:13 -07:00
|
|
|
|
result = Command.Create(outputName, string.Join(" ", remainingArguments))
|
|
|
|
|
.ForwardStdOut()
|
|
|
|
|
.ForwardStdErr()
|
|
|
|
|
.EnvironmentVariable("CLRHOST_CLR_PATH", AppContext.BaseDirectory)
|
|
|
|
|
.Execute();
|
|
|
|
|
|
|
|
|
|
// Clean up
|
|
|
|
|
if (!preserveTemporaryOutput)
|
|
|
|
|
{
|
|
|
|
|
Directory.Delete(tempDir, recursive: true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result.ExitCode;
|
|
|
|
|
}
|
2015-10-30 10:34:02 -07:00
|
|
|
|
|
|
|
|
|
private static int RunInteractive(string scriptName)
|
|
|
|
|
{
|
|
|
|
|
var command = Command.Create($"dotnet-interactive-csi", scriptName)
|
|
|
|
|
.ForwardStdOut()
|
|
|
|
|
.ForwardStdErr();
|
|
|
|
|
var result = command.Execute();
|
|
|
|
|
return result.ExitCode;
|
|
|
|
|
}
|
2015-10-30 15:40:13 -07:00
|
|
|
|
}
|
|
|
|
|
}
|