You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by sh...@apache.org on 2015/12/03 03:34:02 UTC
[30/51] [partial] ios commit: CB-9827 Implement and expose
PlatformApi for iOS
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/26cca47e/bin/node_modules/cordova-common/src/PluginInfo/PluginInfo.js
----------------------------------------------------------------------
diff --git a/bin/node_modules/cordova-common/src/PluginInfo/PluginInfo.js b/bin/node_modules/cordova-common/src/PluginInfo/PluginInfo.js
new file mode 100644
index 0000000..073f3f9
--- /dev/null
+++ b/bin/node_modules/cordova-common/src/PluginInfo/PluginInfo.js
@@ -0,0 +1,416 @@
+/**
+ 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.
+*/
+
+/* jshint sub:true, laxcomma:true, laxbreak:true */
+
+/*
+A class for holidng the information currently stored in plugin.xml
+It should also be able to answer questions like whether the plugin
+is compatible with a given engine version.
+
+TODO (kamrik): refactor this to not use sync functions and return promises.
+*/
+
+
+var path = require('path')
+ , fs = require('fs')
+ , xml_helpers = require('../util/xml-helpers')
+ , CordovaError = require('../CordovaError/CordovaError')
+ ;
+
+function PluginInfo(dirname) {
+ var self = this;
+
+ // METHODS
+ // Defined inside the constructor to avoid the "this" binding problems.
+
+ // <preference> tag
+ // Example: <preference name="API_KEY" />
+ // Used to require a variable to be specified via --variable when installing the plugin.
+ self.getPreferences = getPreferences;
+ function getPreferences(platform) {
+ var arprefs = _getTags(self._et, 'preference', platform, _parsePreference);
+
+ var prefs= {};
+ for(var i in arprefs)
+ {
+ var pref=arprefs[i];
+ prefs[pref.preference]=pref.default;
+ }
+ // returns { key : default | null}
+ return prefs;
+ }
+
+ function _parsePreference(prefTag) {
+ var name = prefTag.attrib.name.toUpperCase();
+ var def = prefTag.attrib.default || null;
+ return {preference: name, default: def};
+ }
+
+ // <asset>
+ self.getAssets = getAssets;
+ function getAssets(platform) {
+ var assets = _getTags(self._et, 'asset', platform, _parseAsset);
+ return assets;
+ }
+
+ function _parseAsset(tag) {
+ var src = tag.attrib.src;
+ var target = tag.attrib.target;
+
+ if ( !src || !target) {
+ var msg =
+ 'Malformed <asset> tag. Both "src" and "target" attributes'
+ + 'must be specified in\n'
+ + self.filepath
+ ;
+ throw new Error(msg);
+ }
+
+ var asset = {
+ itemType: 'asset',
+ src: src,
+ target: target
+ };
+ return asset;
+ }
+
+
+ // <dependency>
+ // Example:
+ // <dependency id="com.plugin.id"
+ // url="https://github.com/myuser/someplugin"
+ // commit="428931ada3891801"
+ // subdir="some/path/here" />
+ self.getDependencies = getDependencies;
+ function getDependencies(platform) {
+ var deps = _getTags(
+ self._et,
+ 'dependency',
+ platform,
+ _parseDependency
+ );
+ return deps;
+ }
+
+ function _parseDependency(tag) {
+ var dep =
+ { id : tag.attrib.id
+ , url : tag.attrib.url || ''
+ , subdir : tag.attrib.subdir || ''
+ , commit : tag.attrib.commit
+ };
+
+ dep.git_ref = dep.commit;
+
+ if ( !dep.id ) {
+ var msg =
+ '<dependency> tag is missing id attribute in '
+ + self.filepath
+ ;
+ throw new CordovaError(msg);
+ }
+ return dep;
+ }
+
+
+ // <config-file> tag
+ self.getConfigFiles = getConfigFiles;
+ function getConfigFiles(platform) {
+ var configFiles = _getTags(self._et, 'config-file', platform, _parseConfigFile);
+ return configFiles;
+ }
+
+ function _parseConfigFile(tag) {
+ var configFile =
+ { target : tag.attrib['target']
+ , parent : tag.attrib['parent']
+ , after : tag.attrib['after']
+ , xmls : tag.getchildren()
+ // To support demuxing via versions
+ , versions : tag.attrib['versions']
+ , deviceTarget: tag.attrib['device-target']
+ };
+ return configFile;
+ }
+
+ // <info> tags, both global and within a <platform>
+ // TODO (kamrik): Do we ever use <info> under <platform>? Example wanted.
+ self.getInfo = getInfo;
+ function getInfo(platform) {
+ var infos = _getTags(
+ self._et,
+ 'info',
+ platform,
+ function(elem) { return elem.text; }
+ );
+ // Filter out any undefined or empty strings.
+ infos = infos.filter(Boolean);
+ return infos;
+ }
+
+ // <source-file>
+ // Examples:
+ // <source-file src="src/ios/someLib.a" framework="true" />
+ // <source-file src="src/ios/someLib.a" compiler-flags="-fno-objc-arc" />
+ self.getSourceFiles = getSourceFiles;
+ function getSourceFiles(platform) {
+ var sourceFiles = _getTagsInPlatform(self._et, 'source-file', platform, _parseSourceFile);
+ return sourceFiles;
+ }
+
+ function _parseSourceFile(tag) {
+ return {
+ itemType: 'source-file',
+ src: tag.attrib.src,
+ framework: isStrTrue(tag.attrib.framework),
+ weak: isStrTrue(tag.attrib.weak),
+ compilerFlags: tag.attrib['compiler-flags'],
+ targetDir: tag.attrib['target-dir']
+ };
+ }
+
+ // <header-file>
+ // Example:
+ // <header-file src="CDVFoo.h" />
+ self.getHeaderFiles = getHeaderFiles;
+ function getHeaderFiles(platform) {
+ var headerFiles = _getTagsInPlatform(self._et, 'header-file', platform, function(tag) {
+ return {
+ itemType: 'header-file',
+ src: tag.attrib.src,
+ targetDir: tag.attrib['target-dir']
+ };
+ });
+ return headerFiles;
+ }
+
+ // <resource-file>
+ // Example:
+ // <resource-file src="FooPluginStrings.xml" target="res/values/FooPluginStrings.xml" device-target="win" arch="x86" versions=">=8.1" />
+ self.getResourceFiles = getResourceFiles;
+ function getResourceFiles(platform) {
+ var resourceFiles = _getTagsInPlatform(self._et, 'resource-file', platform, function(tag) {
+ return {
+ itemType: 'resource-file',
+ src: tag.attrib.src,
+ target: tag.attrib.target,
+ versions: tag.attrib.versions,
+ deviceTarget: tag.attrib['device-target'],
+ arch: tag.attrib.arch
+ };
+ });
+ return resourceFiles;
+ }
+
+ // <lib-file>
+ // Example:
+ // <lib-file src="src/BlackBerry10/native/device/libfoo.so" arch="device" />
+ self.getLibFiles = getLibFiles;
+ function getLibFiles(platform) {
+ var libFiles = _getTagsInPlatform(self._et, 'lib-file', platform, function(tag) {
+ return {
+ itemType: 'lib-file',
+ src: tag.attrib.src,
+ arch: tag.attrib.arch,
+ Include: tag.attrib.Include,
+ versions: tag.attrib.versions,
+ deviceTarget: tag.attrib['device-target'] || tag.attrib.target
+ };
+ });
+ return libFiles;
+ }
+
+ // <hook>
+ // Example:
+ // <hook type="before_build" src="scripts/beforeBuild.js" />
+ self.getHookScripts = getHookScripts;
+ function getHookScripts(hook, platforms) {
+ var scriptElements = self._et.findall('./hook');
+
+ if(platforms) {
+ platforms.forEach(function (platform) {
+ scriptElements = scriptElements.concat(self._et.findall('./platform[@name="' + platform + '"]/hook'));
+ });
+ }
+
+ function filterScriptByHookType(el) {
+ return el.attrib.src && el.attrib.type && el.attrib.type.toLowerCase() === hook;
+ }
+
+ return scriptElements.filter(filterScriptByHookType);
+ }
+
+ self.getJsModules = getJsModules;
+ function getJsModules(platform) {
+ var modules = _getTags(self._et, 'js-module', platform, _parseJsModule);
+ return modules;
+ }
+
+ function _parseJsModule(tag) {
+ var ret = {
+ itemType: 'js-module',
+ name: tag.attrib.name,
+ src: tag.attrib.src,
+ clobbers: tag.findall('clobbers').map(function(tag) { return { target: tag.attrib.target }; }),
+ merges: tag.findall('merges').map(function(tag) { return { target: tag.attrib.target }; }),
+ runs: tag.findall('runs').length > 0
+ };
+
+ return ret;
+ }
+
+ self.getEngines = function() {
+ return self._et.findall('engines/engine').map(function(n) {
+ return {
+ name: n.attrib.name,
+ version: n.attrib.version,
+ platform: n.attrib.platform,
+ scriptSrc: n.attrib.scriptSrc
+ };
+ });
+ };
+
+ self.getPlatforms = function() {
+ return self._et.findall('platform').map(function(n) {
+ return { name: n.attrib.name };
+ });
+ };
+
+ self.getPlatformsArray = function() {
+ return self._et.findall('platform').map(function(n) {
+ return n.attrib.name;
+ });
+ };
+ self.getFrameworks = function(platform) {
+ return _getTags(self._et, 'framework', platform, function(el) {
+ var ret = {
+ itemType: 'framework',
+ type: el.attrib.type,
+ parent: el.attrib.parent,
+ custom: isStrTrue(el.attrib.custom),
+ src: el.attrib.src,
+ weak: isStrTrue(el.attrib.weak),
+ versions: el.attrib.versions,
+ targetDir: el.attrib['target-dir'],
+ deviceTarget: el.attrib['device-target'] || el.attrib.target,
+ arch: el.attrib.arch
+ };
+ return ret;
+ });
+ };
+
+ self.getFilesAndFrameworks = getFilesAndFrameworks;
+ function getFilesAndFrameworks(platform) {
+ // Please avoid changing the order of the calls below, files will be
+ // installed in this order.
+ var items = [].concat(
+ self.getSourceFiles(platform),
+ self.getHeaderFiles(platform),
+ self.getResourceFiles(platform),
+ self.getFrameworks(platform),
+ self.getLibFiles(platform)
+ );
+ return items;
+ }
+ ///// End of PluginInfo methods /////
+
+
+ ///// PluginInfo Constructor logic /////
+ self.filepath = path.join(dirname, 'plugin.xml');
+ if (!fs.existsSync(self.filepath)) {
+ throw new CordovaError('Cannot find plugin.xml for plugin \'' + path.basename(dirname) + '\'. Please try adding it again.');
+ }
+
+ self.dir = dirname;
+ var et = self._et = xml_helpers.parseElementtreeSync(self.filepath);
+ var pelem = et.getroot();
+ self.id = pelem.attrib.id;
+ self.version = pelem.attrib.version;
+
+ // Optional fields
+ self.name = pelem.findtext('name');
+ self.description = pelem.findtext('description');
+ self.license = pelem.findtext('license');
+ self.repo = pelem.findtext('repo');
+ self.issue = pelem.findtext('issue');
+ self.keywords = pelem.findtext('keywords');
+ self.info = pelem.findtext('info');
+ if (self.keywords) {
+ self.keywords = self.keywords.split(',').map( function(s) { return s.trim(); } );
+ }
+ self.getKeywordsAndPlatforms = function () {
+ var ret = self.keywords || [];
+ return ret.concat('ecosystem:cordova').concat(addCordova(self.getPlatformsArray()));
+ };
+} // End of PluginInfo constructor.
+
+// Helper function used to prefix every element of an array with cordova-
+// Useful when we want to modify platforms to be cordova-platform
+function addCordova(someArray) {
+ var newArray = someArray.map(function(element) {
+ return 'cordova-' + element;
+ });
+ return newArray;
+}
+
+// Helper function used by most of the getSomething methods of PluginInfo.
+// Get all elements of a given name. Both in root and in platform sections
+// for the given platform. If transform is given and is a function, it is
+// applied to each element.
+function _getTags(pelem, tag, platform, transform) {
+ var platformTag = pelem.find('./platform[@name="' + platform + '"]');
+ if (platform == 'windows' && !platformTag) {
+ platformTag = pelem.find('platform[@name="' + 'windows8' + '"]');
+ }
+ var tagsInRoot = pelem.findall(tag);
+ tagsInRoot = tagsInRoot || [];
+ var tagsInPlatform = platformTag ? platformTag.findall(tag) : [];
+ var tags = tagsInRoot.concat(tagsInPlatform);
+ if ( typeof transform === 'function' ) {
+ tags = tags.map(transform);
+ }
+ return tags;
+}
+
+// Same as _getTags() but only looks inside a platfrom section.
+function _getTagsInPlatform(pelem, tag, platform, transform) {
+ var platformTag = pelem.find('./platform[@name="' + platform + '"]');
+ if (platform == 'windows' && !platformTag) {
+ platformTag = pelem.find('platform[@name="' + 'windows8' + '"]');
+ }
+ var tags = platformTag ? platformTag.findall(tag) : [];
+ if ( typeof transform === 'function' ) {
+ tags = tags.map(transform);
+ }
+ return tags;
+}
+
+// Check if x is a string 'true'.
+function isStrTrue(x) {
+ return String(x).toLowerCase() == 'true';
+}
+
+module.exports = PluginInfo;
+// Backwards compat:
+PluginInfo.PluginInfo = PluginInfo;
+PluginInfo.loadPluginsDir = function(dir) {
+ var PluginInfoProvider = require('./PluginInfoProvider');
+ return new PluginInfoProvider().getAllWithinSearchPath(dir);
+};
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/26cca47e/bin/node_modules/cordova-common/src/PluginInfo/PluginInfoProvider.js
----------------------------------------------------------------------
diff --git a/bin/node_modules/cordova-common/src/PluginInfo/PluginInfoProvider.js b/bin/node_modules/cordova-common/src/PluginInfo/PluginInfoProvider.js
new file mode 100644
index 0000000..6240119
--- /dev/null
+++ b/bin/node_modules/cordova-common/src/PluginInfo/PluginInfoProvider.js
@@ -0,0 +1,82 @@
+/**
+ 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.
+*/
+
+/* jshint sub:true, laxcomma:true, laxbreak:true */
+
+var fs = require('fs');
+var path = require('path');
+var PluginInfo = require('./PluginInfo');
+var events = require('../events');
+
+function PluginInfoProvider() {
+ this._cache = {};
+ this._getAllCache = {};
+}
+
+PluginInfoProvider.prototype.get = function(dirName) {
+ var absPath = path.resolve(dirName);
+ if (!this._cache[absPath]) {
+ this._cache[absPath] = new PluginInfo(dirName);
+ }
+ return this._cache[absPath];
+};
+
+// Normally you don't need to put() entries, but it's used
+// when copying plugins, and in unit tests.
+PluginInfoProvider.prototype.put = function(pluginInfo) {
+ var absPath = path.resolve(pluginInfo.dir);
+ this._cache[absPath] = pluginInfo;
+};
+
+// Used for plugin search path processing.
+// Given a dir containing multiple plugins, create a PluginInfo object for
+// each of them and return as array.
+// Should load them all in parallel and return a promise, but not yet.
+PluginInfoProvider.prototype.getAllWithinSearchPath = function(dirName) {
+ var absPath = path.resolve(dirName);
+ if (!this._getAllCache[absPath]) {
+ this._getAllCache[absPath] = getAllHelper(absPath, this);
+ }
+ return this._getAllCache[absPath];
+};
+
+function getAllHelper(absPath, provider) {
+ if (!fs.existsSync(absPath)){
+ return [];
+ }
+ // If dir itself is a plugin, return it in an array with one element.
+ if (fs.existsSync(path.join(absPath, 'plugin.xml'))) {
+ return [provider.get(absPath)];
+ }
+ var subdirs = fs.readdirSync(absPath);
+ var plugins = [];
+ subdirs.forEach(function(subdir) {
+ var d = path.join(absPath, subdir);
+ if (fs.existsSync(path.join(d, 'plugin.xml'))) {
+ try {
+ plugins.push(provider.get(d));
+ } catch (e) {
+ events.emit('warn', 'Error parsing ' + path.join(d, 'plugin.xml.\n' + e.stack));
+ }
+ }
+ });
+ return plugins;
+}
+
+module.exports = PluginInfoProvider;
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/26cca47e/bin/node_modules/cordova-common/src/events.js
----------------------------------------------------------------------
diff --git a/bin/node_modules/cordova-common/src/events.js b/bin/node_modules/cordova-common/src/events.js
new file mode 100644
index 0000000..a6ec340
--- /dev/null
+++ b/bin/node_modules/cordova-common/src/events.js
@@ -0,0 +1,19 @@
+/**
+ 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.
+*/
+module.exports = new (require('events').EventEmitter)();
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/26cca47e/bin/node_modules/cordova-common/src/superspawn.js
----------------------------------------------------------------------
diff --git a/bin/node_modules/cordova-common/src/superspawn.js b/bin/node_modules/cordova-common/src/superspawn.js
new file mode 100644
index 0000000..b4129ec
--- /dev/null
+++ b/bin/node_modules/cordova-common/src/superspawn.js
@@ -0,0 +1,154 @@
+/**
+ 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 child_process = require('child_process');
+var fs = require('fs');
+var path = require('path');
+var _ = require('underscore');
+var Q = require('q');
+var shell = require('shelljs');
+var events = require('./events');
+var iswin32 = process.platform == 'win32';
+
+// On Windows, spawn() for batch files requires absolute path & having the extension.
+function resolveWindowsExe(cmd) {
+ var winExtensions = ['.exe', '.cmd', '.bat', '.js', '.vbs'];
+ function isValidExe(c) {
+ return winExtensions.indexOf(path.extname(c)) !== -1 && fs.existsSync(c);
+ }
+ if (isValidExe(cmd)) {
+ return cmd;
+ }
+ cmd = shell.which(cmd) || cmd;
+ if (!isValidExe(cmd)) {
+ winExtensions.some(function(ext) {
+ if (fs.existsSync(cmd + ext)) {
+ cmd = cmd + ext;
+ return true;
+ }
+ });
+ }
+ return cmd;
+}
+
+function maybeQuote(a) {
+ if (/^[^"].*[ &].*[^"]/.test(a)) return '"' + a + '"';
+ return a;
+}
+
+// opts:
+// printCommand: Whether to log the command (default: false)
+// stdio: 'default' is to capture output and returning it as a string to success (same as exec)
+// 'ignore' means don't bother capturing it
+// 'inherit' means pipe the input & output. This is required for anything that prompts.
+// env: Map of extra environment variables.
+// cwd: Working directory for the command.
+// chmod: If truthy, will attempt to set the execute bit before executing on non-Windows platforms.
+// Returns a promise that succeeds only for return code = 0.
+exports.spawn = function(cmd, args, opts) {
+ args = args || [];
+ opts = opts || {};
+ var spawnOpts = {};
+ var d = Q.defer();
+
+ if (iswin32) {
+ cmd = resolveWindowsExe(cmd);
+ // If we couldn't find the file, likely we'll end up failing,
+ // but for things like "del", cmd will do the trick.
+ if (path.extname(cmd) != '.exe') {
+ var cmdArgs = '"' + [cmd].concat(args).map(maybeQuote).join(' ') + '"';
+ // We need to use /s to ensure that spaces are parsed properly with cmd spawned content
+ args = [['/s', '/c', cmdArgs].join(' ')];
+ cmd = 'cmd';
+ spawnOpts.windowsVerbatimArguments = true;
+ } else if (!fs.existsSync(cmd)) {
+ // We need to use /s to ensure that spaces are parsed properly with cmd spawned content
+ args = ['/s', '/c', cmd].concat(args).map(maybeQuote);
+ }
+ }
+
+ if (opts.stdio == 'ignore') {
+ spawnOpts.stdio = 'ignore';
+ } else if (opts.stdio == 'inherit') {
+ spawnOpts.stdio = 'inherit';
+ }
+ if (opts.cwd) {
+ spawnOpts.cwd = opts.cwd;
+ }
+ if (opts.env) {
+ spawnOpts.env = _.extend(_.extend({}, process.env), opts.env);
+ }
+ if (opts.chmod && !iswin32) {
+ try {
+ // This fails when module is installed in a system directory (e.g. via sudo npm install)
+ fs.chmodSync(cmd, '755');
+ } catch (e) {
+ // If the perms weren't set right, then this will come as an error upon execution.
+ }
+ }
+
+ events.emit(opts.printCommand ? 'log' : 'verbose', 'Running command: ' + maybeQuote(cmd) + ' ' + args.map(maybeQuote).join(' '));
+
+ var child = child_process.spawn(cmd, args, spawnOpts);
+ var capturedOut = '';
+ var capturedErr = '';
+
+ if (child.stdout) {
+ child.stdout.setEncoding('utf8');
+ child.stdout.on('data', function(data) {
+ capturedOut += data;
+ });
+
+ child.stderr.setEncoding('utf8');
+ child.stderr.on('data', function(data) {
+ capturedErr += data;
+ });
+ }
+
+ child.on('close', whenDone);
+ child.on('error', whenDone);
+ function whenDone(arg) {
+ child.removeListener('close', whenDone);
+ child.removeListener('error', whenDone);
+ var code = typeof arg == 'number' ? arg : arg && arg.code;
+
+ events.emit('verbose', 'Command finished with error code ' + code + ': ' + cmd + ' ' + args);
+ if (code === 0) {
+ d.resolve(capturedOut.trim());
+ } else {
+ var errMsg = cmd + ': Command failed with exit code ' + code;
+ if (capturedErr) {
+ errMsg += ' Error output:\n' + capturedErr.trim();
+ }
+ var err = new Error(errMsg);
+ err.code = code;
+ d.reject(err);
+ }
+ }
+
+ return d.promise;
+};
+
+exports.maybeSpawn = function(cmd, args, opts) {
+ if (fs.existsSync(cmd)) {
+ return exports.spawn(cmd, args, opts);
+ }
+ return Q(null);
+};
+
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/26cca47e/bin/node_modules/cordova-common/src/util/plist-helpers.js
----------------------------------------------------------------------
diff --git a/bin/node_modules/cordova-common/src/util/plist-helpers.js b/bin/node_modules/cordova-common/src/util/plist-helpers.js
new file mode 100644
index 0000000..9dee5c6
--- /dev/null
+++ b/bin/node_modules/cordova-common/src/util/plist-helpers.js
@@ -0,0 +1,101 @@
+/*
+ *
+ * Copyright 2013 Brett Rudd
+ *
+ * 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.
+ *
+*/
+
+// contains PLIST utility functions
+var __ = require('underscore');
+var plist = require('plist');
+
+// adds node to doc at selector
+module.exports.graftPLIST = graftPLIST;
+function graftPLIST(doc, xml, selector) {
+ var obj = plist.parse('<plist>'+xml+'</plist>');
+
+ var node = doc[selector];
+ if (node && Array.isArray(node) && Array.isArray(obj)){
+ node = node.concat(obj);
+ for (var i =0;i<node.length; i++){
+ for (var j=i+1; j<node.length; ++j) {
+ if (nodeEqual(node[i], node[j]))
+ node.splice(j--,1);
+ }
+ }
+ doc[selector] = node;
+ } else {
+ //plist uses objects for <dict>. If we have two dicts we merge them instead of
+ // overriding the old one. See CB-6472
+ if (node && __.isObject(node) && __.isObject(obj) && !__.isDate(node) && !__.isDate(obj)){//arrays checked above
+ __.extend(obj,node);
+ }
+ doc[selector] = obj;
+ }
+
+ return true;
+}
+
+// removes node from doc at selector
+module.exports.prunePLIST = prunePLIST;
+function prunePLIST(doc, xml, selector) {
+ var obj = plist.parse('<plist>'+xml+'</plist>');
+
+ pruneOBJECT(doc, selector, obj);
+
+ return true;
+}
+
+function pruneOBJECT(doc, selector, fragment) {
+ if (Array.isArray(fragment) && Array.isArray(doc[selector])) {
+ var empty = true;
+ for (var i in fragment) {
+ for (var j in doc[selector]) {
+ empty = pruneOBJECT(doc[selector], j, fragment[i]) && empty;
+ }
+ }
+ if (empty)
+ {
+ delete doc[selector];
+ return true;
+ }
+ }
+ else if (nodeEqual(doc[selector], fragment)) {
+ delete doc[selector];
+ return true;
+ }
+
+ return false;
+}
+
+function nodeEqual(node1, node2) {
+ if (typeof node1 != typeof node2)
+ return false;
+ else if (typeof node1 == 'string') {
+ node2 = escapeRE(node2).replace(new RegExp('\\$[a-zA-Z0-9-_]+','gm'),'(.*?)');
+ return new RegExp('^' + node2 + '$').test(node1);
+ }
+ else {
+ for (var key in node2) {
+ if (!nodeEqual(node1[key], node2[key])) return false;
+ }
+ return true;
+ }
+}
+
+// escape string for use in regex
+function escapeRE(str) {
+ return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '$&');
+}
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/26cca47e/bin/node_modules/cordova-common/src/util/xml-helpers.js
----------------------------------------------------------------------
diff --git a/bin/node_modules/cordova-common/src/util/xml-helpers.js b/bin/node_modules/cordova-common/src/util/xml-helpers.js
new file mode 100644
index 0000000..8b02989
--- /dev/null
+++ b/bin/node_modules/cordova-common/src/util/xml-helpers.js
@@ -0,0 +1,266 @@
+/*
+ *
+ * Copyright 2013 Anis Kadri
+ *
+ * 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, laxcomma:true */
+
+/**
+ * contains XML utility functions, some of which are specific to elementtree
+ */
+
+var fs = require('fs')
+ , path = require('path')
+ , _ = require('underscore')
+ , et = require('elementtree')
+ ;
+
+module.exports = {
+ // compare two et.XML nodes, see if they match
+ // compares tagName, text, attributes and children (recursively)
+ equalNodes: function(one, two) {
+ if (one.tag != two.tag) {
+ return false;
+ } else if (one.text.trim() != two.text.trim()) {
+ return false;
+ } else if (one._children.length != two._children.length) {
+ return false;
+ }
+
+ var oneAttribKeys = Object.keys(one.attrib),
+ twoAttribKeys = Object.keys(two.attrib),
+ i = 0, attribName;
+
+ if (oneAttribKeys.length != twoAttribKeys.length) {
+ return false;
+ }
+
+ for (i; i < oneAttribKeys.length; i++) {
+ attribName = oneAttribKeys[i];
+
+ if (one.attrib[attribName] != two.attrib[attribName]) {
+ return false;
+ }
+ }
+
+ for (i; i < one._children.length; i++) {
+ if (!module.exports.equalNodes(one._children[i], two._children[i])) {
+ return false;
+ }
+ }
+
+ return true;
+ },
+
+ // adds node to doc at selector, creating parent if it doesn't exist
+ graftXML: function(doc, nodes, selector, after) {
+ var parent = resolveParent(doc, selector);
+ if (!parent) {
+ //Try to create the parent recursively if necessary
+ try {
+ var parentToCreate = et.XML('<' + path.basename(selector) + '>'),
+ parentSelector = path.dirname(selector);
+
+ this.graftXML(doc, [parentToCreate], parentSelector);
+ } catch (e) {
+ return false;
+ }
+ parent = resolveParent(doc, selector);
+ if (!parent) return false;
+ }
+
+ nodes.forEach(function (node) {
+ // check if child is unique first
+ if (uniqueChild(node, parent)) {
+ var children = parent.getchildren();
+ var insertIdx = after ? findInsertIdx(children, after) : children.length;
+
+ //TODO: replace with parent.insert after the bug in ElementTree is fixed
+ parent.getchildren().splice(insertIdx, 0, node);
+ }
+ });
+
+ return true;
+ },
+
+ // removes node from doc at selector
+ pruneXML: function(doc, nodes, selector) {
+ var parent = resolveParent(doc, selector);
+ if (!parent) return false;
+
+ nodes.forEach(function (node) {
+ var matchingKid = null;
+ if ((matchingKid = findChild(node, parent)) !== null) {
+ // stupid elementtree takes an index argument it doesn't use
+ // and does not conform to the python lib
+ parent.remove(matchingKid);
+ }
+ });
+
+ return true;
+ },
+
+ parseElementtreeSync: function (filename) {
+ var contents = fs.readFileSync(filename, 'utf-8');
+ if(contents) {
+ //Windows is the BOM. Skip the Byte Order Mark.
+ contents = contents.substring(contents.indexOf('<'));
+ }
+ return new et.ElementTree(et.XML(contents));
+ }
+};
+
+function findChild(node, parent) {
+ var matchingKids = parent.findall(node.tag)
+ , i, j;
+
+ for (i = 0, j = matchingKids.length ; i < j ; i++) {
+ if (module.exports.equalNodes(node, matchingKids[i])) {
+ return matchingKids[i];
+ }
+ }
+ return null;
+}
+
+function uniqueChild(node, parent) {
+ var matchingKids = parent.findall(node.tag)
+ , i = 0;
+
+ if (matchingKids.length === 0) {
+ return true;
+ } else {
+ for (i; i < matchingKids.length; i++) {
+ if (module.exports.equalNodes(node, matchingKids[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+
+var ROOT = /^\/([^\/]*)/,
+ ABSOLUTE = /^\/([^\/]*)\/(.*)/;
+
+function resolveParent(doc, selector) {
+ var parent, tagName, subSelector;
+
+ // handle absolute selector (which elementtree doesn't like)
+ if (ROOT.test(selector)) {
+ tagName = selector.match(ROOT)[1];
+ // test for wildcard "any-tag" root selector
+ if (tagName == '*' || tagName === doc._root.tag) {
+ parent = doc._root;
+
+ // could be an absolute path, but not selecting the root
+ if (ABSOLUTE.test(selector)) {
+ subSelector = selector.match(ABSOLUTE)[2];
+ parent = parent.find(subSelector);
+ }
+ } else {
+ return false;
+ }
+ } else {
+ parent = doc.find(selector);
+ }
+ return parent;
+}
+
+// Find the index at which to insert an entry. After is a ;-separated priority list
+// of tags after which the insertion should be made. E.g. If we need to
+// insert an element C, and the rule is that the order of children has to be
+// As, Bs, Cs. After will be equal to "C;B;A".
+function findInsertIdx(children, after) {
+ var childrenTags = children.map(function(child) { return child.tag; });
+ var afters = after.split(';');
+ var afterIndexes = afters.map(function(current) { return childrenTags.lastIndexOf(current); });
+ var foundIndex = _.find(afterIndexes, function(index) { return index != -1; });
+
+ //add to the beginning if no matching nodes are found
+ return typeof foundIndex === 'undefined' ? 0 : foundIndex+1;
+}
+
+var BLACKLIST = ['platform', 'feature','plugin','engine'];
+var SINGLETONS = ['content', 'author'];
+function mergeXml(src, dest, platform, clobber) {
+ // Do nothing for blacklisted tags.
+ if (BLACKLIST.indexOf(src.tag) != -1) return;
+
+ //Handle attributes
+ Object.getOwnPropertyNames(src.attrib).forEach(function (attribute) {
+ if (clobber || !dest.attrib[attribute]) {
+ dest.attrib[attribute] = src.attrib[attribute];
+ }
+ });
+ //Handle text
+ if (src.text && (clobber || !dest.text)) {
+ dest.text = src.text;
+ }
+ //Handle platform
+ if (platform) {
+ src.findall('platform[@name="' + platform + '"]').forEach(function (platformElement) {
+ platformElement.getchildren().forEach(mergeChild);
+ });
+ }
+
+ //Handle children
+ src.getchildren().forEach(mergeChild);
+
+ function mergeChild (srcChild) {
+ var srcTag = srcChild.tag,
+ destChild = new et.Element(srcTag),
+ foundChild,
+ query = srcTag + '',
+ shouldMerge = true;
+
+ if (BLACKLIST.indexOf(srcTag) === -1) {
+ if (SINGLETONS.indexOf(srcTag) !== -1) {
+ foundChild = dest.find(query);
+ if (foundChild) {
+ destChild = foundChild;
+ dest.remove(destChild);
+ }
+ } else {
+ //Check for an exact match and if you find one don't add
+ Object.getOwnPropertyNames(srcChild.attrib).forEach(function (attribute) {
+ query += '[@' + attribute + '="' + srcChild.attrib[attribute] + '"]';
+ });
+ var foundChildren = dest.findall(query);
+ for(var i = 0; i < foundChildren.length; i++) {
+ foundChild = foundChildren[i];
+ if (foundChild && textMatch(srcChild, foundChild) && (Object.keys(srcChild.attrib).length==Object.keys(foundChild.attrib).length)) {
+ destChild = foundChild;
+ dest.remove(destChild);
+ shouldMerge = false;
+ break;
+ }
+ }
+ }
+
+ mergeXml(srcChild, destChild, platform, clobber && shouldMerge);
+ dest.append(destChild);
+ }
+ }
+}
+
+// Expose for testing.
+module.exports.mergeXml = mergeXml;
+
+function textMatch(elm1, elm2) {
+ var text1 = elm1.text ? elm1.text.replace(/\s+/, '') : '',
+ text2 = elm2.text ? elm2.text.replace(/\s+/, '') : '';
+ return (text1 === '' || text1 === text2);
+}
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/26cca47e/bin/node_modules/plist/.jshintrc
----------------------------------------------------------------------
diff --git a/bin/node_modules/plist/.jshintrc b/bin/node_modules/plist/.jshintrc
new file mode 100644
index 0000000..3f42622
--- /dev/null
+++ b/bin/node_modules/plist/.jshintrc
@@ -0,0 +1,4 @@
+{
+ "laxbreak": true,
+ "laxcomma": true
+}
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/26cca47e/bin/node_modules/plist/.travis.yml
----------------------------------------------------------------------
diff --git a/bin/node_modules/plist/.travis.yml b/bin/node_modules/plist/.travis.yml
new file mode 100644
index 0000000..4ed5002
--- /dev/null
+++ b/bin/node_modules/plist/.travis.yml
@@ -0,0 +1,32 @@
+language: node_js
+node_js:
+- '0.10'
+- '0.11'
+env:
+ global:
+ - secure: xlLmWO7akYQjmDgrv6/b/ZMGILF8FReD+k6A/u8pYRD2JW29hhwvRwIQGcKp9+zmJdn4i5M4D1/qJkCeI3pdhAYBDHvzHOHSEwLJz1ESB2Crv6fa69CtpIufQkWvIxmZoU49tCaLpMBaIroGihJ4DAXdIVOIz6Ur9vXLDhGsE4c=
+ - secure: aQ46RdxL10xR5ZJJTMUKdH5k4tdrzgZ87nlwHC+pTr6bfRw3UKYC+6Rm7yQpg9wq0Io9O9dYCP007gQGSWstbjr1+jXNu/ubtNG+q5cpWBQZZZ013VHh9QJTf1MnetsZxbv8Yhrjg590s6vruT0oqesOnB2CizO/BsKxnY37Nos=
+matrix:
+ include:
+ - node_js: '0.10'
+ env: BROWSER_NAME=chrome BROWSER_VERSION=latest
+ - node_js: '0.10'
+ env: BROWSER_NAME=chrome BROWSER_VERSION=29
+ - node_js: '0.10'
+ env: BROWSER_NAME=firefox BROWSER_VERSION=latest
+ - node_js: '0.10'
+ env: BROWSER_NAME=opera BROWSER_VERSION=latest
+ - node_js: '0.10'
+ env: BROWSER_NAME=safari BROWSER_VERSION=latest
+ - node_js: '0.10'
+ env: BROWSER_NAME=safari BROWSER_VERSION=7
+ - node_js: '0.10'
+ env: BROWSER_NAME=safari BROWSER_VERSION=6
+ - node_js: '0.10'
+ env: BROWSER_NAME=safari BROWSER_VERSION=5
+ - node_js: '0.10'
+ env: BROWSER_NAME=ie BROWSER_VERSION=11
+ - node_js: '0.10'
+ env: BROWSER_NAME=ie BROWSER_VERSION=10
+ - node_js: '0.10'
+ env: BROWSER_NAME=ie BROWSER_VERSION=9
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/26cca47e/bin/node_modules/plist/History.md
----------------------------------------------------------------------
diff --git a/bin/node_modules/plist/History.md b/bin/node_modules/plist/History.md
new file mode 100644
index 0000000..dbcf0d6
--- /dev/null
+++ b/bin/node_modules/plist/History.md
@@ -0,0 +1,112 @@
+
+1.1.0 / 2014-08-27
+==================
+
+ * package: update "browserify" to v5.10.1
+ * package: update "zuul" to v1.10.2
+ * README: add "Sauce Test Status" build badge
+ * travis: use new "plistjs" sauce credentials
+ * travis: set up zuul saucelabs automated testing
+
+1.0.1 / 2014-06-25
+==================
+
+ * add .zuul.yml file for browser testing
+ * remove Testling stuff
+ * build: fix global variable `val` leak
+ * package: use --check-leaks when running mocha tests
+ * README: update examples to use preferred API
+ * package: add "browser" keyword
+
+1.0.0 / 2014-05-20
+==================
+
+ * package: remove "android-browser"
+ * test: add <dict> build() test
+ * test: re-add the empty string build() test
+ * test: remove "fixtures" and legacy "tests" dir
+ * test: add some more build() tests
+ * test: add a parse() CDATA test
+ * test: starting on build() tests
+ * test: more parse() tests
+ * package: attempt to fix "android-browser" testling
+ * parse: better <data> with newline handling
+ * README: add Testling badge
+ * test: add <data> node tests
+ * test: add a <date> parse() test
+ * travis: don't test node v0.6 or v0.8
+ * test: some more parse() tests
+ * test: add simple <string> parsing test
+ * build: add support for an optional "opts" object
+ * package: test mobile devices
+ * test: use multiline to inline the XML
+ * package: beautify
+ * package: fix "mocha" harness
+ * package: more testling browsers
+ * build: add the "version=1.0" attribute
+ * beginnings of "mocha" tests
+ * build: more JSDocs
+ * tests: add test that ensures that empty string conversion works
+ * build: update "xmlbuilder" to v2.2.1
+ * parse: ignore comment and cdata nodes
+ * tests: make the "Newlines" test actually contain a newline
+ * parse: lint
+ * test travis
+ * README: add Travis CI badge
+ * add .travis.yml file
+ * build: updated DTD to reflect name change
+ * parse: return falsey values in an Array plist
+ * build: fix encoding a typed array in the browser
+ * build: add support for Typed Arrays and ArrayBuffers
+ * build: more lint
+ * build: slight cleanup and optimizations
+ * build: use .txt() for the "date" value
+ * parse: always return a Buffer for <data> nodes
+ * build: don't interpret Strings as base64
+ * dist: commit prebuilt plist*.js files
+ * parse: fix typo in deprecate message
+ * parse: fix parse() return value
+ * parse: add jsdoc comments for the deprecated APIs
+ * parse: add `parse()` function
+ * node, parse: use `util-deprecate` module
+ * re-implemented parseFile to be asynchronous
+ * node: fix jsdoc comment
+ * Makefile: fix "node" require stubbing
+ * examples: add "browser" example
+ * package: tweak "main"
+ * package: remove "engines" field
+ * Makefile: fix --exclude command for browserify
+ * package: update "description"
+ * lib: more styling
+ * Makefile: add -build.js and -parse.js dist files
+ * lib: separate out the parse and build logic into their own files
+ * Makefile: add makefile with browserify build rules
+ * package: add "browserify" as a dev dependency
+ * plist: tabs to spaces (again)
+ * add a .jshintrc file
+ * LICENSE: update
+ * node-webkit support
+ * Ignore tests/ in .npmignore file
+ * Remove duplicate devDependencies key
+ * Remove trailing whitespace
+ * adding recent contributors. Bumping npm package number (patch release)
+ * Fixed node.js string handling
+ * bumping version number
+ * Fixed global variable plist leak
+ * patch release 0.4.1
+ * removed temporary debug output file
+ * flipping the cases for writing data and string elements in build(). removed the 125 length check. Added validation of base64 encoding for data fields when parsing. added unit tests.
+ * fixed syntax errors in README examples (issue #20)
+ * added Sync versions of calls. added deprecation warnings for old method calls. updated documentation. If the resulting object from parseStringSync is an array with 1 element, return just the element. If a plist string or file doesnt have a <plist> tag as the document root element, fail noisily (issue #15)
+ * incrementing package version
+ * added cross platform base64 encode/decode for data elements (issue #17.) Comments and hygiene.
+ * refactored the code to use a DOM parser instead of SAX. closes issues #5 and #16
+ * rolling up package version
+ * updated base64 detection regexp. updated README. hygiene.
+ * refactored the build function. Fixes issue #14
+ * refactored tests. Modified tests from issue #9. thanks @sylvinus
+ * upgrade xmlbuilder package version. this is why .end() was needed in last commit; breaking change to xmlbuilder lib. :/
+ * bug fix in build function, forgot to call .end() Refactored tests to use nodeunit
+ * Implemented support for real, identity tests
+ * Refactored base64 detection - still sloppy, fixed date building. Passing tests OK.
+ * Implemented basic plist builder that turns an existing JS object into plist XML. date, real and data types still need to be implemented.
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/26cca47e/bin/node_modules/plist/LICENSE
----------------------------------------------------------------------
diff --git a/bin/node_modules/plist/LICENSE b/bin/node_modules/plist/LICENSE
new file mode 100644
index 0000000..04a9e91
--- /dev/null
+++ b/bin/node_modules/plist/LICENSE
@@ -0,0 +1,24 @@
+(The MIT License)
+
+Copyright (c) 2010-2014 Nathan Rajlich <na...@tootallnate.net>
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/26cca47e/bin/node_modules/plist/Makefile
----------------------------------------------------------------------
diff --git a/bin/node_modules/plist/Makefile b/bin/node_modules/plist/Makefile
new file mode 100644
index 0000000..62695e0
--- /dev/null
+++ b/bin/node_modules/plist/Makefile
@@ -0,0 +1,76 @@
+
+# get Makefile directory name: http://stackoverflow.com/a/5982798/376773
+THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
+THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)
+
+# BIN directory
+BIN := $(THIS_DIR)/node_modules/.bin
+
+# applications
+NODE ?= node
+NPM ?= $(NODE) $(shell which npm)
+BROWSERIFY ?= $(NODE) $(BIN)/browserify
+MOCHA ?= $(NODE) $(BIN)/mocha
+ZUUL ?= $(NODE) $(BIN)/zuul
+
+REPORTER ?= spec
+
+all: dist/plist.js dist/plist-build.js dist/plist-parse.js
+
+install: node_modules
+
+clean:
+ @rm -rf node_modules dist
+
+dist:
+ @mkdir -p $@
+
+dist/plist-build.js: node_modules lib/build.js dist
+ @$(BROWSERIFY) \
+ --standalone plist \
+ lib/build.js > $@
+
+dist/plist-parse.js: node_modules lib/parse.js dist
+ @$(BROWSERIFY) \
+ --standalone plist \
+ lib/parse.js > $@
+
+dist/plist.js: node_modules lib/*.js dist
+ @$(BROWSERIFY) \
+ --standalone plist \
+ --ignore lib/node.js \
+ lib/plist.js > $@
+
+node_modules: package.json
+ @NODE_ENV= $(NPM) install
+ @touch node_modules
+
+test:
+ @if [ "x$(BROWSER_NAME)" = "x" ]; then \
+ $(MAKE) test-node; \
+ else \
+ $(MAKE) test-zuul; \
+ fi
+
+test-node:
+ @$(MOCHA) \
+ --reporter $(REPORTER) \
+ test/*.js
+
+test-zuul:
+ @if [ "x$(BROWSER_PLATFORM)" = "x" ]; then \
+ $(ZUUL) \
+ --ui mocha-bdd \
+ --browser-name $(BROWSER_NAME) \
+ --browser-version $(BROWSER_VERSION) \
+ test/*.js; \
+ else \
+ $(ZUUL) \
+ --ui mocha-bdd \
+ --browser-name $(BROWSER_NAME) \
+ --browser-version $(BROWSER_VERSION) \
+ --browser-platform "$(BROWSER_PLATFORM)" \
+ test/*.js; \
+ fi
+
+.PHONY: all install clean test test-node test-zuul
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/26cca47e/bin/node_modules/plist/README.md
----------------------------------------------------------------------
diff --git a/bin/node_modules/plist/README.md b/bin/node_modules/plist/README.md
new file mode 100644
index 0000000..4d0310a
--- /dev/null
+++ b/bin/node_modules/plist/README.md
@@ -0,0 +1,113 @@
+plist.js
+========
+### Mac OS X Plist parser/builder for Node.js and browsers
+
+[![Sauce Test Status](https://saucelabs.com/browser-matrix/plistjs.svg)](https://saucelabs.com/u/plistjs)
+
+[![Build Status](https://travis-ci.org/TooTallNate/plist.js.svg?branch=master)](https://travis-ci.org/TooTallNate/plist.js)
+
+Provides facilities for reading and writing Mac OS X Plist (property list)
+files. These are often used in programming OS X and iOS applications, as
+well as the iTunes configuration XML file.
+
+Plist files represent stored programming "object"s. They are very similar
+to JSON. A valid Plist file is representable as a native JavaScript Object
+and vice-versa.
+
+
+## Usage
+
+### Node.js
+
+Install using `npm`:
+
+``` bash
+$ npm install --save plist
+```
+
+Then `require()` the _plist_ module in your file:
+
+``` js
+var plist = require('plist');
+
+// now use the `parse()` and `build()` functions
+var val = plist.parse('<plist><string>Hello World!</string></plist>');
+console.log(val); // "Hello World!"
+```
+
+
+### Browser
+
+Include the `dist/plist.js` in a `<script>` tag in your HTML file:
+
+``` html
+<script src="plist.js"></script>
+<script>
+ // now use the `parse()` and `build()` functions
+ var val = plist.parse('<plist><string>Hello World!</string></plist>');
+ console.log(val); // "Hello World!"
+</script>
+```
+
+
+## API
+
+### Parsing
+
+Parsing a plist from filename:
+
+``` javascript
+var fs = require('fs');
+var plist = require('plist');
+
+var obj = plist.parse(fs.readFileSync('myPlist.plist', 'utf8'));
+console.log(JSON.stringify(obj));
+```
+
+Parsing a plist from string payload:
+
+``` javascript
+var plist = require('plist');
+
+var obj = plist.parse('<plist><string>Hello World!</string></plist>');
+console.log(obj); // Hello World!
+```
+
+### Building
+
+Given an existing JavaScript Object, you can turn it into an XML document
+that complies with the plist DTD:
+
+``` javascript
+var plist = require('plist');
+
+console.log(plist.build({ foo: 'bar' }));
+```
+
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2010-2014 Nathan Rajlich <na...@tootallnate.net>
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org