Files
cappuccino/Tools/bake/bake.j
T
2008-12-09 14:43:18 -08:00

301 lines
8.5 KiB
Plaintext

@import <Foundation/Foundation.j>
importPackage(Packages.java.io);
var options = {
base : "trunk",
clean : false,
deploy : false,
deployHost : null,
deployPath : null,
skipUpdate : false,
tag : false,
archive : false,
message : null,
templatePath : OBJJ_HOME + "/lib/bake_template.html"
}
var targetPath,
checkoutsPath,
buildsPath,
productsPath,
version = Math.round(new Date().getTime() / 1000);
CPLogRegister(CPLogPrint);
function readConfig(configFile)
{
var fileData = String(readFile(configFile));
if (!fileData)
throw new Error("Couldn't read file: " + configFile);
var configs = CPJSObjectCreateWithJSON(fileData);
return configs;
}
function update()
{
for (var i = 0; i < options.sources.length; i++)
{
var source = options.sources[i];
source.localSourcePath = checkoutsPath + "/" + source.path.replace(/\W+/g, "_");
switch (source.type)
{
case "git":
if (new File(source.localSourcePath).isDirectory())
{
CPLog.debug("git pull (" + source.localSourcePath + ")");
exec("git pull", null, new File(source.localSourcePath));
}
else
{
CPLog.debug("git clone (" + source.path + ")");
exec(["git", "clone", source.path, source.localSourcePath]);
}
break;
case "svn":
if (new File(source.localSourcePath).isDirectory())
{
CPLog.debug("svn up (" + source.localSourcePath + ")");
exec("svn up", null, new File(source.localSourcePath));
}
else
{
CPLog.debug("svn co (" + source.path + ")");
exec(["svn", "co", source.path, source.localSourcePath]);
}
break;
case "rsync":
CPLog.debug("rsync (" + source.localSourcePath + ")");
exec(["rsync", "-avz", source.path + "/", source.localSourcePath]);
break;
default :
CPLog.error("Unimplemented: " + source.type);
}
}
}
function build()
{
var versionedPath = productsPath + "/" + version + "/" + version;
for (var i = 0; i < options.sources.length; i++)
{
var source = options.sources[i];
for (var j = 0; j < source.parts.length; j++)
{
var part = source.parts[j];
var fromPath = source.localSourcePath + "/" + part.src;
var toPath = versionedPath + "/" + part.dst;
if (part.build)
{
var buildCommand = part.build.replace("BUILD_PATH", buildsPath);
CPLog.debug("Building: " + buildCommand);
exec(buildCommand, null, new File(fromPath));
fromPath = buildsPath + "/" + part.copyFrom;
}
mkdirs(toPath);
var rsyncCommand = "rsync -aC " + fromPath + "/. " + toPath;
CPLog.debug("Rsyncing: " + rsyncCommand);
exec(rsyncCommand);
}
}
if (options.press)
{
var tempPath = versionedPath+"-Stripped";
var pressCommand = ["press", versionedPath, tempPath];
if (options.png)
pressCommand.push("--png");
var result = exec(pressCommand);
if (result.code)
throw new Error("press failed");
exec(["rm", "-rf", versionedPath]);
exec(["mv", tempPath, versionedPath]);
}
var results = exec(["bash", "-c", "find "+versionedPath+" \\( -name \"*.sj\" -or -name \"*.j\" \\) -exec cat {} \\; | wc -c | tr -d \" \""]);
var filesTotal = parseInt(results.stdout);
if (isNaN(filesTotal))
filesTotal = 0;
CPLog.debug("FILES_TOTAL=["+filesTotal+"]");
var substitutions = options.templateVars;
substitutions.VERSION = version;
substitutions.FILES_TOTAL = filesTotal;
var template = readFile(options.templatePath);
if (!template)
throw new Error("Couldn't get template");
for (var variable in substitutions)
template = template.replace(new RegExp("\\$" + variable, "g"), substitutions[variable]);
templateBytes = new java.lang.String(template).getBytes();
templateOutput = new FileOutputStream(productsPath + "/" + version + "/index.html");
templateOutput.write(templateBytes, 0, templateBytes.length);
templateOutput.close();
exec(["tar", "czf", version+".tar.gz", version], null, new File(productsPath));
}
function deploy()
{
for (var i = 0; i < options.deployments.length; i++)
{
var dep = options.deployments[i];
exec(["scp", productsPath + "/" + version + ".tar.gz", dep.host + ":~/" + version + ".tar.gz"]);
exec(["ssh", dep.host,
"tar xzf " + version + ".tar.gz; " +
"mkdir -p " + dep.path + "; " +
"mv " + version + "/" + version + "/ " + dep.path + "/" + version + "; " +
"mv " + version + "/index.html " + dep.path + "/index.html; " +
"rm " + version + ".tar.gz; " +
"rmdir " + version + "; " +
"cd " + dep.path + "; " +
"ln -nsf " + version + " Current"]);
}
}
function main()
{
var bakefile = "bakefile",
commandOpts = {};
while (args.length)
{
var arg = args.shift();
switch (arg)
{
case "--base":
commandOpts.base = args.shift();
break;
case "--tag":
commandOpts.tag = true;
break;
case "--archive":
commandOpts.archive = true;
break;
case "--clean":
commandOpts.clean = true;
break;
case "--deploy":
commandOpts.deploy = true;
break;
case "--press":
commandOpts.press = true;
break;
case "--png":
commandOpts.png = true;
break;
case "--host":
commandOpts.deployHost = args.shift();
break;
case "--path":
commandOpts.deployPath = args.shift();
break;
case "--skip-update":
commandOpts.skipUpdate = true
break;
case "--message":
commandOpts.message = args.shift();
break;
default:
bakefile = arg;
}
}
try
{
var configOpts = readConfig(bakefile);
for (var i in configOpts) options[i] = configOpts[i];
for (var i in commandOpts) options[i] = commandOpts[i];
targetPath = pwd() + "/" + bakefile.match(/^[^\.]+/)[0] + ".oven";
mkdirs(targetPath);
checkoutsPath = targetPath + "/Checkouts"
mkdirs(checkoutsPath);
buildsPath = targetPath + "/Build"
mkdirs(buildsPath);
productsPath = targetPath + "/Products"
mkdirs(productsPath);
if (!options.skipUpdate)
{
CPLog.info("Updating");
update();
}
CPLog.info("Building");
build();
if (options.deploy)
{
CPLog.info("Deploying");
deploy();
}
}
catch (e)
{
CPLog.error(e);
}
}
function exec()
{
var runtime = Packages.java.lang.Runtime.getRuntime()
var p = runtime.exec.apply(runtime, arguments);
var stdout = "";
var reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(p.getInputStream()));
while (s = reader.readLine())
{
stdout += s;
CPLog.info("exec: " + s);
}
var stderr = "";
var reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(p.getErrorStream()));
while (s = reader.readLine())
{
stdout += s;
CPLog.warn("exec: " + s);
}
var code = p.waitFor();
return { code : code, stdout : stdout, stderr : stderr };
}
function pwd()
{
return String(new File("").getAbsolutePath());
}
function mkdirs(path)
{
return new File(path).mkdirs();
}
main();