aspnetcore/makefile.shade

363 lines
11 KiB
Plaintext

var PROJECT='AspNet'
var VERSION='0.2.1'
use namespace='System'
use namespace='System.IO'
use namespace='System.Collections.Generic'
use namespace='System.Net'
use namespace='System.Linq'
use namespace='System.Text.RegularExpressions'
use import="BuildEnv"
functions
@{
static string BASE_DIR = Directory.GetCurrentDirectory();
static string TARGET_DIR = Path.Combine(BASE_DIR, "artifacts", "build");
string[] repos = new[] {
// The repos list is topologically sorted based on build order
"Configuration",
"Caching",
"DataCommon",
"DataCommon.SQLite",
"DataProtection",
"DependencyInjection",
"Options",
"Logging",
"Testing",
"Diagnostics",
"EntityFramework",
"FileSystem",
"WebSocketAbstractions",
"HttpAbstractions",
"Hosting",
"Helios",
"Identity",
"Razor",
"Routing",
"Mvc",
"Scaffolding",
"Security",
"SignalR-Server",
"StaticFiles",
"WebListener",
"KestrelHttpServer",
"WebSockets",
"Entropy",
};
static bool useHttps = UseHttps(BASE_DIR);
static string gitHubUriPrefix = useHttps ? "https://github.com/aspnet/" : "git@github.com:aspnet/";
}
@{
var kBuildVersion = Environment.GetEnvironmentVariable("K_BUILD_VERSION");
if (!string.IsNullOrEmpty(kBuildVersion))
{
VERSION += "-" + kBuildVersion;
}
else
{
VERSION += "-" + BuildNumber;
}
}
#default .compile
#pull
#compile .pull
#install .pull
#pack
directory create='${TARGET_DIR}'
nuget-pack nuspecFile='${Path.Combine(BASE_DIR, "KoreBuild.nuspec")}' packageVersion='${VERSION}' outputDir='${TARGET_DIR}'
#pack-install .pack
nuget-local-publish sourcePackagesDir='${TARGET_DIR}'
#git-pull target='pull'
@{
foreach(var repo in repos)
{
CloneOrUpdate(repo);
}
}
#init
@{
var templatePath = Path.Combine(BASE_DIR, "build-template");
var templateFiles = Files.Include(templatePath + Path.DirectorySeparatorChar + "*.*").Select(Path.GetFileName).ToList();
foreach(var repo in repos)
{
foreach (string fileName in templateFiles)
{
var targetFile = Path.Combine(Directory.GetCurrentDirectory(), repo, fileName);
var sourceFile = Path.Combine(Directory.GetCurrentDirectory(), templatePath, fileName);
// Don't update the makefile
if(fileName.Equals("makefile.shake", StringComparison.OrdinalIgnoreCase) && File.Exists(targetFile))
{
continue;
}
if(!File.Exists(sourceFile) ||
(File.ReadAllText(sourceFile) != File.ReadAllText(targetFile)))
{
Log.Info("Updating " + fileName + " to " + repo);
File.Copy(sourceFile, targetFile, true);
}
}
}
}
#reset-master
-// Resets master branch to release
for each='var repo in GetAllRepos()'
-CloneOrUpdate(repo);
var gitFolder = '${repo}'
git gitCommand='fetch origin'
git gitCommand='checkout origin/release -B master'
#push-master
-// Resets master branch to release
for each='var repo in GetAllRepos()'
var gitFolder = '${repo}'
git gitCommand='push origin master:master -f'
#only-compile target='compile'
@{
var failed = new Dictionary<string, Exception>();
foreach(var repo in repos)
{
try
{
Log.Info(string.Format("Building {0}", repo));
if (IsMono)
{
Exec("build.sh", "compile", repo);
}
else
{
Exec("build.cmd", "compile", repo);
}
Log.Info(string.Format("Build {0} succeeded", repo));
}
catch(Exception ex)
{
Log.Warn(string.Format("Build {0} failed: {1}", repo, ex.Message));
failed[repo] = ex;
}
}
foreach(var repo in repos)
{
Exception ex;
if (failed.TryGetValue(repo, out ex))
{
Log.Warn(string.Format("Build {0} failed: {1}", repo, ex.Message));
}
else
{
Log.Info(string.Format("Build {0} succeeded", repo));
}
}
}
#only-install target='install'
@{
foreach(var repo in repos)
{
if (IsMono)
{
Exec("build.sh", "install", repo);
}
else
{
Exec("build.cmd", "install", repo);
}
}
}
#run-snapshot-manager
@{
Exec(@".nuget\nuget.exe", @"restore -out packages tools\TCDependencyManager\packages.config", "");
var programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
var msbuildPath = Path.Combine(programFiles, "MSBuild", "12.0", "Bin", "MsBuild.exe");
Exec(msbuildPath, "TCDependencyManager.csproj", @"tools\TCDependencyManager");
Exec(@"tools\TCDependencyManager\bin\Debug\TCDependencyManager.exe", "", "");
}
#git-status decription='Show status of repos known by Universe'
@{
foreach(var repo in repos)
{
GitStatus(repo);
}
}
#git-clean decription='REMOVE ALL CHANGES to the working directory'
@{
Console.WriteLine("This runs `git clean -xfd` in all non-Universe repos.");
Console.WriteLine("This should REMOVE ALL CHANGES to the working directory.");
Console.Write("***** Are you sure? ***** (Y or anything else)? ");
if (Console.ReadLine() != "Y")
{
throw new Exception("git-clean cancelled");
}
foreach(var repo in repos)
{
GitClean(repo);
}
}
macro name='GitPull' gitUri='string' gitBranch='string' gitFolder='string'
git-pull
macro name='GitClone' gitUri='string' gitBranch='string'
git-clone
macro name='GitConfig' gitOptionName='string' gitOptionValue='string' gitFolder='string'
git-config
macro name='GitStatus' gitFolder='string'
git gitCommand='status'
macro name='GitClean' gitFolder='string'
git gitCommand='clean -xdf'
macro name='Exec' program='string' commandline='string' workingdir='string'
exec
functions
@{
static bool UseHttps(string directory)
{
var filename = Path.Combine(directory, ".git", "config");
if (!File.Exists(filename))
{
Console.WriteLine("Unable to find '{0}' file", filename);
return false;
}
var url = ReadOriginUrl(filename);
return IsHttpsUrl(url);
}
// Perform equivalent of `git config remote.origin.url` but directly
// read config file to get value.
static string ReadOriginUrl(string filename)
{
// Subsection portion of configuration name is case-sensitive; rest
// of name is case-insensitive.
var beginOriginSection = new Regex(@"^\[(?i:remote) ""origin""\]\s*$");
var beginSection = new Regex(@"^\[");
var urlLine = new Regex(@"^\s+url = (\S+)\s*$", RegexOptions.IgnoreCase);
var inRemoteOriginSection = false;
foreach (var line in File.ReadAllLines(filename))
{
if (beginOriginSection.IsMatch(line))
{
inRemoteOriginSection = true;
continue;
}
if (inRemoteOriginSection)
{
if (beginSection.IsMatch(line))
{
// Read through the section without finding URL line.
break;
}
var match = urlLine.Match(line);
if (match.Success && match.Groups.Count == 2 && match.Groups[1].Success)
{
return match.Groups[1].Value;
}
}
}
Console.WriteLine("Unable to parse '{0}' file", filename);
return null;
}
static bool IsHttpsUrl(string url)
{
if (string.IsNullOrEmpty(url))
{
return false;
}
return url.StartsWith("https://", System.StringComparison.OrdinalIgnoreCase);
}
static bool IsAccessible(string key)
{
var req = WebRequest.CreateHttp("https://github.com/aspnet/" + key);
req.Method = "HEAD";
try
{
using (req.GetResponse());
}
catch (WebException ex)
{
if (ex.Response != null &&
((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotFound)
{
return false;
}
// Ignore any other exception. They should surface as part of git clone with well-known messages.
}
return true;
}
IEnumerable<string> GetAllRepos()
{
var nonDefaultRepos = new[]
{
"KRuntime",
"Claims",
"DataAnnotations",
"SqlClient",
"MusicStore"
};
return Enumerable.Concat(repos, nonDefaultRepos);
}
void CloneOrUpdate(string repo)
{
var repoUrl = gitHubUriPrefix + repo + ".git";
if(Directory.Exists(repo))
{
GitPull(repoUrl, "dev", repo);
}
else
{
if (useHttps &&
!IsAccessible(repo))
{
Log.Warn(string.Format("The repo at '{0}' is not accessible. If you do not have access to this repository, skip the git prompt" +
" for credentials to skip cloning this repository. To avoid this prompt, re-clone the Universe repository over ssh.",
repoUrl));
}
try
{
GitClone(repoUrl, "dev");
}
catch (Exception ex)
{
Log.Warn(string.Format("Unable to clone repository at '{0}': {1}", repoUrl, ex.Message));
return;
}
GitConfig("bugtraq.url", "http://github.com/aspnet/" + repo + "/issues/%BUGID%", repo);
GitConfig("bugtraq.logregex", @"#(\d+)", repo);
}
}
}