Return-Path: X-Original-To: apmail-cordova-commits-archive@www.apache.org Delivered-To: apmail-cordova-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 70AB111FCB for ; Mon, 7 Jul 2014 21:43:14 +0000 (UTC) Received: (qmail 2643 invoked by uid 500); 7 Jul 2014 21:43:10 -0000 Delivered-To: apmail-cordova-commits-archive@cordova.apache.org Received: (qmail 2602 invoked by uid 500); 7 Jul 2014 21:43:09 -0000 Mailing-List: contact commits-help@cordova.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cordova.apache.org Delivered-To: mailing list commits@cordova.apache.org Received: (qmail 1933 invoked by uid 99); 7 Jul 2014 21:43:09 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 07 Jul 2014 21:43:09 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 3ACA99450C7; Mon, 7 Jul 2014 21:43:09 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jsoref@apache.org To: commits@cordova.apache.org Date: Mon, 07 Jul 2014 21:43:55 -0000 Message-Id: <197659fc029441fa97c164fe3de2b0c3@git.apache.org> In-Reply-To: <90290168f34748328779c7a0f2a32bd1@git.apache.org> References: <90290168f34748328779c7a0f2a32bd1@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [49/51] [partial] CB-7087 Retire blackberry10/ directory http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/bar-builder.js ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/bar-builder.js b/bin/templates/project/cordova/lib/bar-builder.js new file mode 100644 index 0000000..cfd029a --- /dev/null +++ b/bin/templates/project/cordova/lib/bar-builder.js @@ -0,0 +1,103 @@ +/* + * Copyright 2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var jWorkflow = require("jWorkflow"), + wrench = require("wrench"), + nativePkgr = require("./native-packager"), + fileManager = require("./file-manager"), + localize = require("./localize"), + logger = require("./logger"), + signingHelper = require("./signing-helper"), + targetIdx = 0; + +function buildTarget(previous, baton) { + baton.take(); + + var target = this.session.targets[targetIdx++], + session = this.session, + config = this.config; + + //Create output folder + wrench.mkdirSyncRecursive(session.outputDir + "/" + target); + + //Copy resources (could be lost if copying assets from other project) + fileManager.copyNative(this.session, target); + //Generate user config here to overwrite default + fileManager.generateUserConfig(session, config); + + if (config.packageCordovaJs) { + //Package cordova.js to chrome folder + fileManager.copyWebworks(this.session); + } + + //Generate frameworkModules.js (this needs to be done AFTER all files have been copied) + fileManager.generateFrameworkModulesJS(session); + + //Call native-packager module for target + nativePkgr.exec(session, target, config, function (code) { + if (code !== 0) { + logger.error(localize.translate("EXCEPTION_NATIVEPACKAGER")); + baton.pass(code); + } else { + if (target === "device" && session.isSigningRequired(config)) { + signingHelper.execSigner(session, target, function (error) { + if (error && error.code) { + baton.pass(error.code); + } else { + //Pass 0 to signify success + baton.pass(0); + } + }); + } else { + baton.pass(code); + } + } + }); +} + +function buildWorkflow(session, context) { + if (session.targets && session.targets.length > 0) { + var order; + + session.targets.forEach(function (target, idx) { + if (idx === 0) { + order = jWorkflow.order(buildTarget, context); + } else { + order = order.andThen(buildTarget, context); + } + }); + + return order; + } else { + logger.debug("NOTHING TO BUILD, NO TARGETS"); + } +} + +module.exports = { + build: function (session, config, callback) { + var context = { + session: session, + config: config + }, + workflow = buildWorkflow(session, context); + + if (workflow) { + workflow.start({ + "callback": callback + }); + } + } +}; http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/bar-conf.js ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/bar-conf.js b/bin/templates/project/cordova/lib/bar-conf.js new file mode 100644 index 0000000..857875b --- /dev/null +++ b/bin/templates/project/cordova/lib/bar-conf.js @@ -0,0 +1,27 @@ +/* + * Copyright 2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var self = {}; + +self.ROOT = ""; +self.CHROME = self.ROOT + "/chrome"; +self.LIB = self.CHROME + "/lib"; +self.EXT = self.CHROME + "/plugin"; +self.UI = self.ROOT + "/ui-resources"; +self.PLUGINS = self.ROOT + "/plugins"; +self.JNEXT_PLUGINS = self.ROOT + "/plugins/jnext"; + +module.exports = self; http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/bb10-ndk-version.js ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/bb10-ndk-version.js b/bin/templates/project/cordova/lib/bb10-ndk-version.js new file mode 100755 index 0000000..760ae70 --- /dev/null +++ b/bin/templates/project/cordova/lib/bb10-ndk-version.js @@ -0,0 +1,29 @@ +#!/usr/bin/env node + +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +var bbtools = process.env.CORDOVA_BBTOOLS, + reg = /host_\d+_\d+/g, + results; + +if (reg.test(bbtools)) { + results = bbtools.match(reg); + console.log(results[0].split('host_')[1].replace('_', '.')); +} else { + return new Error('Unable to find the blackberry ndk on your path.'); +} http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/bbwpignore.js ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/bbwpignore.js b/bin/templates/project/cordova/lib/bbwpignore.js new file mode 100755 index 0000000..29c6399 --- /dev/null +++ b/bin/templates/project/cordova/lib/bbwpignore.js @@ -0,0 +1,129 @@ +/* + * Copyright 2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var fs = require("fs"), + path = require("path"), + BBWPignore; + +function getDirectory(file) { + if (file.match("/$")) { + return file; + } else if (file.indexOf("/") === -1) { + return ""; + } else { + return file.substring(0, file.lastIndexOf("/")); + } +} + +function trim(str) { + return str.replace(/^\s+|\s+$/g, ""); +} + +BBWPignore = function (bbwpIgnoreFile, filesToMatch) { + var comments = [], + directories = [], + wildcardEntries = [], + files = [], + split, + matched = [], + i, + temparr, + tempFiles = []; + temparr = fs.readFileSync(bbwpIgnoreFile, "utf-8").split('\n'); + + //switch all the paths to relative, so if someone has passed absolute paths convert them to relative to .bbwpignore + filesToMatch.forEach(function (file) { + if (file === path.resolve(file)) { //if path is absolute + tempFiles.push(path.relative(path.dirname(bbwpIgnoreFile), file)); + } else { + tempFiles.push(file); + } + }); + filesToMatch = tempFiles; + + //run through all the patterns in the bbwpignore and put them in appropriate arrays + for (i = 0; i < temparr.length; i++) { + temparr[i] = trim(temparr[i]); + if (temparr[i] !== "") { + if (temparr[i].match("^#")) { + comments.push(temparr[i]); + } else if (temparr[i].match("^/") && temparr[i].match("/$")) { + directories.push(temparr[i]); + } else if (temparr[i].indexOf("*") !== -1) { + split = temparr[i].split("/"); + if (split[split.length - 1].indexOf("*") !== -1) { // only wildcards in the file name are supported, not in directory names + wildcardEntries.push(temparr[i]); + } else { + files.push(temparr[i]); + } + } else { + files.push(temparr[i]); + } + } + } + + //run through all the files and check it against each of the patterns collected earlier + filesToMatch.forEach(function (fileToMatch) { + var directory, + dirOrig = getDirectory(fileToMatch), + isMatch = false; + //match directories + directory = "/" + dirOrig + "/"; + if (directories.indexOf(directory) !== -1) { + matched.push(fileToMatch); + //add the directory to the list as well but only check + if (matched.indexOf("/" + dirOrig) === -1) { + matched.push("/" + dirOrig); + } + isMatch = true; + } else { + //handle special case when match patterns begin with / + //match wildCards + wildcardEntries.forEach(function (wildcard) { + if (wildcard.match("^/")) { // special case looking for exact match + wildcard = "^" + wildcard.replace("*", "[^\/]*"); + if (("/" + fileToMatch).match(wildcard)) { + matched.push(fileToMatch); + isMatch = true; + } + } else { + wildcard = wildcard.replace("*", "[^\/]*"); + if (fileToMatch.match(wildcard)) { + matched.push(fileToMatch); + isMatch = true; + } + } + }); + if (!isMatch) { //must be a file + files.forEach(function (file) { + if (file.match("^/")) { // special case looking for exact match + if (file === ("/" + fileToMatch)) { + matched.push(fileToMatch); + isMatch = true; + } + } else if (fileToMatch.match(file)) { + matched.push(fileToMatch); + isMatch = true; + } + }); + + } + } + }); + this.matchedFiles = matched; +}; + +module.exports = BBWPignore; http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/build.js ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/build.js b/bin/templates/project/cordova/lib/build.js new file mode 100755 index 0000000..ab38964 --- /dev/null +++ b/bin/templates/project/cordova/lib/build.js @@ -0,0 +1,129 @@ +#!/usr/bin/env node + +/* + * Copyright 2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var path = require("path"), + exit = require("exit"), + command = require("commander"), + os = require("os"), + utils = require("./utils"), + signingHelper = require("./signing-helper"), + bbProperties = utils.getProperties(), + bbwpArgv = [ + process.argv[0], + path.resolve(path.join(__dirname, process.argv[1])), + path.resolve(path.join(__dirname, "..", "..", "www")), + "-o", + path.resolve(path.join(__dirname, "..", "..", "build")) + ], + async = require("async"), + childProcess = require("child_process"), + pkgrUtils = require("./packager-utils"), + session = require("./session"), + ERROR_VALUE = 2, + commandStr; + +function copyArgIfExists(arg) { + if (command[arg]) { + bbwpArgv.push("--" + arg); + bbwpArgv.push(command[arg]); + } +} + +command + .usage('[--debug | --release] [--no-query] [-k | --keystorepass] [-b | --buildId ] [-p | --params ] [-l | --loglevel ] [--web-inspector] [--no-signing]') + .option('--debug', 'build in debug mode.') + .option('--release', 'build in release mode. This will sign the resulting bar.') + .option('--no-query', 'fail if a password is needed and one isn\'t available') + .option('-k, --keystorepass ', 'signing key password') + .option('-b, --buildId ', 'specifies the build number for signing (typically incremented from previous signing).') + .option('-p, --params ', 'specifies additional parameters to pass to downstream tools.') + .option('-l, --loglevel ', 'set the logging level (error, warn, verbose)') + .option('--web-inspector', 'enables webinspector. Enabled by default in debug mode.).') + .option('--no-signing', 'when building in release mode, this will skip signing'); + +try { + command.parse(process.argv); + + if (command.debug && command.release) { + console.error("Invalid build command: cannot specify both debug and release parameters."); + console.log(command.helpInformation()); + exit(ERROR_VALUE); + } + + signingHelper.warn(); + + utils.series( + [ + function clean(done) { + var cmd = utils.isWindows() ? "clean" : "./clean", + args = [], + opts = { "cwd": path.normalize(__dirname + "/..") }; + + utils.exec(cmd, args, opts, done); + }, + function releaseBuild(allDone) { + var childTasks = [], + keystorepass = session.getKeyStorePass(command), + err; + + if (command.release) { + copyArgIfExists("buildId"); + if (command.signing) { + //Note: Packager refers to signing password as "password" not "keystorepass" + bbwpArgv.push("--password"); + if (keystorepass) { + bbwpArgv.push(keystorepass); + } else if (command.query) { + childTasks.push(utils.prompt.bind(this, {description: "Please enter your keystore password: ", hidden: true})); + childTasks.push(function (password, done) { + bbwpArgv.push(password); + done(); + }); + } else { + err = "No signing password provided. You can omit --no-query, use --no-signing, use --keystorepass, or enter a value for 'keystorepass' in " + pkgrUtils.homedir() + "/.cordova/blackberry10.json"; + } + } + } + + async.waterfall(childTasks, function (error) { allDone(error || err); }); + }, + function build(done) { + //enable webinspector in debug mode or if --webinspector was provided + if (!command.release || command.webInspector) { + bbwpArgv.push("-d"); + } + + copyArgIfExists("params"); + copyArgIfExists("loglevel"); + + //Overwrite process.argv, before calling packager + process.argv = bbwpArgv; + + //Delete cached commander object. It will conflict with the packagers commander + delete require.cache[require.resolve("commander")]; + delete require.cache[require.resolve("commander/lib/commander")]; + + require("./packager").start(done); + } + ] + ); +} catch (e) { + console.error(os.EOL + e); + exit(ERROR_VALUE); +} + http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/clean.js ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/clean.js b/bin/templates/project/cordova/lib/clean.js new file mode 100644 index 0000000..c93cff1 --- /dev/null +++ b/bin/templates/project/cordova/lib/clean.js @@ -0,0 +1,23 @@ +#!/usr/bin/env node + +/* + * Copyright 2013 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var wrench = require('wrench'), + path = require("path"), + buildPath = path.normalize(__dirname + "/../../build/"); + +wrench.rmdirSyncRecursive(buildPath, true); http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/cmdline.js ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/cmdline.js b/bin/templates/project/cordova/lib/cmdline.js new file mode 100644 index 0000000..b05da0f --- /dev/null +++ b/bin/templates/project/cordova/lib/cmdline.js @@ -0,0 +1,67 @@ +/* + * Copyright 2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var command = require("commander"), + logger = require("./logger"), + localize = require("./localize"); + +command + .version('1.0.0.0') + .usage('[drive:][path]archive [-s [dir]] [[ -g genpassword] [-buildId num]] [-o dir] [-d] [-p paramsjsonfile]') + .option('-s, --source [dir]', 'Save source. The default behavior is to not save the source files. If dir is specified then creates dir\\src\\ directory structure. If no dir specified then the path of archive is assumed') + .option('-g, --password ', 'Signing key password') + .option('-buildId ', '[deprecated] Use --buildId.') + .option('-b, --buildId ', 'Specifies the build number for signing (typically incremented from previous signing).') + .option('-o, --output ', 'Redirects output file location to dir. If both -o and dir are not specified then the path of archive is assumed') + .option('-d, --debug', 'Allows use of not signed build on device by utilizing debug token and enables Web Inspector.') + .option('-p, --params ', 'Specifies additional parameters to pass to downstream tools.') + .option('--appdesc ', 'Optionally specifies the path to the bar descriptor file (bar-descriptor.xml). For internal use only.') + .option('-v, --verbose', 'Turn on verbose messages') + .option('-l, --loglevel ', 'set the logging level (error, warn, verbose)'); + +function parseArgs(args) { + var option, + i; + if (!args[2]) { + //no args passed into [node bbwp.js], show the help information + args.push("-h"); + } + + //Handle deprecated option -buildId + for (i = 0; i < args.length; i++) { + if (args[i] === "-buildId") { + args[i] = "--buildId"; + } + } + + command.parse(args); + + //Check for any invalid command line args + for (i = 0; i < args.length; i++) { + //Remove leading dashes if any + option = args[i].substring(2); + if (args[i].indexOf("--") === 0 && !command[option]) { + throw localize.translate("EXCEPTION_CMDLINE_ARG_INVALID", args[i]); + } + } + + return this; +} + +module.exports = { + "commander": command, + "parse": parseArgs +}; http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/conf.js ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/conf.js b/bin/templates/project/cordova/lib/conf.js new file mode 100644 index 0000000..019a84e --- /dev/null +++ b/bin/templates/project/cordova/lib/conf.js @@ -0,0 +1,48 @@ +/* + * Copyright 2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var path = require("path"), + utils = require("./utils"), + fs = require("fs"); + +function getToolsDir() { + if (process.env && process.env.QNX_HOST) { + var bbndkDir = path.join(process.env.QNX_HOST, "usr"); + if (fs.existsSync(bbndkDir)) { + //BBNDK exists on path, use its tools + return bbndkDir; + } + } +} + +module.exports = { + ROOT: path.normalize(__dirname + "/../framework"), + PROJECT_ROOT: path.normalize(__dirname + "/../../"), + NATIVE: path.normalize(__dirname + "/../../native"), + JNEXT_AUTH: path.normalize(__dirname + "/../../native/plugins/jnext/auth.txt"), + BIN: path.normalize(__dirname + "/../framework/bin"), + LIB: path.normalize(__dirname + "/../framework/lib"), + EXT: path.normalize(__dirname + "/../../plugins"), + UI: path.normalize(__dirname + "/../framework/ui-resources"), + DEPENDENCIES: path.normalize(__dirname + "/../framework/dependencies"), + DEPENDENCIES_BOOTSTRAP: path.normalize(__dirname + "/../framework/bootstrap"), + DEPENDENCIES_TOOLS: getToolsDir(), + DEPENDENCIES_WWE: path.normalize(__dirname + "/../dependencies/%s-wwe"), + DEBUG_TOKEN: path.normalize(path.join(utils.getCordovaDir(), "blackberry10debugtoken.bar")), + DEFAULT_ICON: path.normalize(__dirname + "/../default-icon.png"), + BAR_DESCRIPTOR: "bar-descriptor.xml", + BBWP_IGNORE_FILENAME: ".bbwpignore" +}; http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/config-parser.js ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/config-parser.js b/bin/templates/project/cordova/lib/config-parser.js new file mode 100644 index 0000000..3fb87c8 --- /dev/null +++ b/bin/templates/project/cordova/lib/config-parser.js @@ -0,0 +1,696 @@ +/* + * Copyright 2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*jshint sub:true*/ +var fs = require("fs"), + util = require('util'), + xml2js = require('xml2js'), + packagerUtils = require('./packager-utils'), + check = require('validator').check, + sanitize = require('validator').sanitize, + localize = require("./localize"), + logger = require("./logger"), + fileManager = require("./file-manager"), + utils = require("./packager-utils"), + i18nMgr = require("./i18n-manager"), + et = require("elementtree"), + _config_doc, + _self, + _predefinedFeatures; + +//This function will convert a wc3 paramObj with a list of +// elements into a single object +function processParamObj(paramObj) { + var processedObj = {}, + attribs, + paramName, + paramValue; + + if (paramObj) { + //Convert to array for single param entries where only an object is created + if (!Array.isArray(paramObj)) { + paramObj = [paramObj]; + } + + paramObj.forEach(function (param) { + attribs = param["@"]; + + if (attribs) { + paramName = attribs["name"]; + paramValue = attribs["value"]; + + if (paramName && paramValue) { + //Add the key/value pair to the processedObj + processedObj[paramName] = paramValue; + } + } + }); + } + + return processedObj; +} + +function processFeatures(featuresArray, widgetConfig, processPredefinedFeatures) { + var features = [], + attribs; + if (featuresArray) { + featuresArray.forEach(function (feature) { + attribs = feature["@"]; + if (attribs) { + attribs.required = packagerUtils.toBoolean(attribs.required, true); + + // We do NOT want to auto defer networking and JavaScript if the + // blackberry.push feature is being used + if (attribs.id === "blackberry.push") { + widgetConfig.autoDeferNetworkingAndJavaScript = false; + } + + if (_predefinedFeatures[attribs.id]) { + //Handle features that do NOT contain an API namespace + if (processPredefinedFeatures) { + _predefinedFeatures[attribs.id](feature, widgetConfig); + } + } else { + features.push(attribs); + } + } else { + features.push(attribs); + } + }); + } + + return features; +} + +function createAccessListObj(uriOrOrigin, allowSubDomain) { + return { + uri: uriOrOrigin, + allowSubDomain: allowSubDomain + }; +} + +function processVersion(widgetConfig) { + if (widgetConfig.version) { + var versionArray = widgetConfig.version.split("."); + + //if 4rth number in version exists, extract for build id + if (versionArray.length > 3) { + widgetConfig.buildId = versionArray[3]; + widgetConfig.version = widgetConfig.version.substring(0, widgetConfig.version.lastIndexOf('.')); + } + } +} + +function processBuildID(widgetConfig, session) { + if (session.buildId) { + //user specified a build id (--buildId), override any previously set build id + widgetConfig.buildId = session.buildId; + } +} + +function processWidgetData(data, widgetConfig, session) { + var attribs, + featureArray, + uriExist, + originExist, + header; + + if (data["@"]) { + widgetConfig.version = data["@"].version; + widgetConfig.id = data["@"].id; + + if (data["@"]["rim:header"]) { + widgetConfig.customHeaders = {}; + header = data["@"]["rim:header"].split(":"); + // Just set it for now, in the future we can append them + widgetConfig.customHeaders[header[0]] = header[1]; + } + + if (data["@"]["rim:userAgent"]) { + widgetConfig.userAgent = data["@"]["rim:userAgent"]; + } + } + + //Default values + widgetConfig.hasMultiAccess = false; + widgetConfig.accessList = []; + widgetConfig.enableFlash = false; + widgetConfig.autoOrientation = true; + widgetConfig.autoDeferNetworkingAndJavaScript = true; + widgetConfig.theme = "default"; + widgetConfig.autoHideSplashScreen = "true"; + + //set locally available features to access list + if (data.feature) { + featureArray = packagerUtils.isArray(data.feature) ? data.feature : [data.feature]; + } + + //Handle features that do not have source code + featureArray = processFeatures(featureArray, widgetConfig, true); + + //Push empty WIDGET_LOCAL access obj until whitelisting is cleaned up + widgetConfig.accessList.push(createAccessListObj("WIDGET_LOCAL", true)); + + //add whitelisted features to access list + if (data.access) { + //If there is only one access list element, it will be parsed as an object and not an array + if (!packagerUtils.isArray(data.access)) { + data.access = [data.access]; + } + + //check if uri and origin attributes are used + data.access.forEach(function (accessElement, accessIndex) { + attribs = accessElement["@"]; + + if (attribs) { + if (attribs.uri) { + uriExist = true; + } + if (attribs.origin) { + originExist = true; + } + } + }); + if (uriExist === true && originExist === true) { + logger.warn(localize.translate("WARNING_URI_AND_ORIGIN_FOUND_IN_CONFIG")); + } + + data.access.forEach(function (accessElement) { + attribs = accessElement["@"]; + + if (attribs) { + if (attribs.uri === "*" || attribs.origin === "*") { + if (accessElement.feature) { + throw localize.translate("EXCEPTION_FEATURE_DEFINED_WITH_WILDCARD_ACCESS_URI_OR_ORIGIN"); + } + widgetConfig.hasMultiAccess = true; + } else { + attribs.subdomains = packagerUtils.toBoolean(attribs.subdomains); + if (attribs.uri || attribs.origin) { + if (uriExist === true && originExist === true) { + widgetConfig.accessList.push(createAccessListObj(attribs.uri, attribs.subdomains)); //using uri attribute by default + } else { + widgetConfig.accessList.push(createAccessListObj(attribs.uri || attribs.origin, attribs.subdomains)); + } + } + } + } + }); + } +} + +function trim(obj) { + return (typeof obj === "string" ? obj.trim() : obj); +} + +function processSplashScreenIconSrc(data, widgetConfig, key) { + if (data[key]) { + widgetConfig[key] = []; + + if (!(data[key] instanceof Array)) { + data[key] = [data[key]]; + } + + data[key].forEach(function (obj) { + if (obj["@"]) { + widgetConfig[key].push(obj["@"].src); + } else { + widgetConfig[key].push(obj); + } + }); + } +} + +function processSplashScreenData(data, widgetConfig) { + // + // This takes config.xml markup in the form of: + // + // + // + // + // + // + // and turns it into: + // + // icon: ["splash-1280x768.jpg", "splash-768x1280.jpg", "splash-1024x600.jpg", "splash-600x1024.jpg"] + // + // Folder-based localization now done in i18n-manager + // + processSplashScreenIconSrc(data, widgetConfig, "rim:splash"); +} + +function processIconData(data, widgetConfig, session) { + // + // This takes config.xml markup in the form of: + // + // + // + // + // and turns it into: + // + // icon: ["icon-86.png", "icon-150.png"] + // + // Folder-based localization now done in i18n-manager + // + var default_icon_filename = "default-icon.png", + default_icon_src = session.conf.DEFAULT_ICON, + default_icon_dst = session.sourceDir; + + processSplashScreenIconSrc(data, widgetConfig, "icon"); + + if (!widgetConfig.icon) { + packagerUtils.copyFile(default_icon_src, default_icon_dst); + + widgetConfig["icon"] = []; + widgetConfig["icon"].push(default_icon_filename); + } +} + +function validateSplashScreensIcon(widgetConfig, key) { + if (widgetConfig[key]) { + var msg = localize.translate(key === "icon" ? "EXCEPTION_INVALID_ICON_SRC" : "EXCEPTION_INVALID_SPLASH_SRC"); + + if (widgetConfig[key].length === 0) { + // element without src attribute + throw msg; + } else { + widgetConfig[key].forEach(function (src) { + var msg2 = localize.translate(key === "icon" ? "EXCEPTION_INVALID_ICON_SRC_LOCALES" : "EXCEPTION_INVALID_SPLASH_SRC_LOCALES"); + + // check that src attribute is specified and is not empty + check(src, msg).notNull(); + + // check that src attribute does not start with reserved locales folder + src = src.replace(/\\/g, "/"); + check(src, msg2).notRegex("^" + i18nMgr.LOCALES_DIR + "\/"); + }); + } + + } +} + +function processAuthorData(data, widgetConfig) { + if (data.author) { + var attribs = data.author["@"]; + + if (!attribs && typeof data.author === "string") { + //do not sanitize empty objects {} (must be string) + widgetConfig.author = sanitize(data.author).trim(); + } else if (data.author["#"]) { + widgetConfig.author = sanitize(data.author["#"]).trim(); + } + + if (attribs) { + widgetConfig.authorURL = attribs.href; + widgetConfig.copyright = attribs["rim:copyright"]; + widgetConfig.authorEmail = attribs.email; + } + } +} + +function processLicenseData(data, widgetConfig) { + if (data.license && data.license["#"]) { + widgetConfig.license = data.license["#"]; + } else { + widgetConfig.license = ""; + } + + if (data.license && data.license["@"]) { + widgetConfig.licenseURL = data.license["@"].href; + } else { + widgetConfig.licenseURL = ""; + } +} + +function processContentData(data, widgetConfig) { + if (data.content) { + var attribs = data.content["@"], + startPage; + if (attribs) { + widgetConfig.content = attribs.src; + + startPage = packagerUtils.parseUri(attribs.src); + + // if start page is local but does not start with local:///, will prepend it + // replace any backslash with forward slash + if (!packagerUtils.isAbsoluteURI(startPage) && !packagerUtils.isLocalURI(startPage)) { + if (!startPage.relative.match(/^\//)) { + widgetConfig.content = "local:///" + startPage.relative.replace(/\\/g, "/"); + } else { + widgetConfig.content = "local://" + startPage.relative.replace(/\\/g, "/"); + } + } + + widgetConfig.foregroundSource = attribs.src; + widgetConfig.contentType = attribs.type; + widgetConfig.contentCharSet = attribs.charset; + widgetConfig.allowInvokeParams = attribs["rim:allowInvokeParams"]; + //TODO content rim:background + } + } +} + +function processPermissionsData(data, widgetConfig) { + if (data["rim:permissions"] && data["rim:permissions"]["rim:permit"]) { + var permissions = data["rim:permissions"]["rim:permit"]; + + if (permissions instanceof Array) { + widgetConfig.permissions = permissions; + } else { + //user entered one permission and it comes in as an object + widgetConfig.permissions = [permissions]; + } + } else { + widgetConfig.permissions = []; + } + + // We do NOT want to auto defer networking and JavaScript if the + // run_when_backgrounded permission is set + if (widgetConfig.permissions.indexOf("run_when_backgrounded") >= 0) { + widgetConfig.autoDeferNetworkingAndJavaScript = false; + } +} + +function processInvokeTargetsData(data, widgetConfig) { + + if (data["rim:invoke-target"]) { + widgetConfig["invoke-target"] = data["rim:invoke-target"]; + + //If invoke-target is not an array, wrap the invoke-target in an array + utils.wrapPropertyInArray(widgetConfig, "invoke-target"); + + widgetConfig["invoke-target"].forEach(function (invokeTarget) { + if (invokeTarget.type && !packagerUtils.isEmpty(invokeTarget.type)) { + invokeTarget.type = invokeTarget.type.toUpperCase(); + } + + if (invokeTarget.filter) { + utils.wrapPropertyInArray(invokeTarget, "filter"); + + invokeTarget.filter.forEach(function (filter) { + + if (filter["action"]) { + utils.wrapPropertyInArray(filter, "action"); + } + + if (filter["mime-type"]) { + utils.wrapPropertyInArray(filter, "mime-type"); + } + + if (filter["property"]) { + utils.wrapPropertyInArray(filter, "property"); + } + }); + } + }); + } +} + +function validateConfig(widgetConfig) { + check(widgetConfig.version, localize.translate("EXCEPTION_INVALID_VERSION")) + .notNull() + .regex("^[0-9]{1,3}([.][0-9]{1,3}){2,3}$"); + + for (var prop in widgetConfig.name) { + if (widgetConfig.name.hasOwnProperty(prop)) { + check(widgetConfig.name[prop], localize.translate("EXCEPTION_INVALID_NAME")).notEmpty(); + } + } + + check(widgetConfig.author, localize.translate("EXCEPTION_INVALID_AUTHOR")).notNull(); + check(widgetConfig.id, localize.translate("EXCEPTION_INVALID_ID")).notNull().notEmpty(); + + validateSplashScreensIcon(widgetConfig, "rim:splash"); + + validateSplashScreensIcon(widgetConfig, "icon"); + + if (widgetConfig.accessList) { + widgetConfig.accessList.forEach(function (access) { + if (access.uri) { + if (access.uri !== "WIDGET_LOCAL") { + check(access.uri, localize.translate("EXCEPTION_INVALID_ACCESS_URI_NO_PROTOCOL", access.uri)) + .regex("^[a-zA-Z]+:\/\/"); + check(access.uri, localize.translate("EXCEPTION_INVALID_ACCESS_URI_NO_URN", access.uri)) + .notRegex("^[a-zA-Z]+:\/\/$"); + } + } + + if (access.features) { + // Assert each feature has a proper ID and is not empty + access.features.forEach(function (feature) { + if (!feature) { + throw localize.translate("EXCEPTION_INVALID_FEATURE_ID"); + } + check(feature.id, localize.translate("EXCEPTION_INVALID_FEATURE_ID")).notNull().notEmpty(); + }); + } + + }); + } + + if (widgetConfig["invoke-target"]) { + + widgetConfig["invoke-target"].forEach(function (invokeTarget) { + + check(typeof invokeTarget["@"] === "undefined", + localize.translate("EXCEPTION_INVOKE_TARGET_INVALID_ID")) + .equals(false); + check(invokeTarget["@"].id, localize.translate("EXCEPTION_INVOKE_TARGET_INVALID_ID")) + .notNull() + .notEmpty(); + check(invokeTarget.type, localize.translate("EXCEPTION_INVOKE_TARGET_INVALID_TYPE")) + .notNull() + .notEmpty(); + + if (invokeTarget.filter) { + + invokeTarget.filter.forEach(function (filter) { + + check(filter["action"] && filter["action"] instanceof Array && filter["action"].length > 0, + localize.translate("EXCEPTION_INVOKE_TARGET_ACTION_INVALID")) + .equals(true); + + check(filter["mime-type"] && filter["mime-type"] instanceof Array && filter["mime-type"].length > 0, + localize.translate("EXCEPTION_INVOKE_TARGET_MIME_TYPE_INVALID")) + .equals(true); + + if (filter.property) { + filter.property.forEach(function (property) { + check(property["@"] && property["@"]["var"] && typeof property["@"]["var"] === "string", + localize.translate("EXCEPTION_INVOKE_TARGET_FILTER_PROPERTY_INVALID")) + .equals(true); + }); + } + }); + } + }); + } +} + +function processLocalizedText(tag, data, widgetConfig) { + var tagData = data[tag], + DEFAULT = 'default'; + + function processLanguage(tagElement) { + var attribs = tagElement['@'], + language; + + if (attribs) { + language = attribs['xml:lang'] || DEFAULT; + widgetConfig[tag][language.toLowerCase()] = tagElement['#']; + } else { + widgetConfig[tag][DEFAULT] = tagElement; + } + } + + if (Array.isArray(tagData)) { + //i.e. english value + // french value + tagData.forEach(processLanguage); + } else if (tagData instanceof Object) { + //i.e. english value + processLanguage(tagData); + } else { + //i.e value + widgetConfig[tag][DEFAULT] = tagData; + } +} + +function processNameAndDescription(data, widgetConfig) { + widgetConfig.name = {}; + widgetConfig.description = {}; + + processLocalizedText('name', data, widgetConfig); + processLocalizedText('description', data, widgetConfig); +} + +function processCordovaPreferences(data, widgetConfig) { + if (data.preference) { + var preference = JSON.parse(JSON.stringify(processParamObj(data.preference)).toLowerCase()), + hideFormControl = preference.hidekeyboardformaccessorybar; + + widgetConfig.packageCordovaJs = preference.packagecordovajs === "enable"; + widgetConfig.autoHideSplashScreen = preference.autohidesplashscreen !== "false"; + + // + if (preference.backgroundcolor) { + widgetConfig.backgroundColor = processBgColor(preference.backgroundcolor); + } + + // + if (preference.childbrowser) { + widgetConfig.enableChildWebView = (preference.childbrowser === 'disable') === false; + } + + // + if (preference.hidekeyboardformaccessorybar) { + widgetConfig.enableFormControl = (hideFormControl !== 'enable') && (hideFormControl !== 'true'); + } + + // + if (preference.popupblocker) { + widgetConfig.enablePopupBlocker = (preference.popupblocker === 'enable') === true; + } + + // + if (preference.orientation) { + if (preference.orientation === "landscape" || preference.orientation === "portrait" || preference.orientation === "north") { + widgetConfig.autoOrientation = false; + widgetConfig.orientation = preference.orientation; + } else if (preference.orientation !== "auto" && preference.orientation !== "default") { + throw localize.translate("EXCEPTION_INVALID_ORIENTATION_MODE", preference.orientation); + } + } + + // + if (preference.theme && (typeof preference.theme === "string")) { + if (preference.theme === "bright" || preference.theme === "dark" || preference.theme === "inherit" || preference.theme === "default") { + widgetConfig.theme = preference.theme; + } + } + + // + if (preference.websecurity && (typeof preference.websecurity === "string") && (preference.websecurity === "disable")) { + widgetConfig.enableWebSecurity = false; + logger.warn(localize.translate("WARNING_WEBSECURITY_DISABLED")); + } + + // + if (preference.diskcache) { + widgetConfig.enableDiskCache = (preference.diskcache === 'enable'); + } + } +} + +function processBgColor(bgColor) { + //convert bgColor to a number + var bgColorNum = parseInt(bgColor, 16); + + if (isNaN(bgColorNum)) { + //bgColor is not a number, throw error + throw localize.translate("EXCEPTION_BGCOLOR_INVALID", bgColor); + } else { + return bgColorNum; + } +} + +function processResult(data, session) { + var widgetConfig = {}; + + processWidgetData(data, widgetConfig, session); + processIconData(data, widgetConfig, session); + processAuthorData(data, widgetConfig); + processLicenseData(data, widgetConfig); + processContentData(data, widgetConfig); + processPermissionsData(data, widgetConfig); + processInvokeTargetsData(data, widgetConfig); + processSplashScreenData(data, widgetConfig); + processNameAndDescription(data, widgetConfig); + processCordovaPreferences(data, widgetConfig); + + widgetConfig.configXML = "config.xml"; + + //validate the widgetConfig + validateConfig(widgetConfig); + + //special handling for version and grabbing the buildId if specified (4rth number) + processVersion(widgetConfig); + + //if --buildId was specified, it takes precedence + processBuildID(widgetConfig, session); + + //store any config-file element injections + widgetConfig.configFileInjections = _config_doc.findall("config-file"); + + return widgetConfig; +} + +function init() { + //Predefined features are features that do NOT contain an API namespace + _predefinedFeatures = { + "enable-flash" : function (feature, widgetConfig) { + widgetConfig.enableFlash = true; + }, + "blackberry.app.orientation": function (feature, widgetConfig) { + if (feature) { + var params = processParamObj(feature.param), + mode = params.mode; + + if (!mode) { + //No mode provided, throw error + throw localize.translate("EXCEPTION_EMPTY_ORIENTATION_MODE", mode); + } else if (mode === "landscape" || mode === "portrait" || mode === "north") { + widgetConfig.autoOrientation = false;//Overwrites default value + widgetConfig.orientation = mode; + } else if (mode !== "auto") { + //Mode invalid, throw error + throw localize.translate("EXCEPTION_INVALID_ORIENTATION_MODE", mode); + } + + // Throw a warning since this feature is deprecated + logger.warn(localize.translate("WARNING_ORIENTATION_DEPRECATED")); + } + } + }; +} + +_self = { + parse: function (xmlPath, session, callback) { + if (!fs.existsSync(xmlPath)) { + throw localize.translate("EXCEPTION_CONFIG_NOT_FOUND"); + } + + var fileData = fs.readFileSync(xmlPath), + xml = utils.bufferToString(fileData), + parser = new xml2js.Parser({trim: true, normalize: true, explicitRoot: false}); + + //Used for config-file injections + _config_doc = new et.ElementTree(et.XML(xml)); + + init(); + + //parse xml file data + parser.parseString(xml, function (err, result) { + if (err) { + logger.error(localize.translate("EXCEPTION_PARSING_XML")); + fileManager.cleanSource(session); + } else { + callback(processResult(result, session)); + } + }); + } +}; + +module.exports = _self; http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/debugtoken-helper.js ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/debugtoken-helper.js b/bin/templates/project/cordova/lib/debugtoken-helper.js new file mode 100755 index 0000000..4916ba5 --- /dev/null +++ b/bin/templates/project/cordova/lib/debugtoken-helper.js @@ -0,0 +1,202 @@ +/* + * Copyright 2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var childProcess = require("child_process"), + fs = require("fs"), + path = require("path"), + conf = require("./conf"), + localize = require("./localize"), + logger = require("./logger"), + pkgrUtils = require("./packager-utils"), + utils = require("./utils"), + getParams = require("./params"), + workingDir = path.normalize(__dirname + "/.."), + debugTokenDir = path.normalize(path.join(utils.getCordovaDir(), "blackberry10debugtoken.bar")), + properties, + targets, + self = {}; + +function isDebugTokenValid(pin, data) { + var manifests, + i, + l, + expiry = null, + devices = [], + line, + now = new Date(); + + if (!data) { + return false; + } + + manifests = data.toString().replace(/[\r]/g, '').split('\n'); + + for (i = 0, l = manifests.length; i < l; i++) { + if (manifests[i].indexOf("Debug-Token-Expiry-Date: ") >= 0) { + // Parse the expiry date + line = manifests[i].substring("Debug-Token-Expiry-Date: ".length); + expiry = new Date(line.substring(0, line.indexOf("T")) + " " + line.substring(line.indexOf("T") + 1, line.length - 1) + " UTC"); + } else if (manifests[i].indexOf("Debug-Token-Device-Id: ") >= 0) { + line = manifests[i].substring("Debug-Token-Device-Id: ".length); + devices = line.split(","); + } + } + + if (expiry && expiry > now) { + for (i = 0, l = devices.length; i < l; i++) { + if (parseInt(devices[i]) === parseInt(pin, 16)) { + return true; // The debug token is valid if not expired and device pin is included + } + } + } + + return false; +} + +function generateCreateTokenOptions(pins, password) { + var options = [], + params = getParams("blackberry-debugtokenrequest") || {}, + i; + + params["-storepass"] = password; + + Object.getOwnPropertyNames(params).forEach(function (p) { + options.push(p); + + if (params[p]) { + options.push(params[p]); + } + }); + + pins.forEach(function(pin) { + options.push("-devicepin"); + options.push(pin); + }); + + options.push(debugTokenDir); + + return options; +} + +function generateDeployTokenOptions(targetIp, targetPassword) { + var options = [], + params = getParams("blackberry-deploy") || {}; + + params["-installDebugToken"] = debugTokenDir; + params["-device"] = targetIp; + + if (targetPassword) { + params["-password"] = targetPassword; + } + + Object.getOwnPropertyNames(params).forEach(function (p) { + options.push(p); + + if (params[p]) { + options.push(params[p]); + } + }); + + return options; +} + +function execNativeScript(script, options, callback) { + var fullPath = path.join(process.env.CORDOVA_BBTOOLS, script); + + utils.exec(fullPath, options, { + "cwd" : workingDir, + "env" : process.env + }, callback); +} + +self.createToken = function (projectProperties, target, keystorepass, callback) { + var pins = [], + key; + + // Store the global variable "properties" + properties = projectProperties; + + // Gather PINs information from properties + if (target === "all") { + for (key in properties.targets) { + if (properties.targets.hasOwnProperty(key) && properties.targets[key].pin) { + pins.push(properties.targets[key].pin); + } + } + } else { + if (!target) { + target = properties.defaultTarget; + } + + if (properties.targets.hasOwnProperty(target) && properties.targets[target].pin) { + pins.push(properties.targets[target].pin); + } + } + + if (pins.length === 0) { + logger.warn(localize.translate("WARN_NO_DEVICE_PIN_FOUND")); + if (callback && typeof callback === "function") { + callback(-1); + } + } else if (!keystorepass) { + logger.warn(localize.translate("WARN_NO_SIGNING_PASSWORD_PROVIDED", pkgrUtils.homedir())); + if (callback && typeof callback === "function") { + callback(-1); + } + } else { + logger.info(localize.translate("PROGRESS_GENERATING_DEBUG_TOKEN")); + // Call "blackberry-debugtokenrequest" to generate debug token + execNativeScript("blackberry-debugtokenrequest", + generateCreateTokenOptions(pins, keystorepass), + callback + ); + } +}; + +self.deployToken = function (target, targetIp, targetPassword, callback) { + logger.info(localize.translate("PROGRESS_DEPLOYING_DEBUG_TOKEN", target)); + execNativeScript("blackberry-deploy", + generateDeployTokenOptions(targetIp, targetPassword), + callback + ); +}; + +self.checkDebugToken = function (pin, callback) { + var script = path.normalize(path.join(process.env.CORDOVA_BBTOOLS, "blackberry-nativepackager")), + args = [ + "-listManifest", + path.normalize(debugTokenDir) + ]; + + if (!callback || typeof callback !== "function") { + return; + } + + if (!fs.existsSync(debugTokenDir)) { + callback(false); + return; + } + + utils.exec(script, args, { + "cwd": workingDir, + "env": process.env, + _customOptions: { silent: true} + }, function (error, stdout, stderr) { + callback(isDebugTokenValid(pin, stdout)); + }); +}; + +module.exports = self; http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/file-manager.js ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/file-manager.js b/bin/templates/project/cordova/lib/file-manager.js new file mode 100755 index 0000000..977ca2b --- /dev/null +++ b/bin/templates/project/cordova/lib/file-manager.js @@ -0,0 +1,210 @@ +/* + * Copyright 2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var path = require("path"), + util = require("util"), + packagerUtils = require("./packager-utils"), + fs = require("fs"), + conf = require("./conf"), + BBWPignore = require('./bbwpignore'), + wrench = require("wrench"), + zip = require("zip"), + localize = require("./localize"), + logger = require("./logger"), + CLIENT_JS = "client.js", + SERVER_JS = "index.js", + VALID_EXTENSIONS = [".js", ".json"], + CORDOVA_JS_REGEX = /(cordova-.+js)|cordova\.js/, + MODULES_TO_KEEP = ["lib/utils.js", "lib/exception.js"]; + +function unzip(from, to) { + var data, entries, p, parent; + + if (fs.existsSync(from)) { + data = fs.readFileSync(from); + entries = zip.Reader(data).toObject(); + + if (!fs.existsSync(to)) { + wrench.mkdirSyncRecursive(to, "0755"); + } + + for (p in entries) { + if (entries.hasOwnProperty(p)) { + if (p.indexOf("__MACOSX") >= 0) { + continue; + } + + if (p.split("/").length > 1) { + parent = p.split("/").slice(0, -1).join("/"); + wrench.mkdirSyncRecursive(to + "/" + parent, "0755"); + } + + fs.writeFileSync(to + "/" + p, entries[p]); + } + } + } else { + throw localize.translate("EXCEPTION_WIDGET_ARCHIVE_NOT_FOUND", from); + } +} + +function copyDirContents(from, to) { + var files = wrench.readdirSyncRecursive(from), + bbwpignoreFile = path.join(from, conf.BBWP_IGNORE_FILENAME), + bbwpignore, + ignoreFiles = conf.BBWP_IGNORE_FILENAME; + + if (fs.existsSync(bbwpignoreFile)) { + bbwpignore = new BBWPignore(bbwpignoreFile, files); + bbwpignore.matchedFiles.push(conf.BBWP_IGNORE_FILENAME); //add the .bbwpignore file to the ignore list + ignoreFiles = bbwpignore.matchedFiles.join("|"); + } + + + wrench.copyDirSyncRecursive(from, to, {preserve: true, whitelist: false, filter: new RegExp(ignoreFiles, "g")}); +} + +function prepare(session) { + var conf = session.conf, + dest = session.sourcePaths; + + if (fs.existsSync(session.sourceDir)) { + wrench.rmdirSyncRecursive(session.sourceDir); + } + + // unzip archive + if (fs.existsSync(session.archivePath)) { + if (session.archivePath.toLowerCase().match("[.]zip$")) { + unzip(session.archivePath, session.sourceDir); + } else { + copyDirContents(session.archivePath, session.sourceDir); + } + } else { + throw localize.translate("EXCEPTION_INVALID_ARCHIVE_PATH", session.archivePath); + } +} + + +function getModulesArray(dest, files, baseDir) { + var modulesList = [], + EXCLUDE_FILES = ["client.js", "manifest.json"]; + + function isExcluded(file) { + return EXCLUDE_FILES.indexOf(path.basename(file)) !== -1 || !file.match(/\.(js|json)$/); + } + + files.forEach(function (file) { + file = path.resolve(baseDir, file); + + if (!fs.statSync(file).isDirectory()) { + if (!isExcluded(file)) { + modulesList.push({name: path.relative(path.normalize(dest.CHROME), file).replace(/\\/g, "/"), file: file}); + } + } + }); + + return modulesList; +} + +function generateFrameworkModulesJS(session) { + var dest = session.sourcePaths, + modulesList = [], + modulesStr = "(function () { ", + frameworkModulesStr = "window.frameworkModules = [", + libFiles = wrench.readdirSyncRecursive(dest.LIB), + extFiles, + extModules; + + modulesList = modulesList.concat(getModulesArray(dest, libFiles, dest.LIB)); + + if (fs.existsSync(dest.EXT)) { + extFiles = wrench.readdirSyncRecursive(dest.EXT); + extModules = getModulesArray(dest, extFiles, dest.EXT); + modulesList = modulesList.concat(extModules); + } + + modulesList.forEach(function (module, index) { + modulesStr += "define('" + module.name + "', function (require, exports, module) {\n" + + fs.readFileSync(module.file, "utf-8") + "\n" + + "});\n"; + frameworkModulesStr += "'" + module.name + "'" + (index !== modulesList.length - 1 ? ", " : ""); + // Issue with 10.1 webplatform - requires certain files in chrome/lib + if (MODULES_TO_KEEP.indexOf(module.name) < 0) { + fs.unlinkSync(path.normalize(dest.CHROME + "/" + module.name)); + } + }); + + modulesStr += "}());"; + frameworkModulesStr += "];\n"; + fs.writeFileSync(path.normalize(dest.CHROME + "/frameworkModules.js"), frameworkModulesStr + modulesStr); +} + +function copyNative(session, target) { + var src = path.normalize(session.conf.NATIVE + "/" + target), + dest = path.normalize(session.sourceDir); + + copyDirContents(src, dest); +} + +function copyWebworks(session) { + var srcPath = path.normalize(session.conf.PROJECT_ROOT + "/lib"), + dest = path.normalize(session.sourceDir), + srcFiles; + + srcFiles = packagerUtils.listFiles(srcPath, function (file) { + return CORDOVA_JS_REGEX.test(file); + }); + + if (srcFiles.length === 1) { + packagerUtils.copyFile(srcFiles[0], dest); + + //Rename file to webworks.js + fs.renameSync(path.join(dest, path.basename(srcFiles[0])), path.join(dest, "cordova.js")); + } else { + throw localize.translate("EXCEPTION_CORDOVA_JS_IN_LIB_DIR", srcFiles.length); + } +} + +function hasValidExtension(file) { + return VALID_EXTENSIONS.some(function (element, index, array) { + return path.extname(file) === element; + }); +} + +function generateUserConfig(session, config) { + packagerUtils.writeFile(path.join(session.sourcePaths.LIB, "config"), "user.js", "module.exports = " + JSON.stringify(config, null, " ") + ";"); +} + +module.exports = { + unzip: unzip, + + copyNative: copyNative, + + copyWebworks : copyWebworks, + + prepareOutputFiles: prepare, + + generateFrameworkModulesJS: generateFrameworkModulesJS, + + generateUserConfig: generateUserConfig, + + cleanSource: function (session) { + if (!session.keepSource) { + wrench.rmdirSyncRecursive(session.sourceDir); + } + }, + + copyDirContents: copyDirContents +}; http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/i18n-manager.js ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/i18n-manager.js b/bin/templates/project/cordova/lib/i18n-manager.js new file mode 100644 index 0000000..d530f09 --- /dev/null +++ b/bin/templates/project/cordova/lib/i18n-manager.js @@ -0,0 +1,146 @@ +/* + * Copyright 2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*jshint sub:true*/ +var path = require("path"), + fs = require("fs"), + wrench = require("wrench"), + pkgrUtils = require("./packager-utils"), + LOCALES_DIR = "locales"; + +// Given a list of locale files (as follows), based on un-localized splash/icon definition, generate +// localized splash/icon metadata. +// +// zh-hans-cn/a.gif +// zh-hans-cn/f.gif +// zh-hans-cn/images/splash-1024x600.png +// zh-hans-cn/images/splash-600x1024.png +// zh-hans/a.gif +// zh-hans/b.gif +// zh/a.gif +// zh/b.gif +// zh/c.gif +function generateLocalizedMetadataForSplashScreenIcon(config, configKey, xmlObject, xmlObjectKey, localeFiles) { + // localeMap looks like this: + // { + // "zh-hans-cn": ["a.gif", "f.gif", "images/splash-1024x600.png", "images/splash-600x1024.png"], + // "zh-hans": ["a.gif", "b.gif"], + // "zh": ["a.gif", "b.gif", "c.gif"] + // } + var localeMap = {}; + + if (localeFiles) { + localeFiles.forEach(function (path) { + var split = path.replace(/\.\./g, "").split("/"), + locale; + + split = split.filter(function (element) { + return element.length > 0; + }); + + if (split.length > 1) { + locale = split[0]; + + if (!localeMap[locale]) { + localeMap[locale] = []; + } + + // remove locale subfolder from path + split.splice(0, 1); + localeMap[locale].push(split.join("/")); + } + }); + } + + xmlObject[xmlObjectKey] = {}; + xmlObject[xmlObjectKey]["image"] = []; + + if (config[configKey]) { + config[configKey].forEach(function (imgPath) { + imgPath = imgPath.replace(/\\/g, "/"); // replace any backslash with forward slash + + Object.getOwnPropertyNames(localeMap).forEach(function (locale) { + if (localeMap[locale].indexOf(imgPath) !== -1) { + // localized image found for locale + xmlObject[xmlObjectKey]["image"].push({ + text: { + _attr: { + "xml:lang": locale + }, + _value: LOCALES_DIR + "/" + locale + "/" + imgPath + } + }); + } + }); + + xmlObject[xmlObjectKey]["image"].push({ + _value: imgPath + }); + }); + } +} + +function generateLocalizedText(session, config, xmlObject, key) { + var localizedText = config[key], + textElements = [], + locale; + + for (locale in localizedText) { + if (localizedText.hasOwnProperty(locale)) { + //Don't add default locale and don't add locale if it already exists + if (locale !== 'default' && textElements && textElements.indexOf(locale) === -1) { + textElements.push({ + _attr: { + "xml:lang": locale + }, + _value: localizedText[locale] + }); + } + } + } + + xmlObject[key] = { + _value: localizedText['default'], + text: textElements + }; +} + +function generateLocalizedMetadata(session, config, xmlObject, key) { + if (config.icon || config["rim:splash"]) { + var localeFiles, + normalizedLocaleFiles = []; + + if (fs.existsSync(session.sourceDir + "/" + LOCALES_DIR)) { + localeFiles = wrench.readdirSyncRecursive(session.sourceDir + "/" + LOCALES_DIR); + if (pkgrUtils.isWindows()) { + + localeFiles.forEach(function (file) { + file = path.relative(path.resolve(session.sourceDir, "locales"), file).replace(/\\/g, "/"); + normalizedLocaleFiles.push(file); + }); + } else { + normalizedLocaleFiles = localeFiles; + } + } + + generateLocalizedMetadataForSplashScreenIcon(config, key, xmlObject, key === "rim:splash" ? "splashScreens" : key, normalizedLocaleFiles); + } +} + +module.exports = { + LOCALES_DIR: LOCALES_DIR, + generateLocalizedMetadata: generateLocalizedMetadata, + generateLocalizedText: generateLocalizedText +}; http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/install-device ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/install-device b/bin/templates/project/cordova/lib/install-device new file mode 100644 index 0000000..45f8a07 --- /dev/null +++ b/bin/templates/project/cordova/lib/install-device @@ -0,0 +1,56 @@ +#!/usr/bin/env node + +/* + * Copyright 2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var path = require("path"), + utils = require("./utils"), + options = require('commander'), + runUtils = require("./run-utils"), + logger = require("./logger"); + +options + .usage('[--target=id]') + .option('--target ', 'specifies the target to run the application') + .option('-k, --keystorepass ', 'the password of signing key; needed for creating debug token') + .option('--query', 'query on the commandline when a password is needed') + .option('--devicepass ', 'device password') + .option('--no-uninstall', 'does not uninstall application from device') + .option('--no-launch', 'do not launch the application on device') + .on('--help', function() { + console.log(' Examples:'); + console.log(''); + console.log(" Deploying to a predefined target"); + console.log(' $ run --target=Z10'); + console.log(''); + }); +process.argv.forEach(function (argument, index, args) { + if (argument.match(/^--target=/)) { + args.splice(index, 1, "--target", argument.substr("--target=".length)); + } +}); + +options.parse(process.argv); + +options.device = true; +utils.waterfall( + [ + runUtils.getValidatedTarget.bind(this, options), + runUtils.checkBuild, + runUtils.uninstall.bind(this, options), + runUtils.deployToTarget.bind(this, options) + ] +); http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/install-emulator ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/install-emulator b/bin/templates/project/cordova/lib/install-emulator new file mode 100644 index 0000000..afbc581 --- /dev/null +++ b/bin/templates/project/cordova/lib/install-emulator @@ -0,0 +1,56 @@ +#!/usr/bin/env node + +/* + * Copyright 2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var path = require("path"), + utils = require("./utils"), + options = require('commander'), + runUtils = require("./run-utils"), + logger = require("./logger"); + +options + .usage('[--target=id]') + .option('--target ', 'specifies the target to run the application') + .option('--devicepass ', 'device password') + .option('--query', 'query on the commandline when a password is needed') + .option('-k, --keystorepass ', 'the password of signing key; needed for creating debug token') + .option('--no-uninstall', 'does not uninstall application from device') + .option('--no-launch', 'do not launch the application on device') + .on('--help', function() { + console.log(' Examples:'); + console.log(''); + console.log(" Deploying to a predefined target"); + console.log(' $ run --target=Z10'); + console.log(''); + }); +process.argv.forEach(function (argument, index, args) { + if (argument.match(/^--target=/)) { + args.splice(index, 1, "--target", argument.substr("--target=".length)); + } +}); + +options.parse(process.argv); + +options.emulator = true; +utils.waterfall( + [ + runUtils.getValidatedTarget.bind(this, options), + runUtils.checkBuild, + runUtils.uninstall.bind(this, options), + runUtils.deployToTarget.bind(this, options) + ] +); http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/templates/project/cordova/lib/list-devices ---------------------------------------------------------------------- diff --git a/bin/templates/project/cordova/lib/list-devices b/bin/templates/project/cordova/lib/list-devices new file mode 100755 index 0000000..e39b5e2 --- /dev/null +++ b/bin/templates/project/cordova/lib/list-devices @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +<