2015-11-21 03:00:56 +00: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-28 00:19:54 +00:00
|
|
|
|
using Microsoft.DotNet.ProjectModel;
|
2015-11-21 03:00:56 +00:00
|
|
|
|
using NuGet.Frameworks;
|
|
|
|
|
|
|
|
|
|
namespace Microsoft.DotNet.Tools.Run
|
|
|
|
|
{
|
2016-01-31 05:47:50 +00:00
|
|
|
|
public partial class RunCommand
|
2015-11-21 03:00:56 +00:00
|
|
|
|
{
|
|
|
|
|
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-24 00:31:27 +00:00
|
|
|
|
if (IsInteractive())
|
2015-11-21 03:00:56 +00:00
|
|
|
|
{
|
|
|
|
|
return RunInteractive(Project);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return RunExecutable();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-24 00:31:27 +00:00
|
|
|
|
private bool IsInteractive()
|
2015-11-21 03:00:56 +00:00
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(Project))
|
|
|
|
|
{
|
2015-11-24 00:31:27 +00:00
|
|
|
|
if (File.Exists(Project) && (Path.GetExtension(Project).ToLowerInvariant() == ".csx"))
|
2015-11-21 03:00:56 +00:00
|
|
|
|
{
|
2015-11-24 00:31:27 +00:00
|
|
|
|
return true;
|
2015-11-21 03:00:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2015-11-24 00:31:27 +00:00
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CalculateDefaultsForNonAssigned()
|
|
|
|
|
{
|
2015-11-24 03:58:11 +00:00
|
|
|
|
if (string.IsNullOrWhiteSpace(Project))
|
|
|
|
|
{
|
|
|
|
|
Project = Directory.GetCurrentDirectory();
|
|
|
|
|
}
|
2015-11-21 03:00:56 +00: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-24 03:58:11 +00:00
|
|
|
|
CalculateDefaultsForNonAssigned();
|
|
|
|
|
|
2015-12-14 06:07:32 +00: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-21 03:00:56 +00:00
|
|
|
|
|
|
|
|
|
// Compile to that directory
|
2016-01-31 05:47:50 +00:00
|
|
|
|
var result = Command.CreateDotNet($"build", new []
|
2016-01-22 22:04:04 +00:00
|
|
|
|
{
|
|
|
|
|
$"--output",
|
|
|
|
|
$"{tempDir}",
|
|
|
|
|
$"--temp-output",
|
|
|
|
|
$"{tempDir}",
|
|
|
|
|
$"--framework",
|
|
|
|
|
$"{_context.TargetFramework}",
|
|
|
|
|
$"--configuration",
|
|
|
|
|
$"{Configuration}",
|
|
|
|
|
$"{_context.ProjectFile.ProjectDirectory}"
|
|
|
|
|
})
|
2015-11-21 03:00:56 +00:00
|
|
|
|
.ForwardStdOut(onlyIfVerbose: true)
|
|
|
|
|
.ForwardStdErr()
|
|
|
|
|
.Execute();
|
|
|
|
|
|
|
|
|
|
if (result.ExitCode != 0)
|
|
|
|
|
{
|
|
|
|
|
return result.ExitCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Now launch the output and give it the results
|
2016-01-26 14:39:13 +00:00
|
|
|
|
var outputName = _context.GetOutputPathCalculator(tempDir).GetExecutablePath(Configuration);
|
|
|
|
|
|
2015-11-21 03:00:56 +00:00
|
|
|
|
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
|
|
|
{
|
|
|
|
|
if (_context.TargetFramework.IsDesktop())
|
|
|
|
|
{
|
|
|
|
|
// Run mono if we're running a desktop target on non windows
|
2016-01-26 14:39:13 +00:00
|
|
|
|
_args.Insert(0, outputName);
|
2015-11-21 03:00:56 +00: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
|
|
|
|
|
_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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-22 22:04:04 +00:00
|
|
|
|
result = Command.Create(outputName, _args)
|
2015-11-21 03:00:56 +00:00
|
|
|
|
.ForwardStdOut()
|
|
|
|
|
.ForwardStdErr()
|
|
|
|
|
.EnvironmentVariable("DOTNET_HOME", runtime)
|
|
|
|
|
.Execute();
|
2015-12-14 06:40:11 +00:00
|
|
|
|
|
2015-11-21 03:00:56 +00:00
|
|
|
|
// Clean up
|
|
|
|
|
if (!PreserveTemporary)
|
|
|
|
|
{
|
|
|
|
|
Directory.Delete(tempDir, recursive: true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result.ExitCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static int RunInteractive(string scriptName)
|
|
|
|
|
{
|
2016-01-31 05:47:50 +00:00
|
|
|
|
var command = Command.CreateDotNet($"repl-csi", new [] {scriptName})
|
2015-11-21 03:00:56 +00:00
|
|
|
|
.ForwardStdOut()
|
|
|
|
|
.ForwardStdErr();
|
|
|
|
|
var result = command.Execute();
|
|
|
|
|
return result.ExitCode;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|