crosswalk-app-tools
Advanced tools
Comparing version 0.7.2 to 0.8.0
@@ -250,2 +250,28 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
/** | ||
* activityClassName | ||
* @member {String} activityClassName Name for main activity java class | ||
* @instance | ||
* @memberOf AndroidManifest | ||
*/ | ||
Object.defineProperty(AndroidManifest.prototype, "activityClassName", { | ||
get: function() { | ||
var doc = this.read(); | ||
var node = this.findApplicationNode(doc); | ||
if (node) { | ||
var activityNode = this.findChildNode(node, "activity"); | ||
if (activityNode) { | ||
var androidName = activityNode.getAttribute("android:name"); | ||
// Remove leading . | ||
return androidName.split(".").pop(); | ||
} else { | ||
this._output.warning("Did not find <activity> element in AndroidManifest.xml"); | ||
} | ||
} else { | ||
this._output.warning("Did not find <application> element in AndroidManifest.xml"); | ||
} | ||
return null; | ||
} | ||
}); | ||
/** | ||
* Read AndroidManifest.xml | ||
@@ -252,0 +278,0 @@ * @returns {xmldom.Document} XML Document |
@@ -13,3 +13,2 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
var AndroidDependencies = require("./AndroidDependencies"); | ||
var AndroidManifest = require("./AndroidManifest"); | ||
@@ -46,2 +45,3 @@ var AndroidSDK = require("./AndroidSDK"); | ||
instance._channel = "stable"; | ||
instance._lite = false; | ||
instance._shared = false; | ||
@@ -67,5 +67,12 @@ instance._apiTarget = null; | ||
create: { | ||
"crosswalk": "\t\t\tChannel name (stable/beta/canary)\n" + | ||
"\t\t\t\t\t\tor version number (w.x.y.z)", | ||
"shared": " Depend on shared crosswalk installation" | ||
"crosswalk": " Channel name (stable/beta/canary)\n" + | ||
"\t\t\t\t\t\tor version number (w.x.y.z)\n" + | ||
"\t\t\t\t\t\tor crosswalk zip\n" + | ||
"\t\t\t\t\t\tor xwalk_app_template dir", | ||
"lite": " Use crosswalk-lite, see Crosswalk Wiki for details", | ||
"shared": " Depend on shared crosswalk installation", | ||
"targets": " Target ABIs to create" | ||
}, | ||
build: { | ||
"targets": " Target ABIs to build" | ||
} | ||
@@ -100,3 +107,4 @@ }; | ||
"ant", | ||
"java" | ||
"java", | ||
"lzma" | ||
]; | ||
@@ -109,8 +117,8 @@ | ||
var path = ShellJS.which(dep); | ||
msg = "Checking for " + dep + "... " + path; | ||
msg = "Checking for " + dep + "..."; | ||
if (path) { | ||
output.info(msg); | ||
output.info(msg, path); | ||
} else { | ||
found = false; | ||
output.error(msg); | ||
output.error(msg + " " + path); | ||
} | ||
@@ -121,8 +129,8 @@ }); | ||
var androidHome = "ANDROID_HOME"; | ||
msg = "Checking for " + androidHome + "... "; | ||
msg = "Checking for " + androidHome + "..."; | ||
if (process.env[androidHome]) { | ||
output.info(msg + process.env[androidHome]); | ||
output.info(msg, process.env[androidHome]); | ||
} else { | ||
found = false; | ||
output.info(msg + "empty"); | ||
output.info(msg + " empty"); | ||
output.error(androidHome + " needs to be set for builds to work"); | ||
@@ -148,3 +156,3 @@ } | ||
var path = Path.join(ShellJS.tempdir(), dir); | ||
output.info("Testing dummy project in " + path); | ||
output.info("Testing dummy project in", path); | ||
@@ -228,7 +236,7 @@ var dummyPackageId = "com.example.foo"; | ||
* @param {String} apiTarget Android API target (greater android-14) | ||
* @param {String} platformPath Path to root dir of project | ||
* @param {String} activityClassName Class ame for the Activity | ||
* @returns {Boolean} True on success. | ||
*/ | ||
AndroidPlatform.prototype.fillTemplates = | ||
function(apiTarget, platformPath) { | ||
function(apiTarget, activityClassName) { | ||
@@ -243,2 +251,3 @@ // Namespace util | ||
"packageName" : this.packageId, | ||
"activityName": this.packageId + "." + activityClassName, | ||
"apiTarget" : apiTarget, | ||
@@ -250,14 +259,14 @@ "xwalkLibrary" : this._shared ? "xwalk_shared_library" : "xwalk_core_library" | ||
var tpl = new util.TemplateFile(Path.join(__dirname, "..", "data", "AndroidManifest.xml.tpl")); | ||
tpl.render(data, platformPath + Path.sep + "AndroidManifest.xml"); | ||
tpl.render(data, this.platformPath + Path.sep + "AndroidManifest.xml"); | ||
// build.xml | ||
tpl = new util.TemplateFile(Path.join(__dirname, "..", "data", "build.xml.tpl")); | ||
tpl.render(data, platformPath + Path.sep + "build.xml"); | ||
tpl.render(data, this.platformPath + Path.sep + "build.xml"); | ||
// project.properties | ||
tpl = new util.TemplateFile(Path.join(__dirname, "..", "data", "project.properties.tpl")); | ||
tpl.render(data, platformPath + Path.sep + "project.properties"); | ||
tpl.render(data, this.platformPath + Path.sep + "project.properties"); | ||
// Make html5 app dir and copy sample content | ||
var wwwPath = Path.join(platformPath, "assets", "www"); | ||
var wwwPath = Path.join(this.platformPath, "assets", "www"); | ||
ShellJS.mkdir("-p", wwwPath); | ||
@@ -272,8 +281,8 @@ ShellJS.cp("-rf", this.appPath + Path.sep + "*", wwwPath); | ||
* Import Crosswalk libraries and auxiliary files into the project. | ||
* @param {String} crosswalkPath Location of unpacked Crosswalk distribution | ||
* @param {String} platformPath Location of project to import Crosswalk into | ||
* @param {String} crosswalkPath Location of Crosswalk zip or xwalk_app_template build dir | ||
* @param {String} activityClassName Class ame for the Activity | ||
* @returns {String} Imported version on success, otherwise null. | ||
*/ | ||
AndroidPlatform.prototype.importCrosswalkFromZip = | ||
function(crosswalkPath, platformPath) { | ||
AndroidPlatform.prototype.importCrosswalkFromDisk = | ||
function(crosswalkPath, activityClassName) { | ||
@@ -285,14 +294,31 @@ // Namespace util | ||
var indicator = output.createFiniteProgress("Extracting " + crosswalkPath); | ||
// " * Extracting /home/robsta/Devel/tmp/crosswalk/crosswalk-15.44.384.12.zip [##########]" | ||
// Windows breaks at > 78. | ||
// Length of decorations/text is 28, so max length of path is 78-28, | ||
// minus nother 3 for ellipsis is 47. | ||
var indicator; | ||
if (crosswalkPath.length > 47) { | ||
var abbrv = crosswalkPath.substring(crosswalkPath.length - 47); | ||
indicator = output.createFiniteProgress("Extracting ..." + abbrv); | ||
} else { | ||
indicator = output.createFiniteProgress("Extracting " + crosswalkPath); | ||
} | ||
// Extract contents | ||
var zip = null; | ||
var xwalk = null; | ||
try { | ||
zip = new util.CrosswalkZip(crosswalkPath); | ||
if (ShellJS.test("-d", crosswalkPath)) { | ||
xwalk = new util.CrosswalkDir(crosswalkPath); | ||
} else { | ||
xwalk = new util.CrosswalkZip(crosswalkPath); | ||
} | ||
} catch (e) { | ||
// HACK we're in the midst of a progress display, force line break | ||
ShellJS.rm("-f", crosswalkPath); | ||
output.write("\n"); | ||
output.error("Failed to open " + crosswalkPath); | ||
output.error("Invalid file has been deleted, please try again"); | ||
output.error("Failed to read " + crosswalkPath); | ||
if (ShellJS.test("-f", crosswalkPath)) { | ||
// Remove incomplete/corrupted zip so next time we start over downloading. | ||
ShellJS.rm("-f", crosswalkPath); | ||
output.error("Invalid file has been deleted, please try again"); | ||
} | ||
return null; | ||
@@ -303,12 +329,12 @@ } | ||
if (zip.version.major < 9) { | ||
output.error("Crosswalk version " + zip.version.major + " not supported. Use 8+."); | ||
if (xwalk.version.major < 9) { | ||
output.error("Crosswalk version " + xwalk.version.major + " not supported. Use 8+."); | ||
return null; | ||
} else if (zip.version.major > 15) { | ||
output.warning("This tool has not been tested with Crosswalk " + zip.version.major + "."); | ||
} else if (xwalk.version.major > 16) { | ||
output.warning("This tool has not been tested with Crosswalk " + xwalk.version.major + "."); | ||
} | ||
var entry = zip.getEntry(zip.root); | ||
var entry = xwalk.getEntry(xwalk.root); | ||
if (!entry) { | ||
output.error("Failed to find root entry " + zip.root); | ||
output.error("Failed to find root entry " + xwalk.root); | ||
return null; | ||
@@ -324,10 +350,8 @@ } | ||
"xwalk_core_library"; | ||
var name = zip.root + xwalkLibrary + "/"; | ||
entry = zip.getEntry(name); | ||
var name = xwalk.root + xwalkLibrary + "/"; | ||
entry = xwalk.getEntry(name); | ||
if (entry) { | ||
path = Path.join(platformPath, xwalkLibrary); | ||
// Remove existing dir to prevent stale files when updating crosswalk | ||
ShellJS.rm("-rf", path); | ||
path = Path.join(this.platformPath, xwalkLibrary); | ||
ShellJS.mkdir(path); | ||
zip.extractEntryTo(entry, path); | ||
xwalk.extractEntryTo(entry, path); | ||
} else { | ||
@@ -349,6 +373,6 @@ output.error("Failed to find entry " + name); | ||
name = zip.root + "template/libs/xwalk_app_runtime_java.jar"; | ||
entry = zip.getEntry(name); | ||
name = xwalk.root + "template/libs/xwalk_app_runtime_java.jar"; | ||
entry = xwalk.getEntry(name); | ||
if (entry) { | ||
zip.extractEntryTo(entry, platformPath + Path.sep + "libs"); | ||
xwalk.extractEntryTo(entry, this.platformPath + Path.sep + "libs"); | ||
} else { | ||
@@ -362,8 +386,8 @@ output.error("Failed to find entry " + name); | ||
// Extract main activity java file | ||
name = zip.root + "template/src/org/xwalk/app/template/AppTemplateActivity.java"; | ||
entry = zip.getEntry(name); | ||
name = xwalk.root + "template/src/org/xwalk/app/template/AppTemplateActivity.java"; | ||
entry = xwalk.getEntry(name); | ||
if (entry) { | ||
// Create path | ||
var activityDirPath = JavaActivity.pathForPackage(platformPath, this.packageId); | ||
var activityDirPath = JavaActivity.pathForPackage(this.platformPath, this.packageId); | ||
ShellJS.mkdir("-p", activityDirPath); | ||
@@ -376,4 +400,4 @@ if (!ShellJS.test("-d", activityDirPath)) { | ||
var activity = new JavaActivity(output, | ||
Path.join(activityDirPath, "MainActivity.java")); | ||
if (!activity.importFromZip(entry, this.packageId)) | ||
Path.join(activityDirPath, activityClassName + ".java")); | ||
if (!activity.importFromZip(entry, this.packageId, activityClassName)) | ||
return null; | ||
@@ -389,6 +413,6 @@ | ||
// Extract res | ||
name = zip.root + "template/res/"; | ||
entry = zip.getEntry(name); | ||
name = xwalk.root + "template/res/"; | ||
entry = xwalk.getEntry(name); | ||
if (entry) { | ||
zip.extractEntryTo(entry, platformPath + Path.sep + "res"); | ||
xwalk.extractEntryTo(entry, this.platformPath + Path.sep + "res"); | ||
} else { | ||
@@ -402,87 +426,39 @@ output.error("Failed to find entry " + name); | ||
return zip.version.toString(); | ||
return xwalk.version.toString(); | ||
}; | ||
/** | ||
* Turn a freshly created empty Android project into a Crosswalk project. | ||
* @param {String} versionSpec Crosswalk version or channel (stable, beta, canary) | ||
* @param {String} platformPath Path to root dir of project | ||
* @param {Function} callback Callback(version, errormsg) | ||
* @returns {Boolean} True on success. | ||
* Implements {@link PlatformBase.create} | ||
*/ | ||
AndroidPlatform.prototype.importCrosswalk = | ||
function(versionSpec, platformPath, callback) { | ||
AndroidPlatform.prototype.create = | ||
function(packageId, args, callback) { | ||
// Namespace util | ||
var util = this.application.util; | ||
var output = this.application.output; | ||
var channel = null; | ||
var version = null; | ||
if (ShellJS.test("-f", versionSpec)) { | ||
// versionSpec is a filename, import directly | ||
var filename = Path.normalize(Path.resolve(versionSpec)); | ||
output.info("Using " + versionSpec); | ||
errormsg = null; | ||
var importedVersion = this.importCrosswalkFromZip(filename, platformPath); | ||
if (!importedVersion) { | ||
errormsg = "Failed to extract " + filename; | ||
} | ||
callback(importedVersion, errormsg); | ||
if (args.lite && args.shared) { | ||
callback("Options \"lite\" and \"shared\" can not be used together"); | ||
return; | ||
} | ||
} else if (AndroidDependencies.CHANNELS.indexOf(versionSpec) > -1) { | ||
// versionSpec is a channel name | ||
channel = versionSpec; | ||
} else { | ||
version = versionSpec; | ||
if (args.lite) { | ||
this._lite = true; | ||
} | ||
// Download | ||
this.findCrosswalkVersion(version, channel, | ||
function(version, channel, errormsg) { | ||
if (args.shared) { | ||
this._shared = true; | ||
} | ||
if (errormsg) { | ||
callback(null, errormsg); | ||
return; | ||
} | ||
output.info("Found version '" + version + "' in channel '" + channel + "'"); | ||
// Download latest Crosswalk | ||
var deps = new AndroidDependencies(this.application, channel); | ||
deps.download(version, ".", | ||
function(filename, errormsg) { | ||
if (errormsg) { | ||
callback(null, errormsg); | ||
// Check that only same-size ABIs are requested. | ||
if (args.targets) { | ||
var wordSize = 0; | ||
args.targets.forEach(function (abi) { | ||
if (wordSize && | ||
wordSize != util.Targets.ABI_WORDSIZE[abi]) { | ||
callback("Projects can only be created for same-size ABIs (" + args.targets.join(",") + ")"); | ||
return; | ||
} | ||
if (!filename) { | ||
callback(null, "Failed to download Crosswalk"); | ||
return; | ||
} | ||
errormsg = null; | ||
var importedVersion = this.importCrosswalkFromZip(filename, platformPath); | ||
if (!importedVersion) { | ||
errormsg = "Failed to extract " + filename; | ||
} | ||
callback(importedVersion, errormsg); | ||
}.bind(this)); | ||
}.bind(this)); | ||
}; | ||
/** | ||
* Implements {@link PlatformBase.create} | ||
*/ | ||
AndroidPlatform.prototype.create = | ||
function(packageId, args, callback) { | ||
var output = this.application.output; | ||
if (args.shared) { | ||
this._shared = true; | ||
wordSize = util.Targets.ABI_WORDSIZE[abi]; | ||
}); | ||
} | ||
@@ -525,3 +501,10 @@ | ||
if (!this.fillTemplates(apiTarget, path)) { | ||
// Activity class name is the last part of the package-id | ||
// starting in caps, plus "Activity". | ||
// E.g. Package com.example.foo will get activity FooActivity. | ||
var activityClassName = this.application.manifest.packageId.split(".").pop(); | ||
activityClassName = activityClassName[0].toUpperCase() + activityClassName.substring(1); | ||
activityClassName += "Activity"; | ||
if (!this.fillTemplates(apiTarget, activityClassName)) { | ||
callback("Failed to initialise project templates"); | ||
@@ -531,3 +514,16 @@ return; | ||
this.importCrosswalk(versionSpec, path, | ||
var deps = new util.Download01Org(this.application, "android", "stable" /* FIXME this is just a placeholder */); | ||
if (this._lite) { | ||
deps.androidFlavor = "crosswalk-lite"; | ||
} | ||
if (args.targets && args.targets.length > 0) { | ||
// We only handle ABIs with same word size in one create() call | ||
// so just check for the first one. | ||
var wordSize = util.Targets.ABI_WORDSIZE[args.targets[0]]; | ||
deps.androidWordSize = wordSize; | ||
} | ||
deps.importCrosswalk(versionSpec, | ||
function(path) { | ||
return this.importCrosswalkFromDisk(path, activityClassName); | ||
}.bind(this), | ||
function(version, errormsg) { | ||
@@ -541,3 +537,3 @@ | ||
output.info("Project template created at '" + path + "'"); | ||
output.info("Project template created at", path); | ||
callback(null); | ||
@@ -550,105 +546,2 @@ }.bind(this)); | ||
/** | ||
* Find a specific version in a specific channel. | ||
* @param {String} version Version to look for, pick lastest if null is given | ||
* @param {String} channel Release channel to seach in, null for all channels | ||
* @param {Function} callback Callback (version, channel, errormsg) | ||
*/ | ||
AndroidPlatform.prototype.findCrosswalkVersion = | ||
function(version, channel, callback) { | ||
// Namespace util | ||
var util = this.application.util; | ||
var versionName = version ? | ||
version : | ||
"latest version"; | ||
// Start with first channel if not given. | ||
if (!channel) { | ||
channel = AndroidDependencies.CHANNELS[0]; | ||
} | ||
this.output.info("Looking for " + versionName + " in channel '" + channel + "'"); | ||
var deps = new AndroidDependencies(this.application, channel); | ||
deps.fetchVersions(function(versions, errormsg) { | ||
if (errormsg) { | ||
callback(null, null, errormsg); | ||
return; | ||
} | ||
// Look for specific version? | ||
if (version && | ||
versions.indexOf(version) > -1) { | ||
callback(version, channel, null); | ||
return; | ||
} else if (version) { | ||
// Try next channel. | ||
var channelIndex = AndroidDependencies.CHANNELS.indexOf(channel); | ||
if (channelIndex < AndroidDependencies.CHANNELS.length - 1) { | ||
this.output.info("Version " + version + " not found in '" + channel + "', trying next channel"); | ||
channelIndex++; | ||
channel = AndroidDependencies.CHANNELS[channelIndex]; | ||
this.findCrosswalkVersion(version, channel, callback); | ||
} else { | ||
// Already at last channel, version not found | ||
this.output.info("Version " + version + " not found in '" + channel + "', search failed"); | ||
callback(null, null, "Version " + version + " seems not to be available on the server"); | ||
return; | ||
} | ||
} else { | ||
// Use latest from current channel. | ||
version = util.IndexParser.pickLatest(versions, function (errmsg) { | ||
errormsg = errmsg; | ||
}); | ||
callback(version, channel, errormsg); | ||
return; | ||
} | ||
}.bind(this)); | ||
}; | ||
/** | ||
* Implements {@link PlatformBase.update} | ||
*/ | ||
AndroidPlatform.prototype.update = | ||
function(versionSpec, args, callback) { | ||
var output = this.application.output; | ||
var sdk = new AndroidSDK(this.application); | ||
sdk.queryTarget(AndroidPlatform.MIN_API_LEVEL, | ||
function(apiTarget, errormsg) { | ||
if (errormsg) { | ||
callback(errormsg); | ||
return; | ||
} | ||
this._apiTarget = apiTarget; | ||
this.importCrosswalk(versionSpec, this.platformPath, | ||
function(version, errormsg) { | ||
if (errormsg) { | ||
output.error(errormsg); | ||
callback("Updating crosswalk to '" + version + "' failed"); | ||
return; | ||
} | ||
output.info("Project updated to crosswalk '" + version + "'"); | ||
callback(null); | ||
}); | ||
}.bind(this)); | ||
}; | ||
AndroidPlatform.prototype.refresh = | ||
function() { | ||
// TODO implement | ||
}; | ||
/** | ||
* Enable ABIs so they are built into the APK. | ||
@@ -772,5 +665,5 @@ * @param {String} [abi] ABI identifier "armeabi-v7a" / "x86". When not passed, | ||
"armeabi-v7a": 2, | ||
// "arm64": 3, TODO check name | ||
"x86": 6 | ||
// "x86_64": 7, TODO check name | ||
"arm64-v8a": 3, | ||
"x86": 6, | ||
"x86_64": 7 | ||
}; | ||
@@ -1097,2 +990,3 @@ var versionNums = appVersion.split("."); | ||
* @param {Function} callback Error callback | ||
* @returns {AndroidManifest} | ||
*/ | ||
@@ -1111,3 +1005,3 @@ AndroidPlatform.prototype.updateManifest = | ||
manifest.package + "/" + this.application.manifest.packageId + ")"); | ||
return; | ||
return null; | ||
} | ||
@@ -1153,2 +1047,4 @@ | ||
manifest.permissions = this.application.manifest.androidPermissions; | ||
return manifest; | ||
}; | ||
@@ -1159,6 +1055,7 @@ | ||
* @param {Boolean} release True if release build, false if debug | ||
* @param {String} activityClassName Class ame for the Activity | ||
* @returns {Boolean} True if successful, otherwise false. | ||
*/ | ||
AndroidPlatform.prototype.updateJavaActivity = | ||
function(release) { | ||
function(release, activityClassName) { | ||
@@ -1173,3 +1070,3 @@ var output = this.application.output; | ||
var dir = JavaActivity.pathForPackage(this.platformPath, this.packageId); | ||
var path = Path.join(dir, "MainActivity.java"); | ||
var path = Path.join(dir, activityClassName + ".java"); | ||
var activity = new JavaActivity(output, path); | ||
@@ -1216,3 +1113,3 @@ | ||
ShellJS.rm("-rf", wwwPath + Path.sep + "*"); | ||
output.info("Copying app to " + wwwPath); | ||
output.info("Copying app to", wwwPath); | ||
ShellJS.cp("-rf", this.appPath + Path.sep + "*", wwwPath); | ||
@@ -1230,3 +1127,3 @@ | ||
var cwebp = ShellJS.which("cwebp"); | ||
output.info("Checking for cwebp ... " + cwebp); | ||
output.info("Checking for cwebp ...", cwebp); | ||
if (!cwebp) { | ||
@@ -1327,2 +1224,33 @@ output.warning("Webp conversion tool not found, install from http://downloads.webmproject.org/releases/webp"); | ||
/** | ||
* Wrapper for ChildProcess.execSync to preserve some support for nodejs 0.10 | ||
* This can probably go away with Fedora 23. | ||
*/ | ||
AndroidPlatform.prototype.execSync = | ||
function(cmd) { | ||
var execSyncImpl; | ||
if (ChildProcess.execSync) { | ||
// Nodejs >= 0.12 | ||
execSyncImpl = ChildProcess.execSync; | ||
} else { | ||
// Try to use npm module. | ||
try { | ||
// Exec-sync does throw even though it works, so let's use this hack, | ||
// it's just for nodejs 0.10 compat anyway. | ||
execSyncImpl = function(cmd) { try { return require("exec-sync")(cmd); } catch (e) {} return null; }; | ||
} catch (e) { | ||
output.error("NPM module 'exec-sync' not found"); | ||
output.error("Please install this package manually when on nodejs < 0.12"); | ||
execSyncImpl = null; | ||
} | ||
} | ||
if (execSyncImpl !== null) { | ||
return execSyncImpl(cmd); | ||
} | ||
return null; | ||
}; | ||
/** | ||
* Import extensions. | ||
@@ -1426,14 +1354,58 @@ * The directory of one external extension should be like: | ||
// Embedded or shared build? | ||
var abis = []; | ||
var libPath = Path.join(this.platformPath, "xwalk_core_library", "libs"); | ||
if (ShellJS.test("-d", Path.join(this.platformPath, "xwalk_shared_library"))) { | ||
this._shared = true; | ||
abis = [ "shared" ]; | ||
} else if (!args.targets || args.targets.length === 0) { | ||
// Build all available ABIs | ||
ShellJS.ls(libPath).forEach(function (lib) { | ||
if (ShellJS.test("-d", Path.join(libPath, lib))) { | ||
abis.push(lib); | ||
} | ||
}.bind(this)); | ||
} else if (args.targets.length > 0) { | ||
// Build specified target ABIs. | ||
args.targets.forEach(function (abi) { | ||
if (ShellJS.test("-d", Path.join(libPath, abi))) { | ||
abis.push(abi); | ||
} else { | ||
output.error("Failed to find libxwalkcore.so for " + abi + ", skipping"); | ||
} | ||
}); | ||
} else { | ||
callback("Failed to determine which ABIs to build"); | ||
return; | ||
} | ||
// Extract lzma libxwalkcore, because we are not supporting | ||
// compressed runtime yet. | ||
abis.forEach(function (abi) { | ||
lzmaLibPath = Path.join(libPath, abi, "libxwalkcore.so.lzma"); | ||
if (ShellJS.test("-f", lzmaLibPath)) { | ||
if (!ShellJS.which("lzma")) { | ||
var message = "the lzma utility is needed for crosswalk-lite"; | ||
output.error(message); | ||
throw new Error(message); | ||
} | ||
output.info("lzma -d ", lzmaLibPath); | ||
this.execSync("lzma -d " + lzmaLibPath); | ||
} | ||
}.bind(this)); | ||
this.updateEngine(); | ||
this.importExtensions(); | ||
this.updateManifest(callback); | ||
this.updateJavaActivity(configId === "release"); | ||
var manifest = this.updateManifest(callback); | ||
if (!manifest) { | ||
// Callback already called from updateManifest | ||
return; | ||
} | ||
this.updateJavaActivity(configId === "release", manifest.activityClassName); | ||
this.updateWebApp(this.application.manifest.androidWebp); | ||
var closure = { | ||
abis: this._shared ? ["shared"] : ["armeabi-v7a", "x86"], // TODO export option | ||
abis: abis, | ||
abiIndex : 0, | ||
@@ -1447,4 +1419,2 @@ release: configId == "release", // TODO verify above | ||
output.highlight(" * Built package(s):"); | ||
for (var i = 0; i < closure.apks.length; i++) { | ||
@@ -1456,7 +1426,7 @@ | ||
output.write(" + " + closure.apks[i] + "\n"); | ||
output.highlight("Package: " + closure.apks[i]); | ||
} | ||
if (configId === "release") { | ||
output.highlight(" Sign APKs before publishing: " + | ||
"https://developer.android.com/tools/publishing/app-signing.html#signing-manually"); | ||
output.highlight("APKs need to be signed before publishing, see"); | ||
output.highlight("https://developer.android.com/tools/publishing/app-signing.html#signing-manually"); | ||
} | ||
@@ -1463,0 +1433,0 @@ } |
@@ -145,7 +145,7 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
// Fail if path exists. | ||
// Warn if path exists, but this is a valid case when building | ||
// 32- and 64-bit ABIs in one go. | ||
if (ShellJS.test("-e", path)) { | ||
errmsg = "Error: project dir '" + path + "' already exists"; | ||
output.error(errmsg); | ||
callback(null, null, errmsg); | ||
output.warning("Project dir '" + path + "' already exists"); | ||
callback(path, null, null); | ||
return; | ||
@@ -192,8 +192,2 @@ } | ||
AndroidSDK.prototype.refreshProject = | ||
function() { | ||
// TODO | ||
}; | ||
/** | ||
@@ -200,0 +194,0 @@ * Build project by running "ant debug" or "ant release". |
@@ -46,6 +46,7 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
* @param {String} packageId Package identifier for the project | ||
* @param {String} activityClassName Class ame for the Activity | ||
* @returns {Boolean} true on success, otherwise false. | ||
*/ | ||
JavaActivity.prototype.importFromZip = | ||
function(zipEntry, packageId) { | ||
function(zipEntry, packageId, activityClassName) { | ||
@@ -76,3 +77,3 @@ var output = this._output; | ||
} | ||
templateData = templateData.replace(templateClass, "MainActivity"); | ||
templateData = templateData.replace(templateClass, activityClassName); | ||
@@ -89,4 +90,2 @@ // Always load app from manifest instead of index.html | ||
// HACK force newline because we're in the midst of a progress indication | ||
output.write("\n"); | ||
output.warning("File already exists: " + this._path); | ||
@@ -93,0 +92,0 @@ |
@@ -11,69 +11,2 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
stableLatest: function(test) { | ||
test.expect(1); | ||
var application = Util.createTmpApplication("com.example.foo"); | ||
var platformData = { | ||
application: application, | ||
platformId: "android" | ||
}; | ||
var android = new AndroidPlatform(PlatformBase, platformData); | ||
android.findCrosswalkVersion(null, "stable", | ||
function(version, channel, errormsg) { | ||
test.equal(typeof version, "string"); | ||
Util.deleteTmpApplication(application); | ||
test.done(); | ||
}); | ||
}, | ||
beta: function(test) { | ||
test.expect(2); | ||
var application = Util.createTmpApplication("com.example.foo"); | ||
var platformData = { | ||
application: application, | ||
platformId: "android" | ||
}; | ||
var android = new AndroidPlatform(PlatformBase, platformData); | ||
var versionSought = "12.41.296.4"; | ||
var channelSought = "beta"; | ||
android.findCrosswalkVersion(versionSought, null, | ||
function(version, channel, errormsg) { | ||
test.equal(version, versionSought); | ||
test.equal(channel, channelSought); | ||
Util.deleteTmpApplication(application); | ||
test.done(); | ||
}); | ||
}, | ||
invalid: function(test) { | ||
test.expect(2); | ||
var application = Util.createTmpApplication("com.example.foo"); | ||
var platformData = { | ||
application: application, | ||
platformId: "android" | ||
}; | ||
var android = new AndroidPlatform(PlatformBase, platformData); | ||
android.findCrosswalkVersion("0.0.0.0", null, | ||
function(version, channel, errormsg) { | ||
test.equal(version, null); | ||
test.equal(channel, null); | ||
Util.deleteTmpApplication(application); | ||
test.done(); | ||
}); | ||
}, | ||
generateVersionCode: function(test) { | ||
@@ -80,0 +13,0 @@ |
@@ -71,3 +71,3 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
var tmpdir = Util.createTmpDir(); | ||
_output.info("Tempdir: " + tmpdir); | ||
_output.info("Tempdir:", tmpdir); | ||
ShellJS.pushd(tmpdir); | ||
@@ -74,0 +74,0 @@ |
@@ -39,5 +39,2 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
bar: "Another option added by the backend" | ||
}, | ||
update: { // Extra options for command "update" | ||
baz: "Another option added by the backend" | ||
} | ||
@@ -61,27 +58,2 @@ }; | ||
/** | ||
* Implements {@link PlatformBase.update} | ||
*/ | ||
DemoPlatform.prototype.update = | ||
function(versionSpec, args, callback) { | ||
// TODO implement updating of project to new Crosswalk version. | ||
// This function is not supported yet. | ||
this.output.log("DemoPlatform: Updating project\n"); | ||
// Null means success, error string means failure. | ||
callback(null); | ||
}; | ||
DemoPlatform.prototype.refresh = | ||
function(callback) { | ||
// TODO implement updating of project to new Crosswalk version. | ||
// Maybe this function will be not needed, and removed in the future. | ||
this.output.log("DemoPlatform: Refreshing project\n"); | ||
// Null means success, error string means failure. | ||
callback(null); | ||
}; | ||
/** | ||
* Implements {@link PlatformBase.build} | ||
@@ -88,0 +60,0 @@ */ |
{ | ||
"name": "crosswalk-app-tools", | ||
"version": "0.7.2", | ||
"version": "0.8.0", | ||
"description": "An APK packager for the Crosswalk Project -- http://crosswalk-project.org", | ||
@@ -5,0 +5,0 @@ "author": "Robert Staudinger <robert.staudinger@intel.com>", |
@@ -37,7 +37,11 @@ Crosswalk-app-tools | ||
<options> | ||
-c --crosswalk=<version-spec>: Runtime version | ||
-h --help: Print usage information | ||
-p --platforms=<android|windows>: Target platform | ||
-r --release=true: Build release packages | ||
-v --version: Print tool version | ||
-a --android=<android-conf> Extra configurations for Android | ||
-c --crosswalk=<version-spec> Specify Crosswalk version or path | ||
-h --help Print usage information | ||
-k --keep Keep build tree for debugging | ||
-m --manifest=<package-id> Fill manifest.json with default values | ||
-p --platforms=<android|windows> Specify target platform | ||
-r --release Build release packages | ||
-t --targets=<target-archs> Target CPU architectures | ||
-v --version Print tool version | ||
@@ -47,6 +51,28 @@ <path> | ||
<android-conf> | ||
Quoted string with extra config, e.g. "shared" | ||
* "shared" Build APK that depends on crosswalk in the Google Play Store | ||
* "lite" Use crosswalk-lite, see Crosswalk Wiki | ||
<package-id> | ||
Canonical application name, e.g. com.example.foo, needs to | ||
* Comprise of 3 or more period-separated parts | ||
* Begin with lowecase letters | ||
<target-archs> | ||
List of CPU architectures for which to create packages. | ||
Currently supported ABIs are: armeabi-v7a, arm64-v8a, x86, x86_64 | ||
* Prefixes will be matched, so "a","ar", or "arm" yield both ARM APKs | ||
* Same for "x" and "x8", but "x86" is an exact match, only x86-32 conforms | ||
* Short-hands "32" and "64" build ARM and x86 for the requested word size | ||
* Default behavior is equivalent to "32", creation of 32-bit installers | ||
Example: --targets="arm x86" builds both ARM plus 32-bit x86 packages | ||
<version-spec> | ||
* Channel name, i.e. "stable". "beta", or "canary" | ||
* Channel name, i.e. stable/beta/canary | ||
* Version number, e.g. 14.43.343.25 | ||
* Path to release, e.g. $HOME/Downloads/crosswalk-14.43.343.25.zip | ||
* Path to build, e.g. crosswalk/src/out/Release/xwalk_app_template | ||
When passing a local file or directory, only the contained ABIs can be built. | ||
See <target-archs> for details. | ||
@@ -53,0 +79,0 @@ Environment variables |
@@ -41,2 +41,6 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
"\n" + | ||
" crosswalk-app manifest <path> Initialize web manifest in <path>\n" + | ||
" --package-id=<package-id> Canonical package name e.g. com.example.foo\n" + | ||
" --platforms=<target> Optional, e.g. \"windows\"\n" + | ||
"\n" + | ||
" crosswalk-app create <package-id> Create project <package-id>\n" + | ||
@@ -49,6 +53,2 @@ " --platforms=<target> Optional, e.g. \"windows\"\n" + | ||
"\n" + | ||
" crosswalk-app update [<version>] [<dir>] Update Crosswalk to latest in named\n" + | ||
" channel, or specific version\n" + | ||
" Version is \"stable\" when not given" + | ||
"\n" + | ||
" crosswalk-app platforms List available target platforms\n" + | ||
@@ -71,17 +71,10 @@ "\n" + | ||
switch (cmd) { | ||
case "check": | ||
return cmd; | ||
case "create": | ||
var packageId = this.createGetPackageId(); | ||
return packageId !== null ? cmd : null; | ||
case "update": | ||
var version = this.updateGetVersion(); | ||
if (!version) { | ||
// Error: version could not be parsed. | ||
return null; | ||
} | ||
return cmd; | ||
case "build": | ||
var type = this.buildGetType(); | ||
return type !== null ? cmd : null; | ||
case "check": | ||
case "manifest": | ||
case "platforms": | ||
@@ -100,3 +93,3 @@ case "help": | ||
* Get primary command. | ||
* @returns {String} One of "create", "update", "refresh", "build" or null. | ||
* @returns {String} Returns command if valid, or null. | ||
*/ | ||
@@ -120,3 +113,3 @@ CommandParser.prototype.peekCommand = | ||
if (["check", "create", "update", "refresh", "build", "platforms"].indexOf(command) > -1) { | ||
if (["check", "manifest", "create", "build", "platforms"].indexOf(command) > -1) { | ||
return command; | ||
@@ -143,2 +136,15 @@ } | ||
/** | ||
* Get path where to initialize manifest. | ||
* @returns {String} Path | ||
*/ | ||
CommandParser.prototype.manifestGetPath = | ||
function() { | ||
// Command goes like this | ||
// node crosswalk-app manifest <path> ... | ||
// So we take the 3rd element. | ||
return this._argv[3]; | ||
}; | ||
/** | ||
* Get package name when command is "create". | ||
@@ -160,26 +166,2 @@ * @returns {String} Package name as per Android conventions or null. | ||
/** | ||
* Get version when command is "update". | ||
* @returns {String} Crosswalk version string when given and valid. Null when not given, false when invalid. | ||
* @see {@link https://crosswalk-project.org/documentation/downloads.html} | ||
*/ | ||
CommandParser.prototype.updateGetVersion = | ||
function() { | ||
// argv is filled like this: | ||
// node crosswalk-app update [version] [dir] | ||
// So argv[3] is either version or dir. | ||
if (this._argv.length < 4) { | ||
return "stable"; | ||
} | ||
var version = this._argv[3]; | ||
if (CommandParser.validateVersion(version, null)) { | ||
return version; | ||
} | ||
return null; | ||
}; | ||
// FIXME require node 0.12 and use Path.isAbsolute | ||
@@ -199,26 +181,2 @@ CommandParser.prototype.isAbsolute = | ||
/** | ||
* Get dir when command is "update". Defaults to current dir. | ||
*/ | ||
CommandParser.prototype.updateGetDir = | ||
function() { | ||
// argv is filled like this: | ||
// node crosswalk-app update [version] [dir] | ||
// Dir can only be specified if version is given, though, | ||
// no guessing around here. | ||
if (this._argv.length < 5) { | ||
// Dir not given. | ||
return process.cwd(); | ||
} | ||
var path = this._argv[4]; | ||
if (this.isAbsolute(path)) { | ||
return Path.resolve(Path.normalize(path)); | ||
} | ||
return Path.resolve(Path.normalize(Path.join(process.cwd(), path))); | ||
}; | ||
/** | ||
* Get build type when command is "build". | ||
@@ -225,0 +183,0 @@ * @returns {String} One of "debug", "release", or null. |
@@ -16,2 +16,3 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
this._active = false; | ||
this._prefix = this._output.prefix; | ||
} | ||
@@ -28,2 +29,5 @@ | ||
return this._active; | ||
}, | ||
set: function(active) { | ||
this._active = active ? true : false; | ||
} | ||
@@ -50,3 +54,3 @@ }); | ||
// Label | ||
this._output.write(" * " + this._label); | ||
this._output.write(this._prefix + this._label); | ||
@@ -74,12 +78,14 @@ // Progress | ||
if (typeof message == "undefined") | ||
message = ""; | ||
if (this._active) { | ||
if (typeof message == "undefined") | ||
message = ""; | ||
// Also prints \r\n so we're ready for the next output. | ||
this._output.write(" " + message + "\n"); | ||
// Also prints \r\n so we're ready for the next output. | ||
this._output.write(" " + message + "\n"); | ||
this._output.endProgress(); | ||
this._active = false; | ||
this._output.endProgress(); | ||
this._active = false; | ||
} | ||
}; | ||
module.exports = FiniteProgress; |
@@ -16,2 +16,3 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
this._active = false; | ||
this._prefix = this._output.prefix; | ||
} | ||
@@ -28,2 +29,5 @@ | ||
return this._active; | ||
}, | ||
set: function(active) { | ||
this._active = active ? true : false; | ||
} | ||
@@ -47,3 +51,3 @@ }); | ||
var line = " * " + this._label + " [" + tag + "...]"; | ||
var line = this._prefix + this._label + " [" + tag + "...]"; | ||
this._output.write(line); | ||
@@ -59,18 +63,20 @@ }; | ||
if (typeof message == "undefined") | ||
message = ""; | ||
if (this._active) { | ||
if (typeof message == "undefined") | ||
message = ""; | ||
// Clear line | ||
this._output.write('\033[2K'); | ||
// Clear line | ||
this._output.write('\033[2K'); | ||
// Go to column 0 | ||
this._output.write('\033[0G'); | ||
// Go to column 0 | ||
this._output.write('\033[0G'); | ||
var line = " * " + this._label + " [done] " + message + "\n"; | ||
this._output.write(line); | ||
var line = this._prefix + this._label + " [done] " + message + "\n"; | ||
this._output.write(line); | ||
this._output.endProgress(); | ||
this._active = false; | ||
this._output.endProgress(); | ||
this._active = false; | ||
} | ||
}; | ||
module.exports = InfiniteProgress; |
@@ -30,3 +30,3 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
/* TODO | ||
/* TODO | ||
if (!this._fp) { | ||
@@ -53,9 +53,14 @@ throw new FileCreationFailed("Could not open file " + path); | ||
FS.appendFileSync(this._path, output); | ||
return output; | ||
return output; | ||
}; | ||
LogfileOutput.prototype.info = | ||
function(message) { | ||
function(message, path) { | ||
var output = " * " + message + "\n"; | ||
var output; | ||
if (path) { | ||
output = " * " + message + " " + path + "\n"; | ||
} else { | ||
output = " * " + message + "\n"; | ||
} | ||
FS.appendFileSync(this._path, output); | ||
@@ -80,4 +85,11 @@ return output; | ||
LogfileOutput.prototype.verbose = | ||
function(message) { | ||
FS.appendFileSync(this._path, message); | ||
return message; | ||
}; | ||
module.exports = LogfileOutput; |
119
src/Main.js
@@ -12,2 +12,3 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
var CommandParser = require("./CommandParser"); | ||
var Manifest = require("./Manifest"); | ||
var PlatformBase = require("./PlatformBase"); | ||
@@ -154,2 +155,60 @@ var PlatformsManager = require("./PlatformsManager"); | ||
/** | ||
* Initialise web manifest. | ||
* @param {String} path Path to dir or manifest.json | ||
* @param {Object} extraArgs Unparsed extra arguments passed by command-line | ||
* @param {OutputIface} output Output to write to | ||
* @param {Main~mainOperationCb} callback Callback function | ||
* @static | ||
*/ | ||
Main.prototype.initManifest = | ||
function(path, extraArgs, output, callback) { | ||
if (ShellJS.test("-d", path)) { | ||
path = Path.join(path, "manifest.json"); | ||
} else if (Path.basename(path) != "manifest.json") { | ||
output.error("Path needs to point to directory or manifest.json: " + path); | ||
callback(Main.EXIT_CODE_ERROR); | ||
return; | ||
} | ||
var packageId = null; | ||
if (extraArgs["package-id"]) { | ||
if (CommandParser.validatePackageId(extraArgs["package-id"], output)) { | ||
packageId = extraArgs["package-id"]; | ||
} else { | ||
callback(Main.EXIT_CODE_ERROR); | ||
return; | ||
} | ||
} else { | ||
output.warning("Using default package-id 'com.example.foo'"); | ||
packageId = "com.example.foo"; | ||
} | ||
Manifest.addDefaults(output, path, packageId); | ||
var manifest = new Manifest(output, path); | ||
if (extraArgs.platforms) { | ||
// FIXME, only single-platform at the moment | ||
var platform = null; | ||
if (extraArgs.platforms instanceof Array && | ||
extraArgs.platforms.length > 0) { | ||
platform = extraArgs.platforms[0]; | ||
} else if (typeof extraArgs.platforms === "string") { | ||
platform = extraArgs.platforms; | ||
} | ||
// Check | ||
if (platform) { | ||
try { | ||
manifest.targetPlatforms = platform; | ||
} catch (e) { | ||
output.error("Invalid target platform '" + platform + "'"); | ||
callback(Main.EXIT_CODE_ERROR); | ||
return; | ||
} | ||
} | ||
} | ||
output.info("Initialized", path); | ||
callback(Main.EXIT_CODE_OK); | ||
}; | ||
/** | ||
* Collect arguments | ||
@@ -193,3 +252,4 @@ */ | ||
platform = extraArgs.platforms; | ||
} else if (extraArgs.platforms instanceof Array) { | ||
} else if (extraArgs.platforms instanceof Array && | ||
extraArgs.platforms.length > 0) { | ||
platform = extraArgs.platforms[0]; | ||
@@ -214,3 +274,3 @@ } | ||
} | ||
output.info("Copying app template from " + templatePath); | ||
output.info("Copying app template from", templatePath); | ||
ShellJS.cp("-r", Path.join(templatePath, "*"), this.appPath); | ||
@@ -235,2 +295,3 @@ | ||
output.error(errormsg); | ||
// Print full path here, because we want to copy/paste it. | ||
output.info("Logfiles at " + this.logPath); | ||
@@ -247,41 +308,2 @@ callback(Main.EXIT_CODE_ERROR); | ||
/** | ||
* Update crosswalk in the application package. | ||
* @param {String} version Version to update to, or null for latest stable version | ||
* @param {Object} extraArgs Unparsed extra arguments passed by command-line | ||
* @param {Main~mainOperationCb} callback Callback function | ||
* @static | ||
*/ | ||
Main.prototype.update = | ||
function(version, extraArgs, callback) { | ||
var output = this.output; | ||
var project = this.instantiatePlatform(); | ||
if (!project) { | ||
callback(Main.EXIT_CODE_ERROR); | ||
return; | ||
} | ||
// Collect args for this command | ||
var updateArgs = {}; | ||
var argSpec = project.argSpec; | ||
if (argSpec && argSpec.update) { | ||
updateArgs = this.collectArgs(project.platformId, extraArgs, argSpec.update); | ||
} | ||
project.update(version, updateArgs, function(errormsg) { | ||
if (errormsg) { | ||
output.error(errormsg); | ||
output.info("Logfiles at " + this.logPath); | ||
callback(Main.EXIT_CODE_ERROR); | ||
return; | ||
} else { | ||
callback(Main.EXIT_CODE_OK); | ||
return; | ||
} | ||
}.bind(this)); | ||
}; | ||
/** | ||
* Build application package. | ||
@@ -325,2 +347,3 @@ * @param {String} configId Build "debug" or "release" configuration | ||
output.error(errormsg); | ||
// Print full path here, because we want to copy/paste it. | ||
output.info("Logfiles at " + this.logPath); | ||
@@ -445,2 +468,7 @@ callback(Main.EXIT_CODE_ERROR); | ||
case "manifest": | ||
var path = parser.manifestGetPath(); | ||
app.initManifest(path, extraArgs, output, callback); | ||
break; | ||
case "create": | ||
@@ -454,11 +482,2 @@ var packageId = parser.createGetPackageId(); | ||
case "update": | ||
var version = parser.updateGetVersion(); | ||
rootDir = parser.updateGetDir(); | ||
// Chain up the constructor. | ||
Application.call(app, rootDir, null); | ||
app.update(version, extraArgs, callback); | ||
break; | ||
case "build": | ||
@@ -465,0 +484,0 @@ var type = parser.buildGetType(); |
@@ -89,3 +89,3 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
} else { | ||
output.warning("Unsupported value '" + json.display + "' in manifest.json"); | ||
output.warning("Unsupported value '" + json.display + "' for 'display' in manifest.json"); | ||
} | ||
@@ -111,3 +111,3 @@ } | ||
} else { | ||
output.warning("Unsupported value '" + json.orientation + "' in manifest.json"); | ||
output.warning("Unsupported value '" + json.orientation + "' for 'orientation' in manifest.json"); | ||
} | ||
@@ -357,4 +357,3 @@ } | ||
} else { | ||
output.warning("File not found " + path); | ||
output.warning("Using default manifest.json"); | ||
output.warning("File does not exist, creating default manifest.json"); | ||
} | ||
@@ -370,2 +369,5 @@ | ||
// Always overwrite xwalk_package_id | ||
json.xwalk_package_id = packageId; | ||
// Write back | ||
@@ -372,0 +374,0 @@ buffer = FormatJson.plain(json); |
@@ -43,5 +43,6 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
* @param {String} message | ||
* @param {String} [path] | ||
*/ | ||
OutputIface.prototype.info = | ||
function(message) { | ||
function(message, path) { | ||
@@ -75,4 +76,14 @@ throw new Error("OutputIface.info() not implemented."); | ||
/** | ||
* Extra message, only to logfile by default. | ||
* @param {String} message | ||
*/ | ||
OutputIface.prototype.verbose = | ||
function(message) { | ||
throw new Error("OutputIface.verbose() not implemented."); | ||
}; | ||
module.exports = OutputIface; |
@@ -77,7 +77,7 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
OutputTee.prototype.info = | ||
function(message) { | ||
function(message, path) { | ||
this._outputs.forEach(function(output) { | ||
if (output) | ||
output.info(message); | ||
output.info(message, path); | ||
}); | ||
@@ -106,2 +106,12 @@ }; | ||
// Implementation of OutputIface.verbose | ||
OutputTee.prototype.verbose = | ||
function(message) { | ||
this._outputs.forEach(function(output) { | ||
if (output) | ||
output.verbose(message); | ||
}); | ||
}; | ||
// TODO implement for logfile output also. | ||
@@ -108,0 +118,0 @@ OutputTee.prototype.createFiniteProgress = |
@@ -213,23 +213,2 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
/** | ||
* Update platform project to latest Crosswalk. | ||
* @param {String} versionSpec Channel name or version to update to, format w.x.y.z | ||
* @param {Object} args Extra options for the command | ||
* @param {PlatformBase~platformBaseOperationCb} callback callback function | ||
*/ | ||
PlatformBase.prototype.update = | ||
function(versionSpec, args, callback) { | ||
throw new Error("PlatformBase.update() not implemented."); | ||
}; | ||
/** | ||
* Refresh platform project after environment changes. | ||
*/ | ||
PlatformBase.prototype.refresh = | ||
function() { | ||
throw new Error("PlatformBase.refresh() not implemented."); | ||
}; | ||
/** | ||
* Build application package. | ||
@@ -236,0 +215,0 @@ * @param {String} release Configuration identifier for the build |
@@ -32,2 +32,14 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
/** | ||
* Prefix marker for console output lines. | ||
* @member {String} prefix | ||
* @instance | ||
* @memberOf TerminalOutput | ||
*/ | ||
Object.defineProperty(TerminalOutput.prototype, "prefix", { | ||
get: function() { | ||
return " + "; | ||
} | ||
}); | ||
TerminalOutput.prototype.error = | ||
@@ -40,4 +52,6 @@ function(message) { | ||
console.log(""); | ||
this._progress.isActive = false; | ||
} | ||
console.error("*** ERROR: " + message); | ||
// Output in red. | ||
console.error('\x1B[31m' + "*** ERROR: " + message + '\033[0m'); | ||
} | ||
@@ -53,4 +67,6 @@ }; | ||
console.log(""); | ||
this._progress.isActive = false; | ||
} | ||
console.error(" ** WARNING: " + message); | ||
// Output in dark grey so it stands out from the other text. | ||
console.error('\x1B[90m' + " ** WARNING: " + message + '\033[0m'); | ||
} | ||
@@ -60,10 +76,30 @@ }; | ||
TerminalOutput.prototype.info = | ||
function(message) { | ||
function(message, path) { | ||
if (!_config.getSilentConsole()) { | ||
if (this._progress && | ||
this._progress.isActive) { | ||
console.log(""); | ||
this._progress.isActive = false; | ||
} | ||
console.log(" * " + message); | ||
var output; | ||
if (message.length > 75 && path) { | ||
// Overflow, no point in abbreviating | ||
output = this.prefix + message + " " + path; | ||
} | ||
else if (path) { | ||
output = this.prefix + message + " " + path; | ||
// Windows only takes 78 chars before breaking, although 80 wide. | ||
if (output.length > 78) { | ||
var remain = 78 - (this.prefix + message + " ...").length; | ||
var pathAbbrv = path.substring(path.length - remain); | ||
output = this.prefix + message + " ..." + pathAbbrv; | ||
} | ||
} else { | ||
output = this.prefix + message; | ||
} | ||
console.log(output); | ||
} | ||
@@ -79,4 +115,5 @@ }; | ||
console.log(""); | ||
this._progress.isActive = false; | ||
} | ||
console.log('\033[1m' + message + '\033[0m'); | ||
console.log('\033[1m ' + message + '\033[0m'); | ||
} | ||
@@ -93,2 +130,10 @@ }; | ||
TerminalOutput.prototype.verbose = | ||
function(message) { | ||
// Not printed by default. | ||
// FIXME maybe make this configurable | ||
// through verbosity or something. | ||
}; | ||
/** | ||
@@ -95,0 +140,0 @@ * Create progress indicator. |
@@ -10,92 +10,7 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
var Version = require("./Version"); | ||
/** | ||
* Representation of a four part Crosswalk version number. | ||
* @param {Number} major | ||
* @param {Number} minor | ||
* @param {Number} micro | ||
* @param {Number} build | ||
* @constructor | ||
* @memberOf CrosswalkZip | ||
* @inner | ||
*/ | ||
function Version(major, minor, micro, build) { | ||
if (typeof major === "number" && major % 1 === 0) | ||
this._major = major; | ||
else | ||
throw new Error("Invalid major version number '" + major + "'"); | ||
if (typeof minor === "number" && minor % 1 === 0) | ||
this._minor = minor; | ||
else | ||
throw new Error("Invalid minor version number '" + minor + "'"); | ||
if (typeof micro === "number" && micro % 1 === 0) | ||
this._micro = micro; | ||
else | ||
throw new Error("Invalid micro version number '" + micro + "'"); | ||
if (typeof build === "number" && build % 1 === 0) | ||
this._build = build; | ||
else | ||
throw new Error("Invalid build version number '" + build + "'"); | ||
} | ||
/** | ||
* Major version. | ||
* @member {Number} major | ||
* @instance | ||
* @memberOf Version | ||
*/ | ||
Object.defineProperty(Version.prototype, "major", { | ||
get: function() { | ||
return this._major; | ||
} | ||
}); | ||
/** | ||
* Minor version. | ||
* @member {Number} minor | ||
* @instance | ||
* @memberOf Version | ||
*/ | ||
Object.defineProperty(Version.prototype, "minor", { | ||
get: function() { | ||
return this._minor; | ||
} | ||
}); | ||
/** | ||
* Micro version. | ||
* @member {Number} micro | ||
* @instance | ||
* @memberOf Version | ||
*/ | ||
Object.defineProperty(Version.prototype, "micro", { | ||
get: function() { | ||
return this._micro; | ||
} | ||
}); | ||
/** | ||
* Build version. | ||
* @member {Number} build | ||
* @instance | ||
* @memberOf Version | ||
*/ | ||
Object.defineProperty(Version.prototype, "build", { | ||
get: function() { | ||
return this._build; | ||
} | ||
}); | ||
Version.prototype.toString = | ||
function() { | ||
return this.major + "." + this.minor + "." + this.micro + "." + this.build; | ||
}; | ||
/** | ||
* Creates a CrosswalkZip object. | ||
@@ -102,0 +17,0 @@ * @param {String} path Path to downloaded release |
@@ -125,2 +125,6 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
if (res.statusCode != 200) { | ||
this._stream.end(); | ||
this._stream = null; | ||
this._url = null; | ||
res.req.abort(); | ||
callback("Download failed: HTTP Status " + res.statusCode); | ||
@@ -127,0 +131,0 @@ return; |
@@ -10,5 +10,9 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
/** {@link CrosswalkZip} */ | ||
CrosswalkDir: require("./CrosswalkDir"), | ||
/** {@link CrosswalkZip} */ | ||
CrosswalkZip: require("./CrosswalkZip"), | ||
/** {@link Downloader} */ | ||
Downloader: require("./Downloader"), | ||
/** {@link Download01Org} */ | ||
Download01Org: require("./Download01Org"), | ||
/** {@link DownloadHandler} */ | ||
@@ -18,4 +22,8 @@ DownloadHandler: require("./DownloadHandler"), | ||
IndexParser: require("./IndexParser"), | ||
/** {@link Targets} */ | ||
Targets: require("./Targets"), | ||
/** {@link TemplateFile} */ | ||
TemplateFile: require("./TemplateFile"), | ||
/** {@link Version} */ | ||
Version: require("./Version"), | ||
@@ -22,0 +30,0 @@ /** |
@@ -20,14 +20,2 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
TestPlatform.prototype.update = | ||
function(versionSpec, args, callback) { | ||
// Null means success, error string means failure. | ||
callback(null); | ||
}; | ||
TestPlatform.prototype.refresh = | ||
function(callback) { | ||
// Null means success, error string means failure. | ||
callback(null); | ||
}; | ||
TestPlatform.prototype.build = | ||
@@ -47,5 +35,2 @@ function(configId, args, callback) { | ||
bar: "Another create option added by the platform" | ||
}, | ||
update: { // Extra options for command "update" | ||
baz: "Update option added by the platform" | ||
} | ||
@@ -52,0 +37,0 @@ }; |
@@ -36,5 +36,5 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
test.expect(8); | ||
test.expect(6); | ||
var commands = ["create", "update", "refresh", "build", "help", "version"]; | ||
var commands = ["create", "build", "help", "version"]; | ||
var argv = ["foo", "bar"]; | ||
@@ -120,79 +120,2 @@ var cp1; | ||
updateGetVersion: function(test) { | ||
test.expect(8); | ||
// No version, good test, default to "stable" | ||
var argv0 = ["node", "foo", "update"]; | ||
var cp0 = new CommandParser(_output, argv0); | ||
test.equal(cp0.getCommand(), "update"); | ||
var cmd0 = cp0.getCommand(); | ||
test.equal(cmd0, argv0[2]); | ||
var version0 = cp0.updateGetVersion(); | ||
test.equal(version0, "stable"); | ||
// Good test | ||
var argv1 = ["node", "foo", "update", "12.34.56.78"]; | ||
var cp1 = new CommandParser(_output, argv1); | ||
test.equal(cp1.getCommand(), "update"); | ||
var cmd1 = cp1.getCommand(); | ||
test.equal(cmd1, argv1[2]); | ||
var version1 = cp1.updateGetVersion(); | ||
test.equal(version1, argv1[3]); | ||
// Bad test, invalid version | ||
var argv2 = ["node", "foo", "update", "12.34.x6.78"]; | ||
var cp2 = new CommandParser(_output, argv2); | ||
test.equal(cp2.getCommand(), null); | ||
var version2 = cp2.updateGetVersion(); | ||
test.equal(version2, null); | ||
test.done(); | ||
}, | ||
updateGetDir: function(test) { | ||
test.expect(8); | ||
// build inside project | ||
var argv0 = ["node", "foo", "update"]; | ||
var cp0 = new CommandParser(_output, argv0); | ||
test.equal(cp0.getCommand(), "update"); | ||
var cmd0 = cp0.getCommand(); | ||
test.equal(cmd0, argv0[2]); | ||
var version0 = cp0.updateGetVersion(); | ||
test.equal(version0, "stable"); | ||
var dir0 = cp0.updateGetDir(); | ||
test.equal(dir0, process.cwd()); | ||
// command-line with dir specified | ||
var argv1 = ["node", "foo", "update", "beta", "com.example.foo"]; | ||
var cp1 = new CommandParser(_output, argv1); | ||
test.equal(cp1.getCommand(), "update"); | ||
var cmd1 = cp1.getCommand(); | ||
test.equal(cmd1, argv1[2]); | ||
var version1 = cp1.updateGetVersion(); | ||
test.equal(version1, argv1[3]); | ||
var dir1 = cp1.updateGetDir(); | ||
test.equal(dir1, Path.join(process.cwd(), argv1[4])); | ||
test.done(); | ||
}, | ||
buildGetType: function(test) { | ||
@@ -199,0 +122,0 @@ |
@@ -47,3 +47,3 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
var tmpfile = Util.createTmpFile(); | ||
_output.info("Tempfile: " + tmpfile); | ||
_output.info("Tempfile:", tmpfile); | ||
ShellJS.rm(tmpfile); | ||
@@ -50,0 +50,0 @@ |
@@ -20,13 +20,13 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
function testMethod(func, message) { | ||
// Setup | ||
var tmpfile = Util.createTmpFile(); | ||
var log = new LogfileOutput(tmpfile); | ||
// Test | ||
var output = func.call(log, message); | ||
// Read back results to check | ||
var input = FS.readFileSync(tmpfile, {"encoding": "utf8"}); | ||
ShellJS.rm("-f", tmpfile); | ||
@@ -42,3 +42,3 @@ | ||
error: function(test) { | ||
test.expect(1); | ||
@@ -51,3 +51,3 @@ var ret = testMethod(LogfileOutput.prototype.error, "error message"); | ||
warning: function(test) { | ||
test.expect(1); | ||
@@ -60,3 +60,3 @@ var ret = testMethod(LogfileOutput.prototype.warning, "warning message"); | ||
info: function(test) { | ||
test.expect(1); | ||
@@ -67,5 +67,25 @@ var ret = testMethod(LogfileOutput.prototype.info, "info message"); | ||
}, | ||
info2: function(test) { | ||
test.expect(1); | ||
// Setup | ||
var tmpfile = Util.createTmpFile(); | ||
var log = new LogfileOutput(tmpfile); | ||
// Test | ||
var output = log.info("info message", "path"); | ||
// Read back results to check | ||
var input = FS.readFileSync(tmpfile, {"encoding": "utf8"}); | ||
ShellJS.rm("-f", tmpfile); | ||
test.equal(input, output); | ||
test.done(); | ||
}, | ||
highlight: function(test) { | ||
test.expect(1); | ||
@@ -77,9 +97,17 @@ var ret = testMethod(LogfileOutput.prototype.highlight, "highlight message"); | ||
print: function(test) { | ||
write: function(test) { | ||
test.expect(1); | ||
var ret = testMethod(LogfileOutput.prototype.write, "print message"); | ||
var ret = testMethod(LogfileOutput.prototype.write, "write message"); | ||
test.equal(ret, true); | ||
test.done(); | ||
}, | ||
verbose: function(test) { | ||
test.expect(1); | ||
var ret = testMethod(LogfileOutput.prototype.verbose, "verbose message"); | ||
test.equal(ret, true); | ||
test.done(); | ||
} | ||
}; |
@@ -128,46 +128,2 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
update: function(test) { | ||
test.expect(1); | ||
// Good test. | ||
var tmpdir = Util.createTmpDir(); | ||
ShellJS.pushd(tmpdir); | ||
var app = require("../src/Main"); | ||
Application.call(app, tmpdir, _packageId); | ||
// Create | ||
app.create(_packageId, {}, function(errno) { | ||
if (!errno) { | ||
// Update | ||
ShellJS.pushd(_packageId); | ||
app.update("stable", null, function(errno) { | ||
if (!errno) { | ||
// Build | ||
app.build("debug", null, function(errno) { | ||
test.equal(errno, 0); | ||
ShellJS.popd(); | ||
ShellJS.popd(); | ||
ShellJS.rm("-rf", tmpdir); | ||
test.done(); | ||
}); | ||
} else { | ||
ShellJS.popd(); | ||
ShellJS.popd(); | ||
ShellJS.rm("-rf", tmpdir); | ||
test.done(); | ||
} | ||
}); | ||
} else { | ||
ShellJS.popd(); | ||
ShellJS.popd(); | ||
ShellJS.rm("-rf", tmpdir); | ||
test.done(); | ||
} | ||
}); | ||
}, | ||
listPlatforms: function(test) { | ||
@@ -174,0 +130,0 @@ |
@@ -96,3 +96,11 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
test.done(); | ||
}, | ||
verbose: function(test) { | ||
test.expect(1); | ||
var ret = testFunction(OutputTee.prototype.verbose); | ||
test.equal(ret, true); | ||
test.done(); | ||
} | ||
}; |
@@ -60,3 +60,3 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
test.expect(4); | ||
test.expect(2); | ||
@@ -76,10 +76,2 @@ var basePath = Util.createTmpDir(); | ||
platform.update(null, null, function(errormsg) { | ||
test.equal(errormsg, null); | ||
}); | ||
platform.refresh(function(errormsg) { | ||
test.equal(errormsg, null); | ||
}); | ||
platform.build("debug", null, function(errormsg) { | ||
@@ -86,0 +78,0 @@ test.equal(errormsg, null); |
@@ -17,3 +17,3 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
test.expect(3); | ||
test.expect(2); | ||
@@ -26,5 +26,2 @@ var platformInfo = new PlatformInfo(TestPlatform, "test"); | ||
var updateArgs = platformInfo.argSpec.update; | ||
test.equal(typeof updateArgs["--test-baz"], "string"); | ||
test.done(); | ||
@@ -31,0 +28,0 @@ }, |
@@ -42,3 +42,3 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
var tmpfile = Util.createTmpFile(); | ||
_output.info("Tempfile: " + tmpfile); | ||
_output.info("Tempfile:", tmpfile); | ||
@@ -45,0 +45,0 @@ tpl.render({bar: "maman"}, tmpfile); |
@@ -44,5 +44,2 @@ // Copyright © 2014 Intel Corporation. All rights reserved. | ||
crosswalk: "\t\t\tPath to crosswalk zip" | ||
}, | ||
update: { // Extra options for command "update" | ||
crosswalk: "\t\t\tPath to crosswalk zip" | ||
} | ||
@@ -71,8 +68,8 @@ }; | ||
var path = ShellJS.which(dep); | ||
var msg = "Checking for " + dep + "... " + path; | ||
var msg = "Checking for " + dep + "..."; | ||
if (path) { | ||
output.info(msg); | ||
output.info(msg, path); | ||
} else { | ||
found = false; | ||
output.error(msg); | ||
output.error(msg + " " + path); | ||
} | ||
@@ -87,6 +84,6 @@ }); | ||
* @param {String} crosswalkPath Location of unpacked Crosswalk distribution | ||
* @returns {String} Imported version on success, otherwise null. | ||
* @returns {Boolean} True on success. | ||
*/ | ||
WinPlatform.prototype.importCrosswalkFromZip = | ||
function(crosswalkPath, callback) { | ||
WinPlatform.prototype.importCrosswalkFromDisk = | ||
function(crosswalkPath) { | ||
@@ -98,17 +95,22 @@ // Namespace util | ||
if (!crosswalkPath) { | ||
callback("Use --windows-crosswalk=<path> to pass crosswalk zip"); | ||
return; | ||
} else if (!ShellJS.test("-f", crosswalkPath)) { | ||
callback("Crosswalk zip could not be found: " + crosswalkPath); | ||
return; | ||
output.error("Use --windows-crosswalk=<path> to pass crosswalk zip"); | ||
return false; | ||
} else if (!ShellJS.test("-e", crosswalkPath)) { | ||
output.error("Crosswalk zip could not be found: " + crosswalkPath); | ||
return false; | ||
} | ||
var zip = new util.CrosswalkZip(crosswalkPath); | ||
zip.extractEntryTo(zip.root, this.platformPath); | ||
if (!ShellJS.test("-d", this.platformPath)) { | ||
callback("Failed to extract " + crosswalkPath); | ||
return; | ||
var version = null; | ||
if (ShellJS.test("-d", crosswalkPath)) { | ||
ShellJS.mkdir(this.platformPath); | ||
ShellJS.cp(Path.join(crosswalkPath, "*"), this.platformPath); | ||
version = util.Version.createFromPath(crosswalkPath); | ||
} else { | ||
var xwalk = new util.CrosswalkZip(crosswalkPath); | ||
var entry = xwalk.getEntry(xwalk.root); | ||
xwalk.extractEntryTo(entry, this.platformPath); | ||
version = xwalk.version; | ||
} | ||
callback(null); | ||
return version.toString(); | ||
}; | ||
@@ -122,55 +124,33 @@ | ||
// Namespace util | ||
var util = this.application.util; | ||
var output = this.output; | ||
var crosswalkPath = args.crosswalk; | ||
this.importCrosswalkFromZip(crosswalkPath, | ||
function (errormsg) { | ||
var versionSpec = null; | ||
if (args.crosswalk) { | ||
// TODO verify version/channel | ||
versionSpec = args.crosswalk; | ||
} else { | ||
versionSpec = "stable"; | ||
output.info("Defaulting to download channel " + versionSpec); | ||
} | ||
if (!errormsg) { | ||
output.info("Successfully imported " + crosswalkPath); | ||
} | ||
callback(errormsg); | ||
}.bind(this)); | ||
}; | ||
var deps = new util.Download01Org(this.application, "windows", "stable" /* FIXME this is just a placeholder */); | ||
deps.importCrosswalk(versionSpec, | ||
function(path) { | ||
return this.importCrosswalkFromDisk(path); | ||
}.bind(this), | ||
function(version, errormsg) { | ||
/** | ||
* Implements {@link PlatformBase.update} | ||
*/ | ||
WinPlatform.prototype.update = | ||
function(versionSpec, args, callback) { | ||
var output = this.output; | ||
// Rename current dir for backup. | ||
var oldPath = this.platformPath + ".bak"; | ||
ShellJS.mv(this.platformPath, oldPath); | ||
var crosswalkPath = args.crosswalk; | ||
this.importCrosswalkFromZip(crosswalkPath, | ||
function (errormsg) { | ||
if (errormsg) { | ||
// Restore previous project | ||
ShellJS.rm("-rf", this.platformPath); | ||
ShellJS.mv(oldPath, this.platformPath); | ||
} else { | ||
// Delete old project | ||
ShellJS.rm("-rf", oldPath); | ||
output.info("Successfully imported " + crosswalkPath); | ||
output.error(errormsg); | ||
callback("Creating project template failed"); | ||
return; | ||
} | ||
callback(errormsg); | ||
output.info("Project template created at", this.platformPath); | ||
callback(null); | ||
}.bind(this)); | ||
}; | ||
WinPlatform.prototype.refresh = | ||
function(callback) { | ||
// TODO implement updating of project to new Crosswalk version. | ||
// Maybe this function will be not needed, and removed in the future. | ||
this.output.log("WinPlatform: TODO Refreshing project\n"); | ||
// Null means success, error string means failure. | ||
callback(null); | ||
}; | ||
/** | ||
@@ -285,5 +265,3 @@ * Pick windows icon (.ico) from web manifest. | ||
indicator.done(); | ||
// TODO rename so they include version number | ||
output.highlight(" * Built package(s):"); | ||
output.highlight(" + " + metaData.msi); | ||
output.highlight("Package: " + metaData.msi); | ||
callback(null); | ||
@@ -290,0 +268,0 @@ } else { |
@@ -175,5 +175,7 @@ | ||
AddFileComponent(app_root_folder, xwalk_path, 'icudtl.dat'); | ||
AddFileComponent(app_root_folder, xwalk_path, 'ffmpegsumo.dll'); | ||
AddFileComponent(app_root_folder, xwalk_path, 'natives_blob.bin'); | ||
AddFileComponent(app_root_folder, xwalk_path, 'snapshot_blob.bin'); | ||
AddFileComponent(app_root_folder, xwalk_path, 'libEGL.dll'); | ||
AddFileComponent(app_root_folder, xwalk_path, 'libGLESv2.dll'); | ||
AddFileComponent(app_root_folder, xwalk_path, 'osmesa.dll'); | ||
@@ -180,0 +182,0 @@ var subfolder_map = {}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 2 instances in 1 package
429591
84
9
8745
125
36