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
21
build.proj
21
build.proj
|
@ -13,11 +13,11 @@
|
||||||
<PlatformScriptExtension Condition=" '$(OS)' != 'Windows_NT' ">.sh</PlatformScriptExtension>
|
<PlatformScriptExtension Condition=" '$(OS)' != 'Windows_NT' ">.sh</PlatformScriptExtension>
|
||||||
|
|
||||||
<CLITargets Condition=" '$(CLITargets)' == '' ">Prepare;Compile;Test;Package;Publish</CLITargets>
|
<CLITargets Condition=" '$(CLITargets)' == '' ">Prepare;Compile;Test;Package;Publish</CLITargets>
|
||||||
<CLIBuildFileName>$(MSBuildThisFileDirectory)/build_projects/dotnet-cli-build/bin/dotnet-cli-build</CLIBuildFileName>
|
|
||||||
<CLIBuildDll>$(CLIBuildFileName).dll</CLIBuildDll>
|
|
||||||
|
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<RepoRoot>$(MSBuildThisFileDirectory)</RepoRoot>
|
<RepoRoot>$(MSBuildThisFileDirectory)</RepoRoot>
|
||||||
|
<CLIBuildFileName>$(RepoRoot)/build_projects/dotnet-cli-build/bin/dotnet-cli-build</CLIBuildFileName>
|
||||||
|
<CLIBuildDll>$(CLIBuildFileName).dll</CLIBuildDll>
|
||||||
<BuildToolsDir>$(RepoRoot)/build_tools</BuildToolsDir>
|
<BuildToolsDir>$(RepoRoot)/build_tools</BuildToolsDir>
|
||||||
|
|
||||||
<CoreSetupChannel>preview</CoreSetupChannel>
|
<CoreSetupChannel>preview</CoreSetupChannel>
|
||||||
|
@ -33,6 +33,8 @@
|
||||||
<ExeExtension>.exe</ExeExtension>
|
<ExeExtension>.exe</ExeExtension>
|
||||||
<ExeExtension Condition=" '$(OS)' != 'Windows_NT' "></ExeExtension>
|
<ExeExtension Condition=" '$(OS)' != 'Windows_NT' "></ExeExtension>
|
||||||
<DotnetStage0>$(Stage0Path)/dotnet$(ExeExtension)</DotnetStage0>
|
<DotnetStage0>$(Stage0Path)/dotnet$(ExeExtension)</DotnetStage0>
|
||||||
|
|
||||||
|
<DotnetCliBuildDirectory>$(RepoRoot)/build_projects/dotnet-cli-build</DotnetCliBuildDirectory>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -50,10 +52,8 @@
|
||||||
<Target Name="BuildDotnetCliBuildFramework"
|
<Target Name="BuildDotnetCliBuildFramework"
|
||||||
Inputs="@(DotnetCliBuildFrameworkInputs)"
|
Inputs="@(DotnetCliBuildFrameworkInputs)"
|
||||||
Outputs="$(CLIBuildDll)"
|
Outputs="$(CLIBuildDll)"
|
||||||
DependsOnTargets="MSBuildWorkaroundTarget">
|
DependsOnTargets="MSBuildWorkaroundTarget;
|
||||||
<PropertyGroup>
|
RestoreDotnetCliBuildFramework">
|
||||||
<DotnetCliBuildDirectory>$(MSBuildThisFileDirectory)/build_projects/dotnet-cli-build</DotnetCliBuildDirectory>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<DotnetSdkDirectories Include="$([System.IO.Directory]::GetDirectories("$(Stage0Path)/sdk"))" />
|
<DotnetSdkDirectories Include="$([System.IO.Directory]::GetDirectories("$(Stage0Path)/sdk"))" />
|
||||||
|
@ -63,8 +63,6 @@
|
||||||
</AzureStorageToCopy>
|
</AzureStorageToCopy>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Exec Command="$(DotnetStage0) restore" WorkingDirectory="$(DotnetCliBuildDirectory)"/>
|
|
||||||
|
|
||||||
<Exec Command="$(DotnetStage0) publish -o $(DotnetCliBuildDirectory)/bin --framework netcoreapp1.0" WorkingDirectory="$(DotnetCliBuildDirectory)"/>
|
<Exec Command="$(DotnetStage0) publish -o $(DotnetCliBuildDirectory)/bin --framework netcoreapp1.0" WorkingDirectory="$(DotnetCliBuildDirectory)"/>
|
||||||
|
|
||||||
<!-- This is a work around to issue https://github.com/Microsoft/msbuild/issues/658 -->
|
<!-- This is a work around to issue https://github.com/Microsoft/msbuild/issues/658 -->
|
||||||
|
@ -72,6 +70,13 @@
|
||||||
DestinationFiles="%(AzureStorageToCopy.Destination)" />
|
DestinationFiles="%(AzureStorageToCopy.Destination)" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="RestoreDotnetCliBuildFramework"
|
||||||
|
Inputs="$(DotnetCliBuildDirectory)/project.json"
|
||||||
|
Outputs="$(DotnetCliBuildDirectory)/project.lock.json">
|
||||||
|
|
||||||
|
<Exec Command="$(DotnetStage0) restore" WorkingDirectory="$(DotnetCliBuildDirectory)"/>
|
||||||
|
</Target>
|
||||||
|
|
||||||
<Target DependsOnTargets="$(CLITargets)" Name="BuildTheWholeCli"></Target>
|
<Target DependsOnTargets="$(CLITargets)" Name="BuildTheWholeCli"></Target>
|
||||||
|
|
||||||
<Import Project="build/Microsoft.DotNet.Cli.Prepare.targets" />
|
<Import Project="build/Microsoft.DotNet.Cli.Prepare.targets" />
|
||||||
|
|
|
@ -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;
|
var exitCode = _process.ExitCode;
|
||||||
|
|
||||||
ReportExecEnd(exitCode);
|
ReportExecEnd(exitCode);
|
||||||
|
|
||||||
return new CommandResult(
|
return new CommandResult(
|
||||||
_process.StartInfo,
|
_process.StartInfo,
|
||||||
|
@ -239,36 +239,6 @@ namespace Microsoft.DotNet.Cli.Build.Framework
|
||||||
return this;
|
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)
|
public Command OnOutputLine(Action<string> handler)
|
||||||
{
|
{
|
||||||
ThrowIfRunning();
|
ThrowIfRunning();
|
||||||
|
@ -307,28 +277,25 @@ namespace Microsoft.DotNet.Cli.Build.Framework
|
||||||
return prefix + " " + info.Arguments;
|
return prefix + " " + info.Arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReportExecBegin()
|
private void ReportExecBegin()
|
||||||
{
|
{
|
||||||
if (!_quietBuildReporter)
|
if (!_quietBuildReporter)
|
||||||
{
|
{
|
||||||
BuildReporter.BeginSection("EXEC", FormatProcessInfo(_process.StartInfo, includeWorkingDirectory: false));
|
Console.WriteLine($"[> EXEC] {FormatProcessInfo(_process.StartInfo, includeWorkingDirectory: false)}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReportExecEnd(int exitCode)
|
private void ReportExecEnd(int exitCode)
|
||||||
{
|
{
|
||||||
if (!_quietBuildReporter)
|
if (!_quietBuildReporter)
|
||||||
{
|
{
|
||||||
bool success = exitCode == 0;
|
bool success = exitCode == 0;
|
||||||
|
|
||||||
var message = $"{FormatProcessInfo(_process.StartInfo, includeWorkingDirectory: !success)} exited with {exitCode}";
|
var message = $"{FormatProcessInfo(_process.StartInfo, includeWorkingDirectory: !success)} exited with {exitCode}";
|
||||||
|
|
||||||
BuildReporter.EndSection(
|
Console.WriteLine("[< EXEC] {message}");
|
||||||
"EXEC",
|
}
|
||||||
success ? message.Green() : message.Red().Bold(),
|
}
|
||||||
success);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThrowIfRunning([CallerMemberName] string memberName = null)
|
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) { }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,113 +14,96 @@ namespace Microsoft.DotNet.Cli.Build
|
||||||
{
|
{
|
||||||
public override bool Execute()
|
public override bool Execute()
|
||||||
{
|
{
|
||||||
Run(s => Log.LogMessage(s));
|
return CheckCoreclrPlatformDependencies() &&
|
||||||
|
CheckInstallerBuildPlatformDependencies() &&
|
||||||
return true;
|
LocateStage0();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Run(Action<string> logInfo)
|
private bool CheckCoreclrPlatformDependencies()
|
||||||
{
|
{
|
||||||
CheckCoreclrPlatformDependencies();
|
return CheckUbuntuCoreclrAndCoreFxDependencies() &&
|
||||||
CheckInstallerBuildPlatformDependencies();
|
CheckCentOSCoreclrAndCoreFxDependencies();
|
||||||
|
|
||||||
LocateStage0(logInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CheckCoreclrPlatformDependencies()
|
private bool CheckInstallerBuildPlatformDependencies()
|
||||||
{
|
{
|
||||||
CheckUbuntuCoreclrAndCoreFxDependencies();
|
return CheckUbuntuDebianPackageBuildDependencies();
|
||||||
CheckCentOSCoreclrAndCoreFxDependencies();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CheckInstallerBuildPlatformDependencies()
|
private bool CheckUbuntuCoreclrAndCoreFxDependencies()
|
||||||
{
|
{
|
||||||
CheckUbuntuDebianPackageBuildDependencies();
|
bool isSuccessful = true;
|
||||||
}
|
|
||||||
|
|
||||||
private static void CheckUbuntuCoreclrAndCoreFxDependencies()
|
|
||||||
{
|
|
||||||
if (CurrentPlatform.IsPlatform(BuildPlatform.Ubuntu, "14.04"))
|
if (CurrentPlatform.IsPlatform(BuildPlatform.Ubuntu, "14.04"))
|
||||||
{
|
{
|
||||||
var errorMessageBuilder = new StringBuilder();
|
|
||||||
var stage0 = DotNetCli.Stage0.BinPath;
|
var stage0 = DotNetCli.Stage0.BinPath;
|
||||||
|
|
||||||
foreach (var package in PackageDependencies.UbuntuCoreclrAndCoreFxDependencies)
|
foreach (var package in PackageDependencies.UbuntuCoreclrAndCoreFxDependencies)
|
||||||
{
|
{
|
||||||
if (!AptDependencyUtility.PackageIsInstalled(package))
|
if (!AptDependencyUtility.PackageIsInstalled(package))
|
||||||
{
|
{
|
||||||
errorMessageBuilder.Append($"Error: Coreclr package dependency {package} missing.");
|
isSuccessful = false;
|
||||||
errorMessageBuilder.Append(Environment.NewLine);
|
|
||||||
errorMessageBuilder.Append($"-> install with apt-get install {package}");
|
Log.LogError($"Coreclr package dependency {package} missing. Install with `apt-get install {package}`");
|
||||||
errorMessageBuilder.Append(Environment.NewLine);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorMessageBuilder.Length > 0)
|
|
||||||
{
|
|
||||||
throw new BuildFailureException(errorMessageBuilder.ToString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return isSuccessful;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CheckCentOSCoreclrAndCoreFxDependencies()
|
private bool CheckCentOSCoreclrAndCoreFxDependencies()
|
||||||
{
|
{
|
||||||
|
var isSuccessful = true;
|
||||||
|
|
||||||
if (CurrentPlatform.IsPlatform(BuildPlatform.CentOS))
|
if (CurrentPlatform.IsPlatform(BuildPlatform.CentOS))
|
||||||
{
|
{
|
||||||
var errorMessageBuilder = new StringBuilder();
|
|
||||||
|
|
||||||
foreach (var package in PackageDependencies.CentosCoreclrAndCoreFxDependencies)
|
foreach (var package in PackageDependencies.CentosCoreclrAndCoreFxDependencies)
|
||||||
{
|
{
|
||||||
if (!YumDependencyUtility.PackageIsInstalled(package))
|
if (!YumDependencyUtility.PackageIsInstalled(package))
|
||||||
{
|
{
|
||||||
errorMessageBuilder.Append($"Error: Coreclr package dependency {package} missing.");
|
isSuccessful = false;
|
||||||
errorMessageBuilder.Append(Environment.NewLine);
|
|
||||||
errorMessageBuilder.Append($"-> install with yum install {package}");
|
Log.LogError($"Coreclr package dependency {package} missing. Install with yum install {package}");
|
||||||
errorMessageBuilder.Append(Environment.NewLine);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorMessageBuilder.Length > 0)
|
|
||||||
{
|
|
||||||
throw new BuildFailureException(errorMessageBuilder.ToString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return isSuccessful;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CheckUbuntuDebianPackageBuildDependencies()
|
private bool CheckUbuntuDebianPackageBuildDependencies()
|
||||||
{
|
{
|
||||||
|
var isSuccessful = true;
|
||||||
|
|
||||||
if (CurrentPlatform.IsPlatform(BuildPlatform.Ubuntu, "14.04"))
|
if (CurrentPlatform.IsPlatform(BuildPlatform.Ubuntu, "14.04"))
|
||||||
{
|
{
|
||||||
var messageBuilder = new StringBuilder();
|
|
||||||
var aptDependencyUtility = new AptDependencyUtility();
|
var aptDependencyUtility = new AptDependencyUtility();
|
||||||
|
|
||||||
|
|
||||||
foreach (var package in PackageDependencies.DebianPackageBuildDependencies)
|
foreach (var package in PackageDependencies.DebianPackageBuildDependencies)
|
||||||
{
|
{
|
||||||
if (!AptDependencyUtility.PackageIsInstalled(package))
|
if (!AptDependencyUtility.PackageIsInstalled(package))
|
||||||
{
|
{
|
||||||
messageBuilder.Append($"Error: Debian package build dependency {package} missing.");
|
isSuccessful = false;
|
||||||
messageBuilder.Append(Environment.NewLine);
|
|
||||||
messageBuilder.Append($"-> install with apt-get install {package}");
|
Log.LogError($"Debian package build dependency {package} missing. Install with apt-get install {package}");
|
||||||
messageBuilder.Append(Environment.NewLine);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messageBuilder.Length > 0)
|
|
||||||
{
|
|
||||||
throw new BuildFailureException(messageBuilder.ToString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return isSuccessful;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void LocateStage0(Action<string> logInfo)
|
private bool LocateStage0()
|
||||||
{
|
{
|
||||||
// We should have been run in the repo root, so locate the stage 0 relative to current directory
|
// We should have been run in the repo root, so locate the stage 0 relative to current directory
|
||||||
var stage0 = DotNetCli.Stage0.BinPath;
|
var stage0 = DotNetCli.Stage0.BinPath;
|
||||||
|
|
||||||
if (!Directory.Exists(stage0))
|
if (!Directory.Exists(stage0))
|
||||||
{
|
{
|
||||||
throw new BuildFailureException($"Stage 0 directory does not exist: {stage0}");
|
Log.LogError($"Stage 0 directory does not exist: {stage0}");
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Identify the version
|
// Identify the version
|
||||||
|
@ -128,11 +111,16 @@ namespace Microsoft.DotNet.Cli.Build
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(versionFile))
|
if (string.IsNullOrEmpty(versionFile))
|
||||||
{
|
{
|
||||||
throw new Exception($"'.version' file not found in '{stage0}' folder");
|
Log.LogError($"'.version' file not found in '{stage0}' folder");
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var version = File.ReadAllLines(versionFile);
|
var version = File.ReadAllLines(versionFile);
|
||||||
logInfo($"Using Stage 0 Version: {version[1]}");
|
|
||||||
|
Log.LogMessage($"Using Stage 0 Version: {version[1]}");
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +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.IO;
|
|
||||||
using Microsoft.DotNet.InternalAbstractions;
|
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Cli.Build
|
|
||||||
{
|
|
||||||
public static class CliDirs
|
|
||||||
{
|
|
||||||
public static readonly string CoreSetupDownload = Path.Combine(
|
|
||||||
Dirs.Intermediate,
|
|
||||||
"coreSetupDownload",
|
|
||||||
CliDependencyVersions.SharedFrameworkVersion);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +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 Microsoft.DotNet.Cli.Build.Framework;
|
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Cli.Build
|
|
||||||
{
|
|
||||||
public static class CliMonikers
|
|
||||||
{
|
|
||||||
public static string GetSdkDebianPackageName(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
var nugetVersion = c.BuildContext.Get<BuildVersion>("BuildVersion").NuGetVersion;
|
|
||||||
|
|
||||||
return $"dotnet-dev-{nugetVersion}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,391 +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.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
|
||||||
using System.IO.Compression;
|
|
||||||
using Microsoft.Build.Utilities;
|
|
||||||
using Microsoft.DotNet.Cli.Build.Framework;
|
|
||||||
using Microsoft.DotNet.InternalAbstractions;
|
|
||||||
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
|
|
||||||
using static Microsoft.DotNet.Cli.Build.FS;
|
|
||||||
using static Microsoft.DotNet.Cli.Build.Utils;
|
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Cli.Build
|
|
||||||
{
|
|
||||||
public class PrepareTargets
|
|
||||||
{
|
|
||||||
|
|
||||||
// All major targets will depend on this in order to ensure variables are set up right if they are run independently
|
|
||||||
public static BuildTargetResult Init(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
GenerateVersions(c);
|
|
||||||
CheckPrereqs.Run(s => c.Info(s));
|
|
||||||
ExpectedBuildArtifacts(c);
|
|
||||||
SetTelemetryProfile(c);
|
|
||||||
|
|
||||||
var configEnv = Environment.GetEnvironmentVariable("CONFIGURATION");
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(configEnv))
|
|
||||||
{
|
|
||||||
configEnv = "Debug";
|
|
||||||
}
|
|
||||||
|
|
||||||
c.BuildContext["Configuration"] = configEnv;
|
|
||||||
c.BuildContext["Channel"] = Environment.GetEnvironmentVariable("CHANNEL");
|
|
||||||
|
|
||||||
c.Info($"Building {c.BuildContext["Configuration"]} to: {Dirs.Output}");
|
|
||||||
c.Info("Build Environment:");
|
|
||||||
c.Info($" Operating System: {RuntimeEnvironment.OperatingSystem} {RuntimeEnvironment.OperatingSystemVersion}");
|
|
||||||
c.Info($" Platform: {RuntimeEnvironment.OperatingSystemPlatform}");
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult GenerateVersions(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
var commitCount = GitUtils.GetCommitCount();
|
|
||||||
var commitHash = GitUtils.GetCommitHash();
|
|
||||||
|
|
||||||
var branchInfo = ReadBranchInfo(c, Path.Combine(c.BuildContext.BuildDirectory, "branchinfo.txt"));
|
|
||||||
var buildVersion = new BuildVersion()
|
|
||||||
{
|
|
||||||
Major = int.Parse(branchInfo["MAJOR_VERSION"]),
|
|
||||||
Minor = int.Parse(branchInfo["MINOR_VERSION"]),
|
|
||||||
Patch = int.Parse(branchInfo["PATCH_VERSION"]),
|
|
||||||
ReleaseSuffix = branchInfo["RELEASE_SUFFIX"],
|
|
||||||
CommitCount = commitCount
|
|
||||||
};
|
|
||||||
c.BuildContext["BuildVersion"] = buildVersion;
|
|
||||||
|
|
||||||
c.BuildContext["BranchName"] = branchInfo["BRANCH_NAME"];
|
|
||||||
c.BuildContext["CommitHash"] = commitHash;
|
|
||||||
|
|
||||||
c.Info($"Building Version: {buildVersion.SimpleVersion} (NuGet Packages: {buildVersion.NuGetVersion})");
|
|
||||||
c.Info($"From Commit: {commitHash}");
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult ZipTemplates(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
var templateDirectories = Directory.GetDirectories(
|
|
||||||
Path.Combine(Dirs.RepoRoot, "src", "dotnet", "commands", "dotnet-new"));
|
|
||||||
|
|
||||||
foreach (var directory in templateDirectories)
|
|
||||||
{
|
|
||||||
var zipFile = Path.Combine(Path.GetDirectoryName(directory), Path.GetFileName(directory) + ".zip");
|
|
||||||
if (File.Exists(zipFile))
|
|
||||||
{
|
|
||||||
File.Delete(zipFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
ZipFile.CreateFromDirectory(directory, zipFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static BuildTargetResult ExpectedBuildArtifacts(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
var config = Environment.GetEnvironmentVariable("CONFIGURATION");
|
|
||||||
var versionBadgeName = $"{Monikers.GetBadgeMoniker()}_{config}_version_badge.svg";
|
|
||||||
c.BuildContext["VersionBadge"] = Path.Combine(Dirs.Output, versionBadgeName);
|
|
||||||
|
|
||||||
var cliVersion = c.BuildContext.Get<BuildVersion>("BuildVersion").NuGetVersion;
|
|
||||||
var sharedFrameworkVersion = CliDependencyVersions.SharedFrameworkVersion;
|
|
||||||
var hostVersion = CliDependencyVersions.SharedHostVersion;
|
|
||||||
var hostFxrVersion = CliDependencyVersions.HostFxrVersion;
|
|
||||||
|
|
||||||
// Generated Installers + Archives
|
|
||||||
AddInstallerArtifactToContext(c, "dotnet-sdk", "Sdk", cliVersion);
|
|
||||||
AddInstallerArtifactToContext(c, "dotnet-dev", "CombinedFrameworkSDKHost", cliVersion);
|
|
||||||
AddInstallerArtifactToContext(c, "dotnet-sharedframework-sdk", "CombinedFrameworkSDK", cliVersion);
|
|
||||||
AddInstallerArtifactToContext(c, "dotnet-sdk-debug", "SdkSymbols", cliVersion);
|
|
||||||
|
|
||||||
//Downloaded Installers + Archives
|
|
||||||
AddInstallerArtifactToContext(c, "dotnet-host", "SharedHost", hostVersion);
|
|
||||||
AddInstallerArtifactToContext(c, "dotnet-hostfxr", "HostFxr", hostFxrVersion);
|
|
||||||
AddInstallerArtifactToContext(c, "dotnet-sharedframework", "SharedFramework", sharedFrameworkVersion);
|
|
||||||
AddInstallerArtifactToContext(c, "dotnet", "CombinedFrameworkHost", sharedFrameworkVersion);
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult DownloadHostAndSharedFxArtifacts(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
ExpectedBuildArtifacts(c);
|
|
||||||
DownloadHostAndSharedFxArchives(c);
|
|
||||||
DownloadHostAndSharedFxInstallers(c);
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult DownloadHostAndSharedFxArchives(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
var sharedFrameworkVersion = CliDependencyVersions.SharedFrameworkVersion;
|
|
||||||
var sharedFrameworkChannel = CliDependencyVersions.SharedFrameworkChannel;
|
|
||||||
|
|
||||||
var combinedSharedHostAndFrameworkArchiveDownloadFile =
|
|
||||||
Path.Combine(CliDirs.CoreSetupDownload, "combinedSharedHostAndFrameworkArchive");
|
|
||||||
|
|
||||||
Mkdirp(Path.GetDirectoryName(combinedSharedHostAndFrameworkArchiveDownloadFile));
|
|
||||||
|
|
||||||
if (!File.Exists(combinedSharedHostAndFrameworkArchiveDownloadFile))
|
|
||||||
{
|
|
||||||
// Needed for computing the blob path
|
|
||||||
var combinedSharedHostAndFrameworkArchiveBuildContextFile =
|
|
||||||
c.BuildContext.Get<string>("CombinedFrameworkHostCompressedFile");
|
|
||||||
|
|
||||||
AzurePublisher.DownloadFile(
|
|
||||||
CalculateArchiveBlob(
|
|
||||||
combinedSharedHostAndFrameworkArchiveBuildContextFile,
|
|
||||||
sharedFrameworkChannel,
|
|
||||||
sharedFrameworkVersion),
|
|
||||||
combinedSharedHostAndFrameworkArchiveDownloadFile).Wait();
|
|
||||||
|
|
||||||
|
|
||||||
// Unpack the combined archive to shared framework publish directory
|
|
||||||
Rmdir(Dirs.SharedFrameworkPublish);
|
|
||||||
Mkdirp(Dirs.SharedFrameworkPublish);
|
|
||||||
if (CurrentPlatform.IsWindows)
|
|
||||||
{
|
|
||||||
ZipFile.ExtractToDirectory(combinedSharedHostAndFrameworkArchiveDownloadFile, Dirs.SharedFrameworkPublish);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Exec("tar", "xf", combinedSharedHostAndFrameworkArchiveDownloadFile, "-C", Dirs.SharedFrameworkPublish);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult DownloadHostAndSharedFxInstallers(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
if (CurrentPlatform.IsAnyPlatform(BuildPlatform.Windows, BuildPlatform.OSX, BuildPlatform.Ubuntu))
|
|
||||||
{
|
|
||||||
var sharedFrameworkVersion = CliDependencyVersions.SharedFrameworkVersion;
|
|
||||||
var hostVersion = CliDependencyVersions.SharedHostVersion;
|
|
||||||
var hostFxrVersion = CliDependencyVersions.HostFxrVersion;
|
|
||||||
|
|
||||||
var sharedFrameworkChannel = CliDependencyVersions.SharedFrameworkChannel;
|
|
||||||
var sharedHostChannel = CliDependencyVersions.SharedHostChannel;
|
|
||||||
var hostFxrChannel = CliDependencyVersions.HostFxrChannel;
|
|
||||||
|
|
||||||
var sharedFrameworkInstallerDownloadFile = Path.Combine(CliDirs.CoreSetupDownload, "sharedFrameworkInstaller");
|
|
||||||
var sharedHostInstallerDownloadFile = Path.Combine(CliDirs.CoreSetupDownload, "sharedHostInstaller");
|
|
||||||
var hostFxrInstallerDownloadFile = Path.Combine(CliDirs.CoreSetupDownload, "hostFxrInstaller");
|
|
||||||
|
|
||||||
Mkdirp(Path.GetDirectoryName(sharedFrameworkInstallerDownloadFile));
|
|
||||||
Mkdirp(Path.GetDirectoryName(sharedHostInstallerDownloadFile));
|
|
||||||
Mkdirp(Path.GetDirectoryName(hostFxrInstallerDownloadFile));
|
|
||||||
|
|
||||||
if (!File.Exists(sharedFrameworkInstallerDownloadFile))
|
|
||||||
{
|
|
||||||
var sharedFrameworkInstallerDestinationFile = c.BuildContext.Get<string>("SharedFrameworkInstallerFile");
|
|
||||||
Mkdirp(Path.GetDirectoryName(sharedFrameworkInstallerDestinationFile));
|
|
||||||
|
|
||||||
AzurePublisher.DownloadFile(
|
|
||||||
CalculateInstallerBlob(
|
|
||||||
sharedFrameworkInstallerDestinationFile,
|
|
||||||
sharedFrameworkChannel,
|
|
||||||
sharedFrameworkVersion),
|
|
||||||
sharedFrameworkInstallerDownloadFile).Wait();
|
|
||||||
|
|
||||||
File.Copy(sharedFrameworkInstallerDownloadFile, sharedFrameworkInstallerDestinationFile, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!File.Exists(sharedHostInstallerDownloadFile))
|
|
||||||
{
|
|
||||||
var sharedHostInstallerDestinationFile = c.BuildContext.Get<string>("SharedHostInstallerFile");
|
|
||||||
Mkdirp(Path.GetDirectoryName(sharedHostInstallerDestinationFile));
|
|
||||||
|
|
||||||
AzurePublisher.DownloadFile(
|
|
||||||
CalculateInstallerBlob(
|
|
||||||
sharedHostInstallerDestinationFile,
|
|
||||||
sharedHostChannel,
|
|
||||||
hostVersion),
|
|
||||||
sharedHostInstallerDownloadFile).Wait();
|
|
||||||
|
|
||||||
File.Copy(sharedHostInstallerDownloadFile, sharedHostInstallerDestinationFile, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!File.Exists(hostFxrInstallerDownloadFile))
|
|
||||||
{
|
|
||||||
var hostFxrInstallerDestinationFile = c.BuildContext.Get<string>("HostFxrInstallerFile");
|
|
||||||
Mkdirp(Path.GetDirectoryName(hostFxrInstallerDestinationFile));
|
|
||||||
|
|
||||||
AzurePublisher.DownloadFile(
|
|
||||||
CalculateInstallerBlob(
|
|
||||||
hostFxrInstallerDestinationFile,
|
|
||||||
hostFxrChannel,
|
|
||||||
hostFxrVersion),
|
|
||||||
hostFxrInstallerDownloadFile).Wait();
|
|
||||||
|
|
||||||
File.Copy(hostFxrInstallerDownloadFile, hostFxrInstallerDestinationFile, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult CheckPackageCache(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
var ciBuild = string.Equals(Environment.GetEnvironmentVariable("CI_BUILD"), "1", StringComparison.Ordinal);
|
|
||||||
|
|
||||||
// Always set the package cache location local to the build
|
|
||||||
Environment.SetEnvironmentVariable("NUGET_PACKAGES", Dirs.NuGetPackages);
|
|
||||||
|
|
||||||
CleanNuGetTempCache();
|
|
||||||
|
|
||||||
// Determine cache expiration time
|
|
||||||
var cacheExpiration = 7 * 24; // cache expiration in hours
|
|
||||||
var cacheExpirationStr = Environment.GetEnvironmentVariable("NUGET_PACKAGES_CACHE_TIME_LIMIT");
|
|
||||||
if (!string.IsNullOrEmpty(cacheExpirationStr))
|
|
||||||
{
|
|
||||||
cacheExpiration = int.Parse(cacheExpirationStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ciBuild)
|
|
||||||
{
|
|
||||||
var cacheTimeFile = Path.Combine(Dirs.NuGetPackages, "packageCacheTime.txt");
|
|
||||||
|
|
||||||
DateTime? cacheTime = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Read the cache file
|
|
||||||
if (File.Exists(cacheTimeFile))
|
|
||||||
{
|
|
||||||
var content = File.ReadAllText(cacheTimeFile);
|
|
||||||
if (!string.IsNullOrEmpty(content))
|
|
||||||
{
|
|
||||||
cacheTime = DateTime.ParseExact("O", content, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
c.Warn($"Error reading NuGet cache time file, leaving the cache alone");
|
|
||||||
c.Warn($"Error Detail: {ex.ToString()}");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cacheTime == null || (cacheTime.Value.AddHours(cacheExpiration) < DateTime.UtcNow))
|
|
||||||
{
|
|
||||||
// Cache has expired or the status is unknown, clear it and write the file
|
|
||||||
c.Info("Clearing NuGet cache");
|
|
||||||
Rmdir(Dirs.NuGetPackages);
|
|
||||||
Mkdirp(Dirs.NuGetPackages);
|
|
||||||
File.WriteAllText(cacheTimeFile, DateTime.UtcNow.ToString("O"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult RestorePackages(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
CheckPackageCache(c);
|
|
||||||
|
|
||||||
var dotnet = DotNetCli.Stage0;
|
|
||||||
|
|
||||||
dotnet.Restore("--verbosity", "verbose", "--disable-parallel")
|
|
||||||
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "src"))
|
|
||||||
.Execute()
|
|
||||||
.EnsureSuccessful();
|
|
||||||
dotnet.Restore("--verbosity", "verbose", "--disable-parallel", "--infer-runtimes")
|
|
||||||
.WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "tools"))
|
|
||||||
.Execute()
|
|
||||||
.EnsureSuccessful();
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult SetTelemetryProfile(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
var gitResult = Cmd("git", "rev-parse", "HEAD")
|
|
||||||
.CaptureStdOut()
|
|
||||||
.Execute();
|
|
||||||
gitResult.EnsureSuccessful();
|
|
||||||
|
|
||||||
var commitHash = gitResult.StdOut.Trim();
|
|
||||||
|
|
||||||
Environment.SetEnvironmentVariable("DOTNET_CLI_TELEMETRY_PROFILE", $"https://github.com/dotnet/cli;{commitHash}");
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IDictionary<string, string> ReadBranchInfo(BuildTargetContext c, string path)
|
|
||||||
{
|
|
||||||
var lines = File.ReadAllLines(path);
|
|
||||||
var dict = new Dictionary<string, string>();
|
|
||||||
c.Verbose("Branch Info:");
|
|
||||||
foreach (var line in lines)
|
|
||||||
{
|
|
||||||
if (!line.Trim().StartsWith("#") && !string.IsNullOrWhiteSpace(line))
|
|
||||||
{
|
|
||||||
var splat = line.Split(new[] { '=' }, 2);
|
|
||||||
dict[splat[0]] = splat[1];
|
|
||||||
c.Verbose($" {splat[0]} = {splat[1]}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AddInstallerArtifactToContext(
|
|
||||||
BuildTargetContext c,
|
|
||||||
string artifactPrefix,
|
|
||||||
string contextPrefix,
|
|
||||||
string version)
|
|
||||||
{
|
|
||||||
var productName = Monikers.GetProductMoniker(c, artifactPrefix, version);
|
|
||||||
|
|
||||||
var extension = CurrentPlatform.IsWindows ? ".zip" : ".tar.gz";
|
|
||||||
c.BuildContext[contextPrefix + "CompressedFile"] = Path.Combine(Dirs.Packages, productName + extension);
|
|
||||||
|
|
||||||
string installer = "";
|
|
||||||
switch (CurrentPlatform.Current)
|
|
||||||
{
|
|
||||||
case BuildPlatform.Windows:
|
|
||||||
if (contextPrefix.Contains("Combined"))
|
|
||||||
{
|
|
||||||
installer = productName + ".exe";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
installer = productName + ".msi";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BuildPlatform.OSX:
|
|
||||||
installer = productName + ".pkg";
|
|
||||||
break;
|
|
||||||
case BuildPlatform.Ubuntu:
|
|
||||||
installer = productName + ".deb";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(installer))
|
|
||||||
{
|
|
||||||
c.BuildContext[contextPrefix + "InstallerFile"] = Path.Combine(Dirs.Packages, installer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The following CalculateBlob methods are temporary until the core-setup repo up-takes the new Azure Publish layout and
|
|
||||||
// CLI consumes newer Shared FX versions.
|
|
||||||
private static string CalculateArchiveBlob(string archiveFile, string channel, string version)
|
|
||||||
{
|
|
||||||
return $"{channel}/Binaries/{version}/{Path.GetFileName(archiveFile)}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string CalculateInstallerBlob(string installerFile, string channel, string version)
|
|
||||||
{
|
|
||||||
return $"{channel}/Installers/{version}/{Path.GetFileName(installerFile)}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,295 +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.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Microsoft.DotNet.Cli.Build.Framework;
|
|
||||||
using Microsoft.Build.Utilities;
|
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Cli.Build
|
|
||||||
{
|
|
||||||
public class PublishTargets : Task
|
|
||||||
{
|
|
||||||
private static AzurePublisher AzurePublisherTool { get; set; }
|
|
||||||
|
|
||||||
private static DebRepoPublisher DebRepoPublisherTool { get; set; }
|
|
||||||
|
|
||||||
private static string Channel { get; set; }
|
|
||||||
|
|
||||||
private static string CommitHash { get; set; }
|
|
||||||
|
|
||||||
private static string CliNuGetVersion { get; set; }
|
|
||||||
|
|
||||||
private static string SharedFrameworkNugetVersion { get; set; }
|
|
||||||
|
|
||||||
public override bool Execute()
|
|
||||||
{
|
|
||||||
BuildContext context = new BuildSetup("MSBuild").UseAllTargetsFromAssembly<PublishTargets>().CreateBuildContext();
|
|
||||||
BuildTargetContext c = new BuildTargetContext(context, null, null);
|
|
||||||
|
|
||||||
return Publish(c).Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult InitPublish(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
AzurePublisherTool = new AzurePublisher();
|
|
||||||
DebRepoPublisherTool = new DebRepoPublisher(Dirs.Packages);
|
|
||||||
|
|
||||||
CliNuGetVersion = c.BuildContext.Get<BuildVersion>("BuildVersion").NuGetVersion;
|
|
||||||
SharedFrameworkNugetVersion = CliDependencyVersions.SharedFrameworkVersion;
|
|
||||||
Channel = c.BuildContext.Get<string>("Channel");
|
|
||||||
CommitHash = c.BuildContext.Get<string>("CommitHash");
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Target]
|
|
||||||
public static BuildTargetResult Publish(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
if (EnvVars.GetBool("PUBLISH_TO_AZURE_BLOB")) // This is set by CI systems
|
|
||||||
{
|
|
||||||
PrepareTargets.Init(c);
|
|
||||||
|
|
||||||
InitPublish(c);
|
|
||||||
PublishArtifacts(c);
|
|
||||||
FinalizeBuild(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult FinalizeBuild(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
if (CheckIfAllBuildsHavePublished())
|
|
||||||
{
|
|
||||||
string targetContainer = $"{AzurePublisher.Product.Sdk}/{Channel}";
|
|
||||||
string targetVersionFile = $"{targetContainer}/{CommitHash}";
|
|
||||||
string semaphoreBlob = $"{targetContainer}/publishSemaphore";
|
|
||||||
AzurePublisherTool.CreateBlobIfNotExists(semaphoreBlob);
|
|
||||||
string leaseId = AzurePublisherTool.AcquireLeaseOnBlob(semaphoreBlob);
|
|
||||||
|
|
||||||
// Prevent race conditions by dropping a version hint of what version this is. If we see this file
|
|
||||||
// and it is the same as our version then we know that a race happened where two+ builds finished
|
|
||||||
// at the same time and someone already took care of publishing and we have no work to do.
|
|
||||||
if (AzurePublisherTool.IsLatestSpecifiedVersion(targetVersionFile))
|
|
||||||
{
|
|
||||||
AzurePublisherTool.ReleaseLeaseOnBlob(semaphoreBlob, leaseId);
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Regex versionFileRegex = new Regex(@"(?<CommitHash>[\w\d]{40})");
|
|
||||||
|
|
||||||
// Delete old version files
|
|
||||||
AzurePublisherTool.ListBlobs(targetContainer)
|
|
||||||
.Where(s => versionFileRegex.IsMatch(s))
|
|
||||||
.ToList()
|
|
||||||
.ForEach(f => AzurePublisherTool.TryDeleteBlob(f));
|
|
||||||
|
|
||||||
// Drop the version file signaling such for any race-condition builds (see above comment).
|
|
||||||
AzurePublisherTool.DropLatestSpecifiedVersion(targetVersionFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CopyBlobsToLatest(targetContainer);
|
|
||||||
|
|
||||||
string cliVersion = Utils.GetCliVersionFileContent(c);
|
|
||||||
AzurePublisherTool.PublishStringToBlob($"{targetContainer}/latest.version", cliVersion);
|
|
||||||
|
|
||||||
UpdateVersionsRepo(c);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
AzurePublisherTool.ReleaseLeaseOnBlob(semaphoreBlob, leaseId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void CopyBlobsToLatest(string destinationFolder)
|
|
||||||
{
|
|
||||||
foreach (string blob in AzurePublisherTool.ListBlobs(AzurePublisher.Product.Sdk, CliNuGetVersion))
|
|
||||||
{
|
|
||||||
string targetName = Path.GetFileName(blob)
|
|
||||||
.Replace(CliNuGetVersion, "latest");
|
|
||||||
|
|
||||||
string target = $"{destinationFolder}/{targetName}";
|
|
||||||
AzurePublisherTool.CopyBlob(blob, target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool CheckIfAllBuildsHavePublished()
|
|
||||||
{
|
|
||||||
Dictionary<string, bool> badges = new Dictionary<string, bool>()
|
|
||||||
{
|
|
||||||
{ "Windows_x86", false },
|
|
||||||
{ "Windows_x64", false },
|
|
||||||
{ "Ubuntu_x64", false },
|
|
||||||
{ "Ubuntu_16_04_x64", false },
|
|
||||||
{ "RHEL_x64", false },
|
|
||||||
{ "OSX_x64", false },
|
|
||||||
{ "Debian_x64", false },
|
|
||||||
{ "CentOS_x64", false },
|
|
||||||
{ "Fedora_23_x64", false },
|
|
||||||
{ "openSUSE_13_2_x64", false }
|
|
||||||
};
|
|
||||||
|
|
||||||
var versionBadgeName = $"{Monikers.GetBadgeMoniker()}";
|
|
||||||
if (!badges.ContainsKey(versionBadgeName))
|
|
||||||
{
|
|
||||||
throw new ArgumentException($"A new OS build '{versionBadgeName}' was added without adding the moniker to the {nameof(badges)} lookup");
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerable<string> blobs = AzurePublisherTool.ListBlobs(AzurePublisher.Product.Sdk, CliNuGetVersion);
|
|
||||||
foreach (string file in blobs)
|
|
||||||
{
|
|
||||||
string name = Path.GetFileName(file);
|
|
||||||
foreach (string img in badges.Keys)
|
|
||||||
{
|
|
||||||
if ((name.StartsWith($"{img}")) && (name.EndsWith(".svg")))
|
|
||||||
{
|
|
||||||
badges[img] = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return badges.Values.All(v => v);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult PublishArtifacts(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
PublishInstallerFilesToAzure(c);
|
|
||||||
PublishArchivesToAzure(c);
|
|
||||||
PublishDebFilesToDebianRepo(c);
|
|
||||||
PublishCliVersionBadge(c);
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult PublishInstallerFilesToAzure(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
PublishSdkInstallerFileToAzure(c);
|
|
||||||
PublishCombinedFrameworkSDKHostInstallerFileToAzure(c);
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult PublishArchivesToAzure(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
PublishCombinedHostFrameworkSdkArchiveToAzure(c);
|
|
||||||
PublishCombinedFrameworkSDKArchiveToAzure(c);
|
|
||||||
PublishSDKSymbolsArchiveToAzure(c);
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult PublishDebFilesToDebianRepo(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
if (CurrentPlatform.IsPlatform(BuildPlatform.Ubuntu))
|
|
||||||
{
|
|
||||||
PublishSdkDebToDebianRepo(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult PublishCliVersionBadge(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
var versionBadge = c.BuildContext.Get<string>("VersionBadge");
|
|
||||||
UploadFile(versionBadge);
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult PublishSdkInstallerFileToAzure(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
if (CurrentPlatform.IsPlatform(BuildPlatform.Ubuntu))
|
|
||||||
{
|
|
||||||
var installerFile = c.BuildContext.Get<string>("SdkInstallerFile");
|
|
||||||
UploadFile(installerFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult PublishCombinedFrameworkSDKHostInstallerFileToAzure(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
if (CurrentPlatform.IsAnyPlatform(BuildPlatform.Windows, BuildPlatform.OSX))
|
|
||||||
{
|
|
||||||
var installerFile = c.BuildContext.Get<string>("CombinedFrameworkSDKHostInstallerFile");
|
|
||||||
UploadFile(installerFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult PublishCombinedFrameworkSDKArchiveToAzure(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
if (CurrentPlatform.IsPlatform(BuildPlatform.Windows))
|
|
||||||
{
|
|
||||||
var archiveFile = c.BuildContext.Get<string>("CombinedFrameworkSDKCompressedFile");
|
|
||||||
UploadFile(archiveFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult PublishCombinedHostFrameworkSdkArchiveToAzure(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
var archiveFile = c.BuildContext.Get<string>("CombinedFrameworkSDKHostCompressedFile");
|
|
||||||
UploadFile(archiveFile);
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult PublishSDKSymbolsArchiveToAzure(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
var archiveFile = c.BuildContext.Get<string>("SdkSymbolsCompressedFile");
|
|
||||||
UploadFile(archiveFile);
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BuildTargetResult PublishSdkDebToDebianRepo(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
if (CurrentPlatform.IsPlatform(BuildPlatform.Ubuntu))
|
|
||||||
{
|
|
||||||
var version = CliNuGetVersion;
|
|
||||||
|
|
||||||
var packageName = CliMonikers.GetSdkDebianPackageName(c);
|
|
||||||
var installerFile = c.BuildContext.Get<string>("SdkInstallerFile");
|
|
||||||
var uploadUrl = AzurePublisher.CalculateFullUrlForFile(installerFile, AzurePublisher.Product.Sdk, version);
|
|
||||||
|
|
||||||
DebRepoPublisherTool.PublishDebFileToDebianRepo(
|
|
||||||
packageName,
|
|
||||||
version,
|
|
||||||
uploadUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.Success();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void UpdateVersionsRepo(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
string githubAuthToken = EnvVars.EnsureVariable("GITHUB_PASSWORD");
|
|
||||||
string nupkgFilePath = Dirs.Packages;
|
|
||||||
string branchName = c.BuildContext.Get<string>("BranchName");
|
|
||||||
string versionsRepoPath = $"build-info/dotnet/cli/{branchName}/Latest";
|
|
||||||
|
|
||||||
VersionRepoUpdater repoUpdater = new VersionRepoUpdater(githubAuthToken);
|
|
||||||
repoUpdater.UpdatePublishedVersions(nupkgFilePath, versionsRepoPath).Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string UploadFile(string file)
|
|
||||||
{
|
|
||||||
return AzurePublisherTool.UploadFile(file, AzurePublisher.Product.Sdk, CliNuGetVersion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.Cli.Build
|
||||||
|
{
|
||||||
|
public class BuildFailureException : Exception
|
||||||
|
{
|
||||||
|
public BuildFailureException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public BuildFailureException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public BuildFailureException(string message, Exception innerException) : base(message, innerException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -102,22 +102,5 @@ namespace Microsoft.DotNet.Cli.Build
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void CleanBinObj(BuildTargetContext c, string dir)
|
|
||||||
{
|
|
||||||
dir = dir ?? c.BuildContext.BuildDirectory;
|
|
||||||
foreach(var candidate in Directory.EnumerateDirectories(dir))
|
|
||||||
{
|
|
||||||
if (string.Equals(Path.GetFileName(candidate), "bin") ||
|
|
||||||
string.Equals(Path.GetFileName(candidate), "obj"))
|
|
||||||
{
|
|
||||||
Utils.DeleteDirectory(candidate);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CleanBinObj(c, candidate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,22 +15,6 @@ namespace Microsoft.DotNet.Cli.Build
|
||||||
public const string SharedHostBrandName = "Microsoft .NET Core 1.0.0 - Host";
|
public const string SharedHostBrandName = "Microsoft .NET Core 1.0.0 - Host";
|
||||||
public const string HostFxrBrandName = "Microsoft .NET Core 1.0.0 - Host FX Resolver";
|
public const string HostFxrBrandName = "Microsoft .NET Core 1.0.0 - Host FX Resolver";
|
||||||
|
|
||||||
public static string GetProductMoniker(BuildTargetContext c, string artifactPrefix, string version)
|
|
||||||
{
|
|
||||||
string rid = RuntimeEnvironment.GetRuntimeIdentifier();
|
|
||||||
|
|
||||||
if (rid == "ubuntu.16.04-x64" || rid == "fedora.23-x64" || rid == "opensuse.13.2-x64")
|
|
||||||
{
|
|
||||||
return $"{artifactPrefix}-{rid}.{version}";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string osname = GetOSShortName();
|
|
||||||
var arch = CurrentArchitecture.Current.ToString();
|
|
||||||
return $"{artifactPrefix}-{osname}-{arch}.{version}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetBadgeMoniker()
|
public static string GetBadgeMoniker()
|
||||||
{
|
{
|
||||||
switch (RuntimeEnvironment.GetRuntimeIdentifier())
|
switch (RuntimeEnvironment.GetRuntimeIdentifier())
|
||||||
|
@ -55,12 +39,7 @@ namespace Microsoft.DotNet.Cli.Build
|
||||||
{
|
{
|
||||||
return $"dotnet-sharedframework-{SharedFrameworkName}-{sharedFrameworkNugetVersion}".ToLower();
|
return $"dotnet-sharedframework-{SharedFrameworkName}-{sharedFrameworkNugetVersion}".ToLower();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetDebianSharedHostPackageName(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
return $"dotnet-host".ToLower();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetOSShortName()
|
public static string GetOSShortName()
|
||||||
{
|
{
|
||||||
string osname = "";
|
string osname = "";
|
||||||
|
|
|
@ -1,219 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Microsoft.DotNet.InternalAbstractions;
|
|
||||||
using Microsoft.DotNet.Cli.Build.Framework;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
|
|
||||||
using static Microsoft.DotNet.Cli.Build.FS;
|
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Cli.Build
|
|
||||||
{
|
|
||||||
public class SharedFrameworkPublisher
|
|
||||||
{
|
|
||||||
public static string s_sharedFrameworkName = "Microsoft.NETCore.App";
|
|
||||||
|
|
||||||
private string _sharedFrameworkTemplateSourceRoot;
|
|
||||||
private string _sharedFrameworkNugetVersion;
|
|
||||||
private string _sharedFrameworkRid;
|
|
||||||
private string _sharedFrameworkSourceRoot;
|
|
||||||
private string _repoRoot;
|
|
||||||
private string _corehostLockedDirectory;
|
|
||||||
private string _corehostLatestDirectory;
|
|
||||||
|
|
||||||
private Crossgen _crossgenUtil = new Crossgen(DependencyVersions.CoreCLRVersion, DependencyVersions.JitVersion);
|
|
||||||
private string _corehostPackageSource;
|
|
||||||
|
|
||||||
public SharedFrameworkPublisher(
|
|
||||||
string repoRoot,
|
|
||||||
string corehostLockedDirectory,
|
|
||||||
string corehostLatestDirectory,
|
|
||||||
string corehostPackageSource,
|
|
||||||
string sharedFrameworkNugetVersion)
|
|
||||||
{
|
|
||||||
_repoRoot = repoRoot;
|
|
||||||
_corehostLockedDirectory = corehostLockedDirectory;
|
|
||||||
_corehostLatestDirectory = corehostLatestDirectory;
|
|
||||||
_corehostPackageSource = corehostPackageSource;
|
|
||||||
|
|
||||||
_sharedFrameworkTemplateSourceRoot = Path.Combine(repoRoot, "src", "sharedframework", "framework");
|
|
||||||
_sharedFrameworkNugetVersion = sharedFrameworkNugetVersion;
|
|
||||||
|
|
||||||
_sharedFrameworkRid = ComputeSharedFrameworkRid();
|
|
||||||
|
|
||||||
_sharedFrameworkSourceRoot = GenerateSharedFrameworkProject(
|
|
||||||
_sharedFrameworkNugetVersion,
|
|
||||||
_sharedFrameworkTemplateSourceRoot,
|
|
||||||
_sharedFrameworkRid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetSharedFrameworkPublishPath(string outputRootDirectory, string sharedFrameworkNugetVersion)
|
|
||||||
{
|
|
||||||
return Path.Combine(
|
|
||||||
outputRootDirectory,
|
|
||||||
"shared",
|
|
||||||
s_sharedFrameworkName,
|
|
||||||
sharedFrameworkNugetVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string ComputeSharedFrameworkRid()
|
|
||||||
{
|
|
||||||
return RuntimeEnvironment.OperatingSystemPlatform == Platform.Windows
|
|
||||||
? $"win7-{RuntimeEnvironment.RuntimeArchitecture}"
|
|
||||||
: RuntimeEnvironment.GetRuntimeIdentifier();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CopySharedHostArtifacts(string sharedFrameworkPublishRoot)
|
|
||||||
{
|
|
||||||
File.Copy(
|
|
||||||
Path.Combine(_corehostLockedDirectory, HostArtifactNames.DotnetHostBaseName),
|
|
||||||
Path.Combine(sharedFrameworkPublishRoot, HostArtifactNames.DotnetHostBaseName), true);
|
|
||||||
|
|
||||||
File.Copy(
|
|
||||||
Path.Combine(_corehostLockedDirectory, HostArtifactNames.DotnetHostFxrBaseName),
|
|
||||||
Path.Combine(sharedFrameworkPublishRoot, HostArtifactNames.DotnetHostFxrBaseName), true);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PublishSharedFramework(string outputRootDirectory, string commitHash, DotNetCli dotnetCli)
|
|
||||||
{
|
|
||||||
dotnetCli.Restore(
|
|
||||||
"--verbosity", "verbose",
|
|
||||||
"--disable-parallel",
|
|
||||||
"--infer-runtimes",
|
|
||||||
"--fallbacksource", _corehostPackageSource)
|
|
||||||
.WorkingDirectory(_sharedFrameworkSourceRoot)
|
|
||||||
.Execute()
|
|
||||||
.EnsureSuccessful();
|
|
||||||
|
|
||||||
// We publish to a sub folder of the PublishRoot so tools like heat and zip can generate folder structures easier.
|
|
||||||
string sharedFrameworkNameAndVersionRoot = GetSharedFrameworkPublishPath(outputRootDirectory, _sharedFrameworkNugetVersion);
|
|
||||||
if (Directory.Exists(sharedFrameworkNameAndVersionRoot))
|
|
||||||
{
|
|
||||||
Utils.DeleteDirectory(sharedFrameworkNameAndVersionRoot);
|
|
||||||
}
|
|
||||||
|
|
||||||
dotnetCli.Publish(
|
|
||||||
"--output", sharedFrameworkNameAndVersionRoot,
|
|
||||||
"-r", _sharedFrameworkRid,
|
|
||||||
_sharedFrameworkSourceRoot)
|
|
||||||
.Execute()
|
|
||||||
.EnsureSuccessful();
|
|
||||||
|
|
||||||
// Clean up artifacts that dotnet-publish generates which we don't need
|
|
||||||
PublishMutationUtilties.CleanPublishOutput(
|
|
||||||
sharedFrameworkNameAndVersionRoot,
|
|
||||||
"framework",
|
|
||||||
deleteRuntimeConfigJson: true,
|
|
||||||
deleteDepsJson: false);
|
|
||||||
|
|
||||||
// Rename the .deps file
|
|
||||||
var destinationDeps = Path.Combine(sharedFrameworkNameAndVersionRoot, $"{s_sharedFrameworkName}.deps.json");
|
|
||||||
File.Move(Path.Combine(sharedFrameworkNameAndVersionRoot, "framework.deps.json"), destinationDeps);
|
|
||||||
PublishMutationUtilties.ChangeEntryPointLibraryName(destinationDeps, null);
|
|
||||||
|
|
||||||
// Generate RID fallback graph
|
|
||||||
GenerateRuntimeGraph(dotnetCli, destinationDeps);
|
|
||||||
|
|
||||||
CopyHostArtifactsToSharedFramework(sharedFrameworkNameAndVersionRoot);
|
|
||||||
|
|
||||||
if (File.Exists(Path.Combine(sharedFrameworkNameAndVersionRoot, "mscorlib.ni.dll")))
|
|
||||||
{
|
|
||||||
// Publish already places the crossgen'd version of mscorlib into the output, so we can
|
|
||||||
// remove the IL version
|
|
||||||
File.Delete(Path.Combine(sharedFrameworkNameAndVersionRoot, "mscorlib.dll"));
|
|
||||||
}
|
|
||||||
|
|
||||||
_crossgenUtil.CrossgenDirectory(sharedFrameworkNameAndVersionRoot, sharedFrameworkNameAndVersionRoot);
|
|
||||||
|
|
||||||
// Generate .version file for sharedfx
|
|
||||||
var version = _sharedFrameworkNugetVersion;
|
|
||||||
var content = $@"{commitHash}{Environment.NewLine}{version}{Environment.NewLine}";
|
|
||||||
File.WriteAllText(Path.Combine(sharedFrameworkNameAndVersionRoot, ".version"), content);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GenerateRuntimeGraph(DotNetCli dotnetCli, string destinationDeps)
|
|
||||||
{
|
|
||||||
string runtimeGraphGeneratorRuntime = null;
|
|
||||||
switch (RuntimeEnvironment.OperatingSystemPlatform)
|
|
||||||
{
|
|
||||||
case Platform.Windows:
|
|
||||||
runtimeGraphGeneratorRuntime = "win";
|
|
||||||
break;
|
|
||||||
case Platform.Linux:
|
|
||||||
runtimeGraphGeneratorRuntime = "linux";
|
|
||||||
break;
|
|
||||||
case Platform.Darwin:
|
|
||||||
runtimeGraphGeneratorRuntime = "osx";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!string.IsNullOrEmpty(runtimeGraphGeneratorRuntime))
|
|
||||||
{
|
|
||||||
var runtimeGraphGeneratorName = "RuntimeGraphGenerator";
|
|
||||||
var runtimeGraphGeneratorProject = Path.Combine(Dirs.RepoRoot, "tools", "independent", runtimeGraphGeneratorName);
|
|
||||||
var runtimeGraphGeneratorOutput = Path.Combine(Dirs.Output, "tools", "independent", runtimeGraphGeneratorName);
|
|
||||||
|
|
||||||
dotnetCli.Publish(
|
|
||||||
"--output", runtimeGraphGeneratorOutput,
|
|
||||||
runtimeGraphGeneratorProject).Execute().EnsureSuccessful();
|
|
||||||
var runtimeGraphGeneratorExe = Path.Combine(runtimeGraphGeneratorOutput, $"{runtimeGraphGeneratorName}{Constants.ExeSuffix}");
|
|
||||||
|
|
||||||
Cmd(runtimeGraphGeneratorExe, "--project", _sharedFrameworkSourceRoot, "--deps", destinationDeps, runtimeGraphGeneratorRuntime)
|
|
||||||
.Execute()
|
|
||||||
.EnsureSuccessful();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new Exception($"Could not determine rid graph generation runtime for platform {RuntimeEnvironment.OperatingSystemPlatform}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CopyHostArtifactsToSharedFramework(string sharedFrameworkNameAndVersionRoot)
|
|
||||||
{
|
|
||||||
File.Copy(
|
|
||||||
Path.Combine(_corehostLockedDirectory, HostArtifactNames.DotnetHostBaseName),
|
|
||||||
Path.Combine(sharedFrameworkNameAndVersionRoot, HostArtifactNames.DotnetHostBaseName), true);
|
|
||||||
File.Copy(
|
|
||||||
Path.Combine(_corehostLockedDirectory, HostArtifactNames.DotnetHostBaseName),
|
|
||||||
Path.Combine(sharedFrameworkNameAndVersionRoot, $"corehost{Constants.ExeSuffix}"), true);
|
|
||||||
File.Copy(
|
|
||||||
Path.Combine(_corehostLockedDirectory, HostArtifactNames.DotnetHostFxrBaseName),
|
|
||||||
Path.Combine(sharedFrameworkNameAndVersionRoot, HostArtifactNames.DotnetHostFxrBaseName), true);
|
|
||||||
|
|
||||||
// Hostpolicy should be the latest and not the locked version as it is supposed to evolve for
|
|
||||||
// the framework and has a tight coupling with coreclr's API in the framework.
|
|
||||||
File.Copy(
|
|
||||||
Path.Combine(_corehostLatestDirectory, HostArtifactNames.HostPolicyBaseName),
|
|
||||||
Path.Combine(sharedFrameworkNameAndVersionRoot, HostArtifactNames.HostPolicyBaseName), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GenerateSharedFrameworkProject(
|
|
||||||
string sharedFrameworkNugetVersion,
|
|
||||||
string sharedFrameworkTemplatePath,
|
|
||||||
string rid)
|
|
||||||
{
|
|
||||||
string sharedFrameworkProjectPath = Path.Combine(Dirs.Intermediate, "sharedFramework", "framework");
|
|
||||||
Utils.DeleteDirectory(sharedFrameworkProjectPath);
|
|
||||||
CopyRecursive(sharedFrameworkTemplatePath, sharedFrameworkProjectPath, true);
|
|
||||||
|
|
||||||
string templateFile = Path.Combine(sharedFrameworkProjectPath, "project.json.template");
|
|
||||||
JObject sharedFrameworkProject = JsonUtils.ReadProject(templateFile);
|
|
||||||
sharedFrameworkProject["dependencies"]["Microsoft.NETCore.App"] = sharedFrameworkNugetVersion;
|
|
||||||
((JObject)sharedFrameworkProject["runtimes"]).RemoveAll();
|
|
||||||
sharedFrameworkProject["runtimes"][rid] = new JObject();
|
|
||||||
|
|
||||||
string projectJsonPath = Path.Combine(sharedFrameworkProjectPath, "project.json");
|
|
||||||
JsonUtils.WriteProject(sharedFrameworkProject, projectJsonPath);
|
|
||||||
|
|
||||||
Rm(templateFile);
|
|
||||||
|
|
||||||
return sharedFrameworkProjectPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -90,18 +90,5 @@ namespace Microsoft.DotNet.Cli.Build
|
||||||
{
|
{
|
||||||
return $@"{commitHash}{Environment.NewLine}{version}{Environment.NewLine}";
|
return $@"{commitHash}{Environment.NewLine}{version}{Environment.NewLine}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetSharedFrameworkVersionFileContent(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
string SharedFrameworkNugetVersion = c.BuildContext.Get<string>("SharedFrameworkNugetVersion");
|
|
||||||
return $@"{c.BuildContext["CommitHash"]}{Environment.NewLine}{SharedFrameworkNugetVersion}{Environment.NewLine}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetCliVersionFileContent(BuildTargetContext c)
|
|
||||||
{
|
|
||||||
var buildVersion = c.BuildContext.Get<BuildVersion>("BuildVersion");
|
|
||||||
var version = buildVersion.NuGetVersion;
|
|
||||||
return $@"{c.BuildContext["CommitHash"]}{Environment.NewLine}{version}{Environment.NewLine}";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ namespace Microsoft.DotNet.Cli.Build
|
||||||
var result = Command.Create("yum", "list", "installed", packageName)
|
var result = Command.Create("yum", "list", "installed", packageName)
|
||||||
.CaptureStdOut()
|
.CaptureStdOut()
|
||||||
.CaptureStdErr()
|
.CaptureStdErr()
|
||||||
.QuietBuildReporter()
|
|
||||||
.Execute();
|
.Execute();
|
||||||
|
|
||||||
return result.ExitCode == 0;
|
return result.ExitCode == 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue