Bring Host build into separate project

This commit is contained in:
Bryan 2016-05-11 17:20:40 -07:00 committed by Eric Erhardt
parent 07b785c183
commit 7bf08c5bd5
76 changed files with 1065 additions and 320 deletions

View file

@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.DotNet.Cli.Build
{
public class PackageDependencies
{
public static string[] DebianPackageBuildDependencies
{
get
{
return new string[]
{
"devscripts",
"debhelper",
"build-essential"
};
}
}
public static string[] UbuntuCoreclrAndCoreFxDependencies
{
get
{
return new string[]
{
"libc6",
"libedit2",
"libffi6",
"libgcc1",
"libicu52",
"liblldb-3.6",
"libllvm3.6",
"liblttng-ust0",
"liblzma5",
"libncurses5",
"libpython2.7",
"libstdc++6",
"libtinfo5",
"libunwind8",
"liburcu1",
"libuuid1",
"zlib1g",
"libasn1-8-heimdal",
"libcomerr2",
"libcurl3",
"libgcrypt11",
"libgnutls26",
"libgpg-error0",
"libgssapi3-heimdal",
"libgssapi-krb5-2",
"libhcrypto4-heimdal",
"libheimbase1-heimdal",
"libheimntlm0-heimdal",
"libhx509-5-heimdal",
"libidn11",
"libk5crypto3",
"libkeyutils1",
"libkrb5-26-heimdal",
"libkrb5-3",
"libkrb5support0",
"libldap-2.4-2",
"libp11-kit0",
"libroken18-heimdal",
"librtmp0",
"libsasl2-2",
"libsqlite3-0",
"libssl1.0.0",
"libtasn1-6",
"libwind0-heimdal"
};
}
}
public static string[] CentosCoreclrAndCoreFxDependencies
{
get
{
return new string[]
{
"unzip",
"libunwind",
"gettext",
"libcurl-devel",
"openssl-devel",
"zlib",
"libicu-devel"
};
}
}
}
}

View file

@ -0,0 +1,209 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
namespace Microsoft.DotNet.Cli.Build
{
public class AzurePublisher
{
private static readonly string s_dotnetBlobRootUrl = "https://dotnetcli.blob.core.windows.net/dotnet/";
private static readonly string s_dotnetBlobContainerName = "dotnet";
private string _connectionString { get; set; }
private CloudBlobContainer _blobContainer { get; set; }
public AzurePublisher()
{
_connectionString = Environment.GetEnvironmentVariable("CONNECTION_STRING").Trim('"');
_blobContainer = GetDotnetBlobContainer(_connectionString);
}
private CloudBlobContainer GetDotnetBlobContainer(string connectionString)
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
return blobClient.GetContainerReference(s_dotnetBlobContainerName);
}
public void PublishInstallerFile(string installerFile, string channel, string version)
{
var installerFileBlob = CalculateInstallerBlob(installerFile, channel, version);
PublishFile(installerFileBlob, installerFile);
}
public void PublishArchive(string archiveFile, string channel, string version)
{
var archiveFileBlob = CalculateArchiveBlob(archiveFile, channel, version);
PublishFile(archiveFileBlob, archiveFile);
}
public void PublishFile(string blob, string file)
{
CloudBlockBlob blockBlob = _blobContainer.GetBlockBlobReference(blob);
blockBlob.UploadFromFileAsync(file, FileMode.Open).Wait();
SetBlobPropertiesBasedOnFileType(blockBlob);
}
public void PublishStringToBlob(string blob, string content)
{
CloudBlockBlob blockBlob = _blobContainer.GetBlockBlobReference(blob);
blockBlob.UploadTextAsync(content).Wait();
blockBlob.Properties.ContentType = "text/plain";
blockBlob.SetPropertiesAsync().Wait();
}
public void CopyBlob(string sourceBlob, string targetBlob)
{
CloudBlockBlob source = _blobContainer.GetBlockBlobReference(sourceBlob);
CloudBlockBlob target = _blobContainer.GetBlockBlobReference(targetBlob);
// Create the empty blob
using (MemoryStream ms = new MemoryStream())
{
target.UploadFromStreamAsync(ms).Wait();
}
// Copy actual blob data
target.StartCopyAsync(source).Wait();
}
private void SetBlobPropertiesBasedOnFileType(CloudBlockBlob blockBlob)
{
if (Path.GetExtension(blockBlob.Uri.AbsolutePath.ToLower()) == ".svg")
{
blockBlob.Properties.ContentType = "image/svg+xml";
blockBlob.Properties.CacheControl = "no-cache";
blockBlob.SetPropertiesAsync().Wait();
}
else if (Path.GetExtension(blockBlob.Uri.AbsolutePath.ToLower()) == ".version")
{
blockBlob.Properties.ContentType = "text/plain";
blockBlob.SetPropertiesAsync().Wait();
}
}
public IEnumerable<string> ListBlobs(string virtualDirectory)
{
CloudBlobDirectory blobDir = _blobContainer.GetDirectoryReference(virtualDirectory);
BlobContinuationToken continuationToken = new BlobContinuationToken();
var blobFiles = blobDir.ListBlobsSegmentedAsync(continuationToken).Result;
return blobFiles.Results.Select(bf => bf.Uri.PathAndQuery);
}
public string AcquireLeaseOnBlob(string blob)
{
CloudBlockBlob cloudBlob = _blobContainer.GetBlockBlobReference(blob);
System.Threading.Tasks.Task<string> task = cloudBlob.AcquireLeaseAsync(TimeSpan.FromMinutes(1), null);
task.Wait();
return task.Result;
}
public void ReleaseLeaseOnBlob(string blob, string leaseId)
{
CloudBlockBlob cloudBlob = _blobContainer.GetBlockBlobReference(blob);
AccessCondition ac = new AccessCondition() { LeaseId = leaseId };
cloudBlob.ReleaseLeaseAsync(ac).Wait();
}
public bool IsLatestSpecifiedVersion(string version)
{
System.Threading.Tasks.Task<bool> task = _blobContainer.GetBlockBlobReference(version).ExistsAsync();
task.Wait();
return task.Result;
}
public void DropLatestSpecifiedVersion(string version)
{
CloudBlockBlob blob = _blobContainer.GetBlockBlobReference(version);
using (MemoryStream ms = new MemoryStream())
{
blob.UploadFromStreamAsync(ms).Wait();
}
}
public void CreateBlobIfNotExists(string path)
{
System.Threading.Tasks.Task<bool> task = _blobContainer.GetBlockBlobReference(path).ExistsAsync();
task.Wait();
if (!task.Result)
{
CloudBlockBlob blob = _blobContainer.GetBlockBlobReference(path);
using (MemoryStream ms = new MemoryStream())
{
blob.UploadFromStreamAsync(ms).Wait();
}
}
}
public bool TryDeleteBlob(string path)
{
try
{
DeleteBlob(path);
return true;
}
catch (Exception e)
{
Console.WriteLine($"Deleting blob {path} failed with \r\n{e.Message}");
return false;
}
}
public void DeleteBlob(string path)
{
_blobContainer.GetBlockBlobReference(path).DeleteAsync().Wait();
}
public string CalculateInstallerUploadUrl(string installerFile, string channel, string version)
{
return $"{s_dotnetBlobRootUrl}{CalculateInstallerBlob(installerFile, channel, version)}";
}
public string CalculateInstallerBlob(string installerFile, string channel, string version)
{
return $"{channel}/Installers/{version}/{Path.GetFileName(installerFile)}";
}
public string CalculateArchiveUploadUrl(string archiveFile, string channel, string version)
{
return $"{s_dotnetBlobRootUrl}{CalculateArchiveBlob(archiveFile, channel, version)}";
}
public string CalculateArchiveBlob(string archiveFile, string channel, string version)
{
return $"{channel}/Binaries/{version}/{Path.GetFileName(archiveFile)}";
}
public void DownloadFiles(string blobVirtualDirectory, string fileExtension, string downloadPath)
{
CloudBlobDirectory blobDir = _blobContainer.GetDirectoryReference(blobVirtualDirectory);
BlobContinuationToken continuationToken = new BlobContinuationToken();
var blobFiles = blobDir.ListBlobsSegmentedAsync(continuationToken).Result;
foreach (var blobFile in blobFiles.Results.OfType<CloudBlockBlob>())
{
if (Path.GetExtension(blobFile.Uri.AbsoluteUri) == fileExtension)
{
string localBlobFile = Path.Combine(downloadPath, Path.GetFileName(blobFile.Uri.AbsoluteUri));
Console.WriteLine($"Downloading {blobFile.Uri.AbsoluteUri} to {localBlobFile}...");
blobFile.DownloadToFileAsync(localBlobFile, FileMode.Create).Wait();
}
}
}
}
}

View file

@ -0,0 +1,55 @@
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
namespace Microsoft.DotNet.Cli.Build
{
public class DebRepoPublisher
{
private const string _debianRevisionNumber = "1";
private string _repoID;
private string _uploadJsonDirectory;
public DebRepoPublisher(string uploadJsonDirectory)
{
_uploadJsonDirectory = uploadJsonDirectory;
_repoID = Environment.GetEnvironmentVariable("REPO_ID");
}
public void PublishDebFileToDebianRepo(string packageName, string packageVersion, string uploadUrl)
{
var uploadJson = GenerateUploadJsonFile(packageName, packageVersion, uploadUrl);
Cmd(Path.Combine(Dirs.RepoRoot, "scripts", "publish", "repoapi_client.sh"), "-addpkg", uploadJson)
.Execute()
.EnsureSuccessful();
}
private string GenerateUploadJsonFile(string packageName, string packageVersion, string uploadUrl)
{
var uploadJson = Path.Combine(_uploadJsonDirectory, "package_upload.json");
File.Delete(uploadJson);
using (var fileStream = File.Create(uploadJson))
{
using (StreamWriter sw = new StreamWriter(fileStream))
{
sw.WriteLine("{");
sw.WriteLine($" \"name\":\"{packageName}\",");
sw.WriteLine($" \"version\":\"{packageVersion}-{_debianRevisionNumber}\",");
sw.WriteLine($" \"repositoryId\":\"{_repoID}\",");
sw.WriteLine($" \"sourceUrl\":\"{uploadUrl}\"");
sw.WriteLine("}");
}
}
return uploadJson;
}
}
}

View file

@ -0,0 +1,24 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.DotNet.Cli.Build.Framework;
namespace Microsoft.DotNet.Cli.Build
{
public class AptDependencyUtility
{
public static bool PackageIsInstalled(string packageName)
{
var result = Command.Create("dpkg", "-s", packageName)
.CaptureStdOut()
.CaptureStdErr()
.QuietBuildReporter()
.Execute();
return result.ExitCode == 0;
}
}
}

View file

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
namespace Microsoft.DotNet.Cli.Build
{
public class BranchInfo
{
private static readonly string s_branchInfoFileName = "branchinfo.txt";
private string _repoRoot;
private string _branchInfoFile;
public IDictionary<string, string> Entries { get; set; }
public BranchInfo(string repoRoot)
{
_repoRoot = repoRoot;
_branchInfoFile = Path.Combine(_repoRoot, s_branchInfoFileName);
Entries = ReadBranchInfo(_branchInfoFile);
}
private IDictionary<string, string> ReadBranchInfo(string path)
{
var lines = File.ReadAllLines(path);
var dict = new Dictionary<string, string>();
foreach (var line in lines)
{
if (!line.Trim().StartsWith("#") && !string.IsNullOrWhiteSpace(line))
{
var splat = line.Split(new[] { '=' }, 2);
dict[splat[0]] = splat[1];
}
}
return dict;
}
}
}

View file

@ -0,0 +1,13 @@
using System.Collections.Generic;
namespace Microsoft.DotNet.Cli.Build
{
public class BuildVersion : Version
{
public string SimpleVersion => $"{Major}.{Minor}.{Patch}.{CommitCountString}";
public string VersionSuffix => $"{ReleaseSuffix}-{CommitCountString}";
public string NuGetVersion => $"{Major}.{Minor}.{Patch}-{VersionSuffix}";
public string NetCoreAppVersion => $"{Major}.{Minor}.{Patch}-rc3-{CommitCountString}";
public string ProductionVersion => $"{Major}.{Minor}.{Patch}";
}
}

View file

@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.DotNet.InternalAbstractions;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
namespace Microsoft.DotNet.Cli.Build
{
public class Crossgen
{
private string _coreClrVersion;
private string _crossGenPath;
// This is not always correct. The version of crossgen we need to pick up is whatever one was restored as part
// of the Microsoft.NETCore.Runtime.CoreCLR package that is part of the shared library. For now, the version hardcoded
// in CompileTargets and the one in the shared library project.json match and are updated in lock step, but long term
// we need to be able to look at the project.lock.json file and figure out what version of Microsoft.NETCore.Runtime.CoreCLR
// was used, and then select that version.
public Crossgen(string coreClrVersion)
{
_coreClrVersion = coreClrVersion;
_crossGenPath = GetCrossgenPathForVersion();
}
private string GetCrossgenPathForVersion()
{
string arch = RuntimeEnvironment.RuntimeArchitecture;
string packageId;
if (CurrentPlatform.IsWindows)
{
packageId = $"runtime.win7-{arch}.Microsoft.NETCore.Runtime.CoreCLR";
}
else if (CurrentPlatform.IsUbuntu)
{
packageId = "runtime.ubuntu.14.04-x64.Microsoft.NETCore.Runtime.CoreCLR";
}
else if (CurrentPlatform.IsCentOS || CurrentPlatform.IsRHEL)
{
// CentOS runtime is in the runtime.rhel.7-x64... package.
packageId = "runtime.rhel.7-x64.Microsoft.NETCore.Runtime.CoreCLR";
}
else if (CurrentPlatform.IsOSX)
{
packageId = "runtime.osx.10.10-x64.Microsoft.NETCore.Runtime.CoreCLR";
}
else if (CurrentPlatform.IsDebian)
{
packageId = "runtime.debian.8-x64.Microsoft.NETCore.Runtime.CoreCLR";
}
else
{
return null;
}
return Path.Combine(
Dirs.NuGetPackages,
packageId,
_coreClrVersion,
"tools",
$"crossgen{Constants.ExeSuffix}");
}
public void CrossgenDirectory(BuildTargetContext c, string pathToAssemblies)
{
// Check if we need to skip crossgen
if (string.Equals(Environment.GetEnvironmentVariable("DISABLE_CROSSGEN"), "1"))
{
c.Warn("Skipping crossgen for because DISABLE_CROSSGEN is set to 1");
return;
}
string sharedFxPath = c.BuildContext.Get<string>("SharedFrameworkPath");
// HACK
// The input directory can be a portable FAT app (example the CLI itself).
// In that case there can be RID specific managed dependencies which are not right next to the app binary (example System.Diagnostics.TraceSource).
// We need those dependencies during crossgen. For now we just pass all subdirectories of the input directory as input to crossgen.
// The right fix -
// If the assembly has deps.json then parse the json file to get all the dependencies, pass these dependencies as input to crossgen.
// else pass the current directory of assembly as input to crossgen.
var addtionalPaths = Directory.GetDirectories(pathToAssemblies, "*", SearchOption.AllDirectories).ToList();
var paths = new List<string>() { sharedFxPath, pathToAssemblies };
paths.AddRange(addtionalPaths);
var platformAssembliesPaths = string.Join(Path.PathSeparator.ToString(), paths.Distinct());
var env = new Dictionary<string, string>()
{
// disable partial ngen
{ "COMPLUS_ZapDisable", "0" }
};
foreach (var file in Directory.GetFiles(pathToAssemblies))
{
string fileName = Path.GetFileName(file);
if (fileName == "mscorlib.dll" || fileName == "mscorlib.ni.dll" || !PEUtils.HasMetadata(file))
{
continue;
}
string tempPathName = Path.ChangeExtension(file, "readytorun");
IList<string> crossgenArgs = new List<string> {
"-readytorun", "-in", file, "-out", tempPathName,
"-platform_assemblies_paths", platformAssembliesPaths
};
ExecSilent(_crossGenPath, crossgenArgs, env);
File.Copy(tempPathName, file, overwrite: true);
File.Delete(tempPathName);
}
}
}
}

View file

@ -0,0 +1,52 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.DotNet.InternalAbstractions;
namespace Microsoft.DotNet.Cli.Build
{
public static class Dirs
{
public static readonly string RepoRoot = Directory.GetCurrentDirectory();
public static readonly string Output = Path.Combine(
RepoRoot,
"artifacts",
RuntimeEnvironment.GetRuntimeIdentifier());
public static readonly string Intermediate = Path.Combine(Output, "intermediate");
public static readonly string PackagesIntermediate = Path.Combine(Output, "packages/intermediate");
public static readonly string PackagesNoRID = Path.Combine(RepoRoot, "artifacts", "packages");
public static readonly string Packages = Path.Combine(Output, "packages");
public static readonly string Stage1 = Path.Combine(Output, "stage1");
public static readonly string Stage1Compilation = Path.Combine(Output, "stage1compilation");
public static readonly string Stage1Symbols = Path.Combine(Output, "stage1symbols");
public static readonly string Stage2 = Path.Combine(Output, "stage2");
public static readonly string Stage2Compilation = Path.Combine(Output, "stage2compilation");
public static readonly string Stage2Symbols = Path.Combine(Output, "stage2symbols");
public static readonly string CorehostLatest = Path.Combine(Output, "corehost"); // Not using Path.Combine(Output, "corehost", "latest") to keep signing working.
public static readonly string CorehostLocked = Path.Combine(Output, "corehost", "locked");
public static readonly string CorehostLocalPackages = Path.Combine(Output, "corehost");
public static readonly string CorehostDummyPackages = Path.Combine(Output, "corehostdummypackages");
public static readonly string TestOutput = Path.Combine(Output, "tests");
public static readonly string TestArtifacts = Path.Combine(TestOutput, "artifacts");
public static readonly string TestPackages = Path.Combine(TestOutput, "packages");
public static readonly string TestPackagesBuild = Path.Combine(TestOutput, "packagesBuild");
public static readonly string OSXReferenceAssembliesPath = "/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/xbuild-frameworks";
public static readonly string UsrLocalReferenceAssembliesPath = "/usr/local/lib/mono/xbuild-frameworks";
public static readonly string UsrReferenceAssembliesPath = "/usr/lib/mono/xbuild-frameworks";
public static string NuGetPackages = Environment.GetEnvironmentVariable("NUGET_PACKAGES") ?? GetNuGetPackagesDir();
private static string GetNuGetPackagesDir()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), ".nuget", "packages");
}
return Path.Combine(Environment.GetEnvironmentVariable("HOME"), ".nuget", "packages");
}
}
}

View file

@ -0,0 +1,70 @@
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.DotNet.InternalAbstractions;
namespace Microsoft.DotNet.Cli.Build
{
public class DotNetCli
{
public static readonly DotNetCli Stage0 = new DotNetCli(GetStage0Path());
public static readonly DotNetCli Stage1 = new DotNetCli(Dirs.Stage1);
public static readonly DotNetCli Stage2 = new DotNetCli(Dirs.Stage2);
public string BinPath { get; }
public DotNetCli(string binPath)
{
BinPath = binPath;
}
public Command Exec(string command, params string[] args)
{
var newArgs = args.ToList();
newArgs.Insert(0, command);
if (EnvVars.Verbose)
{
newArgs.Insert(0, "-v");
}
return Command.Create(Path.Combine(BinPath, $"dotnet{Constants.ExeSuffix}"), newArgs);
}
public Command Restore(params string[] args) => Exec("restore", args);
public Command Build(params string[] args) => Exec("build", args);
public Command Pack(params string[] args) => Exec("pack", args);
public Command Test(params string[] args) => Exec("test", args);
public Command Publish(params string[] args) => Exec("publish", args);
public string GetRuntimeId()
{
string info = Exec("", "--info").CaptureStdOut().Execute().StdOut;
string rid = Array.Find<string>(info.Split(Environment.NewLine.ToCharArray()), (e) => e.Contains("RID:"))?.Replace("RID:", "").Trim();
if (string.IsNullOrEmpty(rid))
{
throw new BuildFailureException("Could not find the Runtime ID from Stage0 --info or --version");
}
return rid;
}
private static string GetStage0Path()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return Path.Combine(Directory.GetCurrentDirectory(), ".dotnet_stage0",
RuntimeEnvironment.OperatingSystemPlatform.ToString(),
RuntimeEnvironment.RuntimeArchitecture);
}
else
{
return Path.Combine(Directory.GetCurrentDirectory(), ".dotnet_stage0", RuntimeEnvironment.OperatingSystemPlatform.ToString());
}
}
}
}

View file

@ -0,0 +1,32 @@
using System;
namespace Microsoft.DotNet.Cli.Build
{
public class EnvVars
{
public static readonly bool Verbose = GetBool("DOTNET_BUILD_VERBOSE");
private static bool GetBool(string name, bool defaultValue = false)
{
var str = Environment.GetEnvironmentVariable(name);
if (string.IsNullOrEmpty(str))
{
return defaultValue;
}
switch (str.ToLowerInvariant())
{
case "true":
case "1":
case "yes":
return true;
case "false":
case "0":
case "no":
return false;
default:
return defaultValue;
}
}
}
}

View file

@ -0,0 +1,123 @@
using System.IO;
using System.Runtime.InteropServices;
using System;
using Microsoft.DotNet.Cli.Build.Framework;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
namespace Microsoft.DotNet.Cli.Build
{
public static class FS
{
public static void Mkdirp(string dir)
{
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
}
public static void Rm(string file)
{
if(File.Exists(file))
{
File.Delete(file);
}
}
public static void Rmdir(string dir)
{
if(Directory.Exists(dir))
{
Directory.Delete(dir, recursive: true);
}
}
public static void RmFilesInDirRecursive(string dir, string filePattern)
{
var files = Directory.EnumerateFiles(dir, filePattern, SearchOption.AllDirectories);
foreach (var file in files)
{
FS.Rm(file);
}
}
public static void Chmod(string file, string mode, bool recursive = false)
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
if (recursive)
{
Command.Create("chmod", "-R", mode, file).Execute().EnsureSuccessful();
}
else
{
Command.Create("chmod", mode, file).Execute().EnsureSuccessful();
}
}
}
public static void ChmodAll(string searchDir, string pattern, string mode)
{
Exec("find", searchDir, "-type", "f", "-name", pattern, "-exec", "chmod", mode, "{}", ";");
}
public static void FixModeFlags(string dir)
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// Managed code doesn't need 'x'
ChmodAll(dir, "*.dll", "644");
ChmodAll(dir, "*.exe", "644");
// Generally, dylibs and sos have 'x' (no idea if it's required ;))
// (No need to condition this on OS since there shouldn't be any dylibs on Linux,
// but even if they are we may as well set their mode flags :))
ChmodAll(dir, "*.dylib", "755");
ChmodAll(dir, "*.so", "755");
// Executables (those without dots) are executable :)
Exec("find", dir, "-type", "f", "!", "-name", "*.*", "-exec", "chmod", "755", "{}", ";");
}
}
public static void CopyRecursive(string sourceDirectory, string destinationDirectory, bool overwrite = false)
{
Mkdirp(destinationDirectory);
foreach(var dir in Directory.EnumerateDirectories(sourceDirectory))
{
CopyRecursive(dir, Path.Combine(destinationDirectory, Path.GetFileName(dir)), overwrite);
}
foreach(var file in Directory.EnumerateFiles(sourceDirectory))
{
var dest = Path.Combine(destinationDirectory, Path.GetFileName(file));
if (!File.Exists(dest) || overwrite)
{
// We say overwrite true, because we only get here if the file didn't exist (thus it doesn't matter) or we
// wanted to overwrite :)
File.Copy(file, dest, overwrite: true);
}
}
}
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);
}
}
}
}
}

View file

@ -0,0 +1,47 @@
using System.Collections.Generic;
namespace Microsoft.DotNet.Cli.Build
{
public class HostVersion : Version
{
// ------------------------------------------HOST-VERSIONING-------------------------------------------
//
// Host versions are independent of CLI versions. Moreover, these version numbers
// are baked into the binary and is used to look up a serviced binary replacement.
//
//
// Latest hosts for production of nupkgs.
//
// Version constants without suffix
public override int Major => 1;
public override int Minor => 0;
public override int Patch => 1;
public override string ReleaseSuffix => "rc3";
public string LatestHostVersionNoSuffix => $"{Major}.{Minor}.{Patch}";
public string LatestHostFxrVersionNoSuffix => $"{Major}.{Minor}.{Patch}";
public string LatestHostPolicyVersionNoSuffix => $"{Major}.{Minor}.{Patch}";
public string LatestHostPrerelease => ReleaseSuffix;
public string LatestHostBuildMajor => $"{CommitCountString}";
public string LatestHostSuffix => $"{ReleaseSuffix}-{LatestHostBuildMajor}-00";
// Full versions and package information.
public string LatestHostVersion => $"{LatestHostVersionNoSuffix}-{LatestHostSuffix}";
public string LatestHostFxrVersion => $"{LatestHostFxrVersionNoSuffix}-{LatestHostSuffix}";
public string LatestHostPolicyVersion => $"{LatestHostPolicyVersionNoSuffix}-{LatestHostSuffix}";
public Dictionary<string, string> LatestHostPackages => new Dictionary<string, string>()
{
{ "Microsoft.NETCore.DotNetHost", LatestHostVersion },
{ "Microsoft.NETCore.DotNetHostResolver", LatestHostFxrVersion },
{ "Microsoft.NETCore.DotNetHostPolicy", LatestHostPolicyVersion }
};
//
// Locked muxer for consumption in CLI.
//
public bool IsLocked = false; // Set this variable to toggle muxer locking.
public string LockedHostFxrVersion => IsLocked ? "1.0.1-rc2-002468-00" : LatestHostFxrVersion;
public string LockedHostVersion => IsLocked ? "1.0.1-rc2-002468-00" : LatestHostVersion;
}
}

View file

@ -0,0 +1,28 @@
using System;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Microsoft.DotNet.Cli.Build
{
public static class JsonUtils
{
public static JObject ReadProject(string projectJsonPath)
{
using (TextReader projectFileReader = File.OpenText(projectJsonPath))
{
var projectJsonReader = new JsonTextReader(projectFileReader);
var serializer = new JsonSerializer();
return serializer.Deserialize<JObject>(projectJsonReader);
}
}
public static void WriteProject(JObject projectRoot, string projectJsonPath)
{
string projectJson = JsonConvert.SerializeObject(projectRoot, Formatting.Indented);
File.WriteAllText(projectJsonPath, projectJson + Environment.NewLine);
}
}
}

View file

@ -0,0 +1,99 @@
using Microsoft.DotNet.Cli.Build.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.DotNet.Cli.Build
{
public class Monikers
{
public const string SharedFrameworkName = "Microsoft.NETCore.App";
public const string CLISdkBrandName = "Microsoft .NET Core 1.0.0 RC2 - SDK Preview 1";
public const string SharedFxBrandName = "Microsoft .NET Core 1.0.0 RC2 - Runtime";
public const string SharedHostBrandName = "Microsoft .NET Core 1.0.0 RC2 - Host";
public static string GetProductMoniker(BuildTargetContext c, string artifactPrefix, string version)
{
string osname = GetOSShortName();
var arch = CurrentArchitecture.Current.ToString();
return $"{artifactPrefix}-{osname}-{arch}.{version}";
}
public static string GetDebianPackageName(BuildTargetContext c)
{
var channel = c.BuildContext.Get<string>("Channel").ToLower();
var packageName = "";
switch (channel)
{
case "dev":
packageName = "dotnet-nightly";
break;
case "beta":
case "rc1":
case "rc2":
case "preview":
case "rtm":
packageName = "dotnet";
break;
default:
throw new Exception($"Unknown channel - {channel}");
}
return packageName;
}
public static string GetSdkDebianPackageName(BuildTargetContext c)
{
var channel = c.BuildContext.Get<string>("Channel").ToLower();
var nugetVersion = c.BuildContext.Get<BuildVersion>("BuildVersion").NuGetVersion;
var packagePrefix = "";
switch (channel)
{
case "dev":
packagePrefix = "dotnet-nightly";
break;
case "beta":
case "rc1":
case "rc2":
case "preview":
case "rtm":
packagePrefix = "dotnet";
break;
default:
throw new Exception($"Unknown channel - {channel}");
}
return $"{packagePrefix}-dev-{nugetVersion}";
}
public static string GetDebianSharedFrameworkPackageName(BuildTargetContext c)
{
var sharedFrameworkNugetVersion = c.BuildContext.Get<string>("SharedFrameworkNugetVersion");
return $"dotnet-sharedframework-{SharedFrameworkName}-{sharedFrameworkNugetVersion}".ToLower();
}
public static string GetDebianSharedHostPackageName(BuildTargetContext c)
{
return $"dotnet-host".ToLower();
}
public static string GetOSShortName()
{
string osname = "";
switch (CurrentPlatform.Current)
{
case BuildPlatform.Windows:
osname = "win";
break;
default:
osname = CurrentPlatform.Current.ToString().ToLower();
break;
}
return osname;
}
}
}

View file

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection.PortableExecutable;
namespace Microsoft.DotNet.Cli.Build
{
public static class PEUtils
{
public static bool HasMetadata(string pathToFile)
{
try
{
using (var inStream = File.OpenRead(pathToFile))
{
using (var peReader = new PEReader(inStream))
{
return peReader.HasMetadata;
}
}
}
catch (BadImageFormatException) { }
return false;
}
}
}

View file

@ -0,0 +1,157 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using Microsoft.DotNet.Cli.Build.Framework;
namespace Microsoft.DotNet.Cli.Build
{
public static class Utils
{
public static void CleanNuGetTempCache()
{
// Clean NuGet Temp Cache on Linux (seeing some issues on Linux)
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && Directory.Exists("/tmp/NuGet"))
{
Directory.Delete("/tmp/NuGet", recursive: true);
}
}
public static string GetOSName()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return "win";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return "osx";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
throw new NotImplementedException();
}
else
{
throw new PlatformNotSupportedException();
}
}
// Generate a Version 5 (SHA1 Name Based) Guid from a name.
public static Guid GenerateGuidFromName(string name)
{
// Any fixed GUID will do for a namespace.
Guid namespaceId = new Guid("28F1468D-672B-489A-8E0C-7C5B3030630C");
using (SHA1 hasher = SHA1.Create())
{
var nameBytes = System.Text.Encoding.UTF8.GetBytes(name ?? string.Empty);
var namespaceBytes = namespaceId.ToByteArray();
SwapGuidByteOrder(namespaceBytes);
var streamToHash = new byte[namespaceBytes.Length + nameBytes.Length];
Array.Copy(namespaceBytes, streamToHash, namespaceBytes.Length);
Array.Copy(nameBytes, 0, streamToHash, namespaceBytes.Length, nameBytes.Length);
var hashResult = hasher.ComputeHash(streamToHash);
var res = new byte[16];
Array.Copy(hashResult, res, res.Length);
unchecked { res[6] = (byte)(0x50 | (res[6] & 0x0F)); }
unchecked { res[8] = (byte)(0x40 | (res[8] & 0x3F)); }
SwapGuidByteOrder(res);
return new Guid(res);
}
}
// Do a byte order swap, .NET GUIDs store multi byte components in little
// endian.
private static void SwapGuidByteOrder(byte[] b)
{
Swap(b, 0, 3);
Swap(b, 1, 2);
Swap(b, 5, 6);
Swap(b, 7, 8);
}
private static void Swap(byte[] b, int x, int y)
{
byte t = b[x];
b[x] = b[y];
b[y] = t;
}
public static void DeleteDirectory(string path)
{
if (Directory.Exists(path))
{
string[] files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
foreach (string file in files)
{
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
var retry = 5;
while (retry >= 0)
{
try
{
Directory.Delete(path, true);
return;
}
catch (IOException ex)
{
if (retry == 0)
{
throw;
}
System.Threading.Thread.Sleep(200);
retry--;
}
}
}
}
public static void CopyDirectoryRecursively(string path, string destination, bool keepParentDir = false)
{
if (keepParentDir)
{
path = path.TrimEnd(Path.DirectorySeparatorChar);
destination = Path.Combine(destination, Path.GetFileName(path));
Directory.CreateDirectory(destination);
}
foreach (var file in Directory.GetFiles(path, "*", SearchOption.AllDirectories))
{
string destFile = file.Replace(path, destination);
Directory.CreateDirectory(Path.GetDirectoryName(destFile));
File.Copy(file, destFile, true);
}
}
public static string GetVersionFileContent(string commitHash, string version)
{
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}";
}
}
}

View file

@ -0,0 +1,39 @@
using System.Collections.Generic;
namespace Microsoft.DotNet.Cli.Build
{
public abstract class Version
{
public virtual int Major { get; set; }
public virtual int Minor { get; set; }
public virtual int Patch { get; set; }
public virtual int CommitCount { get; set; }
public virtual string CommitCountString => CommitCount.ToString("000000");
public virtual string ReleaseSuffix { get; set; }
public string GenerateMsiVersion()
{
// MSI versioning
// Encode the CLI version to fit into the MSI versioning scheme - https://msdn.microsoft.com/en-us/library/windows/desktop/aa370859(v=vs.85).aspx
// MSI versions are 3 part
// major.minor.build
// Size(bits) of each part 8 8 16
// So we have 32 bits to encode the CLI version
// Starting with most significant bit this how the CLI version is going to be encoded as MSI Version
// CLI major -> 6 bits
// CLI minor -> 6 bits
// CLI patch -> 6 bits
// CLI commitcount -> 14 bits
var major = Major << 26;
var minor = Minor << 20;
var patch = Patch << 14;
var msiVersionNumber = major | minor | patch | CommitCount;
var msiMajor = (msiVersionNumber >> 24) & 0xFF;
var msiMinor = (msiVersionNumber >> 16) & 0xFF;
var msiBuild = msiVersionNumber & 0xFFFF;
return $"{msiMajor}.{msiMinor}.{msiBuild}";
}
}
}

View file

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.DotNet.Cli.Build.Framework;
namespace Microsoft.DotNet.Cli.Build
{
public class YumDependencyUtility
{
public static bool PackageIsInstalled(string packageName)
{
var result = Command.Create("yum", "list", "installed", packageName)
.CaptureStdOut()
.CaptureStdErr()
.QuietBuildReporter()
.Execute();
return result.ExitCode == 0;
}
}
}

View file

@ -0,0 +1,22 @@
{
"version": "1.0.0-*",
"description": "Build scripts for dotnet-cli",
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-24027",
"Microsoft.CSharp": "4.0.1-rc2-24027",
"Microsoft.DotNet.Cli.Build.Framework": "1.0.0-*",
"System.Dynamic.Runtime": "4.0.11-rc2-24027",
"System.Reflection.Metadata": "1.3.0-rc2-24027",
"System.Runtime.Serialization.Primitives": "4.1.1-rc2-24027",
"System.Xml.XmlSerializer": "4.0.11-rc2-24027",
"WindowsAzure.Storage": "6.2.2-preview"
},
"frameworks": {
"netstandard1.5": {
"imports": [
"dnxcore50",
"portable-net45+win8"
]
}
}
}

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.25123" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25123</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>b768bd29-12bf-4c7c-b093-03193fe244d1</ProjectGuid>
<RootNamespace>shared-build-targets-utils</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>