You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by an...@apache.org on 2015/10/20 11:21:21 UTC

[08/12] android commit: CB-9782 Implements PlatformApi contract for Android platform.

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/40028228/bin/node_modules/which/bin/which
----------------------------------------------------------------------
diff --git a/bin/node_modules/which/bin/which b/bin/node_modules/which/bin/which
deleted file mode 100755
index 8432ce2..0000000
--- a/bin/node_modules/which/bin/which
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env node
-var which = require("../")
-if (process.argv.length < 3) {
-  console.error("Usage: which <thing>")
-  process.exit(1)
-}
-
-which(process.argv[2], function (er, thing) {
-  if (er) {
-    console.error(er.message)
-    process.exit(er.errno || 127)
-  }
-  console.log(thing)
-})

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/40028228/bin/node_modules/which/package.json
----------------------------------------------------------------------
diff --git a/bin/node_modules/which/package.json b/bin/node_modules/which/package.json
deleted file mode 100644
index 6c5ccb3..0000000
--- a/bin/node_modules/which/package.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "author": {
-    "name": "Isaac Z. Schlueter",
-    "email": "i@izs.me",
-    "url": "http://blog.izs.me"
-  },
-  "name": "which",
-  "description": "Like which(1) unix command. Find the first instance of an executable in the PATH.",
-  "version": "1.0.5",
-  "repository": {
-    "type": "git",
-    "url": "git://github.com/isaacs/node-which.git"
-  },
-  "main": "which.js",
-  "bin": {
-    "which": "./bin/which"
-  },
-  "engines": {
-    "node": "*"
-  },
-  "dependencies": {},
-  "devDependencies": {},
-  "readme": "The \"which\" util from npm's guts.\n\nFinds the first instance of a specified executable in the PATH\nenvironment variable.  Does not cache the results, so `hash -r` is not\nneeded when the PATH changes.\n",
-  "readmeFilename": "README.md",
-  "bugs": {
-    "url": "https://github.com/isaacs/node-which/issues"
-  },
-  "homepage": "https://github.com/isaacs/node-which",
-  "_id": "which@1.0.5",
-  "_from": "which@"
-}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/40028228/bin/node_modules/which/which.js
----------------------------------------------------------------------
diff --git a/bin/node_modules/which/which.js b/bin/node_modules/which/which.js
deleted file mode 100644
index db7e8f7..0000000
--- a/bin/node_modules/which/which.js
+++ /dev/null
@@ -1,104 +0,0 @@
-module.exports = which
-which.sync = whichSync
-
-var path = require("path")
-  , fs
-  , COLON = process.platform === "win32" ? ";" : ":"
-  , isExe
-
-try {
-  fs = require("graceful-fs")
-} catch (ex) {
-  fs = require("fs")
-}
-
-if (process.platform == "win32") {
-  // On windows, there is no good way to check that a file is executable
-  isExe = function isExe () { return true }
-} else {
-  isExe = function isExe (mod, uid, gid) {
-    //console.error(mod, uid, gid);
-    //console.error("isExe?", (mod & 0111).toString(8))
-    var ret = (mod & 0001)
-        || (mod & 0010) && process.getgid && gid === process.getgid()
-        || (mod & 0100) && process.getuid && uid === process.getuid()
-    //console.error("isExe?", ret)
-    return ret
-  }
-}
-
-
-
-function which (cmd, cb) {
-  if (isAbsolute(cmd)) return cb(null, cmd)
-  var pathEnv = (process.env.PATH || "").split(COLON)
-    , pathExt = [""]
-  if (process.platform === "win32") {
-    pathEnv.push(process.cwd())
-    pathExt = (process.env.PATHEXT || ".EXE").split(COLON)
-    if (cmd.indexOf(".") !== -1) pathExt.unshift("")
-  }
-  //console.error("pathEnv", pathEnv)
-  ;(function F (i, l) {
-    if (i === l) return cb(new Error("not found: "+cmd))
-    var p = path.resolve(pathEnv[i], cmd)
-    ;(function E (ii, ll) {
-      if (ii === ll) return F(i + 1, l)
-      var ext = pathExt[ii]
-      //console.error(p + ext)
-      fs.stat(p + ext, function (er, stat) {
-        if (!er &&
-            stat &&
-            stat.isFile() &&
-            isExe(stat.mode, stat.uid, stat.gid)) {
-          //console.error("yes, exe!", p + ext)
-          return cb(null, p + ext)
-        }
-        return E(ii + 1, ll)
-      })
-    })(0, pathExt.length)
-  })(0, pathEnv.length)
-}
-
-function whichSync (cmd) {
-  if (isAbsolute(cmd)) return cmd
-  var pathEnv = (process.env.PATH || "").split(COLON)
-    , pathExt = [""]
-  if (process.platform === "win32") {
-    pathEnv.push(process.cwd())
-    pathExt = (process.env.PATHEXT || ".EXE").split(COLON)
-    if (cmd.indexOf(".") !== -1) pathExt.unshift("")
-  }
-  for (var i = 0, l = pathEnv.length; i < l; i ++) {
-    var p = path.join(pathEnv[i], cmd)
-    for (var j = 0, ll = pathExt.length; j < ll; j ++) {
-      var cur = p + pathExt[j]
-      var stat
-      try { stat = fs.statSync(cur) } catch (ex) {}
-      if (stat &&
-          stat.isFile() &&
-          isExe(stat.mode, stat.uid, stat.gid)) return cur
-    }
-  }
-  throw new Error("not found: "+cmd)
-}
-
-var isAbsolute = process.platform === "win32" ? absWin : absUnix
-
-function absWin (p) {
-  if (absUnix(p)) return true
-  // pull off the device/UNC bit from a windows path.
-  // from node's lib/path.js
-  var splitDeviceRe =
-        /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?/
-    , result = splitDeviceRe.exec(p)
-    , device = result[1] || ''
-    , isUnc = device && device.charAt(1) !== ':'
-    , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute
-
-  return isAbsolute
-}
-
-function absUnix (p) {
-  return p.charAt(0) === "/" || p === ""
-}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/40028228/bin/templates/cordova/.jshintrc
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/.jshintrc b/bin/templates/cordova/.jshintrc
new file mode 100644
index 0000000..89a121c
--- /dev/null
+++ b/bin/templates/cordova/.jshintrc
@@ -0,0 +1,10 @@
+{
+    "node": true
+  , "bitwise": true
+  , "undef": true
+  , "trailing": true
+  , "quotmark": true
+  , "indent": 4
+  , "unused": "vars"
+  , "latedef": "nofunc"
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/40028228/bin/templates/cordova/Api.js
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/Api.js b/bin/templates/cordova/Api.js
new file mode 100644
index 0000000..62899ef
--- /dev/null
+++ b/bin/templates/cordova/Api.js
@@ -0,0 +1,492 @@
+/**
+    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 Q = require('q');
+var fs = require('fs');
+var path = require('path');
+var shell = require('shelljs');
+
+var CordovaError = require('cordova-common').CordovaError;
+var PlatformJson = require('cordova-common').PlatformJson;
+var ActionStack = require('cordova-common').ActionStack;
+var AndroidProject = require('./lib/AndroidProject');
+var PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger;
+var PluginInfoProvider = require('cordova-common').PluginInfoProvider;
+
+var ConsoleLogger = require('./lib/ConsoleLogger');
+var pluginHandlers = require('./lib/pluginHandlers');
+
+var PLATFORM = 'android';
+
+/**
+ * Class, that acts as abstraction over particular platform. Encapsulates the
+ *   platform's properties and methods.
+ *
+ * Platform that implements own PlatformApi instance _should implement all
+ *   prototype methods_ of this class to be fully compatible with cordova-lib.
+ *
+ * The PlatformApi instance also should define the following field:
+ *
+ * * platform: String that defines a platform name.
+ */
+function Api(platform, platformRootDir, events) {
+    this.platform = PLATFORM;
+    this.root = path.resolve(__dirname, '..');
+    this.events = events || ConsoleLogger.get();
+    // NOTE: trick to share one EventEmitter instance across all js code
+    require('cordova-common').events = this.events;
+
+    this._platformJson = PlatformJson.load(this.root, platform);
+    this._pluginInfoProvider = new PluginInfoProvider();
+    this._munger = new PlatformMunger(this.platform, this.root, this._platformJson, this._pluginInfoProvider);
+
+    var self = this;
+
+    this.locations = {
+        root: self.root,
+        www: path.join(self.root, 'assets/www'),
+        platformWww: path.join(self.root, 'platform_www'),
+        configXml: path.join(self.root, 'res/xml/config.xml'),
+        defaultConfigXml: path.join(self.root, 'cordova/defaults.xml'),
+        strings: path.join(self.root, 'res/values/strings.xml'),
+        manifest: path.join(self.root, 'AndroidManifest.xml'),
+        // NOTE: Due to platformApi spec we need to return relative paths here
+        cordovaJs: 'bin/templates/project/assets/www/cordova.js',
+        cordovaJsSrc: 'cordova-js-src'
+    };
+}
+
+/**
+ * Installs platform to specified directory and creates a platform project.
+ *
+ * @param  {String}  destination Destination directory, where insatll platform to
+ * @param  {ConfigParser}  [config] ConfgiParser instance, used to retrieve
+ *   project creation options, such as package id and project name.
+ * @param  {Object}  [options]  An options object. The most common options are:
+ * @param  {String}  [options.customTemplate]  A path to custom template, that
+ *   should override the default one from platform.
+ * @param  {Boolean}  [options.link]  Flag that indicates that platform's
+ *   sources will be linked to installed platform instead of copying.
+ * @param {EventEmitter} [events] An EventEmitter instance that will be used for
+ *   logging purposes. If no EventEmitter provided, all events will be logged to
+ *   console
+ *
+ * @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi
+ *   instance or rejected with CordovaError.
+ */
+Api.createPlatform = function (destination, config, options, events) {
+    return require('../../lib/create')
+    .create(destination, config, options, events || ConsoleLogger.get())
+    .then(function (destination) {
+        var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
+        return new PlatformApi(PLATFORM, destination, events);
+    });
+};
+
+/**
+ * Updates already installed platform.
+ *
+ * @param  {String}  destination Destination directory, where platform installed
+ * @param  {Object}  [options]  An options object. The most common options are:
+ * @param  {String}  [options.customTemplate]  A path to custom template, that
+ *   should override the default one from platform.
+ * @param  {Boolean}  [options.link]  Flag that indicates that platform's
+ *   sources will be linked to installed platform instead of copying.
+ * @param {EventEmitter} [events] An EventEmitter instance that will be used for
+ *   logging purposes. If no EventEmitter provided, all events will be logged to
+ *   console
+ *
+ * @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi
+ *   instance or rejected with CordovaError.
+ */
+Api.updatePlatform = function (destination, options, events) {
+    return require('../../lib/create')
+    .update(destination, options, events || ConsoleLogger.get())
+    .then(function (destination) {
+        var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
+        return new PlatformApi('android', destination, events);
+    });
+};
+
+/**
+ * Gets a CordovaPlatform object, that represents the platform structure.
+ *
+ * @return  {CordovaPlatform}  A structure that contains the description of
+ *   platform's file structure and other properties of platform.
+ */
+Api.prototype.getPlatformInfo = function () {
+    var result = {};
+    result.locations = this.locations;
+    result.root = this.root;
+    result.name = this.platform;
+    result.version = require('./version');
+    result.projectConfig = this._config;
+
+    return result;
+};
+
+/**
+ * Updates installed platform with provided www assets and new app
+ *   configuration. This method is required for CLI workflow and will be called
+ *   each time before build, so the changes, made to app configuration and www
+ *   code, will be applied to platform.
+ *
+ * @param {CordovaProject} cordovaProject A CordovaProject instance, that defines a
+ *   project structure and configuration, that should be applied to platform
+ *   (contains project's www location and ConfigParser instance for project's
+ *   config).
+ *
+ * @return  {Promise}  Return a promise either fulfilled, or rejected with
+ *   CordovaError instance.
+ */
+Api.prototype.prepare = function (cordovaProject) {
+    return require('./lib/prepare').prepare.call(this, cordovaProject);
+};
+
+/**
+ * Installs a new plugin into platform. This method only copies non-www files
+ *   (sources, libs, etc.) to platform. It also doesn't resolves the
+ *   dependencies of plugin. Both of handling of www files, such as assets and
+ *   js-files and resolving dependencies are the responsibility of caller.
+ *
+ * @param  {PluginInfo}  plugin  A PluginInfo instance that represents plugin
+ *   that will be installed.
+ * @param  {Object}  installOptions  An options object. Possible options below:
+ * @param  {Boolean}  installOptions.link: Flag that specifies that plugin
+ *   sources will be symlinked to app's directory instead of copying (if
+ *   possible).
+ * @param  {Object}  installOptions.variables  An object that represents
+ *   variables that will be used to install plugin. See more details on plugin
+ *   variables in documentation:
+ *   https://cordova.apache.org/docs/en/4.0.0/plugin_ref_spec.md.html
+ *
+ * @return  {Promise}  Return a promise either fulfilled, or rejected with
+ *   CordovaError instance.
+ */
+Api.prototype.addPlugin = function (plugin, installOptions) {
+
+    if (!plugin || plugin.constructor.name !== 'PluginInfo')
+        return Q.reject(new CordovaError('The parameter is incorrect. The first parameter to addPlugin should be a PluginInfo instance'));
+
+    installOptions = installOptions || {};
+    installOptions.variables = installOptions.variables || {};
+
+    var self = this;
+    var actions = new ActionStack();
+    var project = AndroidProject.getProjectFile(this.root);
+
+    // gather all files needs to be handled during install
+    plugin.getFilesAndFrameworks(this.platform)
+        .concat(plugin.getAssets(this.platform))
+        .concat(plugin.getJsModules(this.platform))
+    .forEach(function(item) {
+        actions.push(actions.createAction(
+            pluginHandlers.getInstaller(item.itemType), [item, plugin, project, installOptions],
+            pluginHandlers.getUninstaller(item.itemType), [item, plugin, project, installOptions]));
+    });
+
+    // run through the action stack
+    return actions.process(this.platform)
+    .then(function () {
+        if (project) {
+            project.write();
+        }
+
+        // Add PACKAGE_NAME variable into vars
+        if (!installOptions.variables.PACKAGE_NAME) {
+            installOptions.variables.PACKAGE_NAME = project.getPackageName();
+        }
+
+        self._munger
+            // Ignore passed `is_top_level` option since platform itself doesn't know
+            // anything about managing dependencies - it's responsibility of caller.
+            .add_plugin_changes(plugin, installOptions.variables, /*is_top_level=*/true, /*should_increment=*/true)
+            .save_all();
+
+        var targetDir = installOptions.usePlatformWww ?
+            self.locations.platformWww :
+            self.locations.www;
+
+        self._addModulesInfo(plugin, targetDir);
+    });
+};
+
+/**
+ * Removes an installed plugin from platform.
+ *
+ * Since method accepts PluginInfo instance as input parameter instead of plugin
+ *   id, caller shoud take care of managing/storing PluginInfo instances for
+ *   future uninstalls.
+ *
+ * @param  {PluginInfo}  plugin  A PluginInfo instance that represents plugin
+ *   that will be installed.
+ *
+ * @return  {Promise}  Return a promise either fulfilled, or rejected with
+ *   CordovaError instance.
+ */
+Api.prototype.removePlugin = function (plugin, uninstallOptions) {
+
+    if (!plugin || plugin.constructor.name !== 'PluginInfo')
+        return Q.reject(new CordovaError('The parameter is incorrect. The first parameter to addPlugin should be a PluginInfo instance'));
+
+    var self = this;
+    var actions = new ActionStack();
+    var project = AndroidProject.getProjectFile(this.root);
+
+    // queue up plugin files
+    plugin.getFilesAndFrameworks(this.platform)
+        .concat(plugin.getAssets(this.platform))
+        .concat(plugin.getJsModules(this.platform))
+    .forEach(function(item) {
+        actions.push(actions.createAction(
+            pluginHandlers.getUninstaller(item.itemType), [item, plugin, project, uninstallOptions],
+            pluginHandlers.getInstaller(item.itemType), [item, plugin, project, uninstallOptions]));
+    });
+
+    // run through the action stack
+    return actions.process(this.platform)
+    .then(function() {
+        if (project) {
+            project.write();
+        }
+
+        self._munger
+            // Ignore passed `is_top_level` option since platform itself doesn't know
+            // anything about managing dependencies - it's responsibility of caller.
+            .remove_plugin_changes(plugin, /*is_top_level=*/true)
+            .save_all();
+
+        var targetDir = uninstallOptions.usePlatformWww ?
+            self.locations.platformWww :
+            self.locations.www;
+
+        self._removeModulesInfo(plugin, targetDir);
+    });
+};
+
+/**
+ * Builds an application package for current platform.
+ *
+ * @param  {Object}  buildOptions  A build options. This object's structure is
+ *   highly depends on platform's specific. The most common options are:
+ * @param  {Boolean}  buildOptions.debug  Indicates that packages should be
+ *   built with debug configuration. This is set to true by default unless the
+ *   'release' option is not specified.
+ * @param  {Boolean}  buildOptions.release  Indicates that packages should be
+ *   built with release configuration. If not set to true, debug configuration
+ *   will be used.
+ * @param   {Boolean}  buildOptions.device  Specifies that built app is intended
+ *   to run on device
+ * @param   {Boolean}  buildOptions.emulator: Specifies that built app is
+ *   intended to run on emulator
+ * @param   {String}  buildOptions.target  Specifies the device id that will be
+ *   used to run built application.
+ * @param   {Boolean}  buildOptions.nobuild  Indicates that this should be a
+ *   dry-run call, so no build artifacts will be produced.
+ * @param   {String[]}  buildOptions.archs  Specifies chip architectures which
+ *   app packages should be built for. List of valid architectures is depends on
+ *   platform.
+ * @param   {String}  buildOptions.buildConfig  The path to build configuration
+ *   file. The format of this file is depends on platform.
+ * @param   {String[]} buildOptions.argv Raw array of command-line arguments,
+ *   passed to `build` command. The purpose of this property is to pass a
+ *   platform-specific arguments, and eventually let platform define own
+ *   arguments processing logic.
+ *
+ * @return {Promise<Object[]>} A promise either fulfilled with an array of build
+ *   artifacts (application packages) if package was built successfully,
+ *   or rejected with CordovaError. The resultant build artifact objects is not
+ *   strictly typed and may conatin arbitrary set of fields as in sample below.
+ *
+ *     {
+ *         architecture: 'x86',
+ *         buildType: 'debug',
+ *         path: '/path/to/build',
+ *         type: 'app'
+ *     }
+ *
+ * The return value in most cases will contain only one item but in some cases
+ *   there could be multiple items in output array, e.g. when multiple
+ *   arhcitectures is specified.
+ */
+Api.prototype.build = function (buildOptions) {
+    var self = this;
+    return require('./lib/check_reqs').run()
+    .then(function () {
+        return require('./lib/build').run.call(self, buildOptions);
+    })
+    .then(function (buildResults) {
+        // Cast build result to array of build artifacts
+        return buildResults.apkPaths.map(function (apkPath) {
+            return {
+                buildType: buildResults.buildType,
+                buildMethod: buildResults.buildMethod,
+                path: apkPath,
+                type: 'apk'
+            };
+        });
+    });
+};
+
+/**
+ * Builds an application package for current platform and runs it on
+ *   specified/default device. If no 'device'/'emulator'/'target' options are
+ *   specified, then tries to run app on default device if connected, otherwise
+ *   runs the app on emulator.
+ *
+ * @param   {Object}  runOptions  An options object. The structure is the same
+ *   as for build options.
+ *
+ * @return {Promise} A promise either fulfilled if package was built and ran
+ *   successfully, or rejected with CordovaError.
+ */
+Api.prototype.run = function(runOptions) {
+    var self = this;
+    return require('./lib/check_reqs').run()
+    .then(function () {
+        return require('./lib/run').run.call(self, runOptions);
+    });
+};
+
+/**
+ * Cleans out the build artifacts from platform's directory.
+ *
+ * @return  {Promise}  Return a promise either fulfilled, or rejected with
+ *   CordovaError.
+ */
+Api.prototype.clean = function(cleanOptions) {
+    var self = this;
+    return require('./lib/check_reqs').run()
+    .then(function () {
+        return require('./lib/build').runClean.call(self, cleanOptions);
+    });
+};
+
+/**
+ * Performs a requirements check for current platform. Each platform defines its
+ *   own set of requirements, which should be resolved before platform can be
+ *   built successfully.
+ *
+ * @return  {Promise<Requirement[]>}  Promise, resolved with set of Requirement
+ *   objects for current platform.
+ */
+Api.prototype.requirements = function() {
+    return require('./lib/check_reqs').check_all();
+};
+
+module.exports = Api;
+
+/**
+ * Removes the specified modules from list of installed modules and updates
+ *   platform_json and cordova_plugins.js on disk.
+ *
+ * @param   {PluginInfo}  plugin  PluginInfo instance for plugin, which modules
+ *   needs to be added.
+ * @param   {String}  targetDir  The directory, where updated cordova_plugins.js
+ *   should be written to.
+ */
+Api.prototype._addModulesInfo = function(plugin, targetDir) {
+    var installedModules = this._platformJson.root.modules || [];
+
+    var installedPaths = installedModules.map(function (installedModule) {
+        return installedModule.file;
+    });
+
+    var modulesToInstall = plugin.getJsModules(this.platform)
+    .filter(function (moduleToInstall) {
+        return installedPaths.indexOf(moduleToInstall.file) === -1;
+    }).map(function (moduleToInstall) {
+        var moduleName = plugin.id + '.' + ( moduleToInstall.name || moduleToInstall.src.match(/([^\/]+)\.js/)[1] );
+        var obj = {
+            file: ['plugins', plugin.id, moduleToInstall.src].join('/'),
+            id: moduleName
+        };
+        if (moduleToInstall.clobbers.length > 0) {
+            obj.clobbers = moduleToInstall.clobbers.map(function(o) { return o.target; });
+        }
+        if (moduleToInstall.merges.length > 0) {
+            obj.merges = moduleToInstall.merges.map(function(o) { return o.target; });
+        }
+        if (moduleToInstall.runs) {
+            obj.runs = true;
+        }
+
+        return obj;
+    });
+
+    this._platformJson.root.modules = installedModules.concat(modulesToInstall);
+    this._writePluginModules(targetDir);
+    this._platformJson.save();
+};
+
+/**
+ * Removes the specified modules from list of installed modules and updates
+ *   platform_json and cordova_plugins.js on disk.
+ *
+ * @param   {PluginInfo}  plugin  PluginInfo instance for plugin, which modules
+ *   needs to be removed.
+ * @param   {String}  targetDir  The directory, where updated cordova_plugins.js
+ *   should be written to.
+ */
+Api.prototype._removeModulesInfo = function(plugin, targetDir) {
+    var installedModules = this._platformJson.root.modules || [];
+    var modulesToRemove = plugin.getJsModules(this.platform)
+    .map(function (jsModule) {
+        return  ['plugins', plugin.id, jsModule.src].join('/');
+    });
+
+    var updatedModules = installedModules
+    .filter(function (installedModule) {
+        return (modulesToRemove.indexOf(installedModule.file) === -1);
+    });
+
+    this._platformJson.root.modules = updatedModules;
+    this._writePluginModules(targetDir);
+    this._platformJson.save();
+};
+
+/**
+ * Fetches all installed modules, generates cordova_plugins contents and writes
+ *   it to file.
+ *
+ * @param   {String}  targetDir  Directory, where write cordova_plugins.js to.
+ *   Ususally it is either <platform>/www or <platform>/platform_www
+ *   directories.
+ */
+Api.prototype._writePluginModules = function (targetDir) {
+    var self = this;
+    // Write out moduleObjects as JSON wrapped in a cordova module to cordova_plugins.js
+    var final_contents = 'cordova.define(\'cordova/plugin_list\', function(require, exports, module) {\n';
+    final_contents += 'module.exports = ' + JSON.stringify(this._platformJson.root.modules, null, '    ') + ';\n';
+    final_contents += 'module.exports.metadata = \n';
+    final_contents += '// TOP OF METADATA\n';
+
+    var pluginMetadata = Object.keys(this._platformJson.root.installed_plugins)
+    .reduce(function (metadata, plugin) {
+        metadata[plugin] = self._platformJson.root.installed_plugins[plugin].version;
+        return metadata;
+    }, {});
+
+    final_contents += JSON.stringify(pluginMetadata, null, 4) + '\n';
+    final_contents += '// BOTTOM OF METADATA\n';
+    final_contents += '});'; // Close cordova.define.
+
+    shell.mkdir('-p', targetDir);
+    fs.writeFileSync(path.join(targetDir, 'cordova_plugins.js'), final_contents, 'utf-8');
+};

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/40028228/bin/templates/cordova/build
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/build b/bin/templates/cordova/build
index 3c3aee4..da44783 100755
--- a/bin/templates/cordova/build
+++ b/bin/templates/cordova/build
@@ -19,23 +19,30 @@
        under the License.
 */
 
-var build = require('./lib/build'),
-    reqs  = require('./lib/check_reqs'),
-    args  = process.argv;
+var args  = process.argv;
+var Api = require('./Api');
+var nopt = require('nopt');
+var path = require('path');
 
 // 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 {
-    reqs.run().done(function() {
-        return build.run(args.slice(2));
-    }, function(err) {
-        console.error(err);
-        process.exit(2);
-    });
-}
+if(['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0)
+    require('./lib/build').help();
+
+// Do some basic argument parsing
+var buildOpts = nopt({
+    'verbose' : Boolean,
+    'silent' : Boolean,
+    'debug' : Boolean,
+    'release' : Boolean,
+    'nobuild': Boolean,
+    'buildConfig' : path
+}, { 'd' : '--verbose' });
+
+// Make buildOptions compatible with PlatformApi build method spec
+buildOpts.argv = buildOpts.argv.remain;
+
+new Api().build(buildOpts)
+.catch(function(err) {
+    console.error(err.stack);
+    process.exit(2);
+});

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/40028228/bin/templates/cordova/clean
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/clean b/bin/templates/cordova/clean
index d9a7d49..1f4a53d 100755
--- a/bin/templates/cordova/clean
+++ b/bin/templates/cordova/clean
@@ -19,26 +19,18 @@
        under the License.
 */
 
-var build = require('./lib/build'),
-    reqs  = require('./lib/check_reqs'),
-    args  = process.argv;
+var Api = require('./Api');
 var path  = require('path');
 
 // Support basic help commands
-if(args[2] == '--help' ||
-   args[2] == '/?' ||
-   args[2] == '-h' ||
-   args[2] == 'help' ||
-   args[2] == '-help' ||
-   args[2] == '/help') {
+if(['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
     console.log('Usage: ' + path.relative(process.cwd(), process.argv[1]));
     console.log('Cleans the project directory.');
     process.exit(0);
-} else {
-    reqs.run().done(function() {
-        return build.runClean(args.slice(2));
-    }, function(err) {
-        console.error(err);
-        process.exit(2);
-    });
 }
+
+new Api().clean({argv: process.argv.slice(2)})
+.catch(function(err) {
+    console.error(err.stack);
+    process.exit(2);
+});

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/40028228/bin/templates/cordova/lib/Adb.js
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/Adb.js b/bin/templates/cordova/lib/Adb.js
new file mode 100644
index 0000000..e4fc363
--- /dev/null
+++ b/bin/templates/cordova/lib/Adb.js
@@ -0,0 +1,78 @@
+
+var Q = require('q');
+var os = require('os');
+var events = require('cordova-common').events;
+var spawn = require('cordova-common').superspawn.spawn;
+var CordovaError = require('cordova-common').CordovaError;
+
+var Adb = {};
+
+function isDevice(line) {
+    return line.match(/\w+\tdevice/) && !line.match(/emulator/);
+}
+
+function isEmulator(line) {
+    return line.match(/device/) && line.match(/emulator/);
+}
+
+/**
+ * Lists available/connected devices and emulators
+ *
+ * @param   {Object}   opts            Various options
+ * @param   {Boolean}  opts.emulators  Specifies whether this method returns
+ *   emulators only
+ *
+ * @return  {Promise<String[]>}        list of available/connected
+ *   devices/emulators
+ */
+Adb.devices = function (opts) {
+    return spawn('adb', ['devices'], {cwd: os.tmpdir()})
+    .then(function(output) {
+        return output.split('\n').filter(function (line) {
+            // Filter out either real devices or emulators, depending on options
+            return (line && opts && opts.emulators) ? isEmulator(line) : isDevice(line);
+        }).map(function (line) {
+            return line.replace(/\tdevice/, '').replace('\r', '');
+        });
+    });
+};
+
+Adb.install = function (target, packagePath, opts) {
+    events.emit('verbose', 'Installing apk ' + packagePath + ' on ' + target + '...');
+    var args = ['-s', target, 'install'];
+    if (opts && opts.replace) args.push('-r');
+    return spawn('adb', args.concat(packagePath), {cwd: os.tmpdir()})
+    .then(function(output) {
+        // 'adb install' seems to always returns no error, even if installation fails
+        // so we catching output to detect installation failure
+        if (output.match(/Failure/))
+            return Q.reject(new CordovaError('Failed to install apk to device: ' + output));
+    });
+};
+
+Adb.uninstall = function (target, packageId) {
+    events.emit('verbose', 'Uninstalling ' + packageId + ' from ' + target + '...');
+    return spawn('adb', ['-s', target, 'uninstall', packageId], {cwd: os.tmpdir()});
+};
+
+Adb.shell = function (target, shellCommand) {
+    events.emit('verbose', 'Running command "' + shellCommand + '" on ' + target + '...');
+    var args = ['-s', target, 'shell'];
+    shellCommand = shellCommand.split(/\s+/);
+    return spawn('adb', args.concat(shellCommand), {cwd: os.tmpdir()})
+    .catch(function (output) {
+        return Q.reject(new CordovaError('Failed to execute shell command "' +
+            shellCommand + '"" on device: ' + output));
+    });
+};
+
+Adb.start = function (target, activityName) {
+    events.emit('verbose', 'Starting application "' + activityName + '" on ' + target + '...');
+    return Adb.shell(target, 'am start -W -a android.intent.action.MAIN -n' + activityName)
+    .catch(function (output) {
+        return Q.reject(new CordovaError('Failed to start application "' +
+            activityName + '"" on device: ' + output));
+    });
+};
+
+module.exports = Adb;

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/40028228/bin/templates/cordova/lib/AndroidManifest.js
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/AndroidManifest.js b/bin/templates/cordova/lib/AndroidManifest.js
new file mode 100644
index 0000000..770d527
--- /dev/null
+++ b/bin/templates/cordova/lib/AndroidManifest.js
@@ -0,0 +1,161 @@
+/**
+    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 fs = require('fs');
+var et = require('elementtree');
+var xml= require('cordova-common').xmlHelpers;
+
+var DEFAULT_ORIENTATION = 'default';
+
+/** Wraps an AndroidManifest file */
+function AndroidManifest(path) {
+    this.path = path;
+    this.doc = xml.parseElementtreeSync(path);
+    if (this.doc.getroot().tag !== 'manifest') {
+        throw new Error(path + ' has incorrect root node name (expected "manifest")');
+    }
+}
+
+AndroidManifest.prototype.getVersionName = function() {
+    return this.doc.getroot().attrib['android:versionName'];
+};
+
+AndroidManifest.prototype.setVersionName = function(versionName) {
+    this.doc.getroot().attrib['android:versionName'] = versionName;
+    return this;
+};
+
+AndroidManifest.prototype.getVersionCode = function() {
+    return this.doc.getroot().attrib['android:versionCode'];
+};
+
+AndroidManifest.prototype.setVersionCode = function(versionCode) {
+    this.doc.getroot().attrib['android:versionCode'] = versionCode;
+    return this;
+};
+
+AndroidManifest.prototype.getPackageId = function() {
+    /*jshint -W069 */
+    return this.doc.getroot().attrib['package'];
+    /*jshint +W069 */
+};
+
+AndroidManifest.prototype.setPackageId = function(pkgId) {
+    /*jshint -W069 */
+    this.doc.getroot().attrib['package'] = pkgId;
+    /*jshint +W069 */
+    return this;
+};
+
+AndroidManifest.prototype.getActivity = function() {
+    var activity = this.doc.getroot().find('./application/activity');
+    return {
+        getName: function () {
+            return activity.attrib['android:name'];
+        },
+        setName: function (name) {
+            if (!name) {
+                delete activity.attrib['android:name'];
+            } else {
+                activity.attrib['android:name'] = name;
+            }
+            return this;
+        },
+        getOrientation: function () {
+            return activity.attrib['android:screenOrientation'];
+        },
+        setOrientation: function (orientation) {
+            if (!orientation || orientation.toLowerCase() === DEFAULT_ORIENTATION) {
+                delete activity.attrib['android:screenOrientation'];
+            } else {
+                activity.attrib['android:screenOrientation'] = orientation;
+            }
+            return this;
+        },
+        getLaunchMode: function () {
+            return activity.attrib['android:launchMode'];
+        },
+        setLaunchMode: function (launchMode) {
+            if (!launchMode) {
+                delete activity.attrib['android:launchMode'];
+            } else {
+                activity.attrib['android:launchMode'] = launchMode;
+            }
+            return this;
+        }
+    };
+};
+
+['minSdkVersion', 'maxSdkVersion', 'targetSdkVersion']
+.forEach(function(sdkPrefName) {
+    // Copy variable reference to avoid closure issues
+    var prefName = sdkPrefName;
+
+    AndroidManifest.prototype['get' + capitalize(prefName)] = function() {
+        var usesSdk = this.doc.getroot().find('./uses-sdk');
+        return usesSdk && usesSdk.attrib['android:' + prefName];
+    };
+
+    AndroidManifest.prototype['set' + capitalize(prefName)] = function(prefValue) {
+        var usesSdk = this.doc.getroot().find('./uses-sdk');
+
+        if (!usesSdk && prefValue) { // if there is no required uses-sdk element, we should create it first
+            usesSdk = new et.Element('uses-sdk');
+            this.doc.getroot().append(usesSdk);
+        }
+
+        if (prefValue) {
+            usesSdk.attrib['android:' + prefName] = prefValue;
+        }
+
+        return this;
+    };
+});
+
+AndroidManifest.prototype.getDebuggable = function() {
+    return this.doc.getroot().find('./application').attrib['android:debuggable'] === 'true';
+};
+
+AndroidManifest.prototype.setDebuggable = function(value) {
+    var application = this.doc.getroot().find('./application');
+    if (value) {
+        application.attrib['android:debuggable'] = 'true';
+    } else {
+        // The default value is "false", so we can remove attribute at all.
+        delete application.attrib['android:debuggable'];
+    }
+    return this;
+};
+
+/**
+ * Writes manifest to disk syncronously. If filename is specified, then manifest
+ *   will be written to that file
+ *
+ * @param   {String}  [destPath]  File to write manifest to. If omitted,
+ *   manifest will be written to file it has been read from.
+ */
+AndroidManifest.prototype.write = function(destPath) {
+    fs.writeFileSync(destPath || this.path, this.doc.write({indent: 4}), 'utf-8');
+};
+
+module.exports = AndroidManifest;
+
+function capitalize (str) {
+    return str.charAt(0).toUpperCase() + str.slice(1);
+}

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/40028228/bin/templates/cordova/lib/AndroidProject.js
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/AndroidProject.js b/bin/templates/cordova/lib/AndroidProject.js
new file mode 100644
index 0000000..918a39b
--- /dev/null
+++ b/bin/templates/cordova/lib/AndroidProject.js
@@ -0,0 +1,184 @@
+/**
+    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 fs = require('fs');
+var path = require('path');
+var properties_parser = require('properties-parser');
+var AndroidManifest = require('./AndroidManifest');
+
+var projectFileCache = {};
+
+function addToPropertyList(projectProperties, key, value) {
+    var i = 1;
+    while (projectProperties.get(key + '.' + i))
+        i++;
+
+    projectProperties.set(key + '.' + i, value);
+    projectProperties.dirty = true;
+}
+
+function removeFromPropertyList(projectProperties, key, value) {
+    var i = 1;
+    var currentValue;
+    while ((currentValue = projectProperties.get(key + '.' + i))) {
+        if (currentValue === value) {
+            while ((currentValue = projectProperties.get(key + '.' + (i + 1)))) {
+                projectProperties.set(key + '.' + i, currentValue);
+                i++;
+            }
+            projectProperties.set(key + '.' + i);
+            break;
+        }
+        i++;
+    }
+    projectProperties.dirty = true;
+}
+
+function getRelativeLibraryPath (parentDir, subDir) {
+    var libraryPath = path.relative(parentDir, subDir);
+    return (path.sep == '\\') ? libraryPath.replace(/\\/g, '/') : libraryPath;
+}
+
+function AndroidProject(projectDir) {
+    this._propertiesEditors = {};
+    this._subProjectDirs = {};
+    this._dirty = false;
+    this.projectDir = projectDir;
+    this.platformWww = path.join(this.projectDir, 'platform_www');
+    this.www = path.join(this.projectDir, 'assets/www');
+}
+
+AndroidProject.getProjectFile = function (projectDir) {
+    if (!projectFileCache[projectDir]) {
+        projectFileCache[projectDir] = new AndroidProject(projectDir);
+    }
+
+    return projectFileCache[projectDir];
+};
+
+AndroidProject.purgeCache = function (projectDir) {
+    if (projectDir) {
+        delete projectFileCache[projectDir];
+    } else {
+        projectFileCache = {};
+    }
+};
+
+/**
+ * Reads the package name out of the Android Manifest file
+ *
+ * @param   {String}  projectDir  The absolute path to the directory containing the project
+ *
+ * @return  {String}              The name of the package
+ */
+AndroidProject.prototype.getPackageName = function() {
+    return new AndroidManifest(path.join(this.projectDir, 'AndroidManifest.xml')).getPackageId();
+};
+
+AndroidProject.prototype.getCustomSubprojectRelativeDir = function(plugin_id, src) {
+    // All custom subprojects are prefixed with the last portion of the package id.
+    // This is to avoid collisions when opening multiple projects in Eclipse that have subprojects with the same name.
+    var packageName = this.getPackageName();
+    var lastDotIndex = packageName.lastIndexOf('.');
+    var prefix = packageName.substring(lastDotIndex + 1);
+    var subRelativeDir = path.join(plugin_id, prefix + '-' + path.basename(src));
+    return subRelativeDir;
+};
+
+AndroidProject.prototype.addSubProject = function(parentDir, subDir) {
+    var parentProjectFile = path.resolve(parentDir, 'project.properties');
+    var subProjectFile = path.resolve(subDir, 'project.properties');
+    var parentProperties = this._getPropertiesFile(parentProjectFile);
+    // TODO: Setting the target needs to happen only for pre-3.7.0 projects
+    if (fs.existsSync(subProjectFile)) {
+        var subProperties = this._getPropertiesFile(subProjectFile);
+        subProperties.set('target', parentProperties.get('target'));
+        subProperties.dirty = true;
+        this._subProjectDirs[subDir] = true;
+    }
+    addToPropertyList(parentProperties, 'android.library.reference', getRelativeLibraryPath(parentDir, subDir));
+
+    this._dirty = true;
+};
+
+AndroidProject.prototype.removeSubProject = function(parentDir, subDir) {
+    var parentProjectFile = path.resolve(parentDir, 'project.properties');
+    var parentProperties = this._getPropertiesFile(parentProjectFile);
+    removeFromPropertyList(parentProperties, 'android.library.reference', getRelativeLibraryPath(parentDir, subDir));
+    delete this._subProjectDirs[subDir];
+    this._dirty = true;
+};
+
+AndroidProject.prototype.addGradleReference = function(parentDir, subDir) {
+    var parentProjectFile = path.resolve(parentDir, 'project.properties');
+    var parentProperties = this._getPropertiesFile(parentProjectFile);
+    addToPropertyList(parentProperties, 'cordova.gradle.include', getRelativeLibraryPath(parentDir, subDir));
+    this._dirty = true;
+};
+
+AndroidProject.prototype.removeGradleReference = function(parentDir, subDir) {
+    var parentProjectFile = path.resolve(parentDir, 'project.properties');
+    var parentProperties = this._getPropertiesFile(parentProjectFile);
+    removeFromPropertyList(parentProperties, 'cordova.gradle.include', getRelativeLibraryPath(parentDir, subDir));
+    this._dirty = true;
+};
+
+AndroidProject.prototype.addSystemLibrary = function(parentDir, value) {
+    var parentProjectFile = path.resolve(parentDir, 'project.properties');
+    var parentProperties = this._getPropertiesFile(parentProjectFile);
+    addToPropertyList(parentProperties, 'cordova.system.library', value);
+    this._dirty = true;
+};
+
+AndroidProject.prototype.removeSystemLibrary = function(parentDir, value) {
+    var parentProjectFile = path.resolve(parentDir, 'project.properties');
+    var parentProperties = this._getPropertiesFile(parentProjectFile);
+    removeFromPropertyList(parentProperties, 'cordova.system.library', value);
+    this._dirty = true;
+};
+
+AndroidProject.prototype.write = function() {
+    if (!this._dirty) {
+        return;
+    }
+    this._dirty = false;
+
+    for (var filename in this._propertiesEditors) {
+        var editor = this._propertiesEditors[filename];
+        if (editor.dirty) {
+            fs.writeFileSync(filename, editor.toString());
+            editor.dirty = false;
+        }
+    }
+};
+
+AndroidProject.prototype._getPropertiesFile = function (filename) {
+    if (!this._propertiesEditors[filename]) {
+        if (fs.existsSync(filename)) {
+            this._propertiesEditors[filename] = properties_parser.createEditor(filename);
+        } else {
+            this._propertiesEditors[filename] = properties_parser.createEditor();
+        }
+    }
+
+    return this._propertiesEditors[filename];
+};
+
+
+module.exports = AndroidProject;

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/40028228/bin/templates/cordova/lib/ConsoleLogger.js
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/ConsoleLogger.js b/bin/templates/cordova/lib/ConsoleLogger.js
new file mode 100644
index 0000000..19b03ec
--- /dev/null
+++ b/bin/templates/cordova/lib/ConsoleLogger.js
@@ -0,0 +1,75 @@
+/**
+    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 loggerInstance;
+var util = require('util');
+var EventEmitter = require('events').EventEmitter;
+var CordovaError = require('cordova-common').CordovaError;
+
+/**
+ * @class ConsoleLogger
+ * @extends EventEmitter
+ *
+ * Implementing basic logging for platform. Inherits regular NodeJS
+ *   EventEmitter. All events, emitted on this class instance are immediately
+ *   logged to console.
+ *
+ * Also attaches handler to process' uncaught exceptions, so these exceptions
+ *   logged to console similar to regular error events.
+ */
+function ConsoleLogger() {
+    EventEmitter.call(this);
+
+    var isVerbose = process.argv.indexOf('-d') >= 0 || process.argv.indexOf('--verbose') >= 0;
+    // For CordovaError print only the message without stack trace unless we
+    // are in a verbose mode.
+    process.on('uncaughtException', function(err){
+        if ((err instanceof CordovaError) && isVerbose) {
+            console.error(err.stack);
+        } else {
+            console.error(err.message);
+        }
+        process.exit(1);
+    });
+
+    this.on('results', console.log);
+    this.on('verbose', function () {
+        if (isVerbose)
+            console.log.apply(console, arguments);
+    });
+    this.on('info', console.log);
+    this.on('log', console.log);
+    this.on('warn', console.warn);
+}
+util.inherits(ConsoleLogger, EventEmitter);
+
+/**
+ * Returns already instantiated/newly created instance of ConsoleLogger class.
+ *   This method should be used instead of creating ConsoleLogger directly,
+ *   otherwise we'll get multiple handlers attached to process'
+ *   uncaughtException
+ *
+ * @return  {ConsoleLogger}  New or already created instance of ConsoleLogger
+ */
+ConsoleLogger.get = function () {
+    loggerInstance = loggerInstance || new ConsoleLogger();
+    return loggerInstance;
+};
+
+module.exports = ConsoleLogger;

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/40028228/bin/templates/cordova/lib/appinfo.js
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/appinfo.js b/bin/templates/cordova/lib/appinfo.js
deleted file mode 100644
index e37b89b..0000000
--- a/bin/templates/cordova/lib/appinfo.js
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env node
-
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/
-
-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 (cachedAppInfo = {
-        packageName: packageName[1],
-        activityName: packageName[1] + '/.' + activityName[1]
-    });
-}
-
-exports.getActivityName = function() {
-    return cachedAppInfo ? cachedAppInfo.activityName : readAppInfoFromManifest().activityName;
-};
-
-exports.getPackageName = function() {
-    return cachedAppInfo ? cachedAppInfo.packageName : readAppInfoFromManifest().packageName;
-};


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