cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fil...@apache.org
Subject [04/12] android commit: CB-12546: move check_reqs to templates directory and update module references.
Date Mon, 20 Mar 2017 17:51:22 GMT
CB-12546: move check_reqs to templates directory and update module references.


Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/d40c2244
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/d40c2244
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/d40c2244

Branch: refs/heads/master
Commit: d40c22441fcc9134e12401eb370d623a8f2eb9ea
Parents: 6395eda
Author: filmaj <maj.fil@gmail.com>
Authored: Tue Mar 14 14:18:00 2017 -0700
Committer: filmaj <maj.fil@gmail.com>
Committed: Mon Mar 20 10:08:36 2017 -0700

----------------------------------------------------------------------
 bin/check_reqs                                  |   2 +-
 bin/lib/check_reqs.js                           | 411 ------------------
 bin/lib/create.js                               |   4 +-
 bin/templates/cordova/lib/check_reqs.js         | 412 +++++++++++++++++++
 bin/templates/cordova/lib/emulator.js           |   7 +-
 bin/templates/cordova/lib/list-devices          |   2 +-
 bin/templates/cordova/lib/list-emulator-images  |   2 +-
 .../cordova/lib/list-started-emulators          |   2 +-
 node_modules/pseudomap/LICENSE                  |  15 +
 node_modules/pseudomap/README.md                |  60 +++
 node_modules/pseudomap/map.js                   |   9 +
 node_modules/pseudomap/package.json             |  85 ++++
 node_modules/pseudomap/pseudomap.js             | 113 +++++
 node_modules/pseudomap/test/basic.js            |  86 ++++
 node_modules/yallist/LICENSE                    |  15 +
 node_modules/yallist/README.md                  | 204 +++++++++
 node_modules/yallist/iterator.js                |   7 +
 node_modules/yallist/package.json               |  96 +++++
 node_modules/yallist/yallist.js                 | 370 +++++++++++++++++
 spec/unit/check_reqs.spec.js                    |   9 +-
 20 files changed, 1488 insertions(+), 423 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/bin/check_reqs
----------------------------------------------------------------------
diff --git a/bin/check_reqs b/bin/check_reqs
index 372a383..628628f 100755
--- a/bin/check_reqs
+++ b/bin/check_reqs
@@ -19,7 +19,7 @@
        under the License.
 */
 
-var check_reqs = require('./lib/check_reqs');
+var check_reqs = require('./templates/cordova/lib/check_reqs');
 
 check_reqs.run().done(
     function success() {

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/bin/lib/check_reqs.js
----------------------------------------------------------------------
diff --git a/bin/lib/check_reqs.js b/bin/lib/check_reqs.js
deleted file mode 100644
index 6c93c4d..0000000
--- a/bin/lib/check_reqs.js
+++ /dev/null
@@ -1,411 +0,0 @@
-#!/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.
-*/
-
-/* jshint sub:true */
-
-var shelljs = require('shelljs'),
-    child_process = require('child_process'),
-    Q     = require('q'),
-    path  = require('path'),
-    fs    = require('fs'),
-    os    = require('os'),
-    ROOT  = path.join(__dirname, '..', '..');
-var CordovaError = require('cordova-common').CordovaError;
-
-
-function forgivingWhichSync(cmd) {
-    try {
-        return fs.realpathSync(shelljs.which(cmd));
-    } catch (e) {
-        return '';
-    }
-}
-
-function tryCommand(cmd, errMsg, catchStderr) {
-    var d = Q.defer();
-    child_process.exec(cmd, function(err, stdout, stderr) {
-        if (err) d.reject(new CordovaError(errMsg));
-        // Sometimes it is necessary to return an stderr instead of stdout in case of success, since
-        // some commands prints theirs output to stderr instead of stdout. 'javac' is the example
-        else d.resolve((catchStderr ? stderr : stdout).trim());
-    });
-    return d.promise;
-}
-
-module.exports.isWindows = function() {
-    return (process.platform == 'win32');
-};
-
-module.exports.isDarwin = function() {
-    return (process.platform == 'darwin');
-};
-
-// Get valid target from framework/project.properties
-module.exports.get_target = function() {
-    function extractFromFile(filePath) {
-        var target = shelljs.grep(/\btarget=/, filePath);
-        if (!target) {
-            throw new Error('Could not find android target within: ' + filePath);
-        }
-        return target.split('=')[1].trim();
-    }
-    if (fs.existsSync(path.join(ROOT, 'framework', 'project.properties'))) {
-        return extractFromFile(path.join(ROOT, 'framework', 'project.properties'));
-    }
-    if (fs.existsSync(path.join(ROOT, 'project.properties'))) {
-        // if no target found, we're probably in a project and project.properties is in ROOT.
-        return extractFromFile(path.join(ROOT, 'project.properties'));
-    }
-    throw new Error('Could not find android target. File missing: ' + path.join(ROOT, 'project.properties'));
-};
-
-// Returns a promise. Called only by build and clean commands.
-module.exports.check_ant = function() {
-    return tryCommand('ant -version', 'Failed to run "ant -version", make sure you have ant installed and added to your PATH.')
-    .then(function (output) {
-        // Parse Ant version from command output
-        return /version ((?:\d+\.)+(?:\d+))/i.exec(output)[1];
-    });
-};
-
-module.exports.get_gradle_wrapper = function() {
-    var androidStudioPath;
-    if(os.platform() == 'darwin') {
-      androidStudioPath = path.join('/Applications', 'Android Studio.app', 'Contents', 'gradle');
-    } else if (os.platform() == 'win32') {
-      androidStudioPath = path.join(process.env['ProgramFiles'],'Android', 'Android Studio', 'gradle');
-    }
-
-    if(androidStudioPath !== null && fs.existsSync(androidStudioPath)) {
-      var dirs = fs.readdirSync(androidStudioPath);
-      if(dirs[0].split('-')[0] == 'gradle')
-      {
-        return path.join(androidStudioPath, dirs[0], 'bin', 'gradle');
-      }
-    } else {
-      //OK, let's try to check for Gradle!
-      return forgivingWhichSync('gradle');
-    }
-};
-
-// Returns a promise. Called only by build and clean commands.
-module.exports.check_gradle = function() {
-    var sdkDir = process.env['ANDROID_HOME'];
-    var d = Q.defer();
-    if (!sdkDir)
-        return Q.reject(new CordovaError('Could not find gradle wrapper within Android SDK. Could not find Android SDK directory.\n' +
-            'Might need to install Android SDK or set up \'ANDROID_HOME\' env variable.'));
-
-    var gradlePath = module.exports.get_gradle_wrapper();
-    if(gradlePath.length !== 0)
-      d.resolve(gradlePath);
-    else
-      d.reject(new CordovaError('Could not find an installed version of Gradle either in Android Studio,\n' +
-                                'or on your system to install the gradle wrapper. Please include gradle \n' +
-                                'in your path, or install Android Studio'));
-    return d.promise;
-};
-
-
-// Returns a promise.
-module.exports.check_java = function() {
-    var javacPath = forgivingWhichSync('javac');
-    var hasJavaHome = !!process.env['JAVA_HOME'];
-    return Q().then(function() {
-        if (hasJavaHome) {
-            // Windows java installer doesn't add javac to PATH, nor set JAVA_HOME (ugh).
-            if (!javacPath) {
-                process.env['PATH'] += path.delimiter + path.join(process.env['JAVA_HOME'], 'bin');
-            }
-        } else {
-            if (javacPath) {
-                var msg = 'Failed to find \'JAVA_HOME\' environment variable. Try setting setting it manually.';
-                // OS X has a command for finding JAVA_HOME.
-                if (fs.existsSync('/usr/libexec/java_home')) {
-                    return tryCommand('/usr/libexec/java_home', msg)
-                    .then(function(stdout) {
-                        process.env['JAVA_HOME'] = stdout.trim();
-                    });
-                } else {
-                    // See if we can derive it from javac's location.
-                    // fs.realpathSync is require on Ubuntu, which symplinks from /usr/bin -> JDK
-                    var maybeJavaHome = path.dirname(path.dirname(javacPath));
-                    if (fs.existsSync(path.join(maybeJavaHome, 'lib', 'tools.jar'))) {
-                        process.env['JAVA_HOME'] = maybeJavaHome;
-                    } else {
-                        throw new CordovaError(msg);
-                    }
-                }
-            } else if (module.exports.isWindows()) {
-                // Try to auto-detect java in the default install paths.
-                var oldSilent = shelljs.config.silent;
-                shelljs.config.silent = true;
-                var firstJdkDir =
-                    shelljs.ls(process.env['ProgramFiles'] + '\\java\\jdk*')[0] ||
-                    shelljs.ls('C:\\Program Files\\java\\jdk*')[0] ||
-                    shelljs.ls('C:\\Program Files (x86)\\java\\jdk*')[0];
-                shelljs.config.silent = oldSilent;
-                if (firstJdkDir) {
-                    // shelljs always uses / in paths.
-                    firstJdkDir = firstJdkDir.replace(/\//g, path.sep);
-                    if (!javacPath) {
-                        process.env['PATH'] += path.delimiter + path.join(firstJdkDir, 'bin');
-                    }
-                    process.env['JAVA_HOME'] = firstJdkDir;
-                }
-            }
-        }
-    }).then(function() {
-            var msg =
-                'Failed to run "javac -version", make sure that you have a JDK installed.\n' +
-                'You can get it from: http://www.oracle.com/technetwork/java/javase/downloads.\n';
-            if (process.env['JAVA_HOME']) {
-                msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'] + '\n';
-            }
-            // We use tryCommand with catchStderr = true, because
-            // javac writes version info to stderr instead of stdout
-            return tryCommand('javac -version', msg, true)
-                .then(function (output) {
-                    //Let's check for at least Java 8, and keep it future proof so we can support Java 10
-                    var match = /javac ((?:1\.)(?:[8-9]\.)(?:\d+))|((?:1\.)(?:[1-9]\d+\.)(?:\d+))/i.exec(output);
-                    return match && match[1];
-                });
-        });
-};
-
-// Returns a promise.
-module.exports.check_android = function() {
-    return Q().then(function() {
-        var androidCmdPath = forgivingWhichSync('android');
-        var adbInPath = forgivingWhichSync('adb');
-        var avdmanagerInPath = forgivingWhichSync('avdmanager');
-        var hasAndroidHome = !!process.env['ANDROID_HOME'] && fs.existsSync(process.env['ANDROID_HOME']);
-        function maybeSetAndroidHome(value) {
-            if (!hasAndroidHome && fs.existsSync(value)) {
-                hasAndroidHome = true;
-                process.env['ANDROID_HOME'] = value;
-            }
-        }
-        // First ensure ANDROID_HOME is set
-        // If we have no hints (nothing in PATH), try a few default locations
-        if (!hasAndroidHome && !androidCmdPath && !adbInPath && !avdmanagerInPath) {
-            if (module.exports.isWindows()) {
-                // Android Studio 1.0 installer
-                maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'sdk'));
-                maybeSetAndroidHome(path.join(process.env['ProgramFiles'], 'Android', 'sdk'));
-                // Android Studio pre-1.0 installer
-                maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'android-studio', 'sdk'));
-                maybeSetAndroidHome(path.join(process.env['ProgramFiles'], 'Android', 'android-studio', 'sdk'));
-                // Stand-alone installer
-                maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'android-sdk'));
-                maybeSetAndroidHome(path.join(process.env['ProgramFiles'], 'Android', 'android-sdk'));
-            } else if (module.exports.isDarwin()) {
-                // Android Studio 1.0 installer
-                maybeSetAndroidHome(path.join(process.env['HOME'], 'Library', 'Android', 'sdk'));
-                // Android Studio pre-1.0 installer
-                maybeSetAndroidHome('/Applications/Android Studio.app/sdk');
-                // Stand-alone zip file that user might think to put under /Applications
-                maybeSetAndroidHome('/Applications/android-sdk-macosx');
-                maybeSetAndroidHome('/Applications/android-sdk');
-            }
-            if (process.env['HOME']) {
-                // Stand-alone zip file that user might think to put under their home directory
-                maybeSetAndroidHome(path.join(process.env['HOME'], 'android-sdk-macosx'));
-                maybeSetAndroidHome(path.join(process.env['HOME'], 'android-sdk'));
-            }
-        }
-        if (!hasAndroidHome) {
-            // If we dont have ANDROID_HOME, but we do have some tools on the PATH, try to infer from the tooling PATH.
-            var parentDir, grandParentDir;
-            if (androidCmdPath) {
-                parentDir = path.dirname(androidCmdPath);
-                grandParentDir = path.dirname(parentDir);
-                if (path.basename(parentDir) == 'tools' || fs.existsSync(path.join(grandParentDir, 'tools', 'android'))) {
-                    maybeSetAndroidHome(grandParentDir);
-                } else {
-                    throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
-                        'Detected \'android\' command at ' + parentDir + ' but no \'tools\' directory found near.\n' +
-                        'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools directory.');
-                }
-            }
-            if (adbInPath) {
-                parentDir = path.dirname(adbInPath);
-                grandParentDir = path.dirname(parentDir);
-                if (path.basename(parentDir) == 'platform-tools') {
-                    maybeSetAndroidHome(grandParentDir);
-                } else {
-                    throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
-                        'Detected \'adb\' command at ' + parentDir + ' but no \'platform-tools\' directory found near.\n' +
-                        'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'platform-tools directory.');
-                }
-            }
-            if (avdmanagerInPath) {
-                parentDir = path.dirname(avdmanagerInPath);
-                grandParentDir = path.dirname(parentDir);
-                if (path.basename(parentDir) == 'bin' && path.basename(grandParentDir) == 'tools') {
-                    maybeSetAndroidHome(path.dirname(grandParentDir));
-                } else {
-                    throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
-                        'Detected \'avdmanager\' command at ' + parentDir + ' but no \'tools' + path.sep + 'bin\' directory found near.\n' +
-                        'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools' + path.sep + 'bin directory.');
-                }
-            }
-        }
-        if (!process.env['ANDROID_HOME']) {
-            throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
-                'Failed to find \'android\' command in your \'PATH\'. Try update your \'PATH\' to include path to valid SDK directory.');
-        }
-        if (!fs.existsSync(process.env['ANDROID_HOME'])) {
-            throw new CordovaError('\'ANDROID_HOME\' environment variable is set to non-existent path: ' + process.env['ANDROID_HOME'] +
-                '\nTry update it manually to point to valid SDK directory.');
-        }
-        // Next let's make sure relevant parts of the SDK tooling is in our PATH
-        if (hasAndroidHome && !androidCmdPath) {
-            process.env['PATH'] += path.delimiter + path.join(process.env['ANDROID_HOME'], 'tools');
-        }
-        if (hasAndroidHome && !adbInPath) {
-            process.env['PATH'] += path.delimiter + path.join(process.env['ANDROID_HOME'], 'platform-tools');
-        }
-        if (hasAndroidHome && !avdmanagerInPath) {
-            process.env['PATH'] += path.delimiter + path.join(process.env['ANDROID_HOME'], 'tools', 'bin');
-        }
-        return hasAndroidHome;
-    });
-};
-
-module.exports.getAbsoluteAndroidCmd = function () {
-    var cmd = forgivingWhichSync('android');
-    if(cmd.length === 0)
-      cmd = forgivingWhichSync('avdmanager');
-    if (process.platform === 'win32') {
-        return '"' + cmd + '"';
-    }
-    return cmd.replace(/(\s)/g, '\\$1');
-};
-
-module.exports.check_android_target = function(originalError) {
-    // valid_target can look like:
-    //   android-19
-    //   android-L
-    //   Google Inc.:Google APIs:20
-    //   Google Inc.:Glass Development Kit Preview:20
-    var valid_target = module.exports.get_target();
-    var msg = 'Android SDK not found. Make sure that it is installed. If it is not at the default location, set the ANDROID_HOME environment variable.';
-    //   Changing "targets" to "target" is stupid and makes more code.  Thanks Google!
-    var cmd = 'android list targets --compact';
-    if(forgivingWhichSync('avdmanager').length > 0)
-      cmd = 'avdmanager list target --compact';
-    return tryCommand(cmd, msg)
-    .then(function(output) {
-        var targets = output.split('\n');
-        if (targets.indexOf(valid_target) >= 0) {
-            return targets;
-        }
-
-        var androidCmd = module.exports.getAbsoluteAndroidCmd();
-        var msg = 'Please install Android target: "' + valid_target + '".\n\n' +
-            'Hint: Open the SDK manager by running: ' + androidCmd + '\n' +
-            'You will require:\n' +
-            '1. "SDK Platform" for ' + valid_target + '\n' +
-            '2. "Android SDK Platform-tools (latest)\n' +
-            '3. "Android SDK Build-tools" (latest)';
-        if (originalError) {
-            msg = originalError + '\n' + msg;
-        }
-        throw new CordovaError(msg);
-    });
-};
-
-// Returns a promise.
-module.exports.run = function() {
-     return Q.all([this.check_java(), this.check_android()])
-     .then(function(values) {
-         console.log('ANDROID_HOME=' + process.env['ANDROID_HOME']);
-         console.log('JAVA_HOME=' + process.env['JAVA_HOME']);
-
-         if (!values[0]) {
-            throw new CordovaError('Requirements check failed for JDK 1.8 or greater');
-         }
-
-
-         if (!values[1]) {
-            throw new CordovaError('Requirements check failed for Android SDK');
-         }
-     });
-};
-
-
-/**
- * Object thar represents one of requirements for current platform.
- * @param {String} id         The unique identifier for this requirements.
- * @param {String} name       The name of requirements. Human-readable field.
- * @param {String} version    The version of requirement installed. In some cases could be an array of strings
- *                            (for example, check_android_target returns an array of android targets installed)
- * @param {Boolean} installed Indicates whether the requirement is installed or not
- */
-var Requirement = function (id, name, version, installed) {
-    this.id = id;
-    this.name = name;
-    this.installed = installed || false;
-    this.metadata = {
-        version: version,
-    };
-};
-
-/**
- * Methods that runs all checks one by one and returns a result of checks
- * as an array of Requirement objects. This method intended to be used by cordova-lib check_reqs method
- *
- * @return Promise<Requirement[]> Array of requirements. Due to implementation, promise is always fulfilled.
- */
-module.exports.check_all = function() {
-
-    var requirements = [
-        new Requirement('java', 'Java JDK'),
-        new Requirement('androidSdk', 'Android SDK'),
-        new Requirement('androidTarget', 'Android target'),
-        new Requirement('gradle', 'Gradle')
-    ];
-
-    var checkFns = [
-        this.check_java,
-        this.check_android,
-        this.check_android_target,
-        this.check_gradle
-    ];
-
-    // Then execute requirement checks one-by-one
-    return checkFns.reduce(function (promise, checkFn, idx) {
-        // Update each requirement with results
-        var requirement = requirements[idx];
-        return promise.then(checkFn)
-        .then(function (version) {
-            requirement.installed = true;
-            requirement.metadata.version = version;
-        }, function (err) {
-            requirement.metadata.reason = err instanceof Error ? err.message : err;
-        });
-    }, Q())
-    .then(function () {
-        // When chain is completed, return requirements array to upstream API
-        return requirements;
-    });
-};

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/bin/lib/create.js
----------------------------------------------------------------------
diff --git a/bin/lib/create.js b/bin/lib/create.js
index 0bbb5c9..ae9d65e 100755
--- a/bin/lib/create.js
+++ b/bin/lib/create.js
@@ -23,7 +23,7 @@ var shell = require('shelljs'),
     Q     = require('q'),
     path  = require('path'),
     fs    = require('fs'),
-    check_reqs = require('./check_reqs'),
+    check_reqs = require('./../templates/cordova/lib/check_reqs'),
     ROOT    = path.join(__dirname, '..', '..');
 
 var MIN_SDK_VERSION = 16;
@@ -146,9 +146,7 @@ function copyScripts(projectPath) {
     shell.cp('-r', srcScriptsDir, projectPath);
     shell.cp('-r', path.join(ROOT, 'node_modules'), destScriptsDir);
     shell.cp(path.join(ROOT, 'bin', 'check_reqs*'), destScriptsDir);
-    shell.cp(path.join(ROOT, 'bin', 'lib', 'check_reqs.js'), path.join(projectPath, 'cordova', 'lib', 'check_reqs.js'));
     shell.cp(path.join(ROOT, 'bin', 'android_sdk_version*'), destScriptsDir);
-    shell.cp(path.join(ROOT, 'bin', 'lib', 'android_sdk.js'), path.join(projectPath, 'cordova', 'lib', 'android_sdk.js'));
 }
 
 /**

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/bin/templates/cordova/lib/check_reqs.js
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/check_reqs.js b/bin/templates/cordova/lib/check_reqs.js
new file mode 100644
index 0000000..c861c4b
--- /dev/null
+++ b/bin/templates/cordova/lib/check_reqs.js
@@ -0,0 +1,412 @@
+#!/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.
+*/
+
+/* jshint sub:true */
+
+var shelljs = require('shelljs'),
+    child_process = require('child_process'),
+    Q     = require('q'),
+    path  = require('path'),
+    fs    = require('fs'),
+    os    = require('os'),
+    ROOT  = path.join(__dirname, '..', '..', '..', '..');
+var CordovaError = require('cordova-common').CordovaError;
+
+
+function forgivingWhichSync(cmd) {
+    try {
+        return fs.realpathSync(shelljs.which(cmd));
+    } catch (e) {
+        return '';
+    }
+}
+
+function tryCommand(cmd, errMsg, catchStderr) {
+    var d = Q.defer();
+    child_process.exec(cmd, function(err, stdout, stderr) {
+        if (err) d.reject(new CordovaError(errMsg));
+        // Sometimes it is necessary to return an stderr instead of stdout in case of success, since
+        // some commands prints theirs output to stderr instead of stdout. 'javac' is the example
+        else d.resolve((catchStderr ? stderr : stdout).trim());
+    });
+    return d.promise;
+}
+
+module.exports.isWindows = function() {
+    return (process.platform == 'win32');
+};
+
+module.exports.isDarwin = function() {
+    return (process.platform == 'darwin');
+};
+
+// Get valid target from framework/project.properties if run from this repo
+// Otherwise get target from project.properties file within a generated cordova-android project
+module.exports.get_target = function() {
+    function extractFromFile(filePath) {
+        var target = shelljs.grep(/\btarget=/, filePath);
+        if (!target) {
+            throw new Error('Could not find android target within: ' + filePath);
+        }
+        return target.split('=')[1].trim();
+    }
+    if (fs.existsSync(path.join(ROOT, 'framework', 'project.properties'))) {
+        return extractFromFile(path.join(ROOT, 'framework', 'project.properties'));
+    }
+    if (fs.existsSync(path.join(ROOT, 'project.properties'))) {
+        // if no target found, we're probably in a project and project.properties is in ROOT.
+        return extractFromFile(path.join(ROOT, 'project.properties'));
+    }
+    throw new Error('Could not find android target. File missing: ' + path.join(ROOT, 'project.properties'));
+};
+
+// Returns a promise. Called only by build and clean commands.
+module.exports.check_ant = function() {
+    return tryCommand('ant -version', 'Failed to run "ant -version", make sure you have ant installed and added to your PATH.')
+    .then(function (output) {
+        // Parse Ant version from command output
+        return /version ((?:\d+\.)+(?:\d+))/i.exec(output)[1];
+    });
+};
+
+module.exports.get_gradle_wrapper = function() {
+    var androidStudioPath;
+    if(os.platform() == 'darwin') {
+      androidStudioPath = path.join('/Applications', 'Android Studio.app', 'Contents', 'gradle');
+    } else if (os.platform() == 'win32') {
+      androidStudioPath = path.join(process.env['ProgramFiles'],'Android', 'Android Studio', 'gradle');
+    }
+
+    if(androidStudioPath !== null && fs.existsSync(androidStudioPath)) {
+      var dirs = fs.readdirSync(androidStudioPath);
+      if(dirs[0].split('-')[0] == 'gradle')
+      {
+        return path.join(androidStudioPath, dirs[0], 'bin', 'gradle');
+      }
+    } else {
+      //OK, let's try to check for Gradle!
+      return forgivingWhichSync('gradle');
+    }
+};
+
+// Returns a promise. Called only by build and clean commands.
+module.exports.check_gradle = function() {
+    var sdkDir = process.env['ANDROID_HOME'];
+    var d = Q.defer();
+    if (!sdkDir)
+        return Q.reject(new CordovaError('Could not find gradle wrapper within Android SDK. Could not find Android SDK directory.\n' +
+            'Might need to install Android SDK or set up \'ANDROID_HOME\' env variable.'));
+
+    var gradlePath = module.exports.get_gradle_wrapper();
+    if(gradlePath.length !== 0)
+      d.resolve(gradlePath);
+    else
+      d.reject(new CordovaError('Could not find an installed version of Gradle either in Android Studio,\n' +
+                                'or on your system to install the gradle wrapper. Please include gradle \n' +
+                                'in your path, or install Android Studio'));
+    return d.promise;
+};
+
+
+// Returns a promise.
+module.exports.check_java = function() {
+    var javacPath = forgivingWhichSync('javac');
+    var hasJavaHome = !!process.env['JAVA_HOME'];
+    return Q().then(function() {
+        if (hasJavaHome) {
+            // Windows java installer doesn't add javac to PATH, nor set JAVA_HOME (ugh).
+            if (!javacPath) {
+                process.env['PATH'] += path.delimiter + path.join(process.env['JAVA_HOME'], 'bin');
+            }
+        } else {
+            if (javacPath) {
+                var msg = 'Failed to find \'JAVA_HOME\' environment variable. Try setting setting it manually.';
+                // OS X has a command for finding JAVA_HOME.
+                if (fs.existsSync('/usr/libexec/java_home')) {
+                    return tryCommand('/usr/libexec/java_home', msg)
+                    .then(function(stdout) {
+                        process.env['JAVA_HOME'] = stdout.trim();
+                    });
+                } else {
+                    // See if we can derive it from javac's location.
+                    // fs.realpathSync is require on Ubuntu, which symplinks from /usr/bin -> JDK
+                    var maybeJavaHome = path.dirname(path.dirname(javacPath));
+                    if (fs.existsSync(path.join(maybeJavaHome, 'lib', 'tools.jar'))) {
+                        process.env['JAVA_HOME'] = maybeJavaHome;
+                    } else {
+                        throw new CordovaError(msg);
+                    }
+                }
+            } else if (module.exports.isWindows()) {
+                // Try to auto-detect java in the default install paths.
+                var oldSilent = shelljs.config.silent;
+                shelljs.config.silent = true;
+                var firstJdkDir =
+                    shelljs.ls(process.env['ProgramFiles'] + '\\java\\jdk*')[0] ||
+                    shelljs.ls('C:\\Program Files\\java\\jdk*')[0] ||
+                    shelljs.ls('C:\\Program Files (x86)\\java\\jdk*')[0];
+                shelljs.config.silent = oldSilent;
+                if (firstJdkDir) {
+                    // shelljs always uses / in paths.
+                    firstJdkDir = firstJdkDir.replace(/\//g, path.sep);
+                    if (!javacPath) {
+                        process.env['PATH'] += path.delimiter + path.join(firstJdkDir, 'bin');
+                    }
+                    process.env['JAVA_HOME'] = firstJdkDir;
+                }
+            }
+        }
+    }).then(function() {
+            var msg =
+                'Failed to run "javac -version", make sure that you have a JDK installed.\n' +
+                'You can get it from: http://www.oracle.com/technetwork/java/javase/downloads.\n';
+            if (process.env['JAVA_HOME']) {
+                msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'] + '\n';
+            }
+            // We use tryCommand with catchStderr = true, because
+            // javac writes version info to stderr instead of stdout
+            return tryCommand('javac -version', msg, true)
+                .then(function (output) {
+                    //Let's check for at least Java 8, and keep it future proof so we can support Java 10
+                    var match = /javac ((?:1\.)(?:[8-9]\.)(?:\d+))|((?:1\.)(?:[1-9]\d+\.)(?:\d+))/i.exec(output);
+                    return match && match[1];
+                });
+        });
+};
+
+// Returns a promise.
+module.exports.check_android = function() {
+    return Q().then(function() {
+        var androidCmdPath = forgivingWhichSync('android');
+        var adbInPath = forgivingWhichSync('adb');
+        var avdmanagerInPath = forgivingWhichSync('avdmanager');
+        var hasAndroidHome = !!process.env['ANDROID_HOME'] && fs.existsSync(process.env['ANDROID_HOME']);
+        function maybeSetAndroidHome(value) {
+            if (!hasAndroidHome && fs.existsSync(value)) {
+                hasAndroidHome = true;
+                process.env['ANDROID_HOME'] = value;
+            }
+        }
+        // First ensure ANDROID_HOME is set
+        // If we have no hints (nothing in PATH), try a few default locations
+        if (!hasAndroidHome && !androidCmdPath && !adbInPath && !avdmanagerInPath) {
+            if (module.exports.isWindows()) {
+                // Android Studio 1.0 installer
+                maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'sdk'));
+                maybeSetAndroidHome(path.join(process.env['ProgramFiles'], 'Android', 'sdk'));
+                // Android Studio pre-1.0 installer
+                maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'android-studio', 'sdk'));
+                maybeSetAndroidHome(path.join(process.env['ProgramFiles'], 'Android', 'android-studio', 'sdk'));
+                // Stand-alone installer
+                maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'android-sdk'));
+                maybeSetAndroidHome(path.join(process.env['ProgramFiles'], 'Android', 'android-sdk'));
+            } else if (module.exports.isDarwin()) {
+                // Android Studio 1.0 installer
+                maybeSetAndroidHome(path.join(process.env['HOME'], 'Library', 'Android', 'sdk'));
+                // Android Studio pre-1.0 installer
+                maybeSetAndroidHome('/Applications/Android Studio.app/sdk');
+                // Stand-alone zip file that user might think to put under /Applications
+                maybeSetAndroidHome('/Applications/android-sdk-macosx');
+                maybeSetAndroidHome('/Applications/android-sdk');
+            }
+            if (process.env['HOME']) {
+                // Stand-alone zip file that user might think to put under their home directory
+                maybeSetAndroidHome(path.join(process.env['HOME'], 'android-sdk-macosx'));
+                maybeSetAndroidHome(path.join(process.env['HOME'], 'android-sdk'));
+            }
+        }
+        if (!hasAndroidHome) {
+            // If we dont have ANDROID_HOME, but we do have some tools on the PATH, try to infer from the tooling PATH.
+            var parentDir, grandParentDir;
+            if (androidCmdPath) {
+                parentDir = path.dirname(androidCmdPath);
+                grandParentDir = path.dirname(parentDir);
+                if (path.basename(parentDir) == 'tools' || fs.existsSync(path.join(grandParentDir, 'tools', 'android'))) {
+                    maybeSetAndroidHome(grandParentDir);
+                } else {
+                    throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
+                        'Detected \'android\' command at ' + parentDir + ' but no \'tools\' directory found near.\n' +
+                        'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools directory.');
+                }
+            }
+            if (adbInPath) {
+                parentDir = path.dirname(adbInPath);
+                grandParentDir = path.dirname(parentDir);
+                if (path.basename(parentDir) == 'platform-tools') {
+                    maybeSetAndroidHome(grandParentDir);
+                } else {
+                    throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
+                        'Detected \'adb\' command at ' + parentDir + ' but no \'platform-tools\' directory found near.\n' +
+                        'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'platform-tools directory.');
+                }
+            }
+            if (avdmanagerInPath) {
+                parentDir = path.dirname(avdmanagerInPath);
+                grandParentDir = path.dirname(parentDir);
+                if (path.basename(parentDir) == 'bin' && path.basename(grandParentDir) == 'tools') {
+                    maybeSetAndroidHome(path.dirname(grandParentDir));
+                } else {
+                    throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
+                        'Detected \'avdmanager\' command at ' + parentDir + ' but no \'tools' + path.sep + 'bin\' directory found near.\n' +
+                        'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools' + path.sep + 'bin directory.');
+                }
+            }
+        }
+        if (!process.env['ANDROID_HOME']) {
+            throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
+                'Failed to find \'android\' command in your \'PATH\'. Try update your \'PATH\' to include path to valid SDK directory.');
+        }
+        if (!fs.existsSync(process.env['ANDROID_HOME'])) {
+            throw new CordovaError('\'ANDROID_HOME\' environment variable is set to non-existent path: ' + process.env['ANDROID_HOME'] +
+                '\nTry update it manually to point to valid SDK directory.');
+        }
+        // Next let's make sure relevant parts of the SDK tooling is in our PATH
+        if (hasAndroidHome && !androidCmdPath) {
+            process.env['PATH'] += path.delimiter + path.join(process.env['ANDROID_HOME'], 'tools');
+        }
+        if (hasAndroidHome && !adbInPath) {
+            process.env['PATH'] += path.delimiter + path.join(process.env['ANDROID_HOME'], 'platform-tools');
+        }
+        if (hasAndroidHome && !avdmanagerInPath) {
+            process.env['PATH'] += path.delimiter + path.join(process.env['ANDROID_HOME'], 'tools', 'bin');
+        }
+        return hasAndroidHome;
+    });
+};
+
+module.exports.getAbsoluteAndroidCmd = function () {
+    var cmd = forgivingWhichSync('android');
+    if(cmd.length === 0)
+      cmd = forgivingWhichSync('avdmanager');
+    if (process.platform === 'win32') {
+        return '"' + cmd + '"';
+    }
+    return cmd.replace(/(\s)/g, '\\$1');
+};
+
+module.exports.check_android_target = function(originalError) {
+    // valid_target can look like:
+    //   android-19
+    //   android-L
+    //   Google Inc.:Google APIs:20
+    //   Google Inc.:Glass Development Kit Preview:20
+    var valid_target = module.exports.get_target();
+    var msg = 'Android SDK not found. Make sure that it is installed. If it is not at the default location, set the ANDROID_HOME environment variable.';
+    //   Changing "targets" to "target" is stupid and makes more code.  Thanks Google!
+    var cmd = 'android list targets --compact';
+    if(forgivingWhichSync('avdmanager').length > 0)
+      cmd = 'avdmanager list target --compact';
+    return tryCommand(cmd, msg)
+    .then(function(output) {
+        var targets = output.split('\n');
+        if (targets.indexOf(valid_target) >= 0) {
+            return targets;
+        }
+
+        var androidCmd = module.exports.getAbsoluteAndroidCmd();
+        var msg = 'Please install Android target: "' + valid_target + '".\n\n' +
+            'Hint: Open the SDK manager by running: ' + androidCmd + '\n' +
+            'You will require:\n' +
+            '1. "SDK Platform" for ' + valid_target + '\n' +
+            '2. "Android SDK Platform-tools (latest)\n' +
+            '3. "Android SDK Build-tools" (latest)';
+        if (originalError) {
+            msg = originalError + '\n' + msg;
+        }
+        throw new CordovaError(msg);
+    });
+};
+
+// Returns a promise.
+module.exports.run = function() {
+     return Q.all([this.check_java(), this.check_android()])
+     .then(function(values) {
+         console.log('ANDROID_HOME=' + process.env['ANDROID_HOME']);
+         console.log('JAVA_HOME=' + process.env['JAVA_HOME']);
+
+         if (!values[0]) {
+            throw new CordovaError('Requirements check failed for JDK 1.8 or greater');
+         }
+
+
+         if (!values[1]) {
+            throw new CordovaError('Requirements check failed for Android SDK');
+         }
+     });
+};
+
+
+/**
+ * Object thar represents one of requirements for current platform.
+ * @param {String} id         The unique identifier for this requirements.
+ * @param {String} name       The name of requirements. Human-readable field.
+ * @param {String} version    The version of requirement installed. In some cases could be an array of strings
+ *                            (for example, check_android_target returns an array of android targets installed)
+ * @param {Boolean} installed Indicates whether the requirement is installed or not
+ */
+var Requirement = function (id, name, version, installed) {
+    this.id = id;
+    this.name = name;
+    this.installed = installed || false;
+    this.metadata = {
+        version: version,
+    };
+};
+
+/**
+ * Methods that runs all checks one by one and returns a result of checks
+ * as an array of Requirement objects. This method intended to be used by cordova-lib check_reqs method
+ *
+ * @return Promise<Requirement[]> Array of requirements. Due to implementation, promise is always fulfilled.
+ */
+module.exports.check_all = function() {
+
+    var requirements = [
+        new Requirement('java', 'Java JDK'),
+        new Requirement('androidSdk', 'Android SDK'),
+        new Requirement('androidTarget', 'Android target'),
+        new Requirement('gradle', 'Gradle')
+    ];
+
+    var checkFns = [
+        this.check_java,
+        this.check_android,
+        this.check_android_target,
+        this.check_gradle
+    ];
+
+    // Then execute requirement checks one-by-one
+    return checkFns.reduce(function (promise, checkFn, idx) {
+        // Update each requirement with results
+        var requirement = requirements[idx];
+        return promise.then(checkFn)
+        .then(function (version) {
+            requirement.installed = true;
+            requirement.metadata.version = version;
+        }, function (err) {
+            requirement.metadata.reason = err instanceof Error ? err.message : err;
+        });
+    }, Q())
+    .then(function () {
+        // When chain is completed, return requirements array to upstream API
+        return requirements;
+    });
+};

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/bin/templates/cordova/lib/emulator.js
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/emulator.js b/bin/templates/cordova/lib/emulator.js
index b9e3d5d..b885085 100644
--- a/bin/templates/cordova/lib/emulator.js
+++ b/bin/templates/cordova/lib/emulator.js
@@ -31,6 +31,7 @@ var superspawn = require('cordova-common').superspawn;
 var CordovaError = require('cordova-common').CordovaError;
 var shelljs = require('shelljs');
 var android_sdk = require('./android_sdk');
+var check_reqs = require('./check_reqs');
 
 var Q             = require('q');
 var os            = require('os');
@@ -200,8 +201,7 @@ module.exports.best_image = function() {
 
         var closest = 9999;
         var best = images[0];
-        // Loading check_reqs at run-time to avoid test-time vs run-time directory structure difference issue
-        var project_target = require('./check_reqs').get_target().replace('android-', '');
+        var project_target = check_reqs.get_target().replace('android-', '');
         for (var i in images) {
             var target = images[i].target;
             if(target) {
@@ -280,8 +280,7 @@ module.exports.start = function(emulator_ID, boot_timeout) {
                 return best.name;
             }
 
-            // Loading check_reqs at run-time to avoid test-time vs run-time directory structure difference issue
-            var androidCmd = require('./check_reqs').getAbsoluteAndroidCmd();
+            var androidCmd = check_reqs.getAbsoluteAndroidCmd();
             return Q.reject(new CordovaError('No emulator images (avds) found.\n' +
                 '1. Download desired System Image by running: ' + androidCmd + ' sdk\n' +
                 '2. Create an AVD by running: ' + androidCmd + ' avd\n' +

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/bin/templates/cordova/lib/list-devices
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/list-devices b/bin/templates/cordova/lib/list-devices
index fa84d7f..8e22c7f 100755
--- a/bin/templates/cordova/lib/list-devices
+++ b/bin/templates/cordova/lib/list-devices
@@ -22,7 +22,7 @@
 var devices = require('./device');
 
 // Usage support for when args are given
-require('../lib/check_reqs').check_android().then(function() {
+require('./check_reqs').check_android().then(function() {
     devices.list().done(function(device_list) {
         device_list && device_list.forEach(function(dev) {
             console.log(dev);

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/bin/templates/cordova/lib/list-emulator-images
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/list-emulator-images b/bin/templates/cordova/lib/list-emulator-images
index 03c827f..25e5c81 100755
--- a/bin/templates/cordova/lib/list-emulator-images
+++ b/bin/templates/cordova/lib/list-emulator-images
@@ -22,7 +22,7 @@
 var emulators = require('./emulator');
 
 // Usage support for when args are given
-require('../lib/check_reqs').check_android().then(function() {
+require('./check_reqs').check_android().then(function() {
     emulators.list_images().done(function(emulator_list) {
         emulator_list && emulator_list.forEach(function(emu) {
             console.log(emu.name);

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/bin/templates/cordova/lib/list-started-emulators
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/list-started-emulators b/bin/templates/cordova/lib/list-started-emulators
index a890dec..43ebda2 100755
--- a/bin/templates/cordova/lib/list-started-emulators
+++ b/bin/templates/cordova/lib/list-started-emulators
@@ -22,7 +22,7 @@
 var emulators = require('./emulator');
 
 // Usage support for when args are given
-require('../lib/check_reqs').check_android().then(function() {
+require('./check_reqs').check_android().then(function() {
     emulators.list_started().done(function(emulator_list) {
         emulator_list && emulator_list.forEach(function(emu) {
             console.log(emu);

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/node_modules/pseudomap/LICENSE
----------------------------------------------------------------------
diff --git a/node_modules/pseudomap/LICENSE b/node_modules/pseudomap/LICENSE
new file mode 100644
index 0000000..19129e3
--- /dev/null
+++ b/node_modules/pseudomap/LICENSE
@@ -0,0 +1,15 @@
+The ISC License
+
+Copyright (c) Isaac Z. Schlueter and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/node_modules/pseudomap/README.md
----------------------------------------------------------------------
diff --git a/node_modules/pseudomap/README.md b/node_modules/pseudomap/README.md
new file mode 100644
index 0000000..778bf01
--- /dev/null
+++ b/node_modules/pseudomap/README.md
@@ -0,0 +1,60 @@
+# pseudomap
+
+A thing that is a lot like ES6 `Map`, but without iterators, for use
+in environments where `for..of` syntax and `Map` are not available.
+
+If you need iterators, or just in general a more faithful polyfill to
+ES6 Maps, check out [es6-map](http://npm.im/es6-map).
+
+If you are in an environment where `Map` is supported, then that will
+be returned instead, unless `process.env.TEST_PSEUDOMAP` is set.
+
+You can use any value as keys, and any value as data.  Setting again
+with the identical key will overwrite the previous value.
+
+Internally, data is stored on an `Object.create(null)` style object.
+The key is coerced to a string to generate the key on the internal
+data-bag object.  The original key used is stored along with the data.
+
+In the event of a stringified-key collision, a new key is generated by
+appending an increasing number to the stringified-key until finding
+either the intended key or an empty spot.
+
+Note that because object traversal order of plain objects is not
+guaranteed to be identical to insertion order, the insertion order
+guarantee of `Map.prototype.forEach` is not guaranteed in this
+implementation.  However, in all versions of Node.js and V8 where this
+module works, `forEach` does traverse data in insertion order.
+
+## API
+
+Most of the [Map
+API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map),
+with the following exceptions:
+
+1. A `Map` object is not an iterator.
+2. `values`, `keys`, and `entries` methods are not implemented,
+   because they return iterators.
+3. The argument to the constructor can be an Array of `[key, value]`
+   pairs, or a `Map` or `PseudoMap` object.  But, since iterators
+   aren't used, passing any plain-old iterator won't initialize the
+   map properly.
+
+## USAGE
+
+Use just like a regular ES6 Map.
+
+```javascript
+var PseudoMap = require('pseudomap')
+
+// optionally provide a pseudomap, or an array of [key,value] pairs
+// as the argument to initialize the map with
+var myMap = new PseudoMap()
+
+myMap.set(1, 'number 1')
+myMap.set('1', 'string 1')
+var akey = {}
+var bkey = {}
+myMap.set(akey, { some: 'data' })
+myMap.set(bkey, { some: 'other data' })
+```

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/node_modules/pseudomap/map.js
----------------------------------------------------------------------
diff --git a/node_modules/pseudomap/map.js b/node_modules/pseudomap/map.js
new file mode 100644
index 0000000..7db1599
--- /dev/null
+++ b/node_modules/pseudomap/map.js
@@ -0,0 +1,9 @@
+if (process.env.npm_package_name === 'pseudomap' &&
+    process.env.npm_lifecycle_script === 'test')
+  process.env.TEST_PSEUDOMAP = 'true'
+
+if (typeof Map === 'function' && !process.env.TEST_PSEUDOMAP) {
+  module.exports = Map
+} else {
+  module.exports = require('./pseudomap')
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/node_modules/pseudomap/package.json
----------------------------------------------------------------------
diff --git a/node_modules/pseudomap/package.json b/node_modules/pseudomap/package.json
new file mode 100644
index 0000000..df0511d
--- /dev/null
+++ b/node_modules/pseudomap/package.json
@@ -0,0 +1,85 @@
+{
+  "_args": [
+    [
+      {
+        "raw": "pseudomap@^1.0.1",
+        "scope": null,
+        "escapedName": "pseudomap",
+        "name": "pseudomap",
+        "rawSpec": "^1.0.1",
+        "spec": ">=1.0.1 <2.0.0",
+        "type": "range"
+      },
+      "/Users/maj/src/cordova-android/node_modules/lru-cache"
+    ]
+  ],
+  "_from": "pseudomap@>=1.0.1 <2.0.0",
+  "_id": "pseudomap@1.0.2",
+  "_inCache": true,
+  "_location": "/pseudomap",
+  "_nodeVersion": "4.0.0",
+  "_npmUser": {
+    "name": "isaacs",
+    "email": "i@izs.me"
+  },
+  "_npmVersion": "3.3.2",
+  "_phantomChildren": {},
+  "_requested": {
+    "raw": "pseudomap@^1.0.1",
+    "scope": null,
+    "escapedName": "pseudomap",
+    "name": "pseudomap",
+    "rawSpec": "^1.0.1",
+    "spec": ">=1.0.1 <2.0.0",
+    "type": "range"
+  },
+  "_requiredBy": [
+    "/lru-cache"
+  ],
+  "_resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+  "_shasum": "f052a28da70e618917ef0a8ac34c1ae5a68286b3",
+  "_shrinkwrap": null,
+  "_spec": "pseudomap@^1.0.1",
+  "_where": "/Users/maj/src/cordova-android/node_modules/lru-cache",
+  "author": {
+    "name": "Isaac Z. Schlueter",
+    "email": "i@izs.me",
+    "url": "http://blog.izs.me/"
+  },
+  "bugs": {
+    "url": "https://github.com/isaacs/pseudomap/issues"
+  },
+  "dependencies": {},
+  "description": "A thing that is a lot like ES6 `Map`, but without iterators, for use in environments where `for..of` syntax and `Map` are not available.",
+  "devDependencies": {
+    "tap": "^2.3.1"
+  },
+  "directories": {
+    "test": "test"
+  },
+  "dist": {
+    "shasum": "f052a28da70e618917ef0a8ac34c1ae5a68286b3",
+    "tarball": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz"
+  },
+  "gitHead": "b6dc728207a0321ede6479e34506d3e0e13a940b",
+  "homepage": "https://github.com/isaacs/pseudomap#readme",
+  "license": "ISC",
+  "main": "map.js",
+  "maintainers": [
+    {
+      "name": "isaacs",
+      "email": "i@izs.me"
+    }
+  ],
+  "name": "pseudomap",
+  "optionalDependencies": {},
+  "readme": "ERROR: No README data found!",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/isaacs/pseudomap.git"
+  },
+  "scripts": {
+    "test": "tap test/*.js"
+  },
+  "version": "1.0.2"
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/node_modules/pseudomap/pseudomap.js
----------------------------------------------------------------------
diff --git a/node_modules/pseudomap/pseudomap.js b/node_modules/pseudomap/pseudomap.js
new file mode 100644
index 0000000..25a21d8
--- /dev/null
+++ b/node_modules/pseudomap/pseudomap.js
@@ -0,0 +1,113 @@
+var hasOwnProperty = Object.prototype.hasOwnProperty
+
+module.exports = PseudoMap
+
+function PseudoMap (set) {
+  if (!(this instanceof PseudoMap)) // whyyyyyyy
+    throw new TypeError("Constructor PseudoMap requires 'new'")
+
+  this.clear()
+
+  if (set) {
+    if ((set instanceof PseudoMap) ||
+        (typeof Map === 'function' && set instanceof Map))
+      set.forEach(function (value, key) {
+        this.set(key, value)
+      }, this)
+    else if (Array.isArray(set))
+      set.forEach(function (kv) {
+        this.set(kv[0], kv[1])
+      }, this)
+    else
+      throw new TypeError('invalid argument')
+  }
+}
+
+PseudoMap.prototype.forEach = function (fn, thisp) {
+  thisp = thisp || this
+  Object.keys(this._data).forEach(function (k) {
+    if (k !== 'size')
+      fn.call(thisp, this._data[k].value, this._data[k].key)
+  }, this)
+}
+
+PseudoMap.prototype.has = function (k) {
+  return !!find(this._data, k)
+}
+
+PseudoMap.prototype.get = function (k) {
+  var res = find(this._data, k)
+  return res && res.value
+}
+
+PseudoMap.prototype.set = function (k, v) {
+  set(this._data, k, v)
+}
+
+PseudoMap.prototype.delete = function (k) {
+  var res = find(this._data, k)
+  if (res) {
+    delete this._data[res._index]
+    this._data.size--
+  }
+}
+
+PseudoMap.prototype.clear = function () {
+  var data = Object.create(null)
+  data.size = 0
+
+  Object.defineProperty(this, '_data', {
+    value: data,
+    enumerable: false,
+    configurable: true,
+    writable: false
+  })
+}
+
+Object.defineProperty(PseudoMap.prototype, 'size', {
+  get: function () {
+    return this._data.size
+  },
+  set: function (n) {},
+  enumerable: true,
+  configurable: true
+})
+
+PseudoMap.prototype.values =
+PseudoMap.prototype.keys =
+PseudoMap.prototype.entries = function () {
+  throw new Error('iterators are not implemented in this version')
+}
+
+// Either identical, or both NaN
+function same (a, b) {
+  return a === b || a !== a && b !== b
+}
+
+function Entry (k, v, i) {
+  this.key = k
+  this.value = v
+  this._index = i
+}
+
+function find (data, k) {
+  for (var i = 0, s = '_' + k, key = s;
+       hasOwnProperty.call(data, key);
+       key = s + i++) {
+    if (same(data[key].key, k))
+      return data[key]
+  }
+}
+
+function set (data, k, v) {
+  for (var i = 0, s = '_' + k, key = s;
+       hasOwnProperty.call(data, key);
+       key = s + i++) {
+    if (same(data[key].key, k)) {
+      data[key].value = v
+      return
+    }
+  }
+  data.size++
+  data[key] = new Entry(k, v, key)
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/node_modules/pseudomap/test/basic.js
----------------------------------------------------------------------
diff --git a/node_modules/pseudomap/test/basic.js b/node_modules/pseudomap/test/basic.js
new file mode 100644
index 0000000..4378e45
--- /dev/null
+++ b/node_modules/pseudomap/test/basic.js
@@ -0,0 +1,86 @@
+var t = require('tap')
+
+process.env.TEST_PSEUDOMAP = 'true'
+
+var PM = require('../')
+runTests(PM)
+
+// if possible, verify that Map also behaves the same way
+if (typeof Map === 'function')
+  runTests(Map)
+
+
+function runTests (Map) {
+  t.throws(Map)
+
+  var m = new Map()
+
+  t.equal(m.size, 0)
+
+  m.set(1, '1 string')
+  t.equal(m.get(1), '1 string')
+  t.equal(m.size, 1)
+  m.size = 1000
+  t.equal(m.size, 1)
+  m.size = 0
+  t.equal(m.size, 1)
+
+  m = new Map([[1, 'number 1'], ['1', 'string 1']])
+  t.equal(m.get(1), 'number 1')
+  t.equal(m.get('1'), 'string 1')
+  t.equal(m.size, 2)
+
+  m = new Map(m)
+  t.equal(m.get(1), 'number 1')
+  t.equal(m.get('1'), 'string 1')
+  t.equal(m.size, 2)
+
+  var akey = {}
+  var bkey = {}
+  m.set(akey, { some: 'data' })
+  m.set(bkey, { some: 'other data' })
+  t.same(m.get(akey), { some: 'data' })
+  t.same(m.get(bkey), { some: 'other data' })
+  t.equal(m.size, 4)
+
+  var x = /x/
+  var y = /x/
+  m.set(x, 'x regex')
+  m.set(y, 'y regex')
+  t.equal(m.get(x), 'x regex')
+  m.set(x, 'x again')
+  t.equal(m.get(x), 'x again')
+  t.equal(m.size, 6)
+
+  m.set(NaN, 'not a number')
+  t.equal(m.get(NaN), 'not a number')
+  m.set(NaN, 'it is a ' + typeof NaN)
+  t.equal(m.get(NaN), 'it is a number')
+  m.set('NaN', 'stringie nan')
+  t.equal(m.get(NaN), 'it is a number')
+  t.equal(m.get('NaN'), 'stringie nan')
+  t.equal(m.size, 8)
+
+  m.delete(NaN)
+  t.equal(m.get(NaN), undefined)
+  t.equal(m.size, 7)
+
+  var expect = [
+    { value: 'number 1', key: 1 },
+    { value: 'string 1', key: '1' },
+    { value: { some: 'data' }, key: {} },
+    { value: { some: 'other data' }, key: {} },
+    { value: 'x again', key: /x/ },
+    { value: 'y regex', key: /x/ },
+    { value: 'stringie nan', key: 'NaN' }
+  ]
+  var actual = []
+
+  m.forEach(function (value, key) {
+    actual.push({ value: value, key: key })
+  })
+  t.same(actual, expect)
+
+  m.clear()
+  t.equal(m.size, 0)
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/node_modules/yallist/LICENSE
----------------------------------------------------------------------
diff --git a/node_modules/yallist/LICENSE b/node_modules/yallist/LICENSE
new file mode 100644
index 0000000..19129e3
--- /dev/null
+++ b/node_modules/yallist/LICENSE
@@ -0,0 +1,15 @@
+The ISC License
+
+Copyright (c) Isaac Z. Schlueter and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/node_modules/yallist/README.md
----------------------------------------------------------------------
diff --git a/node_modules/yallist/README.md b/node_modules/yallist/README.md
new file mode 100644
index 0000000..f586101
--- /dev/null
+++ b/node_modules/yallist/README.md
@@ -0,0 +1,204 @@
+# yallist
+
+Yet Another Linked List
+
+There are many doubly-linked list implementations like it, but this
+one is mine.
+
+For when an array would be too big, and a Map can't be iterated in
+reverse order.
+
+
+[![Build Status](https://travis-ci.org/isaacs/yallist.svg?branch=master)](https://travis-ci.org/isaacs/yallist) [![Coverage Status](https://coveralls.io/repos/isaacs/yallist/badge.svg?service=github)](https://coveralls.io/github/isaacs/yallist)
+
+## basic usage
+
+```javascript
+var yallist = require('yallist')
+var myList = yallist.create([1, 2, 3])
+myList.push('foo')
+myList.unshift('bar')
+// of course pop() and shift() are there, too
+console.log(myList.toArray()) // ['bar', 1, 2, 3, 'foo']
+myList.forEach(function (k) {
+  // walk the list head to tail
+})
+myList.forEachReverse(function (k, index, list) {
+  // walk the list tail to head
+})
+var myDoubledList = myList.map(function (k) {
+  return k + k
+})
+// now myDoubledList contains ['barbar', 2, 4, 6, 'foofoo']
+// mapReverse is also a thing
+var myDoubledListReverse = myList.mapReverse(function (k) {
+  return k + k
+}) // ['foofoo', 6, 4, 2, 'barbar']
+
+var reduced = myList.reduce(function (set, entry) {
+  set += entry
+  return set
+}, 'start')
+console.log(reduced) // 'startfoo123bar'
+```
+
+## api
+
+The whole API is considered "public".
+
+Functions with the same name as an Array method work more or less the
+same way.
+
+There's reverse versions of most things because that's the point.
+
+### Yallist
+
+Default export, the class that holds and manages a list.
+
+Call it with either a forEach-able (like an array) or a set of
+arguments, to initialize the list.
+
+The Array-ish methods all act like you'd expect.  No magic length,
+though, so if you change that it won't automatically prune or add
+empty spots.
+
+### Yallist.create(..)
+
+Alias for Yallist function.  Some people like factories.
+
+#### yallist.head
+
+The first node in the list
+
+#### yallist.tail
+
+The last node in the list
+
+#### yallist.length
+
+The number of nodes in the list.  (Change this at your peril.  It is
+not magic like Array length.)
+
+#### yallist.toArray()
+
+Convert the list to an array.
+
+#### yallist.forEach(fn, [thisp])
+
+Call a function on each item in the list.
+
+#### yallist.forEachReverse(fn, [thisp])
+
+Call a function on each item in the list, in reverse order.
+
+#### yallist.get(n)
+
+Get the data at position `n` in the list.  If you use this a lot,
+probably better off just using an Array.
+
+#### yallist.getReverse(n)
+
+Get the data at position `n`, counting from the tail.
+
+#### yallist.map(fn, thisp)
+
+Create a new Yallist with the result of calling the function on each
+item.
+
+#### yallist.mapReverse(fn, thisp)
+
+Same as `map`, but in reverse.
+
+#### yallist.pop()
+
+Get the data from the list tail, and remove the tail from the list.
+
+#### yallist.push(item, ...)
+
+Insert one or more items to the tail of the list.
+
+#### yallist.reduce(fn, initialValue)
+
+Like Array.reduce.
+
+#### yallist.reduceReverse
+
+Like Array.reduce, but in reverse.
+
+#### yallist.reverse
+
+Reverse the list in place.
+
+#### yallist.shift()
+
+Get the data from the list head, and remove the head from the list.
+
+#### yallist.slice([from], [to])
+
+Just like Array.slice, but returns a new Yallist.
+
+#### yallist.sliceReverse([from], [to])
+
+Just like yallist.slice, but the result is returned in reverse.
+
+#### yallist.toArray()
+
+Create an array representation of the list.
+
+#### yallist.toArrayReverse()
+
+Create a reversed array representation of the list.
+
+#### yallist.unshift(item, ...)
+
+Insert one or more items to the head of the list.
+
+#### yallist.unshiftNode(node)
+
+Move a Node object to the front of the list.  (That is, pull it out of
+wherever it lives, and make it the new head.)
+
+If the node belongs to a different list, then that list will remove it
+first.
+
+#### yallist.pushNode(node)
+
+Move a Node object to the end of the list.  (That is, pull it out of
+wherever it lives, and make it the new tail.)
+
+If the node belongs to a list already, then that list will remove it
+first.
+
+#### yallist.removeNode(node)
+
+Remove a node from the list, preserving referential integrity of head
+and tail and other nodes.
+
+Will throw an error if you try to have a list remove a node that
+doesn't belong to it.
+
+### Yallist.Node
+
+The class that holds the data and is actually the list.
+
+Call with `var n = new Node(value, previousNode, nextNode)`
+
+Note that if you do direct operations on Nodes themselves, it's very
+easy to get into weird states where the list is broken.  Be careful :)
+
+#### node.next
+
+The next node in the list.
+
+#### node.prev
+
+The previous node in the list.
+
+#### node.value
+
+The data the node contains.
+
+#### node.list
+
+The list to which this node belongs.  (Null if it does not belong to
+any list.)

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/node_modules/yallist/iterator.js
----------------------------------------------------------------------
diff --git a/node_modules/yallist/iterator.js b/node_modules/yallist/iterator.js
new file mode 100644
index 0000000..4a15bf2
--- /dev/null
+++ b/node_modules/yallist/iterator.js
@@ -0,0 +1,7 @@
+var Yallist = require('./yallist.js')
+
+Yallist.prototype[Symbol.iterator] = function* () {
+  for (let walker = this.head; walker; walker = walker.next) {
+    yield walker.value
+  }
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/node_modules/yallist/package.json
----------------------------------------------------------------------
diff --git a/node_modules/yallist/package.json b/node_modules/yallist/package.json
new file mode 100644
index 0000000..f72c398
--- /dev/null
+++ b/node_modules/yallist/package.json
@@ -0,0 +1,96 @@
+{
+  "_args": [
+    [
+      {
+        "raw": "yallist@^2.0.0",
+        "scope": null,
+        "escapedName": "yallist",
+        "name": "yallist",
+        "rawSpec": "^2.0.0",
+        "spec": ">=2.0.0 <3.0.0",
+        "type": "range"
+      },
+      "/Users/maj/src/cordova-android/node_modules/lru-cache"
+    ]
+  ],
+  "_from": "yallist@>=2.0.0 <3.0.0",
+  "_id": "yallist@2.1.2",
+  "_inCache": true,
+  "_location": "/yallist",
+  "_nodeVersion": "8.0.0-pre",
+  "_npmOperationalInternal": {
+    "host": "packages-12-west.internal.npmjs.com",
+    "tmp": "tmp/yallist-2.1.2.tgz_1489443365033_0.47744474792853"
+  },
+  "_npmUser": {
+    "name": "isaacs",
+    "email": "i@izs.me"
+  },
+  "_npmVersion": "4.3.0",
+  "_phantomChildren": {},
+  "_requested": {
+    "raw": "yallist@^2.0.0",
+    "scope": null,
+    "escapedName": "yallist",
+    "name": "yallist",
+    "rawSpec": "^2.0.0",
+    "spec": ">=2.0.0 <3.0.0",
+    "type": "range"
+  },
+  "_requiredBy": [
+    "/lru-cache"
+  ],
+  "_resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+  "_shasum": "1c11f9218f076089a47dd512f93c6699a6a81d52",
+  "_shrinkwrap": null,
+  "_spec": "yallist@^2.0.0",
+  "_where": "/Users/maj/src/cordova-android/node_modules/lru-cache",
+  "author": {
+    "name": "Isaac Z. Schlueter",
+    "email": "i@izs.me",
+    "url": "http://blog.izs.me/"
+  },
+  "bugs": {
+    "url": "https://github.com/isaacs/yallist/issues"
+  },
+  "dependencies": {},
+  "description": "Yet Another Linked List",
+  "devDependencies": {
+    "tap": "^10.3.0"
+  },
+  "directories": {
+    "test": "test"
+  },
+  "dist": {
+    "shasum": "1c11f9218f076089a47dd512f93c6699a6a81d52",
+    "tarball": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz"
+  },
+  "files": [
+    "yallist.js",
+    "iterator.js"
+  ],
+  "gitHead": "566cd4cd1e2ce57ffa84e295981cd9aa72319391",
+  "homepage": "https://github.com/isaacs/yallist#readme",
+  "license": "ISC",
+  "main": "yallist.js",
+  "maintainers": [
+    {
+      "name": "isaacs",
+      "email": "i@izs.me"
+    }
+  ],
+  "name": "yallist",
+  "optionalDependencies": {},
+  "readme": "ERROR: No README data found!",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/isaacs/yallist.git"
+  },
+  "scripts": {
+    "postpublish": "git push origin --all; git push origin --tags",
+    "postversion": "npm publish",
+    "preversion": "npm test",
+    "test": "tap test/*.js --100"
+  },
+  "version": "2.1.2"
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/node_modules/yallist/yallist.js
----------------------------------------------------------------------
diff --git a/node_modules/yallist/yallist.js b/node_modules/yallist/yallist.js
new file mode 100644
index 0000000..518d233
--- /dev/null
+++ b/node_modules/yallist/yallist.js
@@ -0,0 +1,370 @@
+module.exports = Yallist
+
+Yallist.Node = Node
+Yallist.create = Yallist
+
+function Yallist (list) {
+  var self = this
+  if (!(self instanceof Yallist)) {
+    self = new Yallist()
+  }
+
+  self.tail = null
+  self.head = null
+  self.length = 0
+
+  if (list && typeof list.forEach === 'function') {
+    list.forEach(function (item) {
+      self.push(item)
+    })
+  } else if (arguments.length > 0) {
+    for (var i = 0, l = arguments.length; i < l; i++) {
+      self.push(arguments[i])
+    }
+  }
+
+  return self
+}
+
+Yallist.prototype.removeNode = function (node) {
+  if (node.list !== this) {
+    throw new Error('removing node which does not belong to this list')
+  }
+
+  var next = node.next
+  var prev = node.prev
+
+  if (next) {
+    next.prev = prev
+  }
+
+  if (prev) {
+    prev.next = next
+  }
+
+  if (node === this.head) {
+    this.head = next
+  }
+  if (node === this.tail) {
+    this.tail = prev
+  }
+
+  node.list.length--
+  node.next = null
+  node.prev = null
+  node.list = null
+}
+
+Yallist.prototype.unshiftNode = function (node) {
+  if (node === this.head) {
+    return
+  }
+
+  if (node.list) {
+    node.list.removeNode(node)
+  }
+
+  var head = this.head
+  node.list = this
+  node.next = head
+  if (head) {
+    head.prev = node
+  }
+
+  this.head = node
+  if (!this.tail) {
+    this.tail = node
+  }
+  this.length++
+}
+
+Yallist.prototype.pushNode = function (node) {
+  if (node === this.tail) {
+    return
+  }
+
+  if (node.list) {
+    node.list.removeNode(node)
+  }
+
+  var tail = this.tail
+  node.list = this
+  node.prev = tail
+  if (tail) {
+    tail.next = node
+  }
+
+  this.tail = node
+  if (!this.head) {
+    this.head = node
+  }
+  this.length++
+}
+
+Yallist.prototype.push = function () {
+  for (var i = 0, l = arguments.length; i < l; i++) {
+    push(this, arguments[i])
+  }
+  return this.length
+}
+
+Yallist.prototype.unshift = function () {
+  for (var i = 0, l = arguments.length; i < l; i++) {
+    unshift(this, arguments[i])
+  }
+  return this.length
+}
+
+Yallist.prototype.pop = function () {
+  if (!this.tail) {
+    return undefined
+  }
+
+  var res = this.tail.value
+  this.tail = this.tail.prev
+  if (this.tail) {
+    this.tail.next = null
+  } else {
+    this.head = null
+  }
+  this.length--
+  return res
+}
+
+Yallist.prototype.shift = function () {
+  if (!this.head) {
+    return undefined
+  }
+
+  var res = this.head.value
+  this.head = this.head.next
+  if (this.head) {
+    this.head.prev = null
+  } else {
+    this.tail = null
+  }
+  this.length--
+  return res
+}
+
+Yallist.prototype.forEach = function (fn, thisp) {
+  thisp = thisp || this
+  for (var walker = this.head, i = 0; walker !== null; i++) {
+    fn.call(thisp, walker.value, i, this)
+    walker = walker.next
+  }
+}
+
+Yallist.prototype.forEachReverse = function (fn, thisp) {
+  thisp = thisp || this
+  for (var walker = this.tail, i = this.length - 1; walker !== null; i--) {
+    fn.call(thisp, walker.value, i, this)
+    walker = walker.prev
+  }
+}
+
+Yallist.prototype.get = function (n) {
+  for (var i = 0, walker = this.head; walker !== null && i < n; i++) {
+    // abort out of the list early if we hit a cycle
+    walker = walker.next
+  }
+  if (i === n && walker !== null) {
+    return walker.value
+  }
+}
+
+Yallist.prototype.getReverse = function (n) {
+  for (var i = 0, walker = this.tail; walker !== null && i < n; i++) {
+    // abort out of the list early if we hit a cycle
+    walker = walker.prev
+  }
+  if (i === n && walker !== null) {
+    return walker.value
+  }
+}
+
+Yallist.prototype.map = function (fn, thisp) {
+  thisp = thisp || this
+  var res = new Yallist()
+  for (var walker = this.head; walker !== null;) {
+    res.push(fn.call(thisp, walker.value, this))
+    walker = walker.next
+  }
+  return res
+}
+
+Yallist.prototype.mapReverse = function (fn, thisp) {
+  thisp = thisp || this
+  var res = new Yallist()
+  for (var walker = this.tail; walker !== null;) {
+    res.push(fn.call(thisp, walker.value, this))
+    walker = walker.prev
+  }
+  return res
+}
+
+Yallist.prototype.reduce = function (fn, initial) {
+  var acc
+  var walker = this.head
+  if (arguments.length > 1) {
+    acc = initial
+  } else if (this.head) {
+    walker = this.head.next
+    acc = this.head.value
+  } else {
+    throw new TypeError('Reduce of empty list with no initial value')
+  }
+
+  for (var i = 0; walker !== null; i++) {
+    acc = fn(acc, walker.value, i)
+    walker = walker.next
+  }
+
+  return acc
+}
+
+Yallist.prototype.reduceReverse = function (fn, initial) {
+  var acc
+  var walker = this.tail
+  if (arguments.length > 1) {
+    acc = initial
+  } else if (this.tail) {
+    walker = this.tail.prev
+    acc = this.tail.value
+  } else {
+    throw new TypeError('Reduce of empty list with no initial value')
+  }
+
+  for (var i = this.length - 1; walker !== null; i--) {
+    acc = fn(acc, walker.value, i)
+    walker = walker.prev
+  }
+
+  return acc
+}
+
+Yallist.prototype.toArray = function () {
+  var arr = new Array(this.length)
+  for (var i = 0, walker = this.head; walker !== null; i++) {
+    arr[i] = walker.value
+    walker = walker.next
+  }
+  return arr
+}
+
+Yallist.prototype.toArrayReverse = function () {
+  var arr = new Array(this.length)
+  for (var i = 0, walker = this.tail; walker !== null; i++) {
+    arr[i] = walker.value
+    walker = walker.prev
+  }
+  return arr
+}
+
+Yallist.prototype.slice = function (from, to) {
+  to = to || this.length
+  if (to < 0) {
+    to += this.length
+  }
+  from = from || 0
+  if (from < 0) {
+    from += this.length
+  }
+  var ret = new Yallist()
+  if (to < from || to < 0) {
+    return ret
+  }
+  if (from < 0) {
+    from = 0
+  }
+  if (to > this.length) {
+    to = this.length
+  }
+  for (var i = 0, walker = this.head; walker !== null && i < from; i++) {
+    walker = walker.next
+  }
+  for (; walker !== null && i < to; i++, walker = walker.next) {
+    ret.push(walker.value)
+  }
+  return ret
+}
+
+Yallist.prototype.sliceReverse = function (from, to) {
+  to = to || this.length
+  if (to < 0) {
+    to += this.length
+  }
+  from = from || 0
+  if (from < 0) {
+    from += this.length
+  }
+  var ret = new Yallist()
+  if (to < from || to < 0) {
+    return ret
+  }
+  if (from < 0) {
+    from = 0
+  }
+  if (to > this.length) {
+    to = this.length
+  }
+  for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) {
+    walker = walker.prev
+  }
+  for (; walker !== null && i > from; i--, walker = walker.prev) {
+    ret.push(walker.value)
+  }
+  return ret
+}
+
+Yallist.prototype.reverse = function () {
+  var head = this.head
+  var tail = this.tail
+  for (var walker = head; walker !== null; walker = walker.prev) {
+    var p = walker.prev
+    walker.prev = walker.next
+    walker.next = p
+  }
+  this.head = tail
+  this.tail = head
+  return this
+}
+
+function push (self, item) {
+  self.tail = new Node(item, self.tail, null, self)
+  if (!self.head) {
+    self.head = self.tail
+  }
+  self.length++
+}
+
+function unshift (self, item) {
+  self.head = new Node(item, null, self.head, self)
+  if (!self.tail) {
+    self.tail = self.head
+  }
+  self.length++
+}
+
+function Node (value, prev, next, list) {
+  if (!(this instanceof Node)) {
+    return new Node(value, prev, next, list)
+  }
+
+  this.list = list
+  this.value = value
+
+  if (prev) {
+    prev.next = this
+    this.prev = prev
+  } else {
+    this.prev = null
+  }
+
+  if (next) {
+    next.prev = this
+    this.next = next
+  } else {
+    this.next = null
+  }
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/d40c2244/spec/unit/check_reqs.spec.js
----------------------------------------------------------------------
diff --git a/spec/unit/check_reqs.spec.js b/spec/unit/check_reqs.spec.js
index 1ddc352..33c3b3f 100644
--- a/spec/unit/check_reqs.spec.js
+++ b/spec/unit/check_reqs.spec.js
@@ -18,7 +18,7 @@
 */
 /* jshint laxcomma:true */
 
-var check_reqs = require("../../bin/lib/check_reqs");
+var check_reqs = require("../../bin/templates/cordova/lib/check_reqs");
 var shelljs = require("shelljs");
 var fs = require("fs");
 var path = require("path");
@@ -211,4 +211,11 @@ describe("check_reqs", function () {
             });
         });
     });
+    describe("get_target", function() {
+        it("should retrieve target from framework project.properties file", function() {
+            var target = check_reqs.get_target();
+            expect(target).toBeDefined();
+            expect(target).toContain("android-");
+        });
+    });
 });


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org


Mime
View raw message