/
DotNetCLI.cs
176 lines (155 loc) · 5.52 KB
/
DotNetCLI.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
namespace Xamarin.ProjectTools
{
public class DotNetCLI
{
public string BuildLogFile { get; set; }
public string ProcessLogFile { get; set; }
public string Verbosity { get; set; } = "diag";
public string AndroidSdkPath { get; set; } = AndroidSdkResolver.GetAndroidSdkPath ();
public string AndroidNdkPath { get; set; } = AndroidSdkResolver.GetAndroidNdkPath ();
public string JavaSdkPath { get; set; } = AndroidSdkResolver.GetJavaSdkPath ();
public string ProjectDirectory { get; private set; }
readonly XASdkProject project;
readonly string projectOrSolution;
public DotNetCLI (string projectOrSolution)
{
this.projectOrSolution = projectOrSolution;
ProjectDirectory = Path.GetDirectoryName (projectOrSolution);
}
public DotNetCLI (XASdkProject project, string projectOrSolution)
: this (projectOrSolution)
{
this.project = project;
}
/// <summary>
/// Runs the `dotnet` tool with the specified arguments.
/// </summary>
/// <param name="args">command arguments</param>
/// <returns>Whether or not the command succeeded.</returns>
protected bool Execute (params string [] args)
{
if (string.IsNullOrEmpty (ProcessLogFile))
ProcessLogFile = Path.Combine (XABuildPaths.TestOutputDirectory, $"dotnet{DateTime.Now.ToString ("yyyyMMddHHmmssff")}-process.log");
var procOutput = new StringBuilder ();
bool succeeded;
using (var p = new Process ()) {
p.StartInfo.FileName = Path.Combine (AndroidSdkResolver.GetDotNetPreviewPath (), "dotnet");
p.StartInfo.Arguments = string.Join (" ", args);
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
// Ensure any variable alteration from DotNetXamarinProject.Construct is cleared.
if (!Builder.UseDotNet && !TestEnvironment.IsWindows) {
p.StartInfo.SetEnvironmentVariable ("MSBUILD_EXE_PATH", null);
}
p.ErrorDataReceived += (sender, e) => {
if (e.Data != null) {
procOutput.AppendLine (e.Data);
}
};
p.ErrorDataReceived += (sender, e) => {
if (e.Data != null) {
procOutput.AppendLine (e.Data);
}
};
procOutput.AppendLine ($"Running: {p.StartInfo.FileName} {p.StartInfo.Arguments}");
p.Start ();
p.BeginOutputReadLine ();
p.BeginErrorReadLine ();
bool completed = p.WaitForExit ((int) new TimeSpan (0, 15, 0).TotalMilliseconds);
succeeded = completed && p.ExitCode == 0;
procOutput.AppendLine ($"Exit Code: {p.ExitCode}");
}
File.WriteAllText (ProcessLogFile, procOutput.ToString ());
return succeeded;
}
public bool New (string template, string output = null)
{
var arguments = new List<string> {
"new",
template,
"--output", $"\"{output ?? ProjectDirectory}\"",
};
return Execute (arguments.ToArray ());
}
public bool Build (string target = null, string [] parameters = null)
{
var arguments = GetDefaultCommandLineArgs ("build", target, parameters);
return Execute (arguments.ToArray ());
}
public bool Pack (string target = null, string [] parameters = null)
{
var arguments = GetDefaultCommandLineArgs ("pack", target, parameters);
return Execute (arguments.ToArray ());
}
public bool Publish (string target = null, string [] parameters = null)
{
var arguments = GetDefaultCommandLineArgs ("publish", target, parameters);
return Execute (arguments.ToArray ());
}
public bool Run ()
{
string binlog = Path.Combine (Path.GetDirectoryName (projectOrSolution), "run.binlog");
var arguments = new List<string> {
"run",
"--project", $"\"{projectOrSolution}\"",
"--no-build",
$"/bl:\"{binlog}\""
};
return Execute (arguments.ToArray ());
}
public IEnumerable<string> LastBuildOutput {
get {
if (!string.IsNullOrEmpty (BuildLogFile) && File.Exists (BuildLogFile)) {
return File.ReadLines (BuildLogFile, Encoding.UTF8);
}
return Enumerable.Empty<string> ();
}
}
public bool IsTargetSkipped (string target) => BuildOutput.IsTargetSkipped (LastBuildOutput, target);
List<string> GetDefaultCommandLineArgs (string verb, string target = null, string [] parameters = null)
{
string testDir = Path.GetDirectoryName (projectOrSolution);
if (string.IsNullOrEmpty (ProcessLogFile))
ProcessLogFile = Path.Combine (testDir, "process.log");
if (string.IsNullOrEmpty (BuildLogFile))
BuildLogFile = Path.Combine (testDir, "build.log");
var binlog = string.IsNullOrEmpty (target) ? "msbuild" : target;
var arguments = new List<string> {
verb,
$"\"{projectOrSolution}\"",
"/noconsolelogger",
$"/flp1:LogFile=\"{BuildLogFile}\";Encoding=UTF-8;Verbosity={Verbosity}",
$"/bl:\"{Path.Combine (testDir, $"{binlog}.binlog")}\""
};
if (!string.IsNullOrEmpty (target)) {
arguments.Add ($"/t:{target}");
}
if (project != null) {
arguments.Add ($"/p:Configuration={project.Configuration}");
}
if (Directory.Exists (AndroidSdkPath)) {
arguments.Add ($"/p:AndroidSdkDirectory=\"{AndroidSdkPath}\"");
}
if (Directory.Exists (AndroidNdkPath)) {
arguments.Add ($"/p:AndroidNdkDirectory=\"{AndroidNdkPath}\"");
}
if (Directory.Exists (JavaSdkPath)) {
arguments.Add ($"/p:JavaSdkDirectory=\"{JavaSdkPath}\"");
}
if (parameters != null) {
foreach (var parameter in parameters) {
arguments.Add ($"/p:{parameter}");
}
}
return arguments;
}
}
}