You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by st...@apache.org on 2013/12/06 00:40:42 UTC

[01/23] git commit: [android] call out to platform check_req script

Updated Branches:
  refs/heads/ubuntu 81ce8edd2 -> 1c15a2480


[android] call out to platform check_req script


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

Branch: refs/heads/ubuntu
Commit: 42f4d49fc30ca37fb22309b92f104c2336f70c3f
Parents: de57aff
Author: Michal Mocny <mm...@gmail.com>
Authored: Wed Nov 27 16:38:17 2013 -0500
Committer: Michal Mocny <mm...@gmail.com>
Committed: Thu Nov 28 10:45:58 2013 -0500

----------------------------------------------------------------------
 src/metadata/android_parser.js | 38 ++++---------------------------------
 1 file changed, 4 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/42f4d49f/src/metadata/android_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/android_parser.js b/src/metadata/android_parser.js
index 535d5b2..aeda478 100644
--- a/src/metadata/android_parser.js
+++ b/src/metadata/android_parser.js
@@ -25,7 +25,7 @@ var fs            = require('fs'),
     child_process = require('child_process'),
     project_config= require('../config'),
     Q             = require('q'),
-    config_parser = require('../config_parser');
+    lazy_load     = require('../lazy_load');
 
 var default_prefs = {
     "useBrowserHistory":"true",
@@ -45,40 +45,10 @@ module.exports = function android_parser(project) {
 // Returns a promise.
 module.exports.check_requirements = function(project_root) {
     events.emit('log', 'Checking Android requirements...');
-    var command = 'android list target';
-    events.emit('verbose', 'Running "' + command + '" (output to follow)');
-    var d = Q.defer();
-    child_process.exec(command, function(err, output, stderr) {
-        events.emit('verbose', output);
-        if (err) {
-            d.reject(new Error('The command `android` failed. Make sure you have the latest Android SDK installed, and the `android` command (inside the tools/ folder) added to your path. Output: ' + output));
-        } else {
-            if (output.indexOf('android-17') == -1) {
-                d.reject(new Error('Please install Android target 17 (the Android 4.2 SDK). Make sure you have the latest Android tools installed as well. Run `android` from your command-line to install/update any missing SDKs or tools.'));
-            } else {
-                var custom_path = project_config.has_custom_path(project_root, 'android');
-                var framework_path;
-                if (custom_path) {
-                    framework_path = path.resolve(path.join(custom_path, 'framework'));
-                } else {
-                    framework_path = path.join(util.libDirectory, 'android', 'cordova', require('../../platforms').android.version, 'framework');
-                }
-                var cmd = 'android update project -p "' + framework_path  + '" -t android-17';
-                events.emit('verbose', 'Running "' + cmd + '" (output to follow)...');
-                var d2 = Q.defer();
-                child_process.exec(cmd, function(err, output, stderr) {
-                    events.emit('verbose', output + stderr);
-                    if (err) {
-                        d2.reject(new Error('Error updating the Cordova library to work with your Android environment. Command run: "' + cmd + '", output: ' + output));
-                    } else {
-                        d2.resolve();
-                    }
-                });
-                d.resolve(d2.promise);
-            }
-        }
+    return lazy_load.based_on_config(project_root, 'android').then(function(lib_path) {
+        var check_reqs = require(path.join(lib_path, 'bin', 'lib', 'check_reqs'));
+        return check_reqs.run();
     });
-    return d.promise;
 };
 
 module.exports.prototype = {


[16/23] git commit: CB-5298 Remove redundant requirements check for iOS and Android. The bin/create scripts check.

Posted by st...@apache.org.
CB-5298 Remove redundant requirements check for iOS and Android. The bin/create scripts check.


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

Branch: refs/heads/ubuntu
Commit: 4f8bf24effae0470c5a720969aa34fab2a314cac
Parents: e325e5d
Author: Andrew Grieve <ag...@chromium.org>
Authored: Wed Dec 4 21:34:29 2013 -0500
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Wed Dec 4 21:34:29 2013 -0500

----------------------------------------------------------------------
 spec/metadata/android_parser.spec.js | 12 ------------
 spec/metadata/ios_parser.spec.js     | 29 -----------------------------
 src/metadata/android_parser.js       | 10 +++-------
 src/metadata/ios_parser.js           | 22 ++--------------------
 4 files changed, 5 insertions(+), 68 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/4f8bf24e/spec/metadata/android_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/metadata/android_parser.spec.js b/spec/metadata/android_parser.spec.js
index 92e15e1..52fc78a 100644
--- a/spec/metadata/android_parser.spec.js
+++ b/spec/metadata/android_parser.spec.js
@@ -70,18 +70,6 @@ describe('android project parser', function() {
         });
     });
 
-    describe('check_requirements', function() {
-        it('should fire a callback if there is an error during shelling out', function(done) {
-            exec.andCallFake(function(cmd, opts, cb) {
-                if (!cb) cb = opts;
-                cb(50, 'there was an errorz!', '');
-            });
-            errorWrapper(platforms.android.parser.check_requirements(proj), done, function(err) {
-                expect(err).toContain('there was an errorz!');
-            });
-        });
-    });
-
     describe('instance', function() {
         var p, cp, rm, mkdir, is_cordova, write, read;
         var android_proj = path.join(proj, 'platforms', 'android');

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/4f8bf24e/spec/metadata/ios_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/metadata/ios_parser.spec.js b/spec/metadata/ios_parser.spec.js
index 5f8664d..b56ddce 100644
--- a/spec/metadata/ios_parser.spec.js
+++ b/spec/metadata/ios_parser.spec.js
@@ -71,35 +71,6 @@ describe('ios project parser', function () {
             }).not.toThrow();
         });
     });
-    describe('check_requirements', function() {
-        it('should fire a callback if there is an error during shelling out', function(done) {
-            exec.andCallFake(function(cmd, opts, cb) {
-                if (!cb) cb = opts;
-                cb(50, 'there was an errorz!', '');
-            });
-            errorWrapper(platforms.ios.parser.check_requirements(proj), done, function(err) {
-                expect(err).toContain('there was an errorz!');
-            });
-        });
-        it('should fire a callback if the xcodebuild version is less than 4.5.x', function(done) {
-            exec.andCallFake(function(cmd, opts, cb) {
-                if (!cb) cb = opts;
-                cb(0, 'version 4.4.9', '');
-            });
-            errorWrapper(platforms.ios.parser.check_requirements(proj), done, function(err) {
-                expect(err).toEqual(new Error('Xcode version installed is too old. Minimum: >=4.5.x, yours: 4.4.9'));
-            });
-        });
-        it('should not return an error if the xcodebuild version 2 digits and not proper semver (eg: 5.0), but still satisfies the MIN_XCODE_VERSION', function(done) {
-            exec.andCallFake(function(cmd, opts, cb) {
-                if (!cb) cb = opts;
-                cb(0, 'version 5.0', '');
-            });
-            wrapper(platforms.ios.parser.check_requirements(proj), done, function() {
-                expect(1).toBe(1);
-            });
-        });
-    });
 
     describe('instance', function() {
         var p, cp, rm, mkdir, is_cordova, write, read;

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/4f8bf24e/src/metadata/android_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/android_parser.js b/src/metadata/android_parser.js
index 4ed4ef9..5878678 100644
--- a/src/metadata/android_parser.js
+++ b/src/metadata/android_parser.js
@@ -25,8 +25,7 @@ var fs            = require('fs'),
     child_process = require('child_process'),
     project_config= require('../config'),
     Q             = require('q'),
-    config_parser = require('../config_parser'),
-    lazy_load     = require('../lazy_load');
+    config_parser = require('../config_parser');
 
 var default_prefs = {
     "useBrowserHistory":"true",
@@ -45,11 +44,8 @@ module.exports = function android_parser(project) {
 
 // Returns a promise.
 module.exports.check_requirements = function(project_root) {
-    events.emit('log', 'Checking Android requirements...');
-    return lazy_load.based_on_config(project_root, 'android').then(function(lib_path) {
-        var check_reqs = require(path.join(lib_path, 'bin', 'lib', 'check_reqs'));
-        return check_reqs.run();
-    });
+    // Rely on platform's bin/create script to check requirements.
+    return Q(true);
 };
 
 module.exports.prototype = {

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/4f8bf24e/src/metadata/ios_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/ios_parser.js b/src/metadata/ios_parser.js
index 07a5e7b..d819bf3 100644
--- a/src/metadata/ios_parser.js
+++ b/src/metadata/ios_parser.js
@@ -64,26 +64,8 @@ module.exports = function ios_parser(project) {
 
 // Returns a promise.
 module.exports.check_requirements = function(project_root) {
-    events.emit('log', 'Checking iOS requirements...');
-    // Check xcode + version.
-    var command = 'xcodebuild -version';
-    events.emit('verbose', 'Running "' + command + '" (output to follow)');
-    var d = Q.defer();
-    child_process.exec(command, function(err, output, stderr) {
-        events.emit('verbose', output+stderr);
-        if (err) {
-            d.reject(new Error('Xcode is (probably) not installed, specifically the command `xcodebuild` is unavailable or erroring out. Output of `'+command+'` is: ' + output + stderr));
-        } else {
-            var xc_version = output.split('\n')[0].split(' ')[1];
-            if(xc_version.split('.').length === 2){
-                xc_version += '.0';
-            }
-            if (!semver.satisfies(xc_version, MIN_XCODE_VERSION)) {
-                d.reject(new Error('Xcode version installed is too old. Minimum: ' + MIN_XCODE_VERSION + ', yours: ' + xc_version));
-            } else d.resolve();
-        }
-    });
-    return d.promise;
+    // Rely on platform's bin/create script to check requirements.
+    return Q(true);
 };
 
 module.exports.prototype = {


[10/23] git commit: Update release notes

Posted by st...@apache.org.
Update release notes


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

Branch: refs/heads/ubuntu
Commit: 1558d6c396b0a732cdbdbdca30402e6d4e37d919
Parents: d47a67a
Author: Bryan Higgins <bh...@blackberry.com>
Authored: Fri Nov 29 13:52:06 2013 -0500
Committer: Bryan Higgins <bh...@blackberry.com>
Committed: Fri Nov 29 13:52:06 2013 -0500

----------------------------------------------------------------------
 RELEASENOTES.md | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/1558d6c3/RELEASENOTES.md
----------------------------------------------------------------------
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 1b58d01..5d86a97 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -20,6 +20,16 @@
 -->
 # Cordova-cli changelog
 
+## 3.2.0-0.3.0
+
+* CB-5501 fix blackberry10 platform
+* [android] fixing failing android parser spec tests
+* [android] call out to platform check_req script
+
+## 3.2.0-0.2.0
+
+* CB-5485 fixed issue with use of cordova cli api
+
 ## 3.2.0-0.1.0
 
 * add the output of the plugman results to the console
@@ -162,4 +172,4 @@ Important note: This version targets Cordova version 3.1.0-rc1.
 ### Bugfixes
 
 - Plugins are now installed serially across all installed platforms, rather than in parallel. This avoids race conditions in dependency installation. [CB-4184](https://issues.apache.org/jira/browse/CB-4184)
-- (WP8) All files from project www dir are now copied into the binary, not the top-level www. This means merges and plugin assets are correctly handled.
\ No newline at end of file
+- (WP8) All files from project www dir are now copied into the binary, not the top-level www. This means merges and plugin assets are correctly handled.


[12/23] git commit: [CB-4472] Fix tests broken by previous commit.

Posted by st...@apache.org.
[CB-4472] Fix tests broken by previous commit.


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

Branch: refs/heads/ubuntu
Commit: 2a7bcaeccf415f1ceaaed8f7c19f832add9e5d45
Parents: 933230a
Author: Andrew Grieve <ag...@chromium.org>
Authored: Mon Dec 2 15:56:50 2013 -0500
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Mon Dec 2 15:57:11 2013 -0500

----------------------------------------------------------------------
 spec/config_parser.spec.js |  2 +-
 spec/test-config.xml       | 21 +++++++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2a7bcaec/spec/config_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/config_parser.spec.js b/spec/config_parser.spec.js
index d232cd8..4e3b5d4 100644
--- a/spec/config_parser.spec.js
+++ b/spec/config_parser.spec.js
@@ -21,7 +21,7 @@ var path = require('path'),
     shell = require('shelljs'),
     config_parser = require('../src/config_parser'),
     et = require('elementtree'),
-    xml = path.join(__dirname, '..', 'templates', 'config.xml'),
+    xml = path.join(__dirname, 'test-config.xml'),
     util = require('../src/util'),
     xml_contents = fs.readFileSync(xml, 'utf-8');
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2a7bcaec/spec/test-config.xml
----------------------------------------------------------------------
diff --git a/spec/test-config.xml b/spec/test-config.xml
new file mode 100644
index 0000000..7e206d6
--- /dev/null
+++ b/spec/test-config.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns     = "http://www.w3.org/ns/widgets"
+        xmlns:cdv = "http://cordova.apache.org/ns/1.0"
+        id        = "io.cordova.hellocordova"
+        version   = "0.0.1">
+    <name>Hello Cordova</name>
+
+    <description>
+        A sample Apache Cordova application that responds to the deviceready event.
+    </description>
+
+    <author href="http://cordova.io" email="dev@cordova.apache.org">
+        Apache Cordova Team
+    </author>
+
+    <content src="index.html" />
+
+    <access origin="*" />
+    <preference name="fullscreen" value="true" />
+    <preference name="webviewbounce" value="true" />
+</widget>


[17/23] git commit: CB-5031 Add CLI help text for platform update and plugin search

Posted by st...@apache.org.
CB-5031 Add CLI help text for platform update and plugin search


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

Branch: refs/heads/ubuntu
Commit: 68942e6c808c799b60c49e51439e8bcf5c9f6aeb
Parents: 4f8bf24
Author: mbillau <mi...@gmail.com>
Authored: Thu Dec 5 15:35:00 2013 -0500
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Thu Dec 5 15:35:00 2013 -0500

----------------------------------------------------------------------
 doc/help.txt | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/68942e6c/doc/help.txt
----------------------------------------------------------------------
diff --git a/doc/help.txt b/doc/help.txt
index 1019200..6dce120 100644
--- a/doc/help.txt
+++ b/doc/help.txt
@@ -16,8 +16,12 @@ Project-Level Commands
 
     platform(s) [{add|remove|rm} <PLATFORM>] .. add or remove a specified PLATFORM, OR
                 [{list|ls}] ................... list all installed, available and unavailable platforms
+                [{update|up} <PLATFORM>] ...... update the version of cordova used for a specific
+                                                PLATFORM; use after updating the CLI.
+
     plugin(s) [{add|remove|rm} <PATH|URI>] .... add or remove a plugin from the specified PATH or URI, OR
               [{ls|list}] ..................... list all currently installed plugins
+              [search <keyword1 keyword2...>] . search the plugin registry for plugins matching the keywords
     prepare [PLATFORM..] ...................... copies files for specified platforms, or all platforms,
                                                 so that the project is ready to build in each SDK.
     compile [PLATFORM..] ...................... builds the app for specified platforms, or all platforms


[05/23] Revert "fixed merge conflict due to e2e"

Posted by st...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/platform.spec.js
----------------------------------------------------------------------
diff --git a/e2e/platform.spec.js b/e2e/platform.spec.js
new file mode 100644
index 0000000..879a909
--- /dev/null
+++ b/e2e/platform.spec.js
@@ -0,0 +1,117 @@
+
+var helpers = require('./helpers'),
+    path = require('path'),
+    fs = require('fs'),
+    shell = require('shelljs'),
+    platforms = require('../platforms'),
+    child_process = require('child_process'),
+    config = require('../src/config'),
+    Q = require('q'),
+    events = require('../src/events'),
+    cordova = require('../cordova');
+
+var tmpDir = helpers.tmpDir();
+var project = path.join(tmpDir, 'project');
+
+var platformParser = platforms[helpers.testPlatform].parser;
+
+describe('platform end-to-end', function() {
+    var results;
+
+    beforeEach(function() {
+        shell.rm('-rf', project);
+    });
+    afterEach(function() {
+        shell.rm('-rf', project);
+    });
+
+    // Factoring out some repeated checks.
+    function emptyPlatformList() {
+        return cordova.raw.platform('list').then(function() {
+            var installed = results.match(/Installed platforms: (.*)/);
+            expect(installed).toBeDefined();
+            expect(installed[1].indexOf(helpers.testPlatform)).toBe(-1);
+        });
+    }
+
+    function fullPlatformList() {
+        return cordova.raw.platform('list').then(function() {
+            var installed = results.match(/Installed platforms: (.*)/);
+            expect(installed).toBeDefined();
+            expect(installed[1].indexOf(helpers.testPlatform)).toBeGreaterThan(-1);
+        });
+    }
+
+    // The flows we want to test are add, rm, list, and upgrade.
+    // They should run the appropriate hooks.
+    // They should fail when not inside a Cordova project.
+    // These tests deliberately have no beforeEach and afterEach that are cleaning things up.
+    it('should successfully run', function(done) {
+        // cp then mv because we need to copy everything, but that means it'll copy the whole directory.
+        // Using /* doesn't work because of hidden files.
+        shell.cp('-R', path.join(__dirname, 'fixtures', 'base'), tmpDir);
+        shell.mv(path.join(tmpDir, 'base'), project);
+        process.chdir(project);
+
+        // Now we load the config.json in the newly created project and edit the target platform's lib entry
+        // to point at the fixture version. This is necessary so that cordova.prepare can find cordova.js there.
+        var c = config.read(project);
+        c.lib[helpers.testPlatform].uri = path.join(__dirname, 'fixtures', 'platforms', helpers.testPlatform + '-lib');
+        config.write(project, c);
+
+        // The config.json in the fixture project points at fake "local" paths.
+        // Since it's not a URL, the lazy-loader will just return the junk path.
+        // The platform logic will call the platformParser.check_requirements, which we mock,
+        // and then call the bin/check_reqs and bin/create scripts from it.
+        // We're mocking out shell.exec() as well, to capture that.
+        var check_reqs = spyOn(platformParser, 'check_requirements').andReturn(Q());
+        var exec = spyOn(child_process, 'exec').andCallFake(function(cmd, opts, cb) {
+            if (!cb) cb = opts;
+
+            if (cmd.match(/^"[^"]*create"/)) {
+                // This is a call to the bin/create script, so do the copy ourselves.
+                shell.cp('-R', path.join(__dirname, 'fixtures', 'platforms', 'android'), path.join(project, 'platforms'));
+                cb(null, '', '');
+            } else if(cmd.match(/^"[^"]*version"/)) {
+                cb(null, 'dev', '');
+            } else if(cmd.match(/update\b/)) {
+                fs.writeFileSync(path.join(project, 'platforms', helpers.testPlatform, 'updated'), 'I was updated!', 'utf-8');
+                cb(null, '', '');
+            } else {
+                cb(null, '', '');
+            }
+        });
+
+        events.on('results', function(res) { results = res; });
+
+        // Check there are no platforms yet.
+        emptyPlatformList().then(function() {
+            // Add the testing platform.
+            return cordova.raw.platform('add', [helpers.testPlatform]);
+        }).then(function() {
+            // Check the platform add was successful.
+            expect(path.join(project, 'platforms', helpers.testPlatform)).toExist();
+            expect(path.join(project, 'merges', helpers.testPlatform)).toExist();
+            expect(path.join(project, 'platforms', helpers.testPlatform, 'cordova')).toExist();
+        }).then(fullPlatformList) // Check for it in platform ls.
+        .then(function() {
+            // Try to update the platform.
+            return cordova.raw.platform('update', [helpers.testPlatform]);
+        }).then(function() {
+            // Our fake update script in the exec mock above creates this dummy file.
+            expect(path.join(project, 'platforms', helpers.testPlatform, 'updated')).toExist();
+        }).then(fullPlatformList) // Platform should still be in platform ls.
+        .then(function() {
+            // And now remove it.
+            return cordova.raw.platform('rm', [helpers.testPlatform]);
+        }).then(function() {
+            // It should be gone.
+            expect(path.join(project, 'platforms', helpers.testPlatform)).not.toExist();
+            expect(path.join(project, 'merges', helpers.testPlatform)).not.toExist();
+        }).then(emptyPlatformList) // platform ls should be empty too.
+        .fail(function(err) {
+            expect(err).toBeUndefined();
+        }).fin(done);
+    });
+});
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/plugin.spec.js
----------------------------------------------------------------------
diff --git a/e2e/plugin.spec.js b/e2e/plugin.spec.js
new file mode 100644
index 0000000..0425f90
--- /dev/null
+++ b/e2e/plugin.spec.js
@@ -0,0 +1,67 @@
+
+var helpers = require('./helpers'),
+    path = require('path'),
+    fs = require('fs'),
+    shell = require('shelljs'),
+    Q = require('q'),
+    events = require('../src/events'),
+    cordova = require('../cordova');
+
+var tmpDir = helpers.tmpDir();
+var project = path.join(tmpDir, 'project');
+var pluginsDir = path.join(__dirname, 'fixtures', 'plugins');
+var pluginId = 'org.apache.cordova.fakeplugin1';
+
+describe('plugin end-to-end', function() {
+    var results;
+
+    beforeEach(function() {
+        shell.rm('-rf', project);
+    });
+    afterEach(function() {
+        shell.rm('-rf', project);
+    });
+
+    // The flow tested is: ls, add, ls, rm, ls.
+    // Plugin dependencies are not tested as that should be corvered in plugman tests.
+    // TODO (kamrik): Test the 'plugin search' command.
+    it('should successfully run', function(done) {
+        // cp then mv because we need to copy everything, but that means it'll copy the whole directory.
+        // Using /* doesn't work because of hidden files.
+        shell.cp('-R', path.join(__dirname, 'fixtures', 'base'), tmpDir);
+        shell.mv(path.join(tmpDir, 'base'), project);
+        // Copy some platform to avoid working on a project with no platforms.
+        shell.cp('-R', path.join(__dirname, 'fixtures', 'platforms', helpers.testPlatform), path.join(project, 'platforms'));
+        process.chdir(project);
+
+        events.on('results', function(res) { results = res; });
+
+        // Check there are no plugins yet.
+        cordova.raw.plugin('list').then(function() {
+            expect(results).toMatch(/No plugins added/gi);
+        }).then(function() {
+            // Add a fake plugin from fixtures.
+            return cordova.raw.plugin('add', path.join(pluginsDir, 'fake1'));
+        }).then(function() {
+           expect(path.join(project, 'plugins', pluginId, 'plugin.xml')).toExist();
+        }).then(function() {
+            return cordova.raw.plugin('ls');
+        }).then(function() {
+            expect(results).toContain(pluginId);
+            expect(results.length).toEqual(1);
+        }).then(function() {
+            // And now remove it.
+            return cordova.raw.plugin('rm', pluginId);
+        }).then(function() {
+            // The whole dir should be gone.
+            expect(path.join(project, 'plugins', pluginId)).not.toExist();
+        }).then(function() {
+            return cordova.raw.plugin('ls');
+        }).then(function() {
+            expect(results).toMatch(/No plugins added/gi);
+        }).fail(function(err) {
+            console.log(err);
+            expect(err).toBeUndefined();
+        }).fin(done);
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index b5970a7..440c47b 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
     "cordova": "./bin/cordova"
   },
   "scripts": {
-    "test": "jasmine-node --color spec",
+    "test": "jasmine-node --color spec e2e",
     "win-test" : "jasmine-node --color spec"
   },
   "repository": {


[02/23] git commit: [android] fixing failing android parser spec tests.

Posted by st...@apache.org.
[android] fixing failing android parser spec tests.

Adding back config_parser since it was accidentally removed.
Removing poor tests that tested that the CLI check reqs directly
instead of calling out to platform scripts which we do now.
Those tests also were hard coded for API version 17, and had bugs
where some references were to API version 15 even.  About time we
remove them.


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

Branch: refs/heads/ubuntu
Commit: 758d752b857fc72d60fa406a1c18f23acdc1652f
Parents: 42f4d49
Author: Michal Mocny <mm...@gmail.com>
Authored: Thu Nov 28 11:11:37 2013 -0500
Committer: Michal Mocny <mm...@gmail.com>
Committed: Thu Nov 28 11:14:22 2013 -0500

----------------------------------------------------------------------
 spec/metadata/android_parser.spec.js | 28 ----------------------------
 src/metadata/android_parser.js       |  1 +
 2 files changed, 1 insertion(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/758d752b/spec/metadata/android_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/metadata/android_parser.spec.js b/spec/metadata/android_parser.spec.js
index e0f438b..92e15e1 100644
--- a/spec/metadata/android_parser.spec.js
+++ b/spec/metadata/android_parser.spec.js
@@ -80,34 +80,6 @@ describe('android project parser', function() {
                 expect(err).toContain('there was an errorz!');
             });
         });
-        it('should fire a callback if `android list target` does not return anything containing "android-17"', function(done) {
-            exec.andCallFake(function(cmd, opts, cb) {
-                if (!cb) cb = opts;
-                cb(0, 'android-15', '');
-            });
-            errorWrapper(platforms.android.parser.check_requirements(proj), done, function(err) {
-                expect(err).toEqual(new Error('Please install Android target 17 (the Android 4.2 SDK). Make sure you have the latest Android tools installed as well. Run `android` from your command-line to install/update any missing SDKs or tools.'));
-            });
-        });
-        it('should check that `android` is on the path by calling `android list target`', function(done) {
-            wrapper(platforms.android.parser.check_requirements(proj), done, function() {
-                expect(exec).toHaveBeenCalledWith('android list target', jasmine.any(Function));
-            });
-        });
-        it('should check that we can update an android project by calling `android update project` on stock android path', function(done) {
-            wrapper(platforms.android.parser.check_requirements(proj), done, function() {
-                expect(exec.mostRecentCall.args[0]).toMatch(/^android update project -p .* -t android-17$/gi);
-                expect(exec.mostRecentCall.args[0]).toContain(util.libDirectory);
-            });
-        });
-        it('should check that we can update an android project by calling `android update project` on a custom path if it is so defined', function(done) {
-            var custom_path = path.join('some', 'custom', 'path', 'to', 'android', 'lib');
-            custom.andReturn(custom_path);
-            wrapper(platforms.android.parser.check_requirements(proj), done, function() {
-                expect(exec.mostRecentCall.args[0]).toMatch(/^android update project -p .* -t android-17$/gi);
-                expect(exec.mostRecentCall.args[0]).toContain(custom_path);
-            });
-        });
     });
 
     describe('instance', function() {

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/758d752b/src/metadata/android_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/android_parser.js b/src/metadata/android_parser.js
index aeda478..4ed4ef9 100644
--- a/src/metadata/android_parser.js
+++ b/src/metadata/android_parser.js
@@ -25,6 +25,7 @@ var fs            = require('fs'),
     child_process = require('child_process'),
     project_config= require('../config'),
     Q             = require('q'),
+    config_parser = require('../config_parser'),
     lazy_load     = require('../lazy_load');
 
 var default_prefs = {


[21/23] git commit: add ubuntu platform

Posted by st...@apache.org.
add ubuntu platform


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

Branch: refs/heads/ubuntu
Commit: 7968ae7f9ccc593b7e53bb55da6954a3594a761f
Parents: 6e1d79e
Author: Maxim Ermilov <ma...@canonical.com>
Authored: Wed Nov 27 19:47:24 2013 +0400
Committer: Steven Gill <st...@gmail.com>
Committed: Thu Dec 5 15:39:51 2013 -0800

----------------------------------------------------------------------
 platforms.js                  |   5 ++
 src/lazy_load.js              |   2 +
 src/metadata/ubuntu_parser.js | 177 +++++++++++++++++++++++++++++++++++++
 src/platform.js               |   2 +
 4 files changed, 186 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/7968ae7f/platforms.js
----------------------------------------------------------------------
diff --git a/platforms.js b/platforms.js
index 370d056..d26bf75 100644
--- a/platforms.js
+++ b/platforms.js
@@ -28,6 +28,11 @@ module.exports = {
         url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-android.git',
         version: '3.2.0'
     }, 
+    'ubuntu' : {
+        parser : './src/metadata/ubuntu_parser',
+        url    : 'https://launchpad.net/cordova-ubuntu/3.0/apha1/+download/campo.tar.gz',
+        version: '3.1.0-rc1'
+    }, 
     'wp7' : {
         parser : './src/metadata/wp7_parser',
         url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-wp8.git',

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/7968ae7f/src/lazy_load.js
----------------------------------------------------------------------
diff --git a/src/lazy_load.js b/src/lazy_load.js
index dcaa126..fd95031 100644
--- a/src/lazy_load.js
+++ b/src/lazy_load.js
@@ -40,6 +40,8 @@ module.exports = {
         }
 
         var url = platforms[platform].url + ';a=snapshot;h=' + platforms[platform].version + ';sf=tgz';
+        if (platform == 'ubuntu')
+            url = platforms[platform].url;
         return module.exports.custom(url, 'cordova', platform, platforms[platform].version);
     },
     // Returns a promise for the path to the lazy-loaded directory.

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/7968ae7f/src/metadata/ubuntu_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/ubuntu_parser.js b/src/metadata/ubuntu_parser.js
new file mode 100644
index 0000000..1809ecf
--- /dev/null
+++ b/src/metadata/ubuntu_parser.js
@@ -0,0 +1,177 @@
+/*
+ *
+ * Copyright 2013 Canonical Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var fs            = require('fs'),
+    path          = require('path'),
+    et            = require('elementtree'),
+    xml           = require('../xml-helpers'),
+    util          = require('../util'),
+    events        = require('../events'),
+    shell         = require('shelljs'),
+    project_config= require('../config'),
+    Q             = require('q'),
+    os             = require('os'),
+    config_parser = require('../config_parser');
+
+module.exports = function(project) {
+    this.path = project;
+    this.config = new util.config_parser(this.config_xml());
+    this.update_manifest();
+};
+
+function sanitize(str) {
+    return str.replace(/\n/g, ' ').replace(/^\s+|\s+$/g, '');
+}
+
+// Returns a promise.
+module.exports.check_requirements = function(project_root, callback) {
+    var d = Q.defer();
+
+    events.emit('log', 'Checking ubuntu requirements...');
+    command = "dpkg-query -Wf'${db:Status-abbrev}' cmake debhelper libx11-dev libicu-dev pkg-config qtbase5-dev qtchooser qtdeclarative5-dev qtfeedback5-dev qtlocation5-dev qtmultimedia5-dev qtpim5-dev qtsensors5-dev qtsystems5-dev 2>/dev/null | grep -q '^i'";
+    events.emit('log', 'Running "' + command + '" (output to follow)');
+    shell.exec(command, {silent:true, async:true}, function(code, output) {
+        events.emit('log', output);
+        if (code != 0) {
+            d.reject(new Error('Make sure you have the following packages installed: ' + output));
+        } else {
+            d.resolve();
+        }
+    });
+
+    return d.promise;
+};
+
+module.exports.prototype = {
+    // Returns a promise.
+    update_from_config:function(config) {
+        if (config instanceof config_parser) {
+        } else {
+            return Q.reject(new Error('update_from_config requires a config_parser object'));
+        }
+
+        this.config = new util.config_parser(this.config_xml());
+        this.config.name(config.name());
+        this.config.version(config.version());
+        this.config.packageName(config.packageName());
+
+        this.config.doc.find('description').text = config.doc.find('description').text;
+        this.config.update();
+
+        return this.update_manifest();
+    },
+
+    cordovajs_path:function(libDir) {
+        var jsPath = path.join(libDir, 'www', 'cordova.js');
+        return path.resolve(jsPath);
+    },
+
+    update_manifest: function() {
+        var nodearch2debarch = { 'arm': 'armhf',
+                                 'i386': 'i386',
+                                 'x64': 'amd64'};
+        var arch;
+        if (os.arch() in nodearch2debarch)
+            arch = nodearch2debarch[os.arch()];
+        else
+            return Q.reject(new Error('unknown cpu arch'));
+
+        if (!this.config.doc.find('author') || !this.config.doc.find('author').text.length)
+            return Q.reject(new Error('config.xml should contain author'));
+
+        var manifest = { name: this.config.packageName(),
+                         version: this.config.version(),
+                         title: this.config.name(),
+                         hooks: { cordova: { desktop: "cordova.desktop",
+                                             apparmor: "apparmor.json" } },
+                         framework: "ubuntu-sdk-13.10",
+                         maintainer: sanitize(this.config.doc.find('author').text),
+                         architecture: arch,
+                         description: sanitize(this.config.doc.find('description').text) };
+        fs.writeFileSync(path.join(this.path, 'manifest.json'), JSON.stringify(manifest));
+
+        var name = this.config.name().replace(/\n/g, ' '); //FIXME: escaping
+        var content = "[Desktop Entry]\nName=" + name + "\nExec=./cordova-ubuntu www/\nIcon=qmlscene\nTerminal=false\nType=Application\nX-Ubuntu-Touch=true";
+
+        fs.writeFileSync(path.join(this.path, 'cordova.desktop'), content);
+
+        var policy = { policy_groups: ["networking", "audio"], policy_version: 1 };
+
+        this.config.doc.getroot().findall('./feature/param').forEach(function (element) {
+            if (element.attrib.policy_group && policy.policy_groups.indexOf(policy.policy_groups) === -1)
+                policy.policy_groups.push(element.attrib.policy_group);
+        });
+
+        fs.writeFileSync(path.join(this.path, 'apparmor.json'), JSON.stringify(policy));
+
+        return Q();
+    },
+
+    config_xml:function(){
+        return path.join(this.path, 'config.xml');
+    },
+
+    www_dir:function() {
+        return path.join(this.path, 'www');
+    },
+
+    staging_dir: function() {
+        return path.join(this.path, '.staging', 'www');
+    },
+
+    update_www:function() {
+        var projectRoot = util.isCordova(this.path);
+        var www = util.projectWww(projectRoot);
+
+        shell.rm('-rf', this.www_dir());
+        shell.cp('-rf', www, this.path);
+    },
+
+    update_overrides:function() {
+        var projectRoot = util.isCordova(this.path);
+        var mergesPath = path.join(util.appDir(projectRoot), 'merges', 'ubuntu');
+        if(fs.existsSync(mergesPath)) {
+            var overrides = path.join(mergesPath, '*');
+            shell.cp('-rf', overrides, this.www_dir());
+        }
+    },
+
+    update_staging:function() {
+        var projectRoot = util.isCordova(this.path);
+        var stagingDir = path.join(this.path, '.staging', 'www');
+
+        if(fs.existsSync(stagingDir)) {
+            shell.cp('-rf',
+                     path.join(stagingDir, '*'),
+                     this.www_dir());
+        }
+    },
+
+    // Returns a promise.
+    update_project:function(cfg) {
+        var self = this;
+
+        return this.update_from_config(cfg)
+        .then(function() {
+            self.update_overrides();
+            self.update_staging();
+            util.deleteSvnFolders(self.www_dir());
+        });
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/7968ae7f/src/platform.js
----------------------------------------------------------------------
diff --git a/src/platform.js b/src/platform.js
index 536969c..730e411 100644
--- a/src/platform.js
+++ b/src/platform.js
@@ -159,6 +159,8 @@ module.exports = function platform(command, targets) {
                     available.push('wp8');
                     available.push('windows8');
                 }
+                if (os.platform() === 'linux')
+                    available.push('ubuntu');
 
                 available = available.filter(function(p) {
                     return platforms_on_fs.indexOf(p) < 0; // Only those not already installed.


[03/23] git commit: CB-5501 fix blackberry10 platform

Posted by st...@apache.org.
CB-5501 fix blackberry10 platform


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

Branch: refs/heads/ubuntu
Commit: f7a35b3ca8a8b787fbbe01aebed286802451b64a
Parents: 758d752
Author: Bryan Higgins <bh...@blackberry.com>
Authored: Thu Nov 28 14:34:13 2013 -0500
Committer: Bryan Higgins <bh...@blackberry.com>
Committed: Thu Nov 28 14:35:00 2013 -0500

----------------------------------------------------------------------
 src/lazy_load.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/f7a35b3c/src/lazy_load.js
----------------------------------------------------------------------
diff --git a/src/lazy_load.js b/src/lazy_load.js
index e16dd70..dcaa126 100644
--- a/src/lazy_load.js
+++ b/src/lazy_load.js
@@ -47,7 +47,7 @@ module.exports = {
         var download_dir = (platform == 'wp7' || platform == 'wp8' ? path.join(util.libDirectory, 'wp', id, version) :
                                                                      path.join(util.libDirectory, platform, id, version));
 
-        var lib_dir = platforms[platform] && platforms[platform].subdirectory ? path.join(download_dir, platforms[platform].subdirectory) : download_dir;
+        var lib_dir = platforms[platform] && platforms[platform].subdirectory && platform !== "blackberry10" ? path.join(download_dir, platforms[platform].subdirectory) : download_dir;
 
         if (fs.existsSync(download_dir)) {
             events.emit('verbose', id + ' library for "' + platform + '" already exists. No need to download. Continuing.');
@@ -102,7 +102,7 @@ module.exports = {
                         events.emit('log', 'Download complete');
                         var entries = fs.readdirSync(download_dir);
                         var entry = path.join(download_dir, entries[0]);
-                        shell.mv('-f', path.join(entry, '*'), download_dir);
+                        shell.mv('-f', path.join(entry, (platform=='blackberry10'?'blackberry10':''), '*'), download_dir);
                         shell.rm('-rf', entry);
                         d.resolve(hooker.fire('after_library_download', {
                             platform:platform,


[11/23] git commit: CB-4472 Remove from template config.xml

Posted by st...@apache.org.
CB-4472 Remove <preference> from template config.xml


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

Branch: refs/heads/ubuntu
Commit: 933230a70d5e03282b4fce924e40db41e225d98f
Parents: 1558d6c
Author: Andrew Grieve <ag...@chromium.org>
Authored: Mon Dec 2 15:40:20 2013 -0500
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Mon Dec 2 15:40:20 2013 -0500

----------------------------------------------------------------------
 templates/config.xml | 2 --
 1 file changed, 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/933230a7/templates/config.xml
----------------------------------------------------------------------
diff --git a/templates/config.xml b/templates/config.xml
index 7e206d6..4a9a4d8 100644
--- a/templates/config.xml
+++ b/templates/config.xml
@@ -16,6 +16,4 @@
     <content src="index.html" />
 
     <access origin="*" />
-    <preference name="fullscreen" value="true" />
-    <preference name="webviewbounce" value="true" />
 </widget>


[06/23] Revert "fixed merge conflict due to e2e"

Posted by st...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/assets/www/img/logo.png
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/assets/www/img/logo.png b/e2e/fixtures/platforms/android/assets/www/img/logo.png
new file mode 100644
index 0000000..9519e7d
Binary files /dev/null and b/e2e/fixtures/platforms/android/assets/www/img/logo.png differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/assets/www/index.html
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/assets/www/index.html b/e2e/fixtures/platforms/android/assets/www/index.html
new file mode 100644
index 0000000..bde5741
--- /dev/null
+++ b/e2e/fixtures/platforms/android/assets/www/index.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!--
+    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.
+-->
+<html>
+    <head>
+        <meta charset="utf-8" />
+        <meta name="format-detection" content="telephone=no" />
+        <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
+        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
+        <link rel="stylesheet" type="text/css" href="css/index.css" />
+        <title>Hello World</title>
+    </head>
+    <body>
+        <div class="app">
+            <h1>Apache Cordova</h1>
+            <div id="deviceready" class="blink">
+                <p class="event listening">Connecting to Device</p>
+                <p class="event received">Device is Ready</p>
+            </div>
+        </div>
+        <script type="text/javascript" src="cordova.js"></script>
+        <script type="text/javascript" src="js/index.js"></script>
+        <script type="text/javascript">
+            app.initialize();
+        </script>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/assets/www/js/index.js
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/assets/www/js/index.js b/e2e/fixtures/platforms/android/assets/www/js/index.js
new file mode 100644
index 0000000..31d9064
--- /dev/null
+++ b/e2e/fixtures/platforms/android/assets/www/js/index.js
@@ -0,0 +1,49 @@
+/*
+ * 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 app = {
+    // Application Constructor
+    initialize: function() {
+        this.bindEvents();
+    },
+    // Bind Event Listeners
+    //
+    // Bind any events that are required on startup. Common events are:
+    // 'load', 'deviceready', 'offline', and 'online'.
+    bindEvents: function() {
+        document.addEventListener('deviceready', this.onDeviceReady, false);
+    },
+    // deviceready Event Handler
+    //
+    // The scope of 'this' is the event. In order to call the 'receivedEvent'
+    // function, we must explicity call 'app.receivedEvent(...);'
+    onDeviceReady: function() {
+        app.receivedEvent('deviceready');
+    },
+    // Update DOM on a Received Event
+    receivedEvent: function(id) {
+        var parentElement = document.getElementById(id);
+        var listeningElement = parentElement.querySelector('.listening');
+        var receivedElement = parentElement.querySelector('.received');
+
+        listeningElement.setAttribute('style', 'display:none;');
+        receivedElement.setAttribute('style', 'display:block;');
+
+        console.log('Received Event: ' + id);
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/assets/www/spec.html
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/assets/www/spec.html b/e2e/fixtures/platforms/android/assets/www/spec.html
new file mode 100644
index 0000000..71f00de
--- /dev/null
+++ b/e2e/fixtures/platforms/android/assets/www/spec.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<!--
+    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.
+-->
+<html>
+    <head>
+        <title>Jasmine Spec Runner</title>
+
+        <!-- jasmine source -->
+        <link rel="shortcut icon" type="image/png" href="spec/lib/jasmine-1.2.0/jasmine_favicon.png">
+        <link rel="stylesheet" type="text/css" href="spec/lib/jasmine-1.2.0/jasmine.css">
+        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine.js"></script>
+        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine-html.js"></script>
+
+        <!-- include source files here... -->
+        <script type="text/javascript" src="js/index.js"></script>
+
+        <!-- include spec files here... -->
+        <script type="text/javascript" src="spec/helper.js"></script>
+        <script type="text/javascript" src="spec/index.js"></script>
+
+        <script type="text/javascript">
+            (function() {
+                var jasmineEnv = jasmine.getEnv();
+                jasmineEnv.updateInterval = 1000;
+
+                var htmlReporter = new jasmine.HtmlReporter();
+
+                jasmineEnv.addReporter(htmlReporter);
+
+                jasmineEnv.specFilter = function(spec) {
+                    return htmlReporter.specFilter(spec);
+                };
+
+                var currentWindowOnload = window.onload;
+
+                window.onload = function() {
+                    if (currentWindowOnload) {
+                        currentWindowOnload();
+                    }
+                    execJasmine();
+                };
+
+                function execJasmine() {
+                    jasmineEnv.execute();
+                }
+            })();
+        </script>
+    </head>
+    <body>
+        <div id="stage" style="display:none;"></div>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/build.xml
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/build.xml b/e2e/fixtures/platforms/android/build.xml
new file mode 100644
index 0000000..9674edf
--- /dev/null
+++ b/e2e/fixtures/platforms/android/build.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="TestBase" default="help">
+
+    <!-- The local.properties file is created and updated by the 'android' tool.
+         It contains the path to the SDK. It should *NOT* be checked into
+         Version Control Systems. -->
+    <property file="local.properties" />
+
+    <!-- The ant.properties file can be created by you. It is only edited by the
+         'android' tool to add properties to it.
+         This is the place to change some Ant specific build properties.
+         Here are some properties you may want to change/update:
+
+         source.dir
+             The name of the source directory. Default is 'src'.
+         out.dir
+             The name of the output directory. Default is 'bin'.
+
+         For other overridable properties, look at the beginning of the rules
+         files in the SDK, at tools/ant/build.xml
+
+         Properties related to the SDK location or the project target should
+         be updated using the 'android' tool with the 'update' action.
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems.
+
+         -->
+    <property file="ant.properties" />
+
+    <!-- if sdk.dir was not set from one of the property file, then
+         get it from the ANDROID_HOME env var.
+         This must be done before we load project.properties since
+         the proguard config can use sdk.dir -->
+    <property environment="env" />
+    <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+        <isset property="env.ANDROID_HOME" />
+    </condition>
+
+    <!-- The project.properties file is created and updated by the 'android'
+         tool, as well as ADT.
+
+         This contains project specific properties such as project target, and library
+         dependencies. Lower level build properties are stored in ant.properties
+         (or in .classpath for Eclipse projects).
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems. -->
+    <loadproperties srcFile="project.properties" />
+
+    <!-- quick check on sdk.dir -->
+    <fail
+            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
+            unless="sdk.dir"
+    />
+
+    <!--
+        Import per project custom build rules if present at the root of the project.
+        This is the place to put custom intermediary targets such as:
+            -pre-build
+            -pre-compile
+            -post-compile (This is typically used for code obfuscation.
+                           Compiled code location: ${out.classes.absolute.dir}
+                           If this is not done in place, override ${out.dex.input.absolute.dir})
+            -post-package
+            -post-build
+            -pre-clean
+    -->
+    <import file="custom_rules.xml" optional="true" />
+
+    <!-- Import the actual build file.
+
+         To customize existing targets, there are two options:
+         - Customize only one target:
+             - copy/paste the target into this file, *before* the
+               <import> task.
+             - customize it to your needs.
+         - Customize the whole content of build.xml
+             - copy/paste the content of the rules files (minus the top node)
+               into this file, replacing the <import> task.
+             - customize to your needs.
+
+         ***********************
+         ****** IMPORTANT ******
+         ***********************
+         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+         in order to avoid having your file be overridden by tools such as "android update project"
+    -->
+    <!-- version-tag: 1 -->
+    <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/build
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/build b/e2e/fixtures/platforms/android/cordova/build
new file mode 100755
index 0000000..752945f
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/build
@@ -0,0 +1,35 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var build = require('./lib/build'),
+    reqs  = require('./lib/check_reqs'),
+    args  = process.argv;
+
+// Support basic help commands
+if(args[2] == '--help' || args[2] == '/?' || args[2] == '-h' ||
+                    args[2] == 'help' || args[2] == '-help' || args[2] == '/help') {
+    build.help();
+} else if(reqs.run()) {
+    build.run(args[2]);
+    process.exit(0);
+} else {
+    process.exit(2);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/check_reqs
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/check_reqs b/e2e/fixtures/platforms/android/cordova/check_reqs
new file mode 100755
index 0000000..4a8abee
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/check_reqs
@@ -0,0 +1,27 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var check_reqs = require('./lib/check_reqs');
+
+if(!check_reqs.run()) {
+      process.exit(2);
+}
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/clean
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/clean b/e2e/fixtures/platforms/android/cordova/clean
new file mode 100755
index 0000000..6b72e71
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/clean
@@ -0,0 +1,34 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var clean = require('./lib/clean'),
+    reqs  = require('./lib/check_reqs'),
+    args  = process.argv;
+
+// Usage support for when args are given
+if(args.length > 2) {
+    clean.help();
+} else if(reqs.run()) {
+    clean.run();
+    process.exit(0);
+} else {
+    process.exit(2);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/defaults.xml
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/defaults.xml b/e2e/fixtures/platforms/android/cordova/defaults.xml
new file mode 100644
index 0000000..24e5725
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/defaults.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<widget xmlns     = "http://www.w3.org/ns/widgets"
+        id        = "io.cordova.helloCordova"
+        version   = "2.0.0">
+    <name>Hello Cordova</name>
+
+    <description>
+        A sample Apache Cordova application that responds to the deviceready event.
+    </description>
+
+    <author href="http://cordova.io" email="dev@cordova.apache.org">
+        Apache Cordova Team
+    </author>
+
+    <access origin="*"/>
+
+    <!-- <content src="http://mysite.com/myapp.html" /> for external pages -->
+    <content src="index.html" />
+
+    <preference name="loglevel" value="DEBUG" />
+    <!--
+      <preference name="splashscreen" value="resourceName" />
+      <preference name="backgroundColor" value="0xFFF" />
+      <preference name="loadUrlTimeoutValue" value="20000" />
+      <preference name="InAppBrowserStorageEnabled" value="true" />
+      <preference name="disallowOverscroll" value="true" />
+    -->
+    <!-- This is required for native Android hooks -->
+    <feature name="App">
+        <param name="android-package" value="org.apache.cordova.App" />
+    </feature>
+</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/lib/appinfo.js
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/lib/appinfo.js b/e2e/fixtures/platforms/android/cordova/lib/appinfo.js
new file mode 100755
index 0000000..1f8ebe2
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/lib/appinfo.js
@@ -0,0 +1,41 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var path = require('path');
+var fs = require('fs');
+var cachedAppInfo = null;
+
+function readAppInfoFromManifest() {
+    var manifestPath = path.join(__dirname, '..', '..', 'AndroidManifest.xml');
+    var manifestData = fs.readFileSync(manifestPath, {encoding:'utf8'});
+    var packageName = /\bpackage\s*=\s*"(.+?)"/.exec(manifestData);
+    if (!packageName) throw new Error('Could not find package name within ' + manifestPath);
+    var activityTag = /<activity\b[\s\S]*<\/activity>/.exec(manifestData);
+    if (!activityTag) throw new Error('Could not find <activity> within ' + manifestPath);
+    var activityName = /\bandroid:name\s*=\s*"(.+?)"/.exec(activityTag);
+    if (!activityName) throw new Error('Could not find android:name within ' + manifestPath);
+
+    return packageName[1] + '/.' + activityName[1];
+}
+
+exports.getActivityName = function() {
+    return cachedAppInfo = cachedAppInfo || readAppInfoFromManifest();
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/lib/build.js
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/lib/build.js b/e2e/fixtures/platforms/android/cordova/lib/build.js
new file mode 100755
index 0000000..84e4e02
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/lib/build.js
@@ -0,0 +1,89 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var shell   = require('shelljs'),
+    clean   = require('./clean'),
+    path    = require('path'),
+    fs      = require('fs'),
+    ROOT    = path.join(__dirname, '..', '..');
+
+/*
+ * Builds the project with ant.
+ */
+module.exports.run = function(build_type) {
+    //default build type
+    build_type = typeof build_type !== 'undefined' ? build_type : "--debug";
+    var cmd;
+    switch(build_type) {
+        case '--debug' :
+            clean.run();
+            cmd = 'ant debug -f ' + path.join(ROOT, 'build.xml');
+            break;
+        case '--release' :
+            clean.run();
+            cmd = 'ant release -f ' + path.join(ROOT, 'build.xml');
+            break;
+        case '--nobuild' :
+            console.log('Skipping build...');
+            break;
+        default :
+           console.error('Build option \'' + build_type + '\' not recognized.');
+           process.exit(2);
+           break;
+    }
+    if(cmd) {
+        var result = shell.exec(cmd, {silent:false, async:false});
+        if(result.code > 0) {
+            console.error('ERROR: Failed to build android project.');
+            console.error(result.output);
+            process.exit(2);
+        }
+    }
+}
+
+/*
+ * Gets the path to the apk file, if not such file exists then
+ * the script will error out. (should we error or just return undefined?)
+ */
+module.exports.get_apk = function() {
+    if(fs.existsSync(path.join(ROOT, 'bin'))) {
+        var bin_files = fs.readdirSync(path.join(ROOT, 'bin'));
+        for (file in bin_files) {
+            if(path.extname(bin_files[file]) == '.apk') {
+                return path.join(ROOT, 'bin', bin_files[file]);
+            }
+        }
+        console.error('ERROR : No .apk found in \'bin\' folder');
+        process.exit(2);
+    } else {
+        console.error('ERROR : unable to find project bin folder, could not locate .apk');
+        process.exit(2);
+    }
+}
+
+module.exports.help = function() {
+    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'corodva', 'build')) + ' [build_type]');
+    console.log('Build Types : ');
+    console.log('    \'--debug\': Default build, will build project in using ant debug');
+    console.log('    \'--release\': will build project using ant release');
+    console.log('    \'--nobuild\': will skip build process (can be used with run command)');
+    process.exit(0);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/lib/check_reqs.js
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/lib/check_reqs.js b/e2e/fixtures/platforms/android/cordova/lib/check_reqs.js
new file mode 100755
index 0000000..c064499
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/lib/check_reqs.js
@@ -0,0 +1,78 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var shell = require('shelljs'),
+    path  = require('path'),
+    fs    = require('fs'),
+    ROOT  = path.join(__dirname, '..', '..');
+
+// Get valid target from framework/project.properties
+module.exports.get_target = function() {
+    if(fs.existsSync(path.join(ROOT, 'framework', 'project.properties'))) {
+        var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'framework', 'project.properties'));
+        return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
+    } else if (fs.existsSync(path.join(ROOT, 'project.properties'))) {
+        // if no target found, we're probably in a project and project.properties is in ROOT.
+        var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'project.properties'));
+        return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
+    }
+}
+
+module.exports.check_ant = function() {
+    var test = shell.exec('ant -version', {silent:true, async:false});
+    if(test.code > 0) {
+        console.error('ERROR : executing command \'ant\', make sure you have ant installed and added to your path.');
+        return false;
+    }
+    return true;
+}
+
+module.exports.check_java = function() {
+    if(process.env.JAVA_HOME) {
+        var test = shell.exec('java', {silent:true, async:false});
+        if(test.code > 0) {
+            console.error('ERROR : executing command \'java\', make sure you java environment is set up. Including your JDK and JRE.');
+            return false;
+        }
+        return true;
+    } else {
+        console.error('ERROR : Make sure JAVA_HOME is set, as well as paths to your JDK and JRE for java.');
+        return false;
+    }
+}
+
+module.exports.check_android = function() {
+    var valid_target = this.get_target();
+    var targets = shell.exec('android list targets', {silent:true, async:false});
+
+    if(targets.code > 0 && targets.output.match(/command\snot\sfound/)) {
+        console.error('The command \"android\" failed. Make sure you have the latest Android SDK installed, and the \"android\" command (inside the tools/ folder) is added to your path.');
+        return false;
+    } else if(!targets.output.match(valid_target)) {
+        console.error('Please install Android target ' + valid_target.split('-')[1] + ' (the Android newest SDK). Make sure you have the latest Android tools installed as well. Run \"android\" from your command-line to install/update any missing SDKs or tools.');
+        return false;
+    }
+    return true;
+}
+
+module.exports.run = function() {
+    return this.check_ant() && this.check_java && this.check_android();
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/lib/clean.js
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/lib/clean.js b/e2e/fixtures/platforms/android/cordova/lib/clean.js
new file mode 100755
index 0000000..579a5fa
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/lib/clean.js
@@ -0,0 +1,43 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var shell = require('shelljs'),
+    path  = require('path'),
+    ROOT = path.join(__dirname, '..', '..');
+
+/*
+ * Cleans the project using ant
+ */
+module.exports.run = function() {
+    var cmd = 'ant clean -f ' + path.join(ROOT, 'build.xml');
+    var result = shell.exec(cmd, {silent:false, async:false});
+    if (result.code > 0) {
+        console.error('ERROR: Failed to clean android project.');
+        console.error(result.output);
+        process.exit(2);
+    }
+}
+
+module.exports.help = function() {
+    console.log('Usage: ' + path.relative(process.cwd(), process.argv[1]));
+    console.log('Cleans the project directory.');
+    process.exit(0);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/lib/device.js
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/lib/device.js b/e2e/fixtures/platforms/android/cordova/lib/device.js
new file mode 100755
index 0000000..46686b6
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/lib/device.js
@@ -0,0 +1,95 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var shell = require('shelljs'),
+    path  = require('path'),
+    build = require('./build'),
+    appinfo = require('./appinfo'),
+    exec  = require('child_process').exec,
+    ROOT = path.join(__dirname, '..', '..');
+
+/**
+ * Returns a list of the device ID's found
+ */
+module.exports.list = function() {
+    var cmd = 'adb devices';
+    var result = shell.exec(cmd, {silent:true, async:false});
+    if (result.code > 0) {
+        console.error('Failed to execute android command \'' + cmd + '\'.');
+        process.exit(2);
+    } else {
+        var response = result.output.split('\n');
+        var device_list = [];
+        for (var i = 1; i < response.length; i++) {
+            if (response[i].match(/\w+\tdevice/) && !response[i].match(/emulator/)) {
+                device_list.push(response[i].replace(/\tdevice/, '').replace('\r', ''));
+            }
+        }
+        return device_list;
+    }
+}
+
+/*
+ * Installs a previously built application on the device
+ * and launches it.
+ */
+module.exports.install = function(target) {
+    var device_list = this.list();
+    if (device_list.length > 0) {
+        // default device
+        target = typeof target !== 'undefined' ? target : device_list[0];
+        if (device_list.indexOf(target) > -1) {
+            var apk_path = build.get_apk();
+            var launchName = appinfo.getActivityName();
+            console.log('Installing app on device...');
+            cmd = 'adb -s ' + target + ' install -r ' + apk_path;
+            var install = shell.exec(cmd, {silent:false, async:false});
+            if (install.error || install.output.match(/Failure/)) {
+                console.error('ERROR : Failed to install apk to device : ');
+                console.error(install.output);
+                process.exit(2);
+            }
+
+            //unlock screen
+            cmd = 'adb -s ' + target + ' shell input keyevent 82';
+            shell.exec(cmd, {silent:true, async:false});
+
+            // launch the application
+            console.log('Launching application...');
+            cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName;
+            var launch = shell.exec(cmd, {silent:true, async:false});
+            if(launch.code > 0) {
+                console.error('ERROR : Failed to launch application on emulator : ' + launch.error);
+                console.error(launch.output);
+                process.exit(2);
+            } else {
+                console.log('LANCH SUCCESS');
+            }
+        } else {
+            console.error('ERROR : Unable to find target \'' + target + '\'.');
+            console.error('Failed to deploy to device.');
+            process.exit(2);
+        }
+    } else {
+        console.error('ERROR : Failed to deploy to device, no devices found.');
+        process.exit(2);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/lib/emulator.js
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/lib/emulator.js b/e2e/fixtures/platforms/android/cordova/lib/emulator.js
new file mode 100755
index 0000000..6f8a7dd
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/lib/emulator.js
@@ -0,0 +1,337 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var shell = require('shelljs'),
+    path  = require('path'),
+    appinfo = require('./appinfo'),
+    build = require('./build'),
+    ROOT  = path.join(__dirname, '..', '..'),
+    new_emulator = 'cordova_emulator';
+
+/**
+ * Returns a list of emulator images in the form of objects
+ * {
+       name   : <emulator_name>,
+       path   : <path_to_emulator_image>,
+       target : <api_target>,
+       abi    : <cpu>,
+       skin   : <skin>
+   }
+ */
+module.exports.list_images = function() {
+    var cmd = 'android list avds';
+    var result = shell.exec(cmd, {silent:true, async:false});
+    if (result.code > 0) {
+        console.error('Failed to execute android command \'' + cmd + '\'.');
+        process.exit(2);
+    } else {
+        var response = result.output.split('\n');
+        var emulator_list = [];
+        for (var i = 1; i < response.length; i++) {
+            // To return more detailed information use img_obj
+            var img_obj = {};
+            if (response[i].match(/Name:\s/)) {
+                img_obj['name'] = response[i].split('Name: ')[1].replace('\r', '');
+                if (response[i + 1].match(/Path:\s/)) {
+                    i++;
+                    img_obj['path'] = response[i].split('Path: ')[1].replace('\r', '');
+                }
+                if (response[i + 1].match(/\(API\slevel\s/)) {
+                    i++;
+                    img_obj['target'] = response[i].replace('\r', '');
+                }
+                if (response[i + 1].match(/ABI:\s/)) {
+                    i++;
+                    img_obj['abi'] = response[i].split('ABI: ')[1].replace('\r', '');
+                }
+                if (response[i + 1].match(/Skin:\s/)) {
+                    i++;
+                    img_obj['skin'] = response[i].split('Skin: ')[1].replace('\r', '');
+                }
+
+                emulator_list.push(img_obj);
+            }
+            /* To just return a list of names use this
+            if (response[i].match(/Name:\s/)) {
+                emulator_list.push(response[i].split('Name: ')[1].replace('\r', '');
+            }*/
+
+        }
+        return emulator_list;
+    }
+}
+
+/**
+ * Will return the closest avd to the projects target
+ * or undefined if no avds exist.
+ */
+module.exports.best_image = function() {
+    var project_target = this.get_target().replace('android-', '');
+    var images = this.list_images();
+    var closest = 9999;
+    var best = images[0];
+    for (i in images) {
+        var target = images[i].target;
+        if(target) {
+            var num = target.split('(API level ')[1].replace(')', '');
+            if (num == project_target) {
+                return images[i];
+            } else if (project_target - num < closest && project_target > num) {
+                var closest = project_target - num;
+                best = images[i];
+            }
+        }
+    }
+    return best;
+}
+
+module.exports.list_started = function() {
+    var cmd = 'adb devices';
+    var result = shell.exec(cmd, {silent:true, async:false});
+    if (result.code > 0) {
+        console.error('Failed to execute android command \'' + cmd + '\'.');
+        process.exit(2);
+    } else {
+        var response = result.output.split('\n');
+        var started_emulator_list = [];
+        for (var i = 1; i < response.length; i++) {
+            if (response[i].match(/device/) && response[i].match(/emulator/)) {
+                started_emulator_list.push(response[i].replace(/\tdevice/, '').replace('\r', ''));
+            }
+        }
+        return started_emulator_list;
+    }
+}
+
+module.exports.get_target = function() {
+    var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'project.properties'));
+    return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
+}
+
+module.exports.list_targets = function() {
+    var target_out = shell.exec('android list targets', {silent:true, async:false}).output.split('\n');
+    var targets = [];
+    for (var i = target_out.length; i >= 0; i--) {
+        if(target_out[i].match(/id:/)) {
+            targets.push(targets[i].split(' ')[1]);
+        }
+    }
+    return targets;
+}
+
+/*
+ * Starts an emulator with the given ID,
+ * and returns the started ID of that emulator.
+ * If no ID is given it will used the first image availible,
+ * if no image is availible it will error out (maybe create one?).
+ */
+module.exports.start = function(emulator_ID) {
+    var started_emulators = this.list_started();
+    var num_started = started_emulators.length;
+    if (typeof emulator_ID === 'undefined') {
+        var emulator_list = this.list_images();
+        if (emulator_list.length > 0) {
+            emulator_ID = this.best_image().name;
+            console.log('WARNING : no emulator specified, defaulting to ' + emulator_ID);
+        } else {
+            console.error('ERROR : No emulator images (avds) found, if you would like to create an');
+            console.error(' avd follow the instructions provided here : ');
+            console.error(' http://developer.android.com/tools/devices/index.html')
+            console.error(' Or run \'android create avd --name <name> --target <targetID>\' ');
+            console.error(' in on the command line.');
+            process.exit(2);
+            /*console.log('WARNING : no emulators availible, creating \'' + new_emulator + '\'.');
+            this.create_image(new_emulator, this.get_target());
+            emulator_ID = new_emulator;*/
+        }
+    }
+
+    var pipe_null = (process.platform == 'win32' || process.platform == 'win64'? '> NUL' : '> /dev/null');
+    var cmd = 'emulator -avd ' + emulator_ID + ' ' + pipe_null + ' &';
+    if(process.platform == 'win32' || process.platform == 'win64') {
+        cmd = '%comspec% /c start cmd /c ' + cmd;
+    }
+    var result = shell.exec(cmd, {silent:true, async:false}, function(code, output) {
+        if (code > 0) {
+            console.error('Failed to execute android command \'' + cmd + '\'.');
+            console.error(output);
+            process.exit(2);
+        }
+    });
+
+    // wait for emulator to start
+    console.log('Waiting for emulator...');
+    var new_started = this.wait_for_emulator(num_started);
+    var emulator_id;
+    if (new_started.length > 1) {
+        for (i in new_started) {
+            console.log(new_started[i]);
+            console.log(started_emulators.indexOf(new_started[i]));
+            if (started_emulators.indexOf(new_started[i]) < 0) {
+                emulator_id = new_started[i];
+            }
+        }
+    } else {
+        emulator_id = new_started[0];
+    }
+    if (!emulator_id) {
+        console.error('ERROR :  Failed to start emulator, could not find new emulator');
+        process.exit(2);
+    }
+
+    //wait for emulator to boot up
+    process.stdout.write('Booting up emulator (this may take a while)...');
+    this.wait_for_boot(emulator_id);
+    console.log('BOOT COMPLETE');
+
+    //unlock screen
+    cmd = 'adb -s ' + emulator_id + ' shell input keyevent 82';
+    shell.exec(cmd, {silent:false, async:false});
+
+    //return the new emulator id for the started emulators
+    return emulator_id;
+}
+
+/*
+ * Waits for the new emulator to apear on the started-emulator list.
+ */
+module.exports.wait_for_emulator = function(num_running) {
+    var new_started = this.list_started();
+    if (new_started.length > num_running) {
+        return new_started;
+    } else {
+        this.sleep(1);
+        return this.wait_for_emulator(num_running);
+    }
+}
+
+/*
+ * Waits for the boot animation property of the emulator to switch to 'stopped'
+ */
+module.exports.wait_for_boot = function(emulator_id) {
+    var cmd;
+    // ShellJS opens a lot of file handles, and the default on OS X is too small.
+    // TODO : This is not working, need to find a better way to increese the ulimit.
+    if(process.platform == 'win32' || process.platform == 'win64') {
+        cmd = 'adb -s ' + emulator_id + ' shell getprop init.svc.bootanim';
+    } else {
+        cmd = 'ulimit -S -n 4096; adb -s ' + emulator_id + ' shell getprop init.svc.bootanim';
+    }
+    var boot_anim = shell.exec(cmd, {silent:true, async:false});
+    if (boot_anim.output.match(/stopped/)) {
+        return;
+    } else {
+        process.stdout.write('.');
+        this.sleep(3);
+        return this.wait_for_boot(emulator_id);
+    }
+}
+
+/*
+ * TODO : find a better way to wait for the emulator (maybe using async methods?)
+ */
+module.exports.sleep = function(time_sec) {
+    if (process.platform == 'win32' || process.platform == 'win64') {
+        shell.exec('ping 127.0.0.1 -n ' + time_sec, {silent:true, async:false});
+    } else {
+        shell.exec('sleep ' + time_sec, {silent:true, async:false});
+    }
+}
+
+/*
+ * Create avd
+ * TODO : Enter the stdin input required to complete the creation of an avd.
+ */
+module.exports.create_image = function(name, target) {
+    console.log('Creating avd named ' + name);
+    if (target) {
+        var cmd = 'android create avd --name ' + name + ' --target ' + target;
+        var create = shell.exec(cmd, {sient:false, async:false});
+        if (create.error) {
+            console.error('ERROR : Failed to create emulator image : ');
+            console.error(' Do you have the latest android targets including ' + target + '?');
+            console.error(create.output);
+            process.exit(2);
+        }
+    } else {
+        console.log('WARNING : Project target not found, creating avd with a different target but the project may fail to install.');
+        var cmd = 'android create avd --name ' + name + ' --target ' + this.list_targets()[0];
+        var create = shell.exec(cmd, {sient:false, async:false});
+        if (create.error) {
+            console.error('ERROR : Failed to create emulator image : ');
+            console.error(create.output);
+            process.exit(2);
+        }
+        console.error('ERROR : Unable to create an avd emulator, no targets found.');
+        console.error('Please insure you have targets availible by runing the "android" command').
+        process.exit(2);
+    }
+}
+
+/*
+ * Installs a previously built application on the emulator and launches it.
+ * If no target is specified, then it picks one.
+ * If no started emulators are found, error out.
+ */
+module.exports.install = function(target) {
+    var emulator_list = this.list_started();
+    if (emulator_list.length < 1) {
+        console.error('ERROR : No started emulators found, please start an emultor before deploying your project.');
+        process.exit(2);
+        /*console.log('WARNING : No started emulators found, attemting to start an avd...');
+        this.start(this.best_image().name);*/
+    }
+    // default emulator
+    target = typeof target !== 'undefined' ? target : emulator_list[0];
+    if (emulator_list.indexOf(target) > -1) {
+        console.log('Installing app on emulator...');
+        var apk_path = build.get_apk();
+        var cmd = 'adb -s ' + target + ' install -r ' + apk_path;
+        var install = shell.exec(cmd, {sient:false, async:false});
+        if (install.error || install.output.match(/Failure/)) {
+            console.error('ERROR : Failed to install apk to emulator : ');
+            console.error(install.output);
+            process.exit(2);
+        }
+
+        //unlock screen
+        cmd = 'adb -s ' + target + ' shell input keyevent 82';
+        shell.exec(cmd, {silent:true, async:false});
+
+        // launch the application
+        console.log('Launching application...');
+        var launchName = appinfo.getActivityName();
+        cmd = 'adb -s ' + target + ' shell am start -W -a android.intent.action.MAIN -n ' + launchName;
+        console.log(cmd);
+        var launch = shell.exec(cmd, {silent:false, async:false});
+        if(launch.code > 0) {
+            console.error('ERROR : Failed to launch application on emulator : ' + launch.error);
+            console.error(launch.output);
+            process.exit(2);
+        } else {
+            console.log('LANCH SUCCESS');
+        }
+    } else {
+        console.error('ERROR : Unable to find target \'' + target + '\'.');
+        console.error('Failed to deploy to emulator.');
+        process.exit(2);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/lib/install-device
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/lib/install-device b/e2e/fixtures/platforms/android/cordova/lib/install-device
new file mode 100755
index 0000000..cf53918
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/lib/install-device
@@ -0,0 +1,38 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var device = require('./device'),
+    args   = process.argv;
+
+if(args.length > 2) {
+    var install_target;
+    if (args[2].substring(0, 9) == '--target=') {
+        install_target = args[2].substring(9, args[2].length);
+        device.install(install_target);
+        process.exit(0);
+     } else {
+        console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
+        process.exit(2);
+     }
+} else {
+    device.install();
+    process.exit(0);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/lib/install-emulator
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/lib/install-emulator b/e2e/fixtures/platforms/android/cordova/lib/install-emulator
new file mode 100755
index 0000000..70421be
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/lib/install-emulator
@@ -0,0 +1,38 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var emulator = require('./emulator'),
+    args     = process.argv;
+
+if(args.length > 2) {
+    var install_target;
+    if (args[2].substring(0, 9) == '--target=') {
+        install_target = args[2].substring(9, args[2].length);
+        emulator.install(install_target);
+        process.exit(0);
+     } else {
+        console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
+        process.exit(2);
+     }
+} else {
+    emulator.install();
+    process.exit(0);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/lib/list-devices
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/lib/list-devices b/e2e/fixtures/platforms/android/cordova/lib/list-devices
new file mode 100755
index 0000000..bdd0abd
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/lib/list-devices
@@ -0,0 +1,28 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var devices = require('./device');
+
+// Usage support for when args are given
+var device_list = devices.list();
+for(device in device_list) {
+    console.log(device_list[device]);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/lib/list-emulator-images
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/lib/list-emulator-images b/e2e/fixtures/platforms/android/cordova/lib/list-emulator-images
new file mode 100755
index 0000000..69f4789
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/lib/list-emulator-images
@@ -0,0 +1,29 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var emulators = require('./emulator');
+
+// Usage support for when args are given
+var emulator_list = emulators.list_images();
+for(emulator in emulator_list) {
+    console.log(emulator_list[emulator].name);
+    process.exit(0);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/lib/list-started-emulators
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/lib/list-started-emulators b/e2e/fixtures/platforms/android/cordova/lib/list-started-emulators
new file mode 100755
index 0000000..3e69b2f
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/lib/list-started-emulators
@@ -0,0 +1,29 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var emulators = require('./emulator');
+
+// Usage support for when args are given
+var emulator_list = emulators.list_started();
+for(emulator in emulator_list) {
+    console.log(emulator_list[emulator]);
+    process.exit(0);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/lib/log.js
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/lib/log.js b/e2e/fixtures/platforms/android/cordova/lib/log.js
new file mode 100755
index 0000000..ff14e46
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/lib/log.js
@@ -0,0 +1,43 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var shell = require('shelljs'),
+    path  = require('path'),
+    ROOT = path.join(__dirname, '..', '..');
+
+/*
+ * Starts running logcat in the shell.
+ */
+module.exports.run = function() {
+    var cmd = 'adb logcat | grep -v nativeGetEnabledTags';
+    var result = shell.exec(cmd, {silent:false, async:false});
+    if (result.code > 0) {
+        console.error('ERROR: Failed to run logcat command.');
+        console.error(result.output);
+        process.exit(2);
+    }
+}
+
+module.exports.help = function() {
+    console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'corodva', 'log')));
+    console.log('Gives the logcat output on the command line.');
+    process.exit(0);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/lib/run.js
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/lib/run.js b/e2e/fixtures/platforms/android/cordova/lib/run.js
new file mode 100755
index 0000000..b1c8b2b
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/lib/run.js
@@ -0,0 +1,123 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var path  = require('path'),
+    build = require('./build'),
+    emulator = require('./emulator'),
+    device   = require('./device');
+
+/*
+ * Runs the application on a device if availible.
+ * If not device is found, it will use a started emulator.
+ * If no started emulators are found it will attempt to start an avd.
+ * If no avds are found it will error out.
+ */
+ module.exports.run = function(args) {
+    var build_type;
+    var install_target;
+
+    for (var i=2; i<args.length; i++) {
+        if (args[i] == '--debug') {
+            build_type = '--debug';
+        } else if (args[i] == '--release') {
+            build_type = '--release';
+        } else if (args[i] == '--nobuild') {
+            build_type = '--nobuild';
+        } else if (args[i] == '--device') {
+            install_target = '--device';
+        } else if (args[i] == '--emulator') {
+            install_target = '--emulator';
+        } else if (args[i].substring(0, 9) == '--target=') {
+            install_target = args[i].substring(9, args[i].length);
+        } else {
+            console.error('ERROR : Run option \'' + args[i] + '\' not recognized.');
+            process.exit(2);
+        }
+    }
+    build.run(build_type);
+    if (install_target == '--device') {
+        device.install();
+    } else if (install_target == '--emulator') {
+        if (emulator.list_started() == 0) {
+            emulator.start();
+        }
+        emulator.install();
+    } else if (install_target) {
+        var devices = device.list();
+        var started_emulators = emulator.list_started();
+        var avds = emulator.list_images();
+        if (devices.indexOf(install_target) > -1) {
+            device.install(install_target);
+        } else if (started_emulators.indexOf(install_target) > -1) {
+            emulator.install(install_target);
+        } else {
+            // if target emulator isn't started, then start it.
+            var emulator_ID;
+            for(avd in avds) {
+                if(avds[avd].name == install_target) {
+                    emulator_ID = emulator.start(install_target);
+                    emulator.install(emulator_ID);
+                    break;
+                }
+            }
+            if(!emulator_ID) {
+                console.error('ERROR : Target \'' + install_target + '\' not found, unalbe to run project');
+                process.exit(2);
+            }
+        }
+    } else {
+        // no target given, deploy to device if availible, otherwise use the emulator.
+        var device_list = device.list();
+        if (device_list.length > 0) {
+            console.log('WARNING : No target specified, deploying to device \'' + device_list[0] + '\'.');
+            device.install(device_list[0])
+        } else {
+            var emulator_list = emulator.list_started();
+            if (emulator_list.length > 0) {
+                console.log('WARNING : No target specified, deploying to emulator \'' + emulator_list[0] + '\'.');
+                emulator.install(emulator_list[0]);
+            } else {
+                console.log('WARNING : No started emulators found, starting an emulator.');
+                var best_avd = emulator.best_image();
+                if(best_avd) {
+                    var emulator_ID = emulator.start(best_avd.name);
+                    console.log('WARNING : No target specified, deploying to emulator \'' + emulator_ID + '\'.');
+                    emulator.install(emulator_ID);
+                } else {
+                    emulator.start();
+                }
+            }
+        }
+    }
+}
+
+module.exports.help = function() {
+    console.log('Usage: ' + path.relative(process.cwd(), args[0]) + ' [options]');
+    console.log('Build options :');
+    console.log('    --debug : Builds project in debug mode');
+    console.log('    --release : Builds project in release mode');
+    console.log('    --nobuild : Runs the currently built project without recompiling');
+    console.log('Deploy options :');
+    console.log('    --device : Will deploy the built project to a device');
+    console.log('    --emulator : Will deploy the built project to an emulator if one exists');
+    console.log('    --target=<target_id> : Installs to the target with the specified id.');
+    process.exit(0);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/lib/start-emulator
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/lib/start-emulator b/e2e/fixtures/platforms/android/cordova/lib/start-emulator
new file mode 100755
index 0000000..8ea6d3f
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/lib/start-emulator
@@ -0,0 +1,38 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var emulator = require('./emulator'),
+      args   = process.argv;
+
+if(args.length > 2) {
+    var install_target;
+    if (args[2].substring(0, 9) == '--target=') {
+        install_target = args[2].substring(9, args[2].length);
+        emulator.start(install_target);
+        process.exit(0);
+     } else {
+        console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
+        process.exit(2);
+     }
+} else {
+    emulator.start();
+    process.exit(0);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/log
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/log b/e2e/fixtures/platforms/android/cordova/log
new file mode 100755
index 0000000..514f69c
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/log
@@ -0,0 +1,33 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var log  = require('./lib/log'),
+    reqs = require('./lib/check_reqs'),
+    args = process.argv;
+
+// Usage support for when args are given
+if(args.length > 2) {
+    log.help();
+} else if(reqs.run()) {
+    log.run();
+} else {
+    process.exit(2);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/run
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/run b/e2e/fixtures/platforms/android/cordova/run
new file mode 100755
index 0000000..c3a5772
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/run
@@ -0,0 +1,35 @@
+#!/usr/bin/env node
+
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var run  = require('./lib/run'),
+    reqs = require('./lib/check_reqs'),
+    args = process.argv;
+
+// Support basic help commands
+if (args[2] == '--help' || args[2] == '/?' || args[2] == '-h' ||
+                    args[2] == 'help' || args[2] == '-help' || args[2] == '/help') {
+    run.help();
+} else if(reqs.run()) {
+    run.run(args);
+    process.exit(0);
+} else {
+    process.exit(2);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/cordova/version
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/cordova/version b/e2e/fixtures/platforms/android/cordova/version
new file mode 100755
index 0000000..de1a76d
--- /dev/null
+++ b/e2e/fixtures/platforms/android/cordova/version
@@ -0,0 +1,25 @@
+#!/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.
+*/
+
+// Coho updates this line:
+var VERSION = "3.1.0";
+
+console.log(VERSION);

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/local.properties
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/local.properties b/e2e/fixtures/platforms/android/local.properties
new file mode 100644
index 0000000..d3f5072
--- /dev/null
+++ b/e2e/fixtures/platforms/android/local.properties
@@ -0,0 +1,10 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+
+# location of the SDK. This is only used by Ant
+# For customization when using a Version Control System, please read the
+# header note.
+sdk.dir=/Users/braden/cordova/android/android-sdk-macosx

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/proguard-project.txt
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/proguard-project.txt b/e2e/fixtures/platforms/android/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/e2e/fixtures/platforms/android/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/project.properties
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/project.properties b/e2e/fixtures/platforms/android/project.properties
new file mode 100644
index 0000000..a3ee5ab
--- /dev/null
+++ b/e2e/fixtures/platforms/android/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-17

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/res/drawable-hdpi/icon.png
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/res/drawable-hdpi/icon.png b/e2e/fixtures/platforms/android/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..4d27634
Binary files /dev/null and b/e2e/fixtures/platforms/android/res/drawable-hdpi/icon.png differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/res/drawable-ldpi/icon.png
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/res/drawable-ldpi/icon.png b/e2e/fixtures/platforms/android/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000..cd5032a
Binary files /dev/null and b/e2e/fixtures/platforms/android/res/drawable-ldpi/icon.png differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/res/drawable-mdpi/icon.png
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/res/drawable-mdpi/icon.png b/e2e/fixtures/platforms/android/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..e79c606
Binary files /dev/null and b/e2e/fixtures/platforms/android/res/drawable-mdpi/icon.png differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/res/drawable-xhdpi/icon.png
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/res/drawable-xhdpi/icon.png b/e2e/fixtures/platforms/android/res/drawable-xhdpi/icon.png
new file mode 100644
index 0000000..ec7ffbf
Binary files /dev/null and b/e2e/fixtures/platforms/android/res/drawable-xhdpi/icon.png differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/res/drawable/icon.png
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/res/drawable/icon.png b/e2e/fixtures/platforms/android/res/drawable/icon.png
new file mode 100644
index 0000000..ec7ffbf
Binary files /dev/null and b/e2e/fixtures/platforms/android/res/drawable/icon.png differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/res/values/strings.xml
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/res/values/strings.xml b/e2e/fixtures/platforms/android/res/values/strings.xml
new file mode 100644
index 0000000..1e706b3
--- /dev/null
+++ b/e2e/fixtures/platforms/android/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version='1.0' encoding='utf-8'?>
+<resources>
+    <string name="app_name">TestBase</string>
+</resources>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/res/xml/config.xml
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/res/xml/config.xml b/e2e/fixtures/platforms/android/res/xml/config.xml
new file mode 100644
index 0000000..17ca237
--- /dev/null
+++ b/e2e/fixtures/platforms/android/res/xml/config.xml
@@ -0,0 +1,18 @@
+<?xml version='1.0' encoding='utf-8'?>
+<widget id="org.testing" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
+    <name>Hello Cordova</name>
+    <description>
+        A sample Apache Cordova application that responds to the deviceready event.
+    </description>
+    <access origin="*" />
+    <preference name="loglevel" value="DEBUG" />
+    <feature name="App">
+        <param name="android-package" value="org.apache.cordova.App" />
+    </feature>
+    <author email="dev@cordova.apache.org" href="http://cordova.io">
+        Apache Cordova Team
+    </author>
+    <content src="index.html" />
+    <preference name="fullscreen" value="true" />
+    <preference name="webviewbounce" value="true" />
+</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/src/org/testing/TestBase.java
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/src/org/testing/TestBase.java b/e2e/fixtures/platforms/android/src/org/testing/TestBase.java
new file mode 100644
index 0000000..928e074
--- /dev/null
+++ b/e2e/fixtures/platforms/android/src/org/testing/TestBase.java
@@ -0,0 +1,37 @@
+/*
+       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.
+ */
+
+package org.testing;
+
+import android.os.Bundle;
+import org.apache.cordova.*;
+
+public class TestBase extends CordovaActivity 
+{
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        super.init();
+        // Set by <content src="index.html" /> in config.xml
+        super.loadUrl(Config.getStartUrl());
+        //super.loadUrl("file:///android_asset/www/index.html")
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/plugins/fake1/plugin.xml
----------------------------------------------------------------------
diff --git a/e2e/fixtures/plugins/fake1/plugin.xml b/e2e/fixtures/plugins/fake1/plugin.xml
new file mode 100644
index 0000000..ffdc650
--- /dev/null
+++ b/e2e/fixtures/plugins/fake1/plugin.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
+           id="org.apache.cordova.fakeplugin1"
+      version="0.1.0-dev">
+    <name>Fake1</name>
+    <description>Cordova fake plugin for tests</description>
+    <license>Apache 2.0</license>
+    <keywords>cordova,cli,test</keywords>
+</plugin>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/helpers.js
----------------------------------------------------------------------
diff --git a/e2e/helpers.js b/e2e/helpers.js
new file mode 100644
index 0000000..aa1c790
--- /dev/null
+++ b/e2e/helpers.js
@@ -0,0 +1,43 @@
+
+var path = require('path'),
+    fs = require('fs'),
+    shell = require('shelljs'),
+    os = require('os');
+
+module.exports.tmpDir = function() {
+    var dir = path.join(os.tmpdir(), 'e2e-test');
+    shell.mkdir('-p', dir);
+    return dir;
+};
+
+// Returns the platform that should be used for testing on this host platform.
+/*
+var host = os.platform();
+if (host.match(/win/)) {
+    module.exports.testPlatform = 'wp8';
+} else if (host.match(/darwin/)) {
+    module.exports.testPlatform = 'ios';
+} else {
+    module.exports.testPlatform = 'android';
+}
+*/
+
+// Just use Android everywhere; we're mocking out any calls to the `android` binary.
+module.exports.testPlatform = 'android';
+
+// Add the toExist matcher.
+beforeEach(function() {
+    this.addMatchers({
+        'toExist': function() {
+            var notText = this.isNot ? ' not' : '';
+            var self = this;
+
+            this.message = function() {
+                return 'Expected file ' + self.actual + notText + ' to exist.';
+            };
+
+            return fs.existsSync(this.actual);
+        }
+    });
+});
+


[18/23] git commit: Make sure errors during prepare are reported

Posted by st...@apache.org.
Make sure errors during prepare are reported

>From https://github.com/apache/cordova-cli/pull/49


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

Branch: refs/heads/ubuntu
Commit: ed82c5a9a9419288ed842c8872a7ffba4b966720
Parents: 68942e6
Author: Anton Keks <an...@codeborne.com>
Authored: Thu Dec 5 15:41:30 2013 -0500
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Thu Dec 5 15:41:30 2013 -0500

----------------------------------------------------------------------
 src/metadata/android_parser.js | 4 ++--
 src/prepare.js                 | 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ed82c5a9/src/metadata/android_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/android_parser.js b/src/metadata/android_parser.js
index 5878678..ca8a652 100644
--- a/src/metadata/android_parser.js
+++ b/src/metadata/android_parser.js
@@ -152,11 +152,11 @@ module.exports.prototype = {
         var platformWww = path.join(this.path, 'assets');
         try {
             this.update_from_config(cfg);
+            this.update_overrides();
+            this.update_staging();
         } catch(e) {
             return Q.reject(e);
         }
-        this.update_overrides();
-        this.update_staging();
         // delete any .svn folders copied over
         util.deleteSvnFolders(platformWww);
         return Q();

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ed82c5a9/src/prepare.js
----------------------------------------------------------------------
diff --git a/src/prepare.js b/src/prepare.js
index 9e7719e..92b828d 100644
--- a/src/prepare.js
+++ b/src/prepare.js
@@ -120,6 +120,8 @@ module.exports = function prepare(options) {
                 platform_cfg.merge_with(cfg, platform, true);
 
                 return parser.update_project(cfg);
+            }).fail(function(e) {
+                console.error(e);
             });
         })).then(function() {
             return hooks.fire('after_prepare', options);


[13/23] git commit: add ubuntu to platform.spec list

Posted by st...@apache.org.
add ubuntu to platform.spec list


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

Branch: refs/heads/ubuntu
Commit: 2fb1c8eda59c0d45979140cceb0ef10db8c65098
Parents: 81ce8ed
Author: Maxim Ermilov <ma...@canonical.com>
Authored: Wed Dec 4 04:49:49 2013 +0400
Committer: Maxim Ermilov <ma...@canonical.com>
Committed: Wed Dec 4 04:49:49 2013 +0400

----------------------------------------------------------------------
 spec/platform.spec.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/2fb1c8ed/spec/platform.spec.js
----------------------------------------------------------------------
diff --git a/spec/platform.spec.js b/spec/platform.spec.js
index 6df69a1..dd86fa5 100644
--- a/spec/platform.spec.js
+++ b/spec/platform.spec.js
@@ -151,7 +151,7 @@ describe('platform command', function() {
 
             it('should list out added platforms in a project', function(done) {
                 cordova.on('results', function(res) {
-                    expect(res).toMatch(/^Installed platforms: ios, android, wp7, wp8, blackberry10, firefoxos, windows8\s*Available platforms:\s*$/);
+                    expect(res).toMatch(/^Installed platforms: ios, android, ubuntu, wp7, wp8, blackberry10, firefoxos, windows8\s*Available platforms:\s*$/);
                     done();
                 });
                 cordova.raw.platform('list');


[08/23] git commit: Merge branch 'e2e-tests'

Posted by st...@apache.org.
Merge branch 'e2e-tests'


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

Branch: refs/heads/ubuntu
Commit: 2eedc27e205e9ec381c41a22bc68b72bfcd3f2ab
Parents: af7b240 186baba
Author: Michal Mocny <mm...@gmail.com>
Authored: Fri Nov 29 09:59:58 2013 -0500
Committer: Michal Mocny <mm...@gmail.com>
Committed: Fri Nov 29 09:59:58 2013 -0500

----------------------------------------------------------------------
 e2e/create.spec.js   | 1 +
 e2e/platform.spec.js | 1 +
 e2e/plugin.spec.js   | 1 +
 3 files changed, 3 insertions(+)
----------------------------------------------------------------------



[07/23] git commit: Revert "fixed merge conflict due to e2e"

Posted by st...@apache.org.
Revert "fixed merge conflict due to e2e"

This reverts commit d6e96f206b205d7bb069e6aadf9b126da5ad794c.


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

Branch: refs/heads/ubuntu
Commit: af7b2401ddce24ada81d9c886bfe2e9a89fbefa9
Parents: f7a35b3
Author: Michal Mocny <mm...@gmail.com>
Authored: Fri Nov 29 09:55:36 2013 -0500
Committer: Michal Mocny <mm...@gmail.com>
Committed: Fri Nov 29 09:55:36 2013 -0500

----------------------------------------------------------------------
 e2e/create.spec.js                              |  115 ++
 e2e/fixtures/base/.cordova/config.json          |   22 +
 e2e/fixtures/base/merges/.svn                   |    0
 e2e/fixtures/base/platforms/.svn                |    0
 e2e/fixtures/base/plugins/.svn                  |    0
 e2e/fixtures/base/www/config.xml                |   14 +
 e2e/fixtures/base/www/css/index.css             |  115 ++
 e2e/fixtures/base/www/img/logo.png              |  Bin 0 -> 21814 bytes
 e2e/fixtures/base/www/index.html                |   43 +
 e2e/fixtures/base/www/js/index.js               |   49 +
 e2e/fixtures/base/www/spec.html                 |   68 +
 .../android-lib/framework/assets/www/cordova.js |    1 +
 .../platforms/android/AndroidManifest.xml       |   14 +
 .../platforms/android/assets/www/config.xml     |   14 +
 .../platforms/android/assets/www/cordova.js     | 1712 ++++++++++++++++++
 .../android/assets/www/cordova_plugins.js       |    3 +
 .../platforms/android/assets/www/css/index.css  |  115 ++
 .../platforms/android/assets/www/img/logo.png   |  Bin 0 -> 21814 bytes
 .../platforms/android/assets/www/index.html     |   43 +
 .../platforms/android/assets/www/js/index.js    |   49 +
 .../platforms/android/assets/www/spec.html      |   68 +
 e2e/fixtures/platforms/android/build.xml        |   92 +
 e2e/fixtures/platforms/android/cordova/build    |   35 +
 .../platforms/android/cordova/check_reqs        |   27 +
 e2e/fixtures/platforms/android/cordova/clean    |   34 +
 .../platforms/android/cordova/defaults.xml      |   50 +
 .../platforms/android/cordova/lib/appinfo.js    |   41 +
 .../platforms/android/cordova/lib/build.js      |   89 +
 .../platforms/android/cordova/lib/check_reqs.js |   78 +
 .../platforms/android/cordova/lib/clean.js      |   43 +
 .../platforms/android/cordova/lib/device.js     |   95 +
 .../platforms/android/cordova/lib/emulator.js   |  337 ++++
 .../android/cordova/lib/install-device          |   38 +
 .../android/cordova/lib/install-emulator        |   38 +
 .../platforms/android/cordova/lib/list-devices  |   28 +
 .../android/cordova/lib/list-emulator-images    |   29 +
 .../android/cordova/lib/list-started-emulators  |   29 +
 .../platforms/android/cordova/lib/log.js        |   43 +
 .../platforms/android/cordova/lib/run.js        |  123 ++
 .../android/cordova/lib/start-emulator          |   38 +
 e2e/fixtures/platforms/android/cordova/log      |   33 +
 e2e/fixtures/platforms/android/cordova/run      |   35 +
 e2e/fixtures/platforms/android/cordova/version  |   25 +
 e2e/fixtures/platforms/android/local.properties |   10 +
 .../platforms/android/proguard-project.txt      |   20 +
 .../platforms/android/project.properties        |   14 +
 .../android/res/drawable-hdpi/icon.png          |  Bin 0 -> 6080 bytes
 .../android/res/drawable-ldpi/icon.png          |  Bin 0 -> 3096 bytes
 .../android/res/drawable-mdpi/icon.png          |  Bin 0 -> 4090 bytes
 .../android/res/drawable-xhdpi/icon.png         |  Bin 0 -> 7685 bytes
 .../platforms/android/res/drawable/icon.png     |  Bin 0 -> 7685 bytes
 .../platforms/android/res/values/strings.xml    |    4 +
 .../platforms/android/res/xml/config.xml        |   18 +
 .../android/src/org/testing/TestBase.java       |   37 +
 e2e/fixtures/plugins/fake1/plugin.xml           |   10 +
 e2e/helpers.js                                  |   43 +
 e2e/platform.spec.js                            |  117 ++
 e2e/plugin.spec.js                              |   67 +
 package.json                                    |    2 +-
 59 files changed, 4166 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/create.spec.js
----------------------------------------------------------------------
diff --git a/e2e/create.spec.js b/e2e/create.spec.js
new file mode 100644
index 0000000..5900d7a
--- /dev/null
+++ b/e2e/create.spec.js
@@ -0,0 +1,115 @@
+/**
+    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 helpers = require('./helpers'),
+    path = require('path'),
+    fs = require('fs'),
+    shell = require('shelljs'),
+    Q = require('q'),
+    config = require('../src/config'),
+    events = require('../src/events'),
+    util = require('../src/util'),
+    cordova = require('../cordova');
+
+// A utility function to generate all combinations of elements from 2 arrays.
+// crossConcat(['x', 'y'], ['1', '2', '3'])
+// -> [ 'x1', 'x2', 'x3', 'y1', 'y2', 'y3']
+var crossConcat = function(a, b, delimiter){
+    var result = [];
+    delimiter = delimiter || '';
+    for (var i = 0; i < a.length; i++) {
+        for (var j = 0; j < b.length; j++) {
+            result.push(a[i] + delimiter + b[j]);
+        }
+    }
+    return result;
+};
+
+var tmpDir = helpers.tmpDir();
+var appName = 'TestCreate';
+var appId = 'io.cordova.' + appName.toLocaleLowerCase();
+var project = path.join(tmpDir, appName);
+var cordovaDir = path.join(project, '.cordova');
+var extraConfig = {
+      lib: {
+        www: {
+          uri: path.join(__dirname, 'fixtures', 'base', 'www'),
+          version: "testCordovaCreate",
+          id: appName
+        }
+      }
+    };
+
+describe('create end-to-end', function() {
+
+    beforeEach(function() {
+        shell.rm('-rf', project);
+    });
+    afterEach(function() {
+        shell.rm('-rf', project);
+    });
+
+    var results;
+    events.on('results', function(res) { results = res; });
+
+    it('should successfully run', function(done) {
+        // Call cordova create with no args, should return help.
+        cordova.raw.create().then(function() {
+            expect(results).toMatch(/synopsis/gi);
+        }).then(function() {
+            // Create a real project
+            return cordova.raw.create(project, appId, appName, extraConfig);
+        }).then(function() {
+            // Check if top level dirs exist.
+            var dirs = ['.cordova', 'platforms', 'merges', 'plugins', 'www'];
+            dirs.forEach(function(d) {
+                expect(path.join(project, d)).toExist();
+            });
+
+            // Check if hook dirs exist.
+            var hooksDir = path.join(project, '.cordova', 'hooks');
+            dirs = crossConcat(['platform', 'plugin'], ['add', 'rm', 'ls'], '_');
+            dirs = dirs.concat(['build', 'compile', 'docs', 'emulate', 'prepare', 'run']);
+            dirs = crossConcat(['before', 'after'], dirs, '_');
+            dirs.forEach(function(d) {
+                expect(path.join(hooksDir, d)).toExist();
+            });
+
+            // Check if config files exist.
+            expect(path.join(cordovaDir, 'config.json')).toExist();
+            expect(path.join(project, 'www', 'config.xml')).toExist();
+
+            // Check contents of config.json
+            var cfg = config.read(project);
+            expect(cfg.id).toEqual(appId);
+            expect(cfg.name).toEqual(appName);
+            expect(cfg.lib.www.id).toEqual(appName);
+
+            // Check that www/config.xml was updated.
+            var configXml = new util.config_parser(path.join(project, 'www', 'config.xml'));
+            expect(configXml.packageName()).toEqual(appId);
+
+            // TODO (kamrik): check somehow that we got the right config.xml from the fixture and not some place else.
+            // expect(configXml.name()).toEqual('TestBase');
+        }).fail(function(err) {
+            console.log(err);
+            expect(err).toBeUndefined();
+        }).fin(done);
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/base/.cordova/config.json
----------------------------------------------------------------------
diff --git a/e2e/fixtures/base/.cordova/config.json b/e2e/fixtures/base/.cordova/config.json
new file mode 100644
index 0000000..662fc9d
--- /dev/null
+++ b/e2e/fixtures/base/.cordova/config.json
@@ -0,0 +1,22 @@
+{
+  "id": "org.testing",
+  "name":"TestBase",
+  "lib": {
+    "android": {
+      "uri": "/some/junk/path",
+      "version": "dev",
+      "id": "cordova-android-dev"
+    },
+    "ios": {
+      "uri": "/some/junk/path",
+      "version": "dev",
+      "id": "cordova-ios-dev"
+    },
+    "wp8": {
+      "uri": "/some/junk/path",
+      "version": "dev",
+      "id": "cordova-wp8-dev"
+    }
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/base/merges/.svn
----------------------------------------------------------------------
diff --git a/e2e/fixtures/base/merges/.svn b/e2e/fixtures/base/merges/.svn
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/base/platforms/.svn
----------------------------------------------------------------------
diff --git a/e2e/fixtures/base/platforms/.svn b/e2e/fixtures/base/platforms/.svn
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/base/plugins/.svn
----------------------------------------------------------------------
diff --git a/e2e/fixtures/base/plugins/.svn b/e2e/fixtures/base/plugins/.svn
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/base/www/config.xml
----------------------------------------------------------------------
diff --git a/e2e/fixtures/base/www/config.xml b/e2e/fixtures/base/www/config.xml
new file mode 100644
index 0000000..9e7b9e0
--- /dev/null
+++ b/e2e/fixtures/base/www/config.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='utf-8'?>
+<widget id="org.testing" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
+    <name>TestBase</name>
+    <description>
+        A sample Apache Cordova application that responds to the deviceready event.
+    </description>
+    <author email="dev@cordova.apache.org" href="http://cordova.io">
+        Apache Cordova Team
+    </author>
+    <content src="index.html" />
+    <access origin="*" />
+    <preference name="fullscreen" value="true" />
+    <preference name="webviewbounce" value="true" />
+</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/base/www/css/index.css
----------------------------------------------------------------------
diff --git a/e2e/fixtures/base/www/css/index.css b/e2e/fixtures/base/www/css/index.css
new file mode 100644
index 0000000..51daa79
--- /dev/null
+++ b/e2e/fixtures/base/www/css/index.css
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+* {
+    -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
+}
+
+body {
+    -webkit-touch-callout: none;                /* prevent callout to copy image, etc when tap to hold */
+    -webkit-text-size-adjust: none;             /* prevent webkit from resizing text to fit */
+    -webkit-user-select: none;                  /* prevent copy paste, to allow, change 'none' to 'text' */
+    background-color:#E4E4E4;
+    background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-webkit-gradient(
+        linear,
+        left top,
+        left bottom,
+        color-stop(0, #A7A7A7),
+        color-stop(0.51, #E4E4E4)
+    );
+    background-attachment:fixed;
+    font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
+    font-size:12px;
+    height:100%;
+    margin:0px;
+    padding:0px;
+    text-transform:uppercase;
+    width:100%;
+}
+
+/* Portrait layout (default) */
+.app {
+    background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
+    position:absolute;             /* position in the center of the screen */
+    left:50%;
+    top:50%;
+    height:50px;                   /* text area height */
+    width:225px;                   /* text area width */
+    text-align:center;
+    padding:180px 0px 0px 0px;     /* image height is 200px (bottom 20px are overlapped with text) */
+    margin:-115px 0px 0px -112px;  /* offset vertical: half of image height and text area height */
+                                   /* offset horizontal: half of text area width */
+}
+
+/* Landscape layout (with min-width) */
+@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
+    .app {
+        background-position:left center;
+        padding:75px 0px 75px 170px;  /* padding-top + padding-bottom + text area = image height */
+        margin:-90px 0px 0px -198px;  /* offset vertical: half of image height */
+                                      /* offset horizontal: half of image width and text area width */
+    }
+}
+
+h1 {
+    font-size:24px;
+    font-weight:normal;
+    margin:0px;
+    overflow:visible;
+    padding:0px;
+    text-align:center;
+}
+
+.event {
+    border-radius:4px;
+    -webkit-border-radius:4px;
+    color:#FFFFFF;
+    font-size:12px;
+    margin:0px 30px;
+    padding:2px 0px;
+}
+
+.event.listening {
+    background-color:#333333;
+    display:block;
+}
+
+.event.received {
+    background-color:#4B946A;
+    display:none;
+}
+
+@keyframes fade {
+    from { opacity: 1.0; }
+    50% { opacity: 0.4; }
+    to { opacity: 1.0; }
+}
+ 
+@-webkit-keyframes fade {
+    from { opacity: 1.0; }
+    50% { opacity: 0.4; }
+    to { opacity: 1.0; }
+}
+ 
+.blink {
+    animation:fade 3000ms infinite;
+    -webkit-animation:fade 3000ms infinite;
+}

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/base/www/img/logo.png
----------------------------------------------------------------------
diff --git a/e2e/fixtures/base/www/img/logo.png b/e2e/fixtures/base/www/img/logo.png
new file mode 100644
index 0000000..9519e7d
Binary files /dev/null and b/e2e/fixtures/base/www/img/logo.png differ

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/base/www/index.html
----------------------------------------------------------------------
diff --git a/e2e/fixtures/base/www/index.html b/e2e/fixtures/base/www/index.html
new file mode 100644
index 0000000..bde5741
--- /dev/null
+++ b/e2e/fixtures/base/www/index.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!--
+    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.
+-->
+<html>
+    <head>
+        <meta charset="utf-8" />
+        <meta name="format-detection" content="telephone=no" />
+        <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
+        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
+        <link rel="stylesheet" type="text/css" href="css/index.css" />
+        <title>Hello World</title>
+    </head>
+    <body>
+        <div class="app">
+            <h1>Apache Cordova</h1>
+            <div id="deviceready" class="blink">
+                <p class="event listening">Connecting to Device</p>
+                <p class="event received">Device is Ready</p>
+            </div>
+        </div>
+        <script type="text/javascript" src="cordova.js"></script>
+        <script type="text/javascript" src="js/index.js"></script>
+        <script type="text/javascript">
+            app.initialize();
+        </script>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/base/www/js/index.js
----------------------------------------------------------------------
diff --git a/e2e/fixtures/base/www/js/index.js b/e2e/fixtures/base/www/js/index.js
new file mode 100644
index 0000000..31d9064
--- /dev/null
+++ b/e2e/fixtures/base/www/js/index.js
@@ -0,0 +1,49 @@
+/*
+ * 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 app = {
+    // Application Constructor
+    initialize: function() {
+        this.bindEvents();
+    },
+    // Bind Event Listeners
+    //
+    // Bind any events that are required on startup. Common events are:
+    // 'load', 'deviceready', 'offline', and 'online'.
+    bindEvents: function() {
+        document.addEventListener('deviceready', this.onDeviceReady, false);
+    },
+    // deviceready Event Handler
+    //
+    // The scope of 'this' is the event. In order to call the 'receivedEvent'
+    // function, we must explicity call 'app.receivedEvent(...);'
+    onDeviceReady: function() {
+        app.receivedEvent('deviceready');
+    },
+    // Update DOM on a Received Event
+    receivedEvent: function(id) {
+        var parentElement = document.getElementById(id);
+        var listeningElement = parentElement.querySelector('.listening');
+        var receivedElement = parentElement.querySelector('.received');
+
+        listeningElement.setAttribute('style', 'display:none;');
+        receivedElement.setAttribute('style', 'display:block;');
+
+        console.log('Received Event: ' + id);
+    }
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/base/www/spec.html
----------------------------------------------------------------------
diff --git a/e2e/fixtures/base/www/spec.html b/e2e/fixtures/base/www/spec.html
new file mode 100644
index 0000000..71f00de
--- /dev/null
+++ b/e2e/fixtures/base/www/spec.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<!--
+    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.
+-->
+<html>
+    <head>
+        <title>Jasmine Spec Runner</title>
+
+        <!-- jasmine source -->
+        <link rel="shortcut icon" type="image/png" href="spec/lib/jasmine-1.2.0/jasmine_favicon.png">
+        <link rel="stylesheet" type="text/css" href="spec/lib/jasmine-1.2.0/jasmine.css">
+        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine.js"></script>
+        <script type="text/javascript" src="spec/lib/jasmine-1.2.0/jasmine-html.js"></script>
+
+        <!-- include source files here... -->
+        <script type="text/javascript" src="js/index.js"></script>
+
+        <!-- include spec files here... -->
+        <script type="text/javascript" src="spec/helper.js"></script>
+        <script type="text/javascript" src="spec/index.js"></script>
+
+        <script type="text/javascript">
+            (function() {
+                var jasmineEnv = jasmine.getEnv();
+                jasmineEnv.updateInterval = 1000;
+
+                var htmlReporter = new jasmine.HtmlReporter();
+
+                jasmineEnv.addReporter(htmlReporter);
+
+                jasmineEnv.specFilter = function(spec) {
+                    return htmlReporter.specFilter(spec);
+                };
+
+                var currentWindowOnload = window.onload;
+
+                window.onload = function() {
+                    if (currentWindowOnload) {
+                        currentWindowOnload();
+                    }
+                    execJasmine();
+                };
+
+                function execJasmine() {
+                    jasmineEnv.execute();
+                }
+            })();
+        </script>
+    </head>
+    <body>
+        <div id="stage" style="display:none;"></div>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android-lib/framework/assets/www/cordova.js
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android-lib/framework/assets/www/cordova.js b/e2e/fixtures/platforms/android-lib/framework/assets/www/cordova.js
new file mode 100644
index 0000000..91c51fc
--- /dev/null
+++ b/e2e/fixtures/platforms/android-lib/framework/assets/www/cordova.js
@@ -0,0 +1 @@
+This is a placeholder file.

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/AndroidManifest.xml
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/AndroidManifest.xml b/e2e/fixtures/platforms/android/AndroidManifest.xml
new file mode 100644
index 0000000..be3f245
--- /dev/null
+++ b/e2e/fixtures/platforms/android/AndroidManifest.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='utf-8'?>
+<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="0.0.1" android:windowSoftInputMode="adjustPan" package="org.testing" xmlns:android="http://schemas.android.com/apk/res/android">
+    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <application android:debuggable="true" android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name">
+        <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:name="TestBase" android:theme="@android:style/Theme.Black.NoTitleBar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17" />
+</manifest>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/assets/www/config.xml
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/assets/www/config.xml b/e2e/fixtures/platforms/android/assets/www/config.xml
new file mode 100644
index 0000000..9e7b9e0
--- /dev/null
+++ b/e2e/fixtures/platforms/android/assets/www/config.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='utf-8'?>
+<widget id="org.testing" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
+    <name>TestBase</name>
+    <description>
+        A sample Apache Cordova application that responds to the deviceready event.
+    </description>
+    <author email="dev@cordova.apache.org" href="http://cordova.io">
+        Apache Cordova Team
+    </author>
+    <content src="index.html" />
+    <access origin="*" />
+    <preference name="fullscreen" value="true" />
+    <preference name="webviewbounce" value="true" />
+</widget>

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/assets/www/cordova.js
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/assets/www/cordova.js b/e2e/fixtures/platforms/android/assets/www/cordova.js
new file mode 100644
index 0000000..391eb8c
--- /dev/null
+++ b/e2e/fixtures/platforms/android/assets/www/cordova.js
@@ -0,0 +1,1712 @@
+// Platform: android
+// 3.1.0
+/*
+ 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.
+*/
+;(function() {
+var CORDOVA_JS_BUILD_LABEL = '3.1.0';
+// file: lib/scripts/require.js
+
+var require,
+    define;
+
+(function () {
+    var modules = {},
+    // Stack of moduleIds currently being built.
+        requireStack = [],
+    // Map of module ID -> index into requireStack of modules currently being built.
+        inProgressModules = {},
+        SEPERATOR = ".";
+
+
+
+    function build(module) {
+        var factory = module.factory,
+            localRequire = function (id) {
+                var resultantId = id;
+                //Its a relative path, so lop off the last portion and add the id (minus "./")
+                if (id.charAt(0) === ".") {
+                    resultantId = module.id.slice(0, module.id.lastIndexOf(SEPERATOR)) + SEPERATOR + id.slice(2);
+                }
+                return require(resultantId);
+            };
+        module.exports = {};
+        delete module.factory;
+        factory(localRequire, module.exports, module);
+        return module.exports;
+    }
+
+    require = function (id) {
+        if (!modules[id]) {
+            throw "module " + id + " not found";
+        } else if (id in inProgressModules) {
+            var cycle = requireStack.slice(inProgressModules[id]).join('->') + '->' + id;
+            throw "Cycle in require graph: " + cycle;
+        }
+        if (modules[id].factory) {
+            try {
+                inProgressModules[id] = requireStack.length;
+                requireStack.push(id);
+                return build(modules[id]);
+            } finally {
+                delete inProgressModules[id];
+                requireStack.pop();
+            }
+        }
+        return modules[id].exports;
+    };
+
+    define = function (id, factory) {
+        if (modules[id]) {
+            throw "module " + id + " already defined";
+        }
+
+        modules[id] = {
+            id: id,
+            factory: factory
+        };
+    };
+
+    define.remove = function (id) {
+        delete modules[id];
+    };
+
+    define.moduleMap = modules;
+})();
+
+//Export for use in node
+if (typeof module === "object" && typeof require === "function") {
+    module.exports.require = require;
+    module.exports.define = define;
+}
+
+// file: lib/cordova.js
+define("cordova", function(require, exports, module) {
+
+
+var channel = require('cordova/channel');
+var platform = require('cordova/platform');
+
+/**
+ * Intercept calls to addEventListener + removeEventListener and handle deviceready,
+ * resume, and pause events.
+ */
+var m_document_addEventListener = document.addEventListener;
+var m_document_removeEventListener = document.removeEventListener;
+var m_window_addEventListener = window.addEventListener;
+var m_window_removeEventListener = window.removeEventListener;
+
+/**
+ * Houses custom event handlers to intercept on document + window event listeners.
+ */
+var documentEventHandlers = {},
+    windowEventHandlers = {};
+
+document.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof documentEventHandlers[e] != 'undefined') {
+        documentEventHandlers[e].subscribe(handler);
+    } else {
+        m_document_addEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.addEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    if (typeof windowEventHandlers[e] != 'undefined') {
+        windowEventHandlers[e].subscribe(handler);
+    } else {
+        m_window_addEventListener.call(window, evt, handler, capture);
+    }
+};
+
+document.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubscribing from an event that is handled by a plugin
+    if (typeof documentEventHandlers[e] != "undefined") {
+        documentEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_document_removeEventListener.call(document, evt, handler, capture);
+    }
+};
+
+window.removeEventListener = function(evt, handler, capture) {
+    var e = evt.toLowerCase();
+    // If unsubscribing from an event that is handled by a plugin
+    if (typeof windowEventHandlers[e] != "undefined") {
+        windowEventHandlers[e].unsubscribe(handler);
+    } else {
+        m_window_removeEventListener.call(window, evt, handler, capture);
+    }
+};
+
+function createEvent(type, data) {
+    var event = document.createEvent('Events');
+    event.initEvent(type, false, false);
+    if (data) {
+        for (var i in data) {
+            if (data.hasOwnProperty(i)) {
+                event[i] = data[i];
+            }
+        }
+    }
+    return event;
+}
+
+
+var cordova = {
+    define:define,
+    require:require,
+    version:CORDOVA_JS_BUILD_LABEL,
+    platformId:platform.id,
+    /**
+     * Methods to add/remove your own addEventListener hijacking on document + window.
+     */
+    addWindowEventHandler:function(event) {
+        return (windowEventHandlers[event] = channel.create(event));
+    },
+    addStickyDocumentEventHandler:function(event) {
+        return (documentEventHandlers[event] = channel.createSticky(event));
+    },
+    addDocumentEventHandler:function(event) {
+        return (documentEventHandlers[event] = channel.create(event));
+    },
+    removeWindowEventHandler:function(event) {
+        delete windowEventHandlers[event];
+    },
+    removeDocumentEventHandler:function(event) {
+        delete documentEventHandlers[event];
+    },
+    /**
+     * Retrieve original event handlers that were replaced by Cordova
+     *
+     * @return object
+     */
+    getOriginalHandlers: function() {
+        return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
+        'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
+    },
+    /**
+     * Method to fire event from native code
+     * bNoDetach is required for events which cause an exception which needs to be caught in native code
+     */
+    fireDocumentEvent: function(type, data, bNoDetach) {
+        var evt = createEvent(type, data);
+        if (typeof documentEventHandlers[type] != 'undefined') {
+            if( bNoDetach ) {
+                documentEventHandlers[type].fire(evt);
+            }
+            else {
+                setTimeout(function() {
+                    // Fire deviceready on listeners that were registered before cordova.js was loaded.
+                    if (type == 'deviceready') {
+                        document.dispatchEvent(evt);
+                    }
+                    documentEventHandlers[type].fire(evt);
+                }, 0);
+            }
+        } else {
+            document.dispatchEvent(evt);
+        }
+    },
+    fireWindowEvent: function(type, data) {
+        var evt = createEvent(type,data);
+        if (typeof windowEventHandlers[type] != 'undefined') {
+            setTimeout(function() {
+                windowEventHandlers[type].fire(evt);
+            }, 0);
+        } else {
+            window.dispatchEvent(evt);
+        }
+    },
+
+    /**
+     * Plugin callback mechanism.
+     */
+    // Randomize the starting callbackId to avoid collisions after refreshing or navigating.
+    // This way, it's very unlikely that any new callback would get the same callbackId as an old callback.
+    callbackId: Math.floor(Math.random() * 2000000000),
+    callbacks:  {},
+    callbackStatus: {
+        NO_RESULT: 0,
+        OK: 1,
+        CLASS_NOT_FOUND_EXCEPTION: 2,
+        ILLEGAL_ACCESS_EXCEPTION: 3,
+        INSTANTIATION_EXCEPTION: 4,
+        MALFORMED_URL_EXCEPTION: 5,
+        IO_EXCEPTION: 6,
+        INVALID_ACTION: 7,
+        JSON_EXCEPTION: 8,
+        ERROR: 9
+    },
+
+    /**
+     * Called by native code when returning successful result from an action.
+     */
+    callbackSuccess: function(callbackId, args) {
+        try {
+            cordova.callbackFromNative(callbackId, true, args.status, [args.message], args.keepCallback);
+        } catch (e) {
+            console.log("Error in error callback: " + callbackId + " = "+e);
+        }
+    },
+
+    /**
+     * Called by native code when returning error result from an action.
+     */
+    callbackError: function(callbackId, args) {
+        // TODO: Deprecate callbackSuccess and callbackError in favour of callbackFromNative.
+        // Derive success from status.
+        try {
+            cordova.callbackFromNative(callbackId, false, args.status, [args.message], args.keepCallback);
+        } catch (e) {
+            console.log("Error in error callback: " + callbackId + " = "+e);
+        }
+    },
+
+    /**
+     * Called by native code when returning the result from an action.
+     */
+    callbackFromNative: function(callbackId, success, status, args, keepCallback) {
+        var callback = cordova.callbacks[callbackId];
+        if (callback) {
+            if (success && status == cordova.callbackStatus.OK) {
+                callback.success && callback.success.apply(null, args);
+            } else if (!success) {
+                callback.fail && callback.fail.apply(null, args);
+            }
+
+            // Clear callback if not expecting any more results
+            if (!keepCallback) {
+                delete cordova.callbacks[callbackId];
+            }
+        }
+    },
+    addConstructor: function(func) {
+        channel.onCordovaReady.subscribe(function() {
+            try {
+                func();
+            } catch(e) {
+                console.log("Failed to run constructor: " + e);
+            }
+        });
+    }
+};
+
+
+module.exports = cordova;
+
+});
+
+// file: lib/android/android/nativeapiprovider.js
+define("cordova/android/nativeapiprovider", function(require, exports, module) {
+
+/**
+ * Exports the ExposedJsApi.java object if available, otherwise exports the PromptBasedNativeApi.
+ */
+
+var nativeApi = this._cordovaNative || require('cordova/android/promptbasednativeapi');
+var currentApi = nativeApi;
+
+module.exports = {
+    get: function() { return currentApi; },
+    setPreferPrompt: function(value) {
+        currentApi = value ? require('cordova/android/promptbasednativeapi') : nativeApi;
+    },
+    // Used only by tests.
+    set: function(value) {
+        currentApi = value;
+    }
+};
+
+});
+
+// file: lib/android/android/promptbasednativeapi.js
+define("cordova/android/promptbasednativeapi", function(require, exports, module) {
+
+/**
+ * Implements the API of ExposedJsApi.java, but uses prompt() to communicate.
+ * This is used only on the 2.3 simulator, where addJavascriptInterface() is broken.
+ */
+
+module.exports = {
+    exec: function(service, action, callbackId, argsJson) {
+        return prompt(argsJson, 'gap:'+JSON.stringify([service, action, callbackId]));
+    },
+    setNativeToJsBridgeMode: function(value) {
+        prompt(value, 'gap_bridge_mode:');
+    },
+    retrieveJsMessages: function(fromOnlineEvent) {
+        return prompt(+fromOnlineEvent, 'gap_poll:');
+    }
+};
+
+});
+
+// file: lib/common/argscheck.js
+define("cordova/argscheck", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+var utils = require('cordova/utils');
+
+var moduleExports = module.exports;
+
+var typeMap = {
+    'A': 'Array',
+    'D': 'Date',
+    'N': 'Number',
+    'S': 'String',
+    'F': 'Function',
+    'O': 'Object'
+};
+
+function extractParamName(callee, argIndex) {
+    return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
+}
+
+function checkArgs(spec, functionName, args, opt_callee) {
+    if (!moduleExports.enableChecks) {
+        return;
+    }
+    var errMsg = null;
+    var typeName;
+    for (var i = 0; i < spec.length; ++i) {
+        var c = spec.charAt(i),
+            cUpper = c.toUpperCase(),
+            arg = args[i];
+        // Asterix means allow anything.
+        if (c == '*') {
+            continue;
+        }
+        typeName = utils.typeName(arg);
+        if ((arg === null || arg === undefined) && c == cUpper) {
+            continue;
+        }
+        if (typeName != typeMap[cUpper]) {
+            errMsg = 'Expected ' + typeMap[cUpper];
+            break;
+        }
+    }
+    if (errMsg) {
+        errMsg += ', but got ' + typeName + '.';
+        errMsg = 'Wrong type for parameter "' + extractParamName(opt_callee || args.callee, i) + '" of ' + functionName + ': ' + errMsg;
+        // Don't log when running unit tests.
+        if (typeof jasmine == 'undefined') {
+            console.error(errMsg);
+        }
+        throw TypeError(errMsg);
+    }
+}
+
+function getValue(value, defaultValue) {
+    return value === undefined ? defaultValue : value;
+}
+
+moduleExports.checkArgs = checkArgs;
+moduleExports.getValue = getValue;
+moduleExports.enableChecks = true;
+
+
+});
+
+// file: lib/common/base64.js
+define("cordova/base64", function(require, exports, module) {
+
+var base64 = exports;
+
+base64.fromArrayBuffer = function(arrayBuffer) {
+    var array = new Uint8Array(arrayBuffer);
+    return uint8ToBase64(array);
+};
+
+//------------------------------------------------------------------------------
+
+/* This code is based on the performance tests at http://jsperf.com/b64tests
+ * This 12-bit-at-a-time algorithm was the best performing version on all
+ * platforms tested.
+ */
+
+var b64_6bit = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+var b64_12bit;
+
+var b64_12bitTable = function() {
+    b64_12bit = [];
+    for (var i=0; i<64; i++) {
+        for (var j=0; j<64; j++) {
+            b64_12bit[i*64+j] = b64_6bit[i] + b64_6bit[j];
+        }
+    }
+    b64_12bitTable = function() { return b64_12bit; };
+    return b64_12bit;
+};
+
+function uint8ToBase64(rawData) {
+    var numBytes = rawData.byteLength;
+    var output="";
+    var segment;
+    var table = b64_12bitTable();
+    for (var i=0;i<numBytes-2;i+=3) {
+        segment = (rawData[i] << 16) + (rawData[i+1] << 8) + rawData[i+2];
+        output += table[segment >> 12];
+        output += table[segment & 0xfff];
+    }
+    if (numBytes - i == 2) {
+        segment = (rawData[i] << 16) + (rawData[i+1] << 8);
+        output += table[segment >> 12];
+        output += b64_6bit[(segment & 0xfff) >> 6];
+        output += '=';
+    } else if (numBytes - i == 1) {
+        segment = (rawData[i] << 16);
+        output += table[segment >> 12];
+        output += '==';
+    }
+    return output;
+}
+
+});
+
+// file: lib/common/builder.js
+define("cordova/builder", function(require, exports, module) {
+
+var utils = require('cordova/utils');
+
+function each(objects, func, context) {
+    for (var prop in objects) {
+        if (objects.hasOwnProperty(prop)) {
+            func.apply(context, [objects[prop], prop]);
+        }
+    }
+}
+
+function clobber(obj, key, value) {
+    exports.replaceHookForTesting(obj, key);
+    obj[key] = value;
+    // Getters can only be overridden by getters.
+    if (obj[key] !== value) {
+        utils.defineGetter(obj, key, function() {
+            return value;
+        });
+    }
+}
+
+function assignOrWrapInDeprecateGetter(obj, key, value, message) {
+    if (message) {
+        utils.defineGetter(obj, key, function() {
+            console.log(message);
+            delete obj[key];
+            clobber(obj, key, value);
+            return value;
+        });
+    } else {
+        clobber(obj, key, value);
+    }
+}
+
+function include(parent, objects, clobber, merge) {
+    each(objects, function (obj, key) {
+        try {
+            var result = obj.path ? require(obj.path) : {};
+
+            if (clobber) {
+                // Clobber if it doesn't exist.
+                if (typeof parent[key] === 'undefined') {
+                    assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+                } else if (typeof obj.path !== 'undefined') {
+                    // If merging, merge properties onto parent, otherwise, clobber.
+                    if (merge) {
+                        recursiveMerge(parent[key], result);
+                    } else {
+                        assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+                    }
+                }
+                result = parent[key];
+            } else {
+                // Overwrite if not currently defined.
+                if (typeof parent[key] == 'undefined') {
+                    assignOrWrapInDeprecateGetter(parent, key, result, obj.deprecated);
+                } else {
+                    // Set result to what already exists, so we can build children into it if they exist.
+                    result = parent[key];
+                }
+            }
+
+            if (obj.children) {
+                include(result, obj.children, clobber, merge);
+            }
+        } catch(e) {
+            utils.alert('Exception building cordova JS globals: ' + e + ' for key "' + key + '"');
+        }
+    });
+}
+
+/**
+ * Merge properties from one object onto another recursively.  Properties from
+ * the src object will overwrite existing target property.
+ *
+ * @param target Object to merge properties into.
+ * @param src Object to merge properties from.
+ */
+function recursiveMerge(target, src) {
+    for (var prop in src) {
+        if (src.hasOwnProperty(prop)) {
+            if (target.prototype && target.prototype.constructor === target) {
+                // If the target object is a constructor override off prototype.
+                clobber(target.prototype, prop, src[prop]);
+            } else {
+                if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
+                    recursiveMerge(target[prop], src[prop]);
+                } else {
+                    clobber(target, prop, src[prop]);
+                }
+            }
+        }
+    }
+}
+
+exports.buildIntoButDoNotClobber = function(objects, target) {
+    include(target, objects, false, false);
+};
+exports.buildIntoAndClobber = function(objects, target) {
+    include(target, objects, true, false);
+};
+exports.buildIntoAndMerge = function(objects, target) {
+    include(target, objects, true, true);
+};
+exports.recursiveMerge = recursiveMerge;
+exports.assignOrWrapInDeprecateGetter = assignOrWrapInDeprecateGetter;
+exports.replaceHookForTesting = function() {};
+
+});
+
+// file: lib/common/channel.js
+define("cordova/channel", function(require, exports, module) {
+
+var utils = require('cordova/utils'),
+    nextGuid = 1;
+
+/**
+ * Custom pub-sub "channel" that can have functions subscribed to it
+ * This object is used to define and control firing of events for
+ * cordova initialization, as well as for custom events thereafter.
+ *
+ * The order of events during page load and Cordova startup is as follows:
+ *
+ * onDOMContentLoaded*         Internal event that is received when the web page is loaded and parsed.
+ * onNativeReady*              Internal event that indicates the Cordova native side is ready.
+ * onCordovaReady*             Internal event fired when all Cordova JavaScript objects have been created.
+ * onDeviceReady*              User event fired to indicate that Cordova is ready
+ * onResume                    User event fired to indicate a start/resume lifecycle event
+ * onPause                     User event fired to indicate a pause lifecycle event
+ * onDestroy*                  Internal event fired when app is being destroyed (User should use window.onunload event, not this one).
+ *
+ * The events marked with an * are sticky. Once they have fired, they will stay in the fired state.
+ * All listeners that subscribe after the event is fired will be executed right away.
+ *
+ * The only Cordova events that user code should register for are:
+ *      deviceready           Cordova native code is initialized and Cordova APIs can be called from JavaScript
+ *      pause                 App has moved to background
+ *      resume                App has returned to foreground
+ *
+ * Listeners can be registered as:
+ *      document.addEventListener("deviceready", myDeviceReadyListener, false);
+ *      document.addEventListener("resume", myResumeListener, false);
+ *      document.addEventListener("pause", myPauseListener, false);
+ *
+ * The DOM lifecycle events should be used for saving and restoring state
+ *      window.onload
+ *      window.onunload
+ *
+ */
+
+/**
+ * Channel
+ * @constructor
+ * @param type  String the channel name
+ */
+var Channel = function(type, sticky) {
+    this.type = type;
+    // Map of guid -> function.
+    this.handlers = {};
+    // 0 = Non-sticky, 1 = Sticky non-fired, 2 = Sticky fired.
+    this.state = sticky ? 1 : 0;
+    // Used in sticky mode to remember args passed to fire().
+    this.fireArgs = null;
+    // Used by onHasSubscribersChange to know if there are any listeners.
+    this.numHandlers = 0;
+    // Function that is called when the first listener is subscribed, or when
+    // the last listener is unsubscribed.
+    this.onHasSubscribersChange = null;
+},
+    channel = {
+        /**
+         * Calls the provided function only after all of the channels specified
+         * have been fired. All channels must be sticky channels.
+         */
+        join: function(h, c) {
+            var len = c.length,
+                i = len,
+                f = function() {
+                    if (!(--i)) h();
+                };
+            for (var j=0; j<len; j++) {
+                if (c[j].state === 0) {
+                    throw Error('Can only use join with sticky channels.');
+                }
+                c[j].subscribe(f);
+            }
+            if (!len) h();
+        },
+        create: function(type) {
+            return channel[type] = new Channel(type, false);
+        },
+        createSticky: function(type) {
+            return channel[type] = new Channel(type, true);
+        },
+
+        /**
+         * cordova Channels that must fire before "deviceready" is fired.
+         */
+        deviceReadyChannelsArray: [],
+        deviceReadyChannelsMap: {},
+
+        /**
+         * Indicate that a feature needs to be initialized before it is ready to be used.
+         * This holds up Cordova's "deviceready" event until the feature has been initialized
+         * and Cordova.initComplete(feature) is called.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        waitForInitialization: function(feature) {
+            if (feature) {
+                var c = channel[feature] || this.createSticky(feature);
+                this.deviceReadyChannelsMap[feature] = c;
+                this.deviceReadyChannelsArray.push(c);
+            }
+        },
+
+        /**
+         * Indicate that initialization code has completed and the feature is ready to be used.
+         *
+         * @param feature {String}     The unique feature name
+         */
+        initializationComplete: function(feature) {
+            var c = this.deviceReadyChannelsMap[feature];
+            if (c) {
+                c.fire();
+            }
+        }
+    };
+
+function forceFunction(f) {
+    if (typeof f != 'function') throw "Function required as first argument!";
+}
+
+/**
+ * Subscribes the given function to the channel. Any time that
+ * Channel.fire is called so too will the function.
+ * Optionally specify an execution context for the function
+ * and a guid that can be used to stop subscribing to the channel.
+ * Returns the guid.
+ */
+Channel.prototype.subscribe = function(f, c) {
+    // need a function to call
+    forceFunction(f);
+    if (this.state == 2) {
+        f.apply(c || this, this.fireArgs);
+        return;
+    }
+
+    var func = f,
+        guid = f.observer_guid;
+    if (typeof c == "object") { func = utils.close(c, f); }
+
+    if (!guid) {
+        // first time any channel has seen this subscriber
+        guid = '' + nextGuid++;
+    }
+    func.observer_guid = guid;
+    f.observer_guid = guid;
+
+    // Don't add the same handler more than once.
+    if (!this.handlers[guid]) {
+        this.handlers[guid] = func;
+        this.numHandlers++;
+        if (this.numHandlers == 1) {
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+/**
+ * Unsubscribes the function with the given guid from the channel.
+ */
+Channel.prototype.unsubscribe = function(f) {
+    // need a function to unsubscribe
+    forceFunction(f);
+
+    var guid = f.observer_guid,
+        handler = this.handlers[guid];
+    if (handler) {
+        delete this.handlers[guid];
+        this.numHandlers--;
+        if (this.numHandlers === 0) {
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+/**
+ * Calls all functions subscribed to this channel.
+ */
+Channel.prototype.fire = function(e) {
+    var fail = false,
+        fireArgs = Array.prototype.slice.call(arguments);
+    // Apply stickiness.
+    if (this.state == 1) {
+        this.state = 2;
+        this.fireArgs = fireArgs;
+    }
+    if (this.numHandlers) {
+        // Copy the values first so that it is safe to modify it from within
+        // callbacks.
+        var toCall = [];
+        for (var item in this.handlers) {
+            toCall.push(this.handlers[item]);
+        }
+        for (var i = 0; i < toCall.length; ++i) {
+            toCall[i].apply(this, fireArgs);
+        }
+        if (this.state == 2 && this.numHandlers) {
+            this.numHandlers = 0;
+            this.handlers = {};
+            this.onHasSubscribersChange && this.onHasSubscribersChange();
+        }
+    }
+};
+
+
+// defining them here so they are ready super fast!
+// DOM event that is received when the web page is loaded and parsed.
+channel.createSticky('onDOMContentLoaded');
+
+// Event to indicate the Cordova native side is ready.
+channel.createSticky('onNativeReady');
+
+// Event to indicate that all Cordova JavaScript objects have been created
+// and it's time to run plugin constructors.
+channel.createSticky('onCordovaReady');
+
+// Event to indicate that all automatically loaded JS plugins are loaded and ready.
+channel.createSticky('onPluginsReady');
+
+// Event to indicate that Cordova is ready
+channel.createSticky('onDeviceReady');
+
+// Event to indicate a resume lifecycle event
+channel.create('onResume');
+
+// Event to indicate a pause lifecycle event
+channel.create('onPause');
+
+// Event to indicate a destroy lifecycle event
+channel.createSticky('onDestroy');
+
+// Channels that must fire before "deviceready" is fired.
+channel.waitForInitialization('onCordovaReady');
+channel.waitForInitialization('onDOMContentLoaded');
+
+module.exports = channel;
+
+});
+
+// file: lib/android/exec.js
+define("cordova/exec", function(require, exports, module) {
+
+/**
+ * Execute a cordova command.  It is up to the native side whether this action
+ * is synchronous or asynchronous.  The native side can return:
+ *      Synchronous: PluginResult object as a JSON string
+ *      Asynchronous: Empty string ""
+ * If async, the native side will cordova.callbackSuccess or cordova.callbackError,
+ * depending upon the result of the action.
+ *
+ * @param {Function} success    The success callback
+ * @param {Function} fail       The fail callback
+ * @param {String} service      The name of the service to use
+ * @param {String} action       Action to be run in cordova
+ * @param {String[]} [args]     Zero or more arguments to pass to the method
+ */
+var cordova = require('cordova'),
+    nativeApiProvider = require('cordova/android/nativeapiprovider'),
+    utils = require('cordova/utils'),
+    base64 = require('cordova/base64'),
+    jsToNativeModes = {
+        PROMPT: 0,
+        JS_OBJECT: 1,
+        // This mode is currently for benchmarking purposes only. It must be enabled
+        // on the native side through the ENABLE_LOCATION_CHANGE_EXEC_MODE
+        // constant within CordovaWebViewClient.java before it will work.
+        LOCATION_CHANGE: 2
+    },
+    nativeToJsModes = {
+        // Polls for messages using the JS->Native bridge.
+        POLLING: 0,
+        // For LOAD_URL to be viable, it would need to have a work-around for
+        // the bug where the soft-keyboard gets dismissed when a message is sent.
+        LOAD_URL: 1,
+        // For the ONLINE_EVENT to be viable, it would need to intercept all event
+        // listeners (both through addEventListener and window.ononline) as well
+        // as set the navigator property itself.
+        ONLINE_EVENT: 2,
+        // Uses reflection to access private APIs of the WebView that can send JS
+        // to be executed.
+        // Requires Android 3.2.4 or above.
+        PRIVATE_API: 3
+    },
+    jsToNativeBridgeMode,  // Set lazily.
+    nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT,
+    pollEnabled = false,
+    messagesFromNative = [];
+
+function androidExec(success, fail, service, action, args) {
+    // Set default bridge modes if they have not already been set.
+    // By default, we use the failsafe, since addJavascriptInterface breaks too often
+    if (jsToNativeBridgeMode === undefined) {
+        androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
+    }
+
+    // Process any ArrayBuffers in the args into a string.
+    for (var i = 0; i < args.length; i++) {
+        if (utils.typeName(args[i]) == 'ArrayBuffer') {
+            args[i] = base64.fromArrayBuffer(args[i]);
+        }
+    }
+
+    var callbackId = service + cordova.callbackId++,
+        argsJson = JSON.stringify(args);
+
+    if (success || fail) {
+        cordova.callbacks[callbackId] = {success:success, fail:fail};
+    }
+
+    if (jsToNativeBridgeMode == jsToNativeModes.LOCATION_CHANGE) {
+        window.location = 'http://cdv_exec/' + service + '#' + action + '#' + callbackId + '#' + argsJson;
+    } else {
+        var messages = nativeApiProvider.get().exec(service, action, callbackId, argsJson);
+        // If argsJson was received by Java as null, try again with the PROMPT bridge mode.
+        // This happens in rare circumstances, such as when certain Unicode characters are passed over the bridge on a Galaxy S2.  See CB-2666.
+        if (jsToNativeBridgeMode == jsToNativeModes.JS_OBJECT && messages === "@Null arguments.") {
+            androidExec.setJsToNativeBridgeMode(jsToNativeModes.PROMPT);
+            androidExec(success, fail, service, action, args);
+            androidExec.setJsToNativeBridgeMode(jsToNativeModes.JS_OBJECT);
+            return;
+        } else {
+            androidExec.processMessages(messages);
+        }
+    }
+}
+
+function pollOnceFromOnlineEvent() {
+    pollOnce(true);
+}
+
+function pollOnce(opt_fromOnlineEvent) {
+    var msg = nativeApiProvider.get().retrieveJsMessages(!!opt_fromOnlineEvent);
+    androidExec.processMessages(msg);
+}
+
+function pollingTimerFunc() {
+    if (pollEnabled) {
+        pollOnce();
+        setTimeout(pollingTimerFunc, 50);
+    }
+}
+
+function hookOnlineApis() {
+    function proxyEvent(e) {
+        cordova.fireWindowEvent(e.type);
+    }
+    // The network module takes care of firing online and offline events.
+    // It currently fires them only on document though, so we bridge them
+    // to window here (while first listening for exec()-releated online/offline
+    // events).
+    window.addEventListener('online', pollOnceFromOnlineEvent, false);
+    window.addEventListener('offline', pollOnceFromOnlineEvent, false);
+    cordova.addWindowEventHandler('online');
+    cordova.addWindowEventHandler('offline');
+    document.addEventListener('online', proxyEvent, false);
+    document.addEventListener('offline', proxyEvent, false);
+}
+
+hookOnlineApis();
+
+androidExec.jsToNativeModes = jsToNativeModes;
+androidExec.nativeToJsModes = nativeToJsModes;
+
+androidExec.setJsToNativeBridgeMode = function(mode) {
+    if (mode == jsToNativeModes.JS_OBJECT && !window._cordovaNative) {
+        console.log('Falling back on PROMPT mode since _cordovaNative is missing. Expected for Android 3.2 and lower only.');
+        mode = jsToNativeModes.PROMPT;
+    }
+    nativeApiProvider.setPreferPrompt(mode == jsToNativeModes.PROMPT);
+    jsToNativeBridgeMode = mode;
+};
+
+androidExec.setNativeToJsBridgeMode = function(mode) {
+    if (mode == nativeToJsBridgeMode) {
+        return;
+    }
+    if (nativeToJsBridgeMode == nativeToJsModes.POLLING) {
+        pollEnabled = false;
+    }
+
+    nativeToJsBridgeMode = mode;
+    // Tell the native side to switch modes.
+    nativeApiProvider.get().setNativeToJsBridgeMode(mode);
+
+    if (mode == nativeToJsModes.POLLING) {
+        pollEnabled = true;
+        setTimeout(pollingTimerFunc, 1);
+    }
+};
+
+// Processes a single message, as encoded by NativeToJsMessageQueue.java.
+function processMessage(message) {
+    try {
+        var firstChar = message.charAt(0);
+        if (firstChar == 'J') {
+            eval(message.slice(1));
+        } else if (firstChar == 'S' || firstChar == 'F') {
+            var success = firstChar == 'S';
+            var keepCallback = message.charAt(1) == '1';
+            var spaceIdx = message.indexOf(' ', 2);
+            var status = +message.slice(2, spaceIdx);
+            var nextSpaceIdx = message.indexOf(' ', spaceIdx + 1);
+            var callbackId = message.slice(spaceIdx + 1, nextSpaceIdx);
+            var payloadKind = message.charAt(nextSpaceIdx + 1);
+            var payload;
+            if (payloadKind == 's') {
+                payload = message.slice(nextSpaceIdx + 2);
+            } else if (payloadKind == 't') {
+                payload = true;
+            } else if (payloadKind == 'f') {
+                payload = false;
+            } else if (payloadKind == 'N') {
+                payload = null;
+            } else if (payloadKind == 'n') {
+                payload = +message.slice(nextSpaceIdx + 2);
+            } else if (payloadKind == 'A') {
+                var data = message.slice(nextSpaceIdx + 2);
+                var bytes = window.atob(data);
+                var arraybuffer = new Uint8Array(bytes.length);
+                for (var i = 0; i < bytes.length; i++) {
+                    arraybuffer[i] = bytes.charCodeAt(i);
+                }
+                payload = arraybuffer.buffer;
+            } else if (payloadKind == 'S') {
+                payload = window.atob(message.slice(nextSpaceIdx + 2));
+            } else {
+                payload = JSON.parse(message.slice(nextSpaceIdx + 1));
+            }
+            cordova.callbackFromNative(callbackId, success, status, [payload], keepCallback);
+        } else {
+            console.log("processMessage failed: invalid message:" + message);
+        }
+    } catch (e) {
+        console.log("processMessage failed: Message: " + message);
+        console.log("processMessage failed: Error: " + e);
+        console.log("processMessage failed: Stack: " + e.stack);
+    }
+}
+
+// This is called from the NativeToJsMessageQueue.java.
+androidExec.processMessages = function(messages) {
+    if (messages) {
+        messagesFromNative.push(messages);
+        // Check for the reentrant case, and enqueue the message if that's the case.
+        if (messagesFromNative.length > 1) {
+            return;
+        }
+        while (messagesFromNative.length) {
+            // Don't unshift until the end so that reentrancy can be detected.
+            messages = messagesFromNative[0];
+            // The Java side can send a * message to indicate that it
+            // still has messages waiting to be retrieved.
+            if (messages == '*') {
+                messagesFromNative.shift();
+                window.setTimeout(pollOnce, 0);
+                return;
+            }
+
+            var spaceIdx = messages.indexOf(' ');
+            var msgLen = +messages.slice(0, spaceIdx);
+            var message = messages.substr(spaceIdx + 1, msgLen);
+            messages = messages.slice(spaceIdx + msgLen + 1);
+            processMessage(message);
+            if (messages) {
+                messagesFromNative[0] = messages;
+            } else {
+                messagesFromNative.shift();
+            }
+        }
+    }
+};
+
+module.exports = androidExec;
+
+});
+
+// file: lib/common/init.js
+define("cordova/init", function(require, exports, module) {
+
+var channel = require('cordova/channel');
+var cordova = require('cordova');
+var modulemapper = require('cordova/modulemapper');
+var platform = require('cordova/platform');
+var pluginloader = require('cordova/pluginloader');
+
+var platformInitChannelsArray = [channel.onNativeReady, channel.onPluginsReady];
+
+function logUnfiredChannels(arr) {
+    for (var i = 0; i < arr.length; ++i) {
+        if (arr[i].state != 2) {
+            console.log('Channel not fired: ' + arr[i].type);
+        }
+    }
+}
+
+window.setTimeout(function() {
+    if (channel.onDeviceReady.state != 2) {
+        console.log('deviceready has not fired after 5 seconds.');
+        logUnfiredChannels(platformInitChannelsArray);
+        logUnfiredChannels(channel.deviceReadyChannelsArray);
+    }
+}, 5000);
+
+// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
+// We replace it so that properties that can't be clobbered can instead be overridden.
+function replaceNavigator(origNavigator) {
+    var CordovaNavigator = function() {};
+    CordovaNavigator.prototype = origNavigator;
+    var newNavigator = new CordovaNavigator();
+    // This work-around really only applies to new APIs that are newer than Function.bind.
+    // Without it, APIs such as getGamepads() break.
+    if (CordovaNavigator.bind) {
+        for (var key in origNavigator) {
+            if (typeof origNavigator[key] == 'function') {
+                newNavigator[key] = origNavigator[key].bind(origNavigator);
+            }
+        }
+    }
+    return newNavigator;
+}
+if (window.navigator) {
+    window.navigator = replaceNavigator(window.navigator);
+}
+
+if (!window.console) {
+    window.console = {
+        log: function(){}
+    };
+}
+if (!window.console.warn) {
+    window.console.warn = function(msg) {
+        this.log("warn: " + msg);
+    };
+}
+
+// Register pause, resume and deviceready channels as events on document.
+channel.onPause = cordova.addDocumentEventHandler('pause');
+channel.onResume = cordova.addDocumentEventHandler('resume');
+channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
+
+// Listen for DOMContentLoaded and notify our channel subscribers.
+if (document.readyState == 'complete' || document.readyState == 'interactive') {
+    channel.onDOMContentLoaded.fire();
+} else {
+    document.addEventListener('DOMContentLoaded', function() {
+        channel.onDOMContentLoaded.fire();
+    }, false);
+}
+
+// _nativeReady is global variable that the native side can set
+// to signify that the native code is ready. It is a global since
+// it may be called before any cordova JS is ready.
+if (window._nativeReady) {
+    channel.onNativeReady.fire();
+}
+
+modulemapper.clobbers('cordova', 'cordova');
+modulemapper.clobbers('cordova/exec', 'cordova.exec');
+modulemapper.clobbers('cordova/exec', 'Cordova.exec');
+
+// Call the platform-specific initialization.
+platform.bootstrap && platform.bootstrap();
+
+pluginloader.load(function() {
+    channel.onPluginsReady.fire();
+});
+
+/**
+ * Create all cordova objects once native side is ready.
+ */
+channel.join(function() {
+    modulemapper.mapModules(window);
+
+    platform.initialize && platform.initialize();
+
+    // Fire event to notify that all objects are created
+    channel.onCordovaReady.fire();
+
+    // Fire onDeviceReady event once page has fully loaded, all
+    // constructors have run and cordova info has been received from native
+    // side.
+    channel.join(function() {
+        require('cordova').fireDocumentEvent('deviceready');
+    }, channel.deviceReadyChannelsArray);
+
+}, platformInitChannelsArray);
+
+
+});
+
+// file: lib/common/modulemapper.js
+define("cordova/modulemapper", function(require, exports, module) {
+
+var builder = require('cordova/builder'),
+    moduleMap = define.moduleMap,
+    symbolList,
+    deprecationMap;
+
+exports.reset = function() {
+    symbolList = [];
+    deprecationMap = {};
+};
+
+function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
+    if (!(moduleName in moduleMap)) {
+        throw new Error('Module ' + moduleName + ' does not exist.');
+    }
+    symbolList.push(strategy, moduleName, symbolPath);
+    if (opt_deprecationMessage) {
+        deprecationMap[symbolPath] = opt_deprecationMessage;
+    }
+}
+
+// Note: Android 2.3 does have Function.bind().
+exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
+    addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
+};
+
+exports.runs = function(moduleName) {
+    addEntry('r', moduleName, null);
+};
+
+function prepareNamespace(symbolPath, context) {
+    if (!symbolPath) {
+        return context;
+    }
+    var parts = symbolPath.split('.');
+    var cur = context;
+    for (var i = 0, part; part = parts[i]; ++i) {
+        cur = cur[part] = cur[part] || {};
+    }
+    return cur;
+}
+
+exports.mapModules = function(context) {
+    var origSymbols = {};
+    context.CDV_origSymbols = origSymbols;
+    for (var i = 0, len = symbolList.length; i < len; i += 3) {
+        var strategy = symbolList[i];
+        var moduleName = symbolList[i + 1];
+        var module = require(moduleName);
+        // <runs/>
+        if (strategy == 'r') {
+            continue;
+        }
+        var symbolPath = symbolList[i + 2];
+        var lastDot = symbolPath.lastIndexOf('.');
+        var namespace = symbolPath.substr(0, lastDot);
+        var lastName = symbolPath.substr(lastDot + 1);
+
+        var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
+        var parentObj = prepareNamespace(namespace, context);
+        var target = parentObj[lastName];
+
+        if (strategy == 'm' && target) {
+            builder.recursiveMerge(target, module);
+        } else if ((strategy == 'd' && !target) || (strategy != 'd')) {
+            if (!(symbolPath in origSymbols)) {
+                origSymbols[symbolPath] = target;
+            }
+            builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
+        }
+    }
+};
+
+exports.getOriginalSymbol = function(context, symbolPath) {
+    var origSymbols = context.CDV_origSymbols;
+    if (origSymbols && (symbolPath in origSymbols)) {
+        return origSymbols[symbolPath];
+    }
+    var parts = symbolPath.split('.');
+    var obj = context;
+    for (var i = 0; i < parts.length; ++i) {
+        obj = obj && obj[parts[i]];
+    }
+    return obj;
+};
+
+exports.reset();
+
+
+});
+
+// file: lib/android/platform.js
+define("cordova/platform", function(require, exports, module) {
+
+module.exports = {
+    id: 'android',
+    bootstrap: function() {
+        var channel = require('cordova/channel'),
+            cordova = require('cordova'),
+            exec = require('cordova/exec'),
+            modulemapper = require('cordova/modulemapper');
+
+        // Tell the native code that a page change has occurred.
+        exec(null, null, 'PluginManager', 'startup', []);
+        // Tell the JS that the native side is ready.
+        channel.onNativeReady.fire();
+
+        // TODO: Extract this as a proper plugin.
+        modulemapper.clobbers('cordova/plugin/android/app', 'navigator.app');
+
+        // Inject a listener for the backbutton on the document.
+        var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
+        backButtonChannel.onHasSubscribersChange = function() {
+            // If we just attached the first handler or detached the last handler,
+            // let native know we need to override the back button.
+            exec(null, null, "App", "overrideBackbutton", [this.numHandlers == 1]);
+        };
+
+        // Add hardware MENU and SEARCH button handlers
+        cordova.addDocumentEventHandler('menubutton');
+        cordova.addDocumentEventHandler('searchbutton');
+
+        // Let native code know we are all done on the JS side.
+        // Native code will then un-hide the WebView.
+        channel.onCordovaReady.subscribe(function() {
+            exec(null, null, "App", "show", []);
+        });
+    }
+};
+
+});
+
+// file: lib/android/plugin/android/app.js
+define("cordova/plugin/android/app", function(require, exports, module) {
+
+var exec = require('cordova/exec');
+
+module.exports = {
+    /**
+    * Clear the resource cache.
+    */
+    clearCache:function() {
+        exec(null, null, "App", "clearCache", []);
+    },
+
+    /**
+    * Load the url into the webview or into new browser instance.
+    *
+    * @param url           The URL to load
+    * @param props         Properties that can be passed in to the activity:
+    *      wait: int                           => wait msec before loading URL
+    *      loadingDialog: "Title,Message"      => display a native loading dialog
+    *      loadUrlTimeoutValue: int            => time in msec to wait before triggering a timeout error
+    *      clearHistory: boolean              => clear webview history (default=false)
+    *      openExternal: boolean              => open in a new browser (default=false)
+    *
+    * Example:
+    *      navigator.app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000});
+    */
+    loadUrl:function(url, props) {
+        exec(null, null, "App", "loadUrl", [url, props]);
+    },
+
+    /**
+    * Cancel loadUrl that is waiting to be loaded.
+    */
+    cancelLoadUrl:function() {
+        exec(null, null, "App", "cancelLoadUrl", []);
+    },
+
+    /**
+    * Clear web history in this web view.
+    * Instead of BACK button loading the previous web page, it will exit the app.
+    */
+    clearHistory:function() {
+        exec(null, null, "App", "clearHistory", []);
+    },
+
+    /**
+    * Go to previous page displayed.
+    * This is the same as pressing the backbutton on Android device.
+    */
+    backHistory:function() {
+        exec(null, null, "App", "backHistory", []);
+    },
+
+    /**
+    * Override the default behavior of the Android back button.
+    * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired.
+    *
+    * Note: The user should not have to call this method.  Instead, when the user
+    *       registers for the "backbutton" event, this is automatically done.
+    *
+    * @param override        T=override, F=cancel override
+    */
+    overrideBackbutton:function(override) {
+        exec(null, null, "App", "overrideBackbutton", [override]);
+    },
+
+    /**
+    * Exit and terminate the application.
+    */
+    exitApp:function() {
+        return exec(null, null, "App", "exitApp", []);
+    }
+};
+
+});
+
+// file: lib/common/pluginloader.js
+define("cordova/pluginloader", function(require, exports, module) {
+
+var modulemapper = require('cordova/modulemapper');
+
+// Helper function to inject a <script> tag.
+function injectScript(url, onload, onerror) {
+    var script = document.createElement("script");
+    // onload fires even when script fails loads with an error.
+    script.onload = onload;
+    script.onerror = onerror || onload;
+    script.src = url;
+    document.head.appendChild(script);
+}
+
+function onScriptLoadingComplete(moduleList, finishPluginLoading) {
+    // Loop through all the plugins and then through their clobbers and merges.
+    for (var i = 0, module; module = moduleList[i]; i++) {
+        if (module) {
+            try {
+                if (module.clobbers && module.clobbers.length) {
+                    for (var j = 0; j < module.clobbers.length; j++) {
+                        modulemapper.clobbers(module.id, module.clobbers[j]);
+                    }
+                }
+
+                if (module.merges && module.merges.length) {
+                    for (var k = 0; k < module.merges.length; k++) {
+                        modulemapper.merges(module.id, module.merges[k]);
+                    }
+                }
+
+                // Finally, if runs is truthy we want to simply require() the module.
+                // This can be skipped if it had any merges or clobbers, though,
+                // since the mapper will already have required the module.
+                if (module.runs && !(module.clobbers && module.clobbers.length) && !(module.merges && module.merges.length)) {
+                    modulemapper.runs(module.id);
+                }
+            }
+            catch(err) {
+                // error with module, most likely clobbers, should we continue?
+            }
+        }
+    }
+
+    finishPluginLoading();
+}
+
+// Handler for the cordova_plugins.js content.
+// See plugman's plugin_loader.js for the details of this object.
+// This function is only called if the really is a plugins array that isn't empty.
+// Otherwise the onerror response handler will just call finishPluginLoading().
+function handlePluginsObject(path, moduleList, finishPluginLoading) {
+    // Now inject the scripts.
+    var scriptCounter = moduleList.length;
+
+    if (!scriptCounter) {
+        finishPluginLoading();
+        return;
+    }
+    function scriptLoadedCallback() {
+        if (!--scriptCounter) {
+            onScriptLoadingComplete(moduleList, finishPluginLoading);
+        }
+    }
+
+    for (var i = 0; i < moduleList.length; i++) {
+        injectScript(path + moduleList[i].file, scriptLoadedCallback);
+    }
+}
+
+function injectPluginScript(pathPrefix, finishPluginLoading) {
+    injectScript(pathPrefix + 'cordova_plugins.js', function(){
+        try {
+            var moduleList = require("cordova/plugin_list");
+            handlePluginsObject(pathPrefix, moduleList, finishPluginLoading);
+        } catch (e) {
+            // Error loading cordova_plugins.js, file not found or something
+            // this is an acceptable error, pre-3.0.0, so we just move on.
+            finishPluginLoading();
+        }
+    }, finishPluginLoading); // also, add script load error handler for file not found
+}
+
+function findCordovaPath() {
+    var path = null;
+    var scripts = document.getElementsByTagName('script');
+    var term = 'cordova.js';
+    for (var n = scripts.length-1; n>-1; n--) {
+        var src = scripts[n].src;
+        if (src.indexOf(term) == (src.length - term.length)) {
+            path = src.substring(0, src.length - term.length);
+            break;
+        }
+    }
+    return path;
+}
+
+// Tries to load all plugins' js-modules.
+// This is an async process, but onDeviceReady is blocked on onPluginsReady.
+// onPluginsReady is fired when there are no plugins to load, or they are all done.
+exports.load = function(callback) {
+    var pathPrefix = findCordovaPath();
+    if (pathPrefix === null) {
+        console.log('Could not find cordova.js script tag. Plugin loading may fail.');
+        pathPrefix = '';
+    }
+    injectPluginScript(pathPrefix, callback);
+};
+
+
+});
+
+// file: lib/common/urlutil.js
+define("cordova/urlutil", function(require, exports, module) {
+
+var urlutil = exports;
+var anchorEl = document.createElement('a');
+
+/**
+ * For already absolute URLs, returns what is passed in.
+ * For relative URLs, converts them to absolute ones.
+ */
+urlutil.makeAbsolute = function(url) {
+  anchorEl.href = url;
+  return anchorEl.href;
+};
+
+});
+
+// file: lib/common/utils.js
+define("cordova/utils", function(require, exports, module) {
+
+var utils = exports;
+
+/**
+ * Defines a property getter / setter for obj[key].
+ */
+utils.defineGetterSetter = function(obj, key, getFunc, opt_setFunc) {
+    if (Object.defineProperty) {
+        var desc = {
+            get: getFunc,
+            configurable: true
+        };
+        if (opt_setFunc) {
+            desc.set = opt_setFunc;
+        }
+        Object.defineProperty(obj, key, desc);
+    } else {
+        obj.__defineGetter__(key, getFunc);
+        if (opt_setFunc) {
+            obj.__defineSetter__(key, opt_setFunc);
+        }
+    }
+};
+
+/**
+ * Defines a property getter for obj[key].
+ */
+utils.defineGetter = utils.defineGetterSetter;
+
+utils.arrayIndexOf = function(a, item) {
+    if (a.indexOf) {
+        return a.indexOf(item);
+    }
+    var len = a.length;
+    for (var i = 0; i < len; ++i) {
+        if (a[i] == item) {
+            return i;
+        }
+    }
+    return -1;
+};
+
+/**
+ * Returns whether the item was found in the array.
+ */
+utils.arrayRemove = function(a, item) {
+    var index = utils.arrayIndexOf(a, item);
+    if (index != -1) {
+        a.splice(index, 1);
+    }
+    return index != -1;
+};
+
+utils.typeName = function(val) {
+    return Object.prototype.toString.call(val).slice(8, -1);
+};
+
+/**
+ * Returns an indication of whether the argument is an array or not
+ */
+utils.isArray = function(a) {
+    return utils.typeName(a) == 'Array';
+};
+
+/**
+ * Returns an indication of whether the argument is a Date or not
+ */
+utils.isDate = function(d) {
+    return utils.typeName(d) == 'Date';
+};
+
+/**
+ * Does a deep clone of the object.
+ */
+utils.clone = function(obj) {
+    if(!obj || typeof obj == 'function' || utils.isDate(obj) || typeof obj != 'object') {
+        return obj;
+    }
+
+    var retVal, i;
+
+    if(utils.isArray(obj)){
+        retVal = [];
+        for(i = 0; i < obj.length; ++i){
+            retVal.push(utils.clone(obj[i]));
+        }
+        return retVal;
+    }
+
+    retVal = {};
+    for(i in obj){
+        if(!(i in retVal) || retVal[i] != obj[i]) {
+            retVal[i] = utils.clone(obj[i]);
+        }
+    }
+    return retVal;
+};
+
+/**
+ * Returns a wrapped version of the function
+ */
+utils.close = function(context, func, params) {
+    if (typeof params == 'undefined') {
+        return function() {
+            return func.apply(context, arguments);
+        };
+    } else {
+        return function() {
+            return func.apply(context, params);
+        };
+    }
+};
+
+/**
+ * Create a UUID
+ */
+utils.createUUID = function() {
+    return UUIDcreatePart(4) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(2) + '-' +
+        UUIDcreatePart(6);
+};
+
+/**
+ * Extends a child object from a parent object using classical inheritance
+ * pattern.
+ */
+utils.extend = (function() {
+    // proxy used to establish prototype chain
+    var F = function() {};
+    // extend Child from Parent
+    return function(Child, Parent) {
+        F.prototype = Parent.prototype;
+        Child.prototype = new F();
+        Child.__super__ = Parent.prototype;
+        Child.prototype.constructor = Child;
+    };
+}());
+
+/**
+ * Alerts a message in any available way: alert or console.log.
+ */
+utils.alert = function(msg) {
+    if (window.alert) {
+        window.alert(msg);
+    } else if (console && console.log) {
+        console.log(msg);
+    }
+};
+
+
+//------------------------------------------------------------------------------
+function UUIDcreatePart(length) {
+    var uuidpart = "";
+    for (var i=0; i<length; i++) {
+        var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
+        if (uuidchar.length == 1) {
+            uuidchar = "0" + uuidchar;
+        }
+        uuidpart += uuidchar;
+    }
+    return uuidpart;
+}
+
+
+});
+
+window.cordova = require('cordova');
+// file: lib/scripts/bootstrap.js
+
+require('cordova/init');
+
+})();
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/assets/www/cordova_plugins.js
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/assets/www/cordova_plugins.js b/e2e/fixtures/platforms/android/assets/www/cordova_plugins.js
new file mode 100644
index 0000000..fbe1f44
--- /dev/null
+++ b/e2e/fixtures/platforms/android/assets/www/cordova_plugins.js
@@ -0,0 +1,3 @@
+cordova.define('cordova/plugin_list', function(require, exports, module) {
+module.exports = []
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/af7b2401/e2e/fixtures/platforms/android/assets/www/css/index.css
----------------------------------------------------------------------
diff --git a/e2e/fixtures/platforms/android/assets/www/css/index.css b/e2e/fixtures/platforms/android/assets/www/css/index.css
new file mode 100644
index 0000000..51daa79
--- /dev/null
+++ b/e2e/fixtures/platforms/android/assets/www/css/index.css
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+* {
+    -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
+}
+
+body {
+    -webkit-touch-callout: none;                /* prevent callout to copy image, etc when tap to hold */
+    -webkit-text-size-adjust: none;             /* prevent webkit from resizing text to fit */
+    -webkit-user-select: none;                  /* prevent copy paste, to allow, change 'none' to 'text' */
+    background-color:#E4E4E4;
+    background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+    background-image:-webkit-gradient(
+        linear,
+        left top,
+        left bottom,
+        color-stop(0, #A7A7A7),
+        color-stop(0.51, #E4E4E4)
+    );
+    background-attachment:fixed;
+    font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
+    font-size:12px;
+    height:100%;
+    margin:0px;
+    padding:0px;
+    text-transform:uppercase;
+    width:100%;
+}
+
+/* Portrait layout (default) */
+.app {
+    background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
+    position:absolute;             /* position in the center of the screen */
+    left:50%;
+    top:50%;
+    height:50px;                   /* text area height */
+    width:225px;                   /* text area width */
+    text-align:center;
+    padding:180px 0px 0px 0px;     /* image height is 200px (bottom 20px are overlapped with text) */
+    margin:-115px 0px 0px -112px;  /* offset vertical: half of image height and text area height */
+                                   /* offset horizontal: half of text area width */
+}
+
+/* Landscape layout (with min-width) */
+@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
+    .app {
+        background-position:left center;
+        padding:75px 0px 75px 170px;  /* padding-top + padding-bottom + text area = image height */
+        margin:-90px 0px 0px -198px;  /* offset vertical: half of image height */
+                                      /* offset horizontal: half of image width and text area width */
+    }
+}
+
+h1 {
+    font-size:24px;
+    font-weight:normal;
+    margin:0px;
+    overflow:visible;
+    padding:0px;
+    text-align:center;
+}
+
+.event {
+    border-radius:4px;
+    -webkit-border-radius:4px;
+    color:#FFFFFF;
+    font-size:12px;
+    margin:0px 30px;
+    padding:2px 0px;
+}
+
+.event.listening {
+    background-color:#333333;
+    display:block;
+}
+
+.event.received {
+    background-color:#4B946A;
+    display:none;
+}
+
+@keyframes fade {
+    from { opacity: 1.0; }
+    50% { opacity: 0.4; }
+    to { opacity: 1.0; }
+}
+ 
+@-webkit-keyframes fade {
+    from { opacity: 1.0; }
+    50% { opacity: 0.4; }
+    to { opacity: 1.0; }
+}
+ 
+.blink {
+    animation:fade 3000ms infinite;
+    -webkit-animation:fade 3000ms infinite;
+}


[20/23] git commit: updated to 3.2.0-0.4.0

Posted by st...@apache.org.
updated to 3.2.0-0.4.0


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

Branch: refs/heads/ubuntu
Commit: 6e1d79e31a5e50bd55685dc6ba9e3c7e96048eed
Parents: 5e4af11
Author: Steven Gill <st...@gmail.com>
Authored: Thu Dec 5 15:38:54 2013 -0800
Committer: Steven Gill <st...@gmail.com>
Committed: Thu Dec 5 15:38:54 2013 -0800

----------------------------------------------------------------------
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/6e1d79e3/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index d93025e..95af02e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "cordova",
-  "version": "3.2.0-0.3.0",
+  "version": "3.2.0-0.4.0",
   "preferGlobal": "true",
   "description": "Cordova command line interface tool",
   "main": "cordova",


[23/23] git commit: Merge branch 'ubuntu' of github.com:Zaspire/cordova-cli into ubuntu

Posted by st...@apache.org.
Merge branch 'ubuntu' of github.com:Zaspire/cordova-cli into ubuntu


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

Branch: refs/heads/ubuntu
Commit: 1c15a2480ec5c0d75dc568a5b62f809710ee9749
Parents: 1bb0e02 2fb1c8e
Author: Steven Gill <st...@gmail.com>
Authored: Thu Dec 5 15:40:21 2013 -0800
Committer: Steven Gill <st...@gmail.com>
Committed: Thu Dec 5 15:40:21 2013 -0800

----------------------------------------------------------------------
 spec/platform.spec.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------



[22/23] git commit: platforms now points to apache to grab cordova-ubuntu

Posted by st...@apache.org.
platforms now points to apache to grab cordova-ubuntu


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

Branch: refs/heads/ubuntu
Commit: 1bb0e0285bb60e42f89a96bda98f72ef44676258
Parents: 7968ae7
Author: Steven Gill <st...@gmail.com>
Authored: Wed Nov 27 15:32:34 2013 -0800
Committer: Steven Gill <st...@gmail.com>
Committed: Thu Dec 5 15:39:52 2013 -0800

----------------------------------------------------------------------
 platforms.js     | 2 +-
 src/lazy_load.js | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/1bb0e028/platforms.js
----------------------------------------------------------------------
diff --git a/platforms.js b/platforms.js
index d26bf75..c8e0075 100644
--- a/platforms.js
+++ b/platforms.js
@@ -31,7 +31,7 @@ module.exports = {
     'ubuntu' : {
         parser : './src/metadata/ubuntu_parser',
         url    : 'https://launchpad.net/cordova-ubuntu/3.0/apha1/+download/campo.tar.gz',
-        version: '3.1.0-rc1'
+        version: '3.2.0'
     }, 
     'wp7' : {
         parser : './src/metadata/wp7_parser',

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/1bb0e028/src/lazy_load.js
----------------------------------------------------------------------
diff --git a/src/lazy_load.js b/src/lazy_load.js
index fd95031..dcaa126 100644
--- a/src/lazy_load.js
+++ b/src/lazy_load.js
@@ -40,8 +40,6 @@ module.exports = {
         }
 
         var url = platforms[platform].url + ';a=snapshot;h=' + platforms[platform].version + ';sf=tgz';
-        if (platform == 'ubuntu')
-            url = platforms[platform].url;
         return module.exports.custom(url, 'cordova', platform, platforms[platform].version);
     },
     // Returns a promise for the path to the lazy-loaded directory.


[09/23] git commit: Update version to 3.2.0-0.3.0

Posted by st...@apache.org.
Update version to 3.2.0-0.3.0


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

Branch: refs/heads/ubuntu
Commit: d47a67a6f75c7e03ac59dd73a755af807444bce1
Parents: 2eedc27
Author: Bryan Higgins <bh...@blackberry.com>
Authored: Fri Nov 29 13:46:12 2013 -0500
Committer: Bryan Higgins <bh...@blackberry.com>
Committed: Fri Nov 29 13:46:12 2013 -0500

----------------------------------------------------------------------
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d47a67a6/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index 440c47b..aadf0e7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "cordova",
-  "version": "3.2.0-0.2.0",
+  "version": "3.2.0-0.3.0",
   "preferGlobal": "true",
   "description": "Cordova command line interface tool",
   "main": "cordova",


[19/23] git commit: CB-5034 add registry info to README

Posted by st...@apache.org.
CB-5034 add registry info to README


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

Branch: refs/heads/ubuntu
Commit: 5e4af119c36227852954ec10d8d3b03314377d4b
Parents: ed82c5a
Author: mbillau <mi...@gmail.com>
Authored: Wed Oct 23 15:40:37 2013 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Thu Dec 5 15:43:36 2013 -0500

----------------------------------------------------------------------
 README.md | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/5e4af119/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 716bc16..f26d248 100644
--- a/README.md
+++ b/README.md
@@ -78,8 +78,9 @@ Now the `cordova` and `plugman` in your path are the local git versions. Don't f
 
 cordova-cli has a single global `create` command that creates new cordova projects into a specified directory. Once you create a project, `cd` into it and you can execute a variety of project-level commands. Completely inspired by git's interface.
 
-## Global Command
+## Global Commands
 
+- `help` display a help page with all available commands
 - `create <directory> [<id> [<name>]]` create a new cordova project with optional name and id (package name, reverse-domain style)
 
 <a name="project_commands" />
@@ -88,9 +89,11 @@ cordova-cli has a single global `create` command that creates new cordova projec
 - `platform [ls | list]` list all platforms the project will build to
 - `platform add <platform> [<platform> ...]` add one (or more) platforms as a build target for the project
 - `platform [rm | remove] <platform> [<platform> ...]` removes one (or more) platforms as a build target for the project
+- `platform [up | update] <platform> ` - updates the Cordova version used for the given platform
 - `plugin [ls | list]` list all plugins added to the project
 - `plugin add <path-to-plugin> [<path-to-plugin> ...]` add one (or more) plugins to the project
 - `plugin [rm | remove] <plugin-name> [<plugin-name> ...]` remove one (or more) added plugins
+- `plugin search [<keyword1> <keyword2> ...]` search the plugin registry for plugins matching the list of keywords
 - `prepare [platform...]` copies files into the specified platforms, or all platforms. it is then ready for building by Eclipse/Xcode/etc.
 - `compile [platform...]` compiles the app into a binary for each added platform. With no parameters, builds for all platforms, otherwise builds for the specified platforms.
 - `build [<platform> [<platform> [...]]]` an alias for `cordova prepare` followed by `cordova compile`


[14/23] git commit: removed 'win-test' fixture, e2e runs fine on windows now.

Posted by st...@apache.org.
removed 'win-test' fixture, e2e runs fine on windows now.


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

Branch: refs/heads/ubuntu
Commit: 3a53c222c78585e323e153427f06be5d4aed0464
Parents: 2a7bcae
Author: Jesse MacFadyen <pu...@gmail.com>
Authored: Wed Dec 4 13:05:12 2013 -0800
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Wed Dec 4 13:05:12 2013 -0800

----------------------------------------------------------------------
 package.json | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/3a53c222/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index aadf0e7..d93025e 100644
--- a/package.json
+++ b/package.json
@@ -12,8 +12,7 @@
     "cordova": "./bin/cordova"
   },
   "scripts": {
-    "test": "jasmine-node --color spec e2e",
-    "win-test" : "jasmine-node --color spec"
+    "test": "jasmine-node --color spec e2e"
   },
   "repository": {
     "type": "git",


[04/23] git commit: Fix e2e tests on Windows

Posted by st...@apache.org.
Fix e2e tests on Windows

There were two problems.
 1. Couldn't delete the tmp project dir on Windows because it was the CWD
    dir of the node process and Windows can't delete "busy" dirs.
 2. There was an interaction between tests in spec and those in e2e.
    Jasmine ran the e2e tests first, the CWD stayed in temp dir, but some
    tests in spec assume that CWD is the cordova source root dir.

Both problems solved by process.chdir(<source root>) after each e2e test.


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

Branch: refs/heads/ubuntu
Commit: 186baba03ad3cca368290113d5f7ccb9e28050ba
Parents: ad01299
Author: Mark Koudritsky <ka...@chromium.org>
Authored: Thu Nov 28 11:48:14 2013 -0500
Committer: Michal Mocny <mm...@gmail.com>
Committed: Fri Nov 29 09:53:50 2013 -0500

----------------------------------------------------------------------
 e2e/create.spec.js   | 1 +
 e2e/platform.spec.js | 1 +
 e2e/plugin.spec.js   | 1 +
 3 files changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/186baba0/e2e/create.spec.js
----------------------------------------------------------------------
diff --git a/e2e/create.spec.js b/e2e/create.spec.js
index 5900d7a..3f1304c 100644
--- a/e2e/create.spec.js
+++ b/e2e/create.spec.js
@@ -62,6 +62,7 @@ describe('create end-to-end', function() {
         shell.rm('-rf', project);
     });
     afterEach(function() {
+        process.chdir(path.join(__dirname, '..'));  // Needed to rm the dir on Windows.
         shell.rm('-rf', project);
     });
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/186baba0/e2e/platform.spec.js
----------------------------------------------------------------------
diff --git a/e2e/platform.spec.js b/e2e/platform.spec.js
index 879a909..be5761e 100644
--- a/e2e/platform.spec.js
+++ b/e2e/platform.spec.js
@@ -22,6 +22,7 @@ describe('platform end-to-end', function() {
         shell.rm('-rf', project);
     });
     afterEach(function() {
+        process.chdir(path.join(__dirname, '..'));  // Needed to rm the dir on Windows.
         shell.rm('-rf', project);
     });
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/186baba0/e2e/plugin.spec.js
----------------------------------------------------------------------
diff --git a/e2e/plugin.spec.js b/e2e/plugin.spec.js
index 0425f90..dd493bb 100644
--- a/e2e/plugin.spec.js
+++ b/e2e/plugin.spec.js
@@ -19,6 +19,7 @@ describe('plugin end-to-end', function() {
         shell.rm('-rf', project);
     });
     afterEach(function() {
+        process.chdir(path.join(__dirname, '..'));  // Needed to rm the dir on Windows.
         shell.rm('-rf', project);
     });
 


[15/23] git commit: windows8. fixes version number parsing logic

Posted by st...@apache.org.
windows8. fixes version number parsing logic


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

Branch: refs/heads/ubuntu
Commit: e325e5dd63a31c30cd0b493e6b56b0816f341094
Parents: 3a53c22
Author: sgrebnov <se...@gmail.com>
Authored: Wed Dec 4 13:53:05 2013 +0400
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Wed Dec 4 13:09:46 2013 -0800

----------------------------------------------------------------------
 src/metadata/windows8_parser.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/e325e5dd/src/metadata/windows8_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/windows8_parser.js b/src/metadata/windows8_parser.js
index f8e0776..e85b86f 100644
--- a/src/metadata/windows8_parser.js
+++ b/src/metadata/windows8_parser.js
@@ -296,8 +296,8 @@ module.exports.prototype = {
 
     // Adjust version number as per CB-5337 Windows8 build fails due to invalid app version        
     fixConfigVersion: function (version) {
-        if(version && version.match(/\.d/g)) {
-            var numVersionComponents = version.match(/\.d/g).length + 1;
+        if(version && version.match(/\.\d/g)) {
+            var numVersionComponents = version.match(/\.\d/g).length + 1;
             while (numVersionComponents++ < 4) {
                 version += '.0';
             }