dotnet-installer/src/Microsoft.DotNet.Tools.Run/Program.cs

150 lines
5.9 KiB
C#
Raw Normal View History

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);
// This is required to be an option because otherwise we can't tell if the first argument is a project or the first argument to pass to an application
var project = app.Option("-p|--project <PROJECT_PATH>", "The path to the project to run (defaults to the current directory). Can be a path to a project.json or a project directory.", CommandOptionType.SingleValue);
2015-10-30 15:40:13 -07:00
app.OnExecute(() =>
{
// Locate the project and get the name and full path
var path = project.Value();
2015-10-30 10:34:02 -07:00
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
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-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");
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";
}
}
// 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);
}
}
2015-10-30 15:40:13 -07:00
result = Command.Create(outputName, string.Join(" ", remainingArguments))
.ForwardStdOut()
.ForwardStdErr()
.EnvironmentVariable("DOTNET_HOME", runtime)
2015-10-30 15:40:13 -07:00
.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-repl-csi", scriptName)
2015-10-30 10:34:02 -07:00
.ForwardStdOut()
.ForwardStdErr();
var result = command.Execute();
return result.ExitCode;
}
2015-10-30 15:40:13 -07:00
}
}