Build Cleanup: Part 2 (#3890)
* Remove deprecated build_projects sources * Remove BuildSetup, StandardGoals, and Target Attributes * Incremental restore of tasks dll * CheckPreReq conforms with MSBuild Error Handling guidelines * Eliminate deprecated content * PR Feedback
This commit is contained in:
parent
354a43ff83
commit
24d2e638d5
31 changed files with 95 additions and 2111 deletions
|
@ -1,52 +0,0 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
public static class AnsiColorExtensions
|
||||
{
|
||||
public static string Black(this string text)
|
||||
{
|
||||
return "\x1B[30m" + text + "\x1B[39m";
|
||||
}
|
||||
|
||||
public static string Red(this string text)
|
||||
{
|
||||
return "\x1B[31m" + text + "\x1B[39m";
|
||||
}
|
||||
public static string Green(this string text)
|
||||
{
|
||||
return "\x1B[32m" + text + "\x1B[39m";
|
||||
}
|
||||
|
||||
public static string Yellow(this string text)
|
||||
{
|
||||
return "\x1B[33m" + text + "\x1B[39m";
|
||||
}
|
||||
|
||||
public static string Blue(this string text)
|
||||
{
|
||||
return "\x1B[34m" + text + "\x1B[39m";
|
||||
}
|
||||
|
||||
public static string Magenta(this string text)
|
||||
{
|
||||
return "\x1B[35m" + text + "\x1B[39m";
|
||||
}
|
||||
|
||||
public static string Cyan(this string text)
|
||||
{
|
||||
return "\x1B[36m" + text + "\x1B[39m";
|
||||
}
|
||||
|
||||
public static string White(this string text)
|
||||
{
|
||||
return "\x1B[37m" + text + "\x1B[39m";
|
||||
}
|
||||
|
||||
public static string Bold(this string text)
|
||||
{
|
||||
return "\x1B[1m" + text + "\x1B[22m";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
// 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.IO;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
public class AnsiConsole
|
||||
{
|
||||
private AnsiConsole(TextWriter writer)
|
||||
{
|
||||
Writer = writer;
|
||||
|
||||
OriginalForegroundColor = Console.ForegroundColor;
|
||||
}
|
||||
|
||||
private int _boldRecursion;
|
||||
|
||||
public static AnsiConsole GetOutput()
|
||||
{
|
||||
return new AnsiConsole(Console.Out);
|
||||
}
|
||||
|
||||
public static AnsiConsole GetError()
|
||||
{
|
||||
return new AnsiConsole(Console.Error);
|
||||
}
|
||||
|
||||
public TextWriter Writer { get; }
|
||||
|
||||
public ConsoleColor OriginalForegroundColor { get; }
|
||||
|
||||
private void SetColor(ConsoleColor color)
|
||||
{
|
||||
const int Light = 0x08;
|
||||
int c = (int)color;
|
||||
|
||||
Console.ForegroundColor =
|
||||
c < 0 ? color : // unknown, just use it
|
||||
_boldRecursion > 0 ? (ConsoleColor)(c | Light) : // ensure color is light
|
||||
(ConsoleColor)(c & ~Light); // ensure color is dark
|
||||
}
|
||||
|
||||
private void SetBold(bool bold)
|
||||
{
|
||||
_boldRecursion += bold ? 1 : -1;
|
||||
if (_boldRecursion > 1 || (_boldRecursion == 1 && !bold))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// switches on _boldRecursion to handle boldness
|
||||
SetColor(Console.ForegroundColor);
|
||||
}
|
||||
|
||||
public void WriteLine(string message)
|
||||
{
|
||||
Write(message);
|
||||
Writer.WriteLine();
|
||||
}
|
||||
|
||||
|
||||
public void Write(string message)
|
||||
{
|
||||
var escapeScan = 0;
|
||||
for (;;)
|
||||
{
|
||||
var escapeIndex = message.IndexOf("\x1b[", escapeScan, StringComparison.Ordinal);
|
||||
if (escapeIndex == -1)
|
||||
{
|
||||
var text = message.Substring(escapeScan);
|
||||
Writer.Write(text);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
var startIndex = escapeIndex + 2;
|
||||
var endIndex = startIndex;
|
||||
while (endIndex != message.Length &&
|
||||
message[endIndex] >= 0x20 &&
|
||||
message[endIndex] <= 0x3f)
|
||||
{
|
||||
endIndex += 1;
|
||||
}
|
||||
|
||||
var text = message.Substring(escapeScan, escapeIndex - escapeScan);
|
||||
Writer.Write(text);
|
||||
if (endIndex == message.Length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
switch (message[endIndex])
|
||||
{
|
||||
case 'm':
|
||||
int value;
|
||||
if (int.TryParse(message.Substring(startIndex, endIndex - startIndex), out value))
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 1:
|
||||
SetBold(true);
|
||||
break;
|
||||
case 22:
|
||||
SetBold(false);
|
||||
break;
|
||||
case 30:
|
||||
SetColor(ConsoleColor.Black);
|
||||
break;
|
||||
case 31:
|
||||
SetColor(ConsoleColor.Red);
|
||||
break;
|
||||
case 32:
|
||||
SetColor(ConsoleColor.Green);
|
||||
break;
|
||||
case 33:
|
||||
SetColor(ConsoleColor.Yellow);
|
||||
break;
|
||||
case 34:
|
||||
SetColor(ConsoleColor.Blue);
|
||||
break;
|
||||
case 35:
|
||||
SetColor(ConsoleColor.Magenta);
|
||||
break;
|
||||
case 36:
|
||||
SetColor(ConsoleColor.Cyan);
|
||||
break;
|
||||
case 37:
|
||||
SetColor(ConsoleColor.Gray);
|
||||
break;
|
||||
case 39:
|
||||
Console.ForegroundColor = OriginalForegroundColor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
escapeScan = endIndex + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,177 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
public class BuildContext
|
||||
{
|
||||
private IDictionary<string, BuildTargetResult> _completedTargets = new Dictionary<string, BuildTargetResult>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public static readonly string DefaultTarget = "Default";
|
||||
|
||||
private int _maxTargetLen;
|
||||
private Stack<string> _targetStack = new Stack<string>();
|
||||
|
||||
public IDictionary<string, BuildTarget> Targets { get; }
|
||||
|
||||
public IDictionary<string, object> Properties = new Dictionary<string, object>();
|
||||
|
||||
public string BuildDirectory { get; }
|
||||
|
||||
public object this[string name]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties.ContainsKey(name))
|
||||
{
|
||||
return Properties[name];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new KeyNotFoundException("No property with key " + name + " was found.");
|
||||
}
|
||||
}
|
||||
set { Properties[name] = value; }
|
||||
}
|
||||
|
||||
public BuildContext(IDictionary<string, BuildTarget> targets, string buildDirectory)
|
||||
{
|
||||
Targets = targets;
|
||||
BuildDirectory = buildDirectory;
|
||||
_maxTargetLen = targets.Values.Select(t => t.Name.Length).Max();
|
||||
}
|
||||
|
||||
public T Get<T>(string name) => (T)this[name];
|
||||
|
||||
public BuildTargetResult RunTarget(string name) => RunTarget(name, force: false);
|
||||
|
||||
public BuildTargetResult RunTarget(string name, bool force)
|
||||
{
|
||||
BuildTarget target;
|
||||
if (!Targets.TryGetValue(name, out target))
|
||||
{
|
||||
throw new UndefinedTargetException($"Undefined target: {name}");
|
||||
}
|
||||
|
||||
if (!EvaluateTargetConditions(target))
|
||||
{
|
||||
Reporter.Verbose.WriteLine($"Skipping, Target Conditions not met: {target.Name}");
|
||||
return new BuildTargetResult(target, success: true);
|
||||
}
|
||||
|
||||
// Check if it's been completed
|
||||
BuildTargetResult result;
|
||||
if (!force && _completedTargets.TryGetValue(name, out result))
|
||||
{
|
||||
Reporter.Verbose.WriteLine($"Skipping completed target: {target.Name}");
|
||||
return result;
|
||||
}
|
||||
|
||||
// It hasn't, or we're forcing, so run it
|
||||
result = ExecTarget(target);
|
||||
_completedTargets[target.Name] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Verbose(string message)
|
||||
{
|
||||
Reporter.Output.WriteLine("trace".White() + $": {message}");
|
||||
}
|
||||
|
||||
public void Info(string message)
|
||||
{
|
||||
Reporter.Output.WriteLine("info ".Green() + $": {message}");
|
||||
}
|
||||
|
||||
public void Warn(string message)
|
||||
{
|
||||
Reporter.Output.WriteLine("warn ".Yellow() + $": {message}");
|
||||
}
|
||||
|
||||
public void Error(string message)
|
||||
{
|
||||
Reporter.Error.WriteLine("error".Red().Bold() + $": {message}");
|
||||
}
|
||||
|
||||
private bool EvaluateTargetConditions(BuildTarget target)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(target));
|
||||
}
|
||||
|
||||
if (target.Conditions == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (var condition in target.Conditions)
|
||||
{
|
||||
if (!condition())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private BuildTargetResult ExecTarget(BuildTarget target)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(target));
|
||||
}
|
||||
|
||||
var sectionName = $"{target.Name.PadRight(_maxTargetLen + 2).Yellow()} ({target.Source.White()})";
|
||||
BuildReporter.BeginSection("TARGET", sectionName);
|
||||
|
||||
BuildTargetResult result;
|
||||
|
||||
// Run the dependencies
|
||||
var dependencyResults = new Dictionary<string, BuildTargetResult>();
|
||||
var failedDependencyResult = RunDependencies(target, dependencyResults);
|
||||
if (failedDependencyResult != null)
|
||||
{
|
||||
result = failedDependencyResult;
|
||||
}
|
||||
else if (target.Body != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
result = target.Body(new BuildTargetContext(this, target, dependencyResults));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result = new BuildTargetResult(target, success: false, exception: ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new BuildTargetResult(target, success: true);
|
||||
}
|
||||
BuildReporter.EndSection("TARGET", sectionName, result.Success);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private BuildTargetResult RunDependencies(BuildTarget target, Dictionary<string, BuildTargetResult> dependencyResults)
|
||||
{
|
||||
BuildTargetResult result = null;
|
||||
foreach (var dependency in target.Dependencies)
|
||||
{
|
||||
result = RunTarget(dependency);
|
||||
dependencyResults[dependency] = result;
|
||||
|
||||
if (!result.Success)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
public class BuildFailureException : Exception
|
||||
{
|
||||
public BuildTarget Target { get; }
|
||||
|
||||
public BuildFailureException()
|
||||
{
|
||||
}
|
||||
|
||||
public BuildFailureException(BuildTarget target) : base($"The '{target.Name}' target failed")
|
||||
{
|
||||
Target = target;
|
||||
}
|
||||
|
||||
public BuildFailureException(BuildTarget target, Exception innerException) : base($"The '{target.Name}' target failed", innerException)
|
||||
{
|
||||
Target = target;
|
||||
}
|
||||
|
||||
public BuildFailureException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public BuildFailureException(string message, BuildTarget target) : base(message)
|
||||
{
|
||||
Target = target;
|
||||
}
|
||||
|
||||
public BuildFailureException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
public BuildFailureException(string message, Exception innerException, BuildTarget target) : base(message, innerException)
|
||||
{
|
||||
Target = target;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
public static class BuildReporter
|
||||
{
|
||||
private const string TimeSpanFormat = @"hh\:mm\:ss\.fff";
|
||||
private static DateTime _initialTime = DateTime.Now;
|
||||
|
||||
public static void BeginSection(string type, string name)
|
||||
{
|
||||
Reporter.Output.WriteLine($"[{type.PadRight(10)} >]".Green() + $" [....] [{(DateTime.Now - _initialTime).ToString(TimeSpanFormat)}]".Blue() + $" {name}");
|
||||
}
|
||||
|
||||
public static void EndSection(string type, string name, bool success)
|
||||
{
|
||||
var header = $"[{type.PadRight(10)} <]";
|
||||
if(success)
|
||||
{
|
||||
header = header.Green();
|
||||
}
|
||||
else
|
||||
{
|
||||
header = header.Red();
|
||||
}
|
||||
var successString = success ? " OK " : "FAIL";
|
||||
Reporter.Output.WriteLine(header + $" [{successString}] [{(DateTime.Now - _initialTime).ToString(TimeSpanFormat)}]".Blue() + $" {name}");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,173 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
public class BuildSetup
|
||||
{
|
||||
private Dictionary<string, BuildTarget> _targets = new Dictionary<string, BuildTarget>();
|
||||
|
||||
public IList<TargetOverride> _overrides = new List<TargetOverride>();
|
||||
|
||||
public string ProductName { get; }
|
||||
|
||||
public BuildSetup(string productName)
|
||||
{
|
||||
ProductName = productName;
|
||||
}
|
||||
|
||||
public static BuildSetup Create(string productName)
|
||||
{
|
||||
return new BuildSetup(productName);
|
||||
}
|
||||
|
||||
public BuildSetup UseTargets(IEnumerable<BuildTarget> targets)
|
||||
{
|
||||
foreach (var target in targets)
|
||||
{
|
||||
BuildTarget previousTarget;
|
||||
if (_targets.TryGetValue(target.Name, out previousTarget))
|
||||
{
|
||||
_overrides.Add(new TargetOverride(target.Name, previousTarget.Source, target.Source));
|
||||
}
|
||||
_targets[target.Name] = target;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuildSetup UseAllTargetsFromAssembly<T>()
|
||||
{
|
||||
var asm = typeof(T).GetTypeInfo().Assembly;
|
||||
return UseTargets(asm.GetExportedTypes().SelectMany(t => CollectTargets(t)));
|
||||
}
|
||||
|
||||
public BuildSetup UseTargetsFrom<T>()
|
||||
{
|
||||
return UseTargets(CollectTargets(typeof(T)));
|
||||
}
|
||||
|
||||
public BuildContext CreateBuildContext()
|
||||
{
|
||||
return new BuildContext(_targets, Directory.GetCurrentDirectory());
|
||||
}
|
||||
|
||||
public int Run(string[] args)
|
||||
{
|
||||
var targets = new[] { BuildContext.DefaultTarget };
|
||||
if(args.Length > 0)
|
||||
{
|
||||
targets = args;
|
||||
}
|
||||
|
||||
Reporter.Output.WriteBanner($"Building {ProductName}");
|
||||
|
||||
if (_overrides.Any())
|
||||
{
|
||||
foreach (var targetOverride in _overrides)
|
||||
{
|
||||
Reporter.Verbose.WriteLine($"Target {targetOverride.Name} from {targetOverride.OriginalSource} was overridden in {targetOverride.OverrideSource}");
|
||||
}
|
||||
}
|
||||
|
||||
var context = CreateBuildContext();
|
||||
BuildTargetResult result = null;
|
||||
try
|
||||
{
|
||||
foreach (var target in targets)
|
||||
{
|
||||
result = context.RunTarget(target);
|
||||
if(!result.Success)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Reporter.Error.WriteLine(ex.ToString().Red());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(result != null && !result.Success)
|
||||
{
|
||||
Reporter.Error.WriteLine($"Build failed: {result.ErrorMessage}".Red());
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Reporter.Output.WriteLine("Build succeeded".Green());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<BuildTarget> CollectTargets(Type typ)
|
||||
{
|
||||
return from m in typ.GetMethods()
|
||||
let targetAttribute = m.GetCustomAttribute<TargetAttribute>()
|
||||
let conditionalAttributes = m.GetCustomAttributes<TargetConditionAttribute>(false)
|
||||
where targetAttribute != null
|
||||
select CreateTarget(m, targetAttribute, conditionalAttributes);
|
||||
}
|
||||
|
||||
private static BuildTarget CreateTarget(
|
||||
MethodInfo methodInfo,
|
||||
TargetAttribute targetAttribute,
|
||||
IEnumerable<TargetConditionAttribute> targetConditionAttributes)
|
||||
{
|
||||
var name = targetAttribute.Name ?? methodInfo.Name;
|
||||
|
||||
var conditions = ExtractTargetConditionsFromAttributes(targetConditionAttributes);
|
||||
|
||||
return new BuildTarget(
|
||||
name,
|
||||
$"{methodInfo.DeclaringType.FullName}.{methodInfo.Name}",
|
||||
targetAttribute.Dependencies,
|
||||
conditions,
|
||||
(Func<BuildTargetContext, BuildTargetResult>)methodInfo.CreateDelegate(typeof(Func<BuildTargetContext, BuildTargetResult>)));
|
||||
}
|
||||
|
||||
private static IEnumerable<Func<bool>> ExtractTargetConditionsFromAttributes(
|
||||
IEnumerable<TargetConditionAttribute> targetConditionAttributes)
|
||||
{
|
||||
if (targetConditionAttributes == null || targetConditionAttributes.Count() == 0)
|
||||
{
|
||||
return Enumerable.Empty<Func<bool>>();
|
||||
}
|
||||
|
||||
return targetConditionAttributes
|
||||
.Select<TargetConditionAttribute, Func<bool>>(c => c.EvaluateCondition)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private string GenerateSourceString(string file, int? line, string member)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(file) && line != null)
|
||||
{
|
||||
return $"{file}:{line}";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(member))
|
||||
{
|
||||
return member;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public class TargetOverride
|
||||
{
|
||||
public string Name { get; }
|
||||
public string OriginalSource { get; }
|
||||
public string OverrideSource { get; }
|
||||
|
||||
public TargetOverride(string name, string originalSource, string overrideSource)
|
||||
{
|
||||
Name = name;
|
||||
OriginalSource = originalSource;
|
||||
OverrideSource = overrideSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
public class BuildTarget
|
||||
{
|
||||
public string Name { get; }
|
||||
public string Source { get; }
|
||||
public IEnumerable<string> Dependencies { get; }
|
||||
public IEnumerable<Func<bool>> Conditions { get; }
|
||||
public Func<BuildTargetContext, BuildTargetResult> Body { get; }
|
||||
|
||||
public BuildTarget(string name, string source) : this(name, source, Enumerable.Empty<string>(), Enumerable.Empty<Func<bool>>(), null) { }
|
||||
public BuildTarget(string name, string source, IEnumerable<string> dependencies) : this(name, source, dependencies, Enumerable.Empty<Func<bool>>(), null) { }
|
||||
public BuildTarget(
|
||||
string name,
|
||||
string source,
|
||||
IEnumerable<string> dependencies,
|
||||
IEnumerable<Func<bool>> conditions,
|
||||
Func<BuildTargetContext, BuildTargetResult> body)
|
||||
{
|
||||
Name = name;
|
||||
Source = source;
|
||||
Dependencies = dependencies;
|
||||
Conditions = conditions;
|
||||
Body = body;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
public class BuildTargetContext
|
||||
{
|
||||
private IDictionary<string, BuildTargetResult> _dependencyResults;
|
||||
|
||||
public BuildContext BuildContext { get; }
|
||||
public BuildTarget Target { get; }
|
||||
|
||||
public BuildTargetContext(BuildContext buildContext, BuildTarget target, IDictionary<string, BuildTargetResult> dependencyResults)
|
||||
{
|
||||
BuildContext = buildContext;
|
||||
Target = target;
|
||||
_dependencyResults = dependencyResults;
|
||||
}
|
||||
|
||||
public BuildTargetResult Success()
|
||||
{
|
||||
return new BuildTargetResult(Target, success: true);
|
||||
}
|
||||
|
||||
public BuildTargetResult Failed() => Failed(errorMessage: string.Empty);
|
||||
|
||||
public BuildTargetResult Failed(string errorMessage)
|
||||
{
|
||||
return new BuildTargetResult(Target, success: false, errorMessage: errorMessage);
|
||||
}
|
||||
|
||||
public void Info(string message) => BuildContext.Info(message);
|
||||
public void Warn(string message) => BuildContext.Warn(message);
|
||||
public void Error(string message) => BuildContext.Error(message);
|
||||
public void Verbose(string message) => BuildContext.Verbose(message);
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
public class BuildTargetResult
|
||||
{
|
||||
public BuildTarget Target { get; }
|
||||
public bool Success { get; }
|
||||
public string ErrorMessage { get; }
|
||||
public Exception Exception { get; }
|
||||
|
||||
public BuildTargetResult(BuildTarget target, bool success) : this(target, success, errorMessage: string.Empty) { }
|
||||
|
||||
public BuildTargetResult(BuildTarget target, bool success, Exception exception) : this(target, success, exception.ToString())
|
||||
{
|
||||
Exception = exception;
|
||||
}
|
||||
|
||||
public BuildTargetResult(BuildTarget target, bool success, string errorMessage)
|
||||
{
|
||||
Target = target;
|
||||
Success = success;
|
||||
ErrorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public void EnsureSuccessful()
|
||||
{
|
||||
if(!Success)
|
||||
{
|
||||
if(string.IsNullOrEmpty(ErrorMessage))
|
||||
{
|
||||
throw new BuildFailureException(Target, Exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new BuildFailureException(ErrorMessage, Exception, Target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -202,7 +202,7 @@ namespace Microsoft.DotNet.Cli.Build.Framework
|
|||
|
||||
var exitCode = _process.ExitCode;
|
||||
|
||||
ReportExecEnd(exitCode);
|
||||
ReportExecEnd(exitCode);
|
||||
|
||||
return new CommandResult(
|
||||
_process.StartInfo,
|
||||
|
@ -239,36 +239,6 @@ namespace Microsoft.DotNet.Cli.Build.Framework
|
|||
return this;
|
||||
}
|
||||
|
||||
public Command ForwardStdOut(TextWriter to = null)
|
||||
{
|
||||
ThrowIfRunning();
|
||||
_process.StartInfo.RedirectStandardOutput = true;
|
||||
if (to == null)
|
||||
{
|
||||
_stdOutForward = Reporter.Output.WriteLine;
|
||||
}
|
||||
else
|
||||
{
|
||||
_stdOutForward = to.WriteLine;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Command ForwardStdErr(TextWriter to = null)
|
||||
{
|
||||
ThrowIfRunning();
|
||||
_process.StartInfo.RedirectStandardError = true;
|
||||
if (to == null)
|
||||
{
|
||||
_stdErrForward = Reporter.Error.WriteLine;
|
||||
}
|
||||
else
|
||||
{
|
||||
_stdErrForward = to.WriteLine;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Command OnOutputLine(Action<string> handler)
|
||||
{
|
||||
ThrowIfRunning();
|
||||
|
@ -307,28 +277,25 @@ namespace Microsoft.DotNet.Cli.Build.Framework
|
|||
return prefix + " " + info.Arguments;
|
||||
}
|
||||
|
||||
private void ReportExecBegin()
|
||||
{
|
||||
if (!_quietBuildReporter)
|
||||
{
|
||||
BuildReporter.BeginSection("EXEC", FormatProcessInfo(_process.StartInfo, includeWorkingDirectory: false));
|
||||
}
|
||||
}
|
||||
|
||||
private void ReportExecEnd(int exitCode)
|
||||
{
|
||||
if (!_quietBuildReporter)
|
||||
{
|
||||
bool success = exitCode == 0;
|
||||
|
||||
var message = $"{FormatProcessInfo(_process.StartInfo, includeWorkingDirectory: !success)} exited with {exitCode}";
|
||||
|
||||
BuildReporter.EndSection(
|
||||
"EXEC",
|
||||
success ? message.Green() : message.Red().Bold(),
|
||||
success);
|
||||
}
|
||||
}
|
||||
private void ReportExecBegin()
|
||||
{
|
||||
if (!_quietBuildReporter)
|
||||
{
|
||||
Console.WriteLine($"[> EXEC] {FormatProcessInfo(_process.StartInfo, includeWorkingDirectory: false)}");
|
||||
}
|
||||
}
|
||||
|
||||
private void ReportExecEnd(int exitCode)
|
||||
{
|
||||
if (!_quietBuildReporter)
|
||||
{
|
||||
bool success = exitCode == 0;
|
||||
|
||||
var message = $"{FormatProcessInfo(_process.StartInfo, includeWorkingDirectory: !success)} exited with {exitCode}";
|
||||
|
||||
Console.WriteLine("[< EXEC] {message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void ThrowIfRunning([CallerMemberName] string memberName = null)
|
||||
{
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
// 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.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
public static class DebugHelper
|
||||
{
|
||||
[Conditional("DEBUG")]
|
||||
public static void HandleDebugSwitch(ref string[] args)
|
||||
{
|
||||
if (args.Length > 0 && string.Equals("--debug", args[0], StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
args = args.Skip(1).ToArray();
|
||||
WaitForDebugger();
|
||||
}
|
||||
}
|
||||
|
||||
private static void WaitForDebugger()
|
||||
{
|
||||
Console.WriteLine("Waiting for debugger to attach. Press ENTER to continue");
|
||||
Console.WriteLine($"Process ID: {Process.GetCurrentProcess().Id}");
|
||||
Console.ReadLine();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
// Stupid-simple console manager
|
||||
internal class Reporter
|
||||
{
|
||||
private static readonly Reporter Null = new Reporter(console: null);
|
||||
private static object _lock = new object();
|
||||
|
||||
private readonly AnsiConsole _console;
|
||||
|
||||
private Reporter(AnsiConsole console)
|
||||
{
|
||||
_console = console;
|
||||
}
|
||||
|
||||
public static Reporter Output { get; } = new Reporter(AnsiConsole.GetOutput());
|
||||
public static Reporter Error { get; } = new Reporter(AnsiConsole.GetOutput());
|
||||
public static Reporter Verbose { get; } = new Reporter(AnsiConsole.GetOutput());
|
||||
|
||||
public void WriteLine(string message)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_console?.WriteLine(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteLine()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_console?.Writer?.WriteLine();
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(string message)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_console?.Writer?.Write(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteBanner(string content)
|
||||
{
|
||||
string border = new string('*', content.Length + 6);
|
||||
WriteLine($@"{border}
|
||||
* {content} *
|
||||
{border}".Green());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
public static class StandardGoals
|
||||
{
|
||||
public static BuildSetup UseStandardGoals(this BuildSetup self)
|
||||
{
|
||||
return self.UseTargets(new[]
|
||||
{
|
||||
new BuildTarget("Default", "Standard Goals", new [] { "Prepare", "Compile", "Test", "Package", "Publish" }),
|
||||
new BuildTarget("Prepare", "Standard Goals"),
|
||||
new BuildTarget("Compile", "Standard Goals"),
|
||||
new BuildTarget("Test", "Standard Goals"),
|
||||
new BuildTarget("Package", "Standard Goals"),
|
||||
new BuildTarget("Publish", "Standard Goals")
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
|
||||
public class TargetAttribute : Attribute
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public IEnumerable<string> Dependencies { get; }
|
||||
|
||||
public TargetAttribute()
|
||||
{
|
||||
Dependencies = Enumerable.Empty<string>();
|
||||
}
|
||||
|
||||
// Attributes can only use constants, so a comma-separated string is better :)
|
||||
public TargetAttribute(params string[] dependencies)
|
||||
{
|
||||
Dependencies = dependencies;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
|
||||
public class BuildArchitecturesAttribute : TargetConditionAttribute
|
||||
{
|
||||
private IEnumerable<BuildArchitecture> _buildArchitectures;
|
||||
|
||||
public BuildArchitecturesAttribute(params BuildArchitecture[] architectures)
|
||||
{
|
||||
if (architectures == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(architectures));
|
||||
}
|
||||
|
||||
_buildArchitectures = architectures;
|
||||
}
|
||||
|
||||
public override bool EvaluateCondition()
|
||||
{
|
||||
var currentArchitecture = CurrentArchitecture.Current;
|
||||
|
||||
if (currentArchitecture == default(BuildArchitecture))
|
||||
{
|
||||
throw new Exception("Unrecognized Architecture");
|
||||
}
|
||||
|
||||
foreach (var architecture in _buildArchitectures)
|
||||
{
|
||||
if (architecture == currentArchitecture)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
|
||||
public class BuildPlatformsAttribute : TargetConditionAttribute
|
||||
{
|
||||
private IEnumerable<BuildPlatform> _buildPlatforms;
|
||||
private string _version;
|
||||
|
||||
public BuildPlatformsAttribute(params BuildPlatform[] platforms)
|
||||
{
|
||||
if (platforms == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(platforms));
|
||||
}
|
||||
|
||||
_buildPlatforms = platforms;
|
||||
}
|
||||
|
||||
public BuildPlatformsAttribute(BuildPlatform platform, string version)
|
||||
{
|
||||
_buildPlatforms = new BuildPlatform[] { platform };
|
||||
_version = version;
|
||||
}
|
||||
|
||||
public override bool EvaluateCondition()
|
||||
{
|
||||
foreach (var platform in _buildPlatforms)
|
||||
{
|
||||
if (CurrentPlatform.IsPlatform(platform, _version))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
|
||||
public class EnvironmentAttribute : TargetConditionAttribute
|
||||
{
|
||||
private string _envVar;
|
||||
private string[] _expectedVals;
|
||||
|
||||
public EnvironmentAttribute(string envVar, params string[] expectedVals)
|
||||
{
|
||||
if (string.IsNullOrEmpty(envVar))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(envVar));
|
||||
}
|
||||
if (expectedVals == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(expectedVals));
|
||||
}
|
||||
|
||||
_envVar = envVar;
|
||||
_expectedVals = expectedVals;
|
||||
}
|
||||
|
||||
public override bool EvaluateCondition()
|
||||
{
|
||||
var actualVal = Environment.GetEnvironmentVariable(_envVar);
|
||||
|
||||
if (_expectedVals.Any())
|
||||
{
|
||||
return _expectedVals.Any(ev => string.Equals(actualVal, ev, StringComparison.Ordinal));
|
||||
}
|
||||
else
|
||||
{
|
||||
return !string.IsNullOrEmpty(actualVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
public abstract class TargetConditionAttribute : Attribute
|
||||
{
|
||||
public abstract bool EvaluateCondition();
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Build.Framework
|
||||
{
|
||||
public class UndefinedTargetException : Exception
|
||||
{
|
||||
public UndefinedTargetException(string message) : base(message) { }
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue