npm version 2.8.5. [CB-3612] added run command. Cleaned up some tests ,removed some duplicate specs, added run specs. Updated help documentation. Updated commands invoked by cordova-cli (compile->./cordova/build, emulate->./cordova/emulate)
Project: http://git-wip-us.apache.org/repos/asf/cordova-cli/repo Commit: http://git-wip-us.apache.org/repos/asf/cordova-cli/commit/05196b36 Tree: http://git-wip-us.apache.org/repos/asf/cordova-cli/tree/05196b36 Diff: http://git-wip-us.apache.org/repos/asf/cordova-cli/diff/05196b36 Branch: refs/heads/2.8.x Commit: 05196b3671422b6d917fcc0ea68d6ae209250bd1 Parents: 1a40e10 Author: Fil Maj <[email protected]> Authored: Wed Jun 5 11:54:31 2013 -0700 Committer: Fil Maj <[email protected]> Committed: Thu Jun 6 18:29:03 2013 -0700 ---------------------------------------------------------------------- bin/cordova | 2 +- cordova.js | 2 + doc/help.txt | 27 +++-- package.json | 2 +- spec/cordova-cli/compile.spec.js | 74 +++++------ spec/cordova-cli/create.spec.js | 2 + spec/cordova-cli/emulate.spec.js | 57 +++++---- spec/cordova-cli/run.spec.js | 138 +++++++++++++++++++++ spec/platform-script/android/android.spec.js | 10 -- spec/platform-script/ios/ios.spec.js | 10 -- src/compile.js | 13 +-- src/create.js | 2 + src/emulate.js | 6 +- src/run.js | 101 +++++++++++++++ 14 files changed, 332 insertions(+), 114 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/05196b36/bin/cordova ---------------------------------------------------------------------- diff --git a/bin/cordova b/bin/cordova index 941f461..17b3569 100755 --- a/bin/cordova +++ b/bin/cordova @@ -33,7 +33,7 @@ if (version) { var r; if (cmd == 'create' || cmd == 'docs' || cmd == 'serve') { r = cordova[cmd].apply(this, opts); - } else if (cmd == 'emulate' || cmd == 'build' || cmd == 'prepare' || cmd == 'compile') { + } else if (cmd == 'emulate' || cmd == 'build' || cmd == 'prepare' || cmd == 'compile' || cmd == 'run') { r = cordova[cmd].call(this, opts); } else { // platform or plugin cmds http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/05196b36/cordova.js ---------------------------------------------------------------------- diff --git a/cordova.js b/cordova.js index 73d3a64..efdc4b2 100644 --- a/cordova.js +++ b/cordova.js @@ -19,6 +19,7 @@ var cordova_events = require('./src/events'), prepare = require('./src/prepare'), platform = require('./src/platform'), + run = require('./src/run'), hooker = require('./src/hooker'), util = require('./src/util'), path = require('path'), @@ -40,6 +41,7 @@ module.exports = { platforms: platform, prepare: prepare, compile: compile, + run: run, emulate: require('./src/emulate'), plugin: require('./src/plugin'), plugins: require('./src/plugin'), http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/05196b36/doc/help.txt ---------------------------------------------------------------------- diff --git a/doc/help.txt b/doc/help.txt index fea484c..73510d0 100644 --- a/doc/help.txt +++ b/doc/help.txt @@ -5,23 +5,30 @@ Synopsis Global Commands create [path] [id] [name] ......... creates a cordova project in the specified directory optional name and id (package name, reverse-domain style) - -v ................................ prints out this utility's version Project-Level Commands platform(s) [add|remove|ls [name]] ... adds or removes a platform, or lists all currently-added platforms plugin(s) [add|remove|ls [path]] ..... adds or removes a plugin (from the specified path), or lists all currently-added plugins - prepare [platform...] ............. copies files into the specified platforms, or all platforms. - it is then ready for building by Eclipse/Xcode/etc. - compile [platform...] ............. builds the app for the specified (or all) platforms - build ............................. alias for prepare and then compile - emulate ........................... starts emulator for cordova project - serve <platform> [port] ........... runs a local web server for the www/ directory of the given platform + prepare [platform...] ................ copies files into the specified platforms, or all platforms + it is then ready for building by Eclipse/Xcode/etc + compile [platform...] ................ builds the app for the specified (or all) platforms + build [platform...]................... alias for prepare and then compile + emulate [platform...] ................ starts emulator for the specified (or all) platforms, then deploys application to emulator + run [platform...] .................... deployes the application to the specified (or all) platform devices, which must be + connected and configured for running via your machine + serve <platform> [port] .............. runs a local web server for the www/ directory of the given platform the default port is 8000 note that you must edit the native code to point at the server! - ripple <platform> [port] .......... uses the serve command as a base and then wraps the server - with ripple to test your app in your desktop browser. - help .............................. shows this! + ripple <platform> [port] ............. uses the serve command as a base and then wraps the server + with ripple to test your app in your desktop browser + help ................................. shows this! + +Command-line Flags/Options + + -v, --version ......................... prints out this utility's version + -d, --verbose ......................... debug, or verbose, mode. Makes this utility very chatty, logging everything it does, including + redirecting output of commands it shells out to back to stdout Example usage http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/05196b36/package.json ---------------------------------------------------------------------- diff --git a/package.json b/package.json index 82db18f..f3d386c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cordova", - "version": "2.8.4", + "version": "2.8.5", "preferGlobal": "true", "description": "Cordova command line interface tool", "main": "cordova", http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/05196b36/spec/cordova-cli/compile.spec.js ---------------------------------------------------------------------- diff --git a/spec/cordova-cli/compile.spec.js b/spec/cordova-cli/compile.spec.js index 814d2ab..bd7dc42 100644 --- a/spec/cordova-cli/compile.spec.js +++ b/spec/cordova-cli/compile.spec.js @@ -35,53 +35,49 @@ describe('compile command', function() { shell.mkdir('-p', tempDir); }); - it('should not run inside a Cordova-based project with no added platforms', function() { - this.after(function() { + describe('failure', function() { + afterEach(function() { process.chdir(cwd); + spyOn(shell, 'exec'); }); - - cordova.create(tempDir); - process.chdir(tempDir); - expect(function() { - cordova.compile(); - }).toThrow(); - }); - - it('should run inside a Cordova-based project with at least one added platform', function() { - // move platform project fixtures over to fake cordova into thinking platforms were added - // TODO: possibly add this to helper? - // Just make a folder instead of moving the whole platform? - shell.mkdir('-p', tempDir); - shell.mv('-f', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir)); - this.after(function() { - process.chdir(cwd); - shell.mv('-f', path.join(tempDir, 'android'), path.join(cordova_project, 'platforms', 'android')); + it('should not run inside a Cordova-based project with no added platforms', function() { + cordova.create(tempDir); + process.chdir(tempDir); + expect(function() { + cordova.compile(); + }).toThrow(); + }); + it('should not run outside of a Cordova-based project', function() { + shell.mkdir('-p', tempDir); + process.chdir(tempDir); + expect(function() { + cordova.compile(); + }).toThrow(); }); - - process.chdir(cordova_project); - - var sh_spy = spyOn(shell, 'exec'); - - expect(function() { - cordova.compile(); - expect(sh_spy).toHaveBeenCalled(); - }).not.toThrow(); }); - it('should not run outside of a Cordova-based project', function() { - this.after(function() { + + describe('success', function() { + beforeEach(function() { + cordova.create(tempDir); + shell.cp('-Rf', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir, 'platforms')); + process.chdir(tempDir); + }); + afterEach(function() { process.chdir(cwd); }); + it('should run inside a Cordova-based project with at least one added platform', function() { + // move platform project fixtures over to fake cordova into thinking platforms were added + // TODO: possibly add this to helper? + var sh_spy = spyOn(shell, 'exec'); - shell.mkdir('-p', tempDir); - process.chdir(tempDir); - - // we don't actually want it building the project (if it does somehow exist) - var sh_spy = spyOn(shell, 'exec'); - - expect(function() { - cordova.compile(); - }).toThrow(); + expect(function() { + cordova.compile(); + expect(sh_spy).toHaveBeenCalled(); + expect(sh_spy.mostRecentCall.args[0]).toMatch(/cordova.build"$/gi); + }).not.toThrow(); + }); }); + /* Is this a repeat of the util.spec.js test? */ it('should not treat a .gitignore file as a platform', function() { var gitignore = path.join(cordova_project, 'platforms', '.gitignore'); http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/05196b36/spec/cordova-cli/create.spec.js ---------------------------------------------------------------------- diff --git a/spec/cordova-cli/create.spec.js b/spec/cordova-cli/create.spec.js index 8a31ed6..4dad502 100644 --- a/spec/cordova-cli/create.spec.js +++ b/spec/cordova-cli/create.spec.js @@ -42,6 +42,8 @@ describe('create command', function () { expect(fs.existsSync(path.join(hooks, 'after_emulate'))).toBe(true); expect(fs.existsSync(path.join(hooks, 'before_docs'))).toBe(true); expect(fs.existsSync(path.join(hooks, 'after_docs'))).toBe(true); + expect(fs.existsSync(path.join(hooks, 'before_run'))).toBe(true); + expect(fs.existsSync(path.join(hooks, 'after_run'))).toBe(true); }); it('should throw if the directory is already a cordova project', function() { shell.mkdir('-p', path.join(tempDir, '.cordova')); http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/05196b36/spec/cordova-cli/emulate.spec.js ---------------------------------------------------------------------- diff --git a/spec/cordova-cli/emulate.spec.js b/spec/cordova-cli/emulate.spec.js index a3e5136..64464cb 100644 --- a/spec/cordova-cli/emulate.spec.js +++ b/spec/cordova-cli/emulate.spec.js @@ -37,43 +37,44 @@ describe('emulate command', function() { cordova.create(tempDir); }); - it('should not run inside a Cordova-based project with no added platforms', function() { - this.after(function() { + describe('failure', function() { + afterEach(function() { process.chdir(cwd); }); + it('should not run inside a Cordova-based project with no added platforms', function() { + process.chdir(tempDir); + expect(function() { + cordova.emulate(); + }).toThrow(); + }); + it('should not run outside of a Cordova-based project', function() { + shell.mkdir('-p', tempDir); + process.chdir(tempDir); - process.chdir(tempDir); - expect(function() { - cordova.emulate(); - }).toThrow(); - }); - - it('should run inside a Cordova-based project with at least one added platform', function() { - this.after(function() { - process.chdir(cwd); + expect(function() { + cordova.emulate(); + }).toThrow(); }); + }); - var s = spyOn(shell, 'exec'); - var a_spy = spyOn(android_parser.prototype, 'update_project'); - expect(function() { + describe('success', function() { + beforeEach(function() { shell.cp('-Rf', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir, 'platforms')); process.chdir(tempDir); - cordova.emulate(); - a_spy.mostRecentCall.args[1](); // fake out android parser - expect(s).toHaveBeenCalled(); - }).not.toThrow(); - }); - it('should not run outside of a Cordova-based project', function() { - this.after(function() { + }); + afterEach(function() { process.chdir(cwd); }); - - shell.mkdir('-p', tempDir); - process.chdir(tempDir); - - expect(function() { - cordova.emulate(); - }).toThrow(); + it('should run inside a Cordova-based project with at least one added platform', function() { + var s = spyOn(shell, 'exec'); + var a_spy = spyOn(android_parser.prototype, 'update_project'); + expect(function() { + cordova.emulate(); + a_spy.mostRecentCall.args[1](); // fake out android parser + expect(s).toHaveBeenCalled(); + expect(s.mostRecentCall.args[0]).toMatch(/cordova.emulate"$/gi); + }).not.toThrow(); + }); }); describe('hooks', function() { http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/05196b36/spec/cordova-cli/run.spec.js ---------------------------------------------------------------------- diff --git a/spec/cordova-cli/run.spec.js b/spec/cordova-cli/run.spec.js new file mode 100644 index 0000000..fb4da30 --- /dev/null +++ b/spec/cordova-cli/run.spec.js @@ -0,0 +1,138 @@ +/** + 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 cordova = require('../../cordova'), + et = require('elementtree'), + shell = require('shelljs'), + path = require('path'), + fs = require('fs'), + config_parser = require('../../src/config_parser'), + android_parser = require('../../src/metadata/android_parser'), + hooker = require('../../src/hooker'), + fixtures = path.join(__dirname, '..', 'fixtures'), + hooks = path.join(fixtures, 'hooks'), + tempDir = path.join(__dirname, '..', '..', 'temp'), + cordova_project = path.join(fixtures, 'projects', 'cordova'); + +var cwd = process.cwd(); + +describe('run command', function() { + beforeEach(function() { + shell.rm('-rf', tempDir); + cordova.create(tempDir); + }); + + describe('failure', function() { + afterEach(function() { + process.chdir(cwd); + }); + it('should not run inside a Cordova-based project with no added platforms', function() { + process.chdir(tempDir); + expect(function() { + cordova.run(); + }).toThrow(); + }); + it('should not run outside of a Cordova-based project', function() { + shell.mkdir('-p', tempDir); + process.chdir(tempDir); + + expect(function() { + cordova.run(); + }).toThrow(); + }); + }); + + describe('success', function() { + beforeEach(function() { + shell.cp('-Rf', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir, 'platforms')); + process.chdir(tempDir); + }); + afterEach(function() { + process.chdir(cwd); + }); + it('should invoke prepare', function() { + var spy = spyOn(cordova, 'prepare'); + spyOn(shell, 'exec'); + cordova.run(); + expect(spy).toHaveBeenCalled(); + }); + it('should shell out to underlying `run` platform-level scripts', function(done) { + spyOn(cordova, 'prepare').andCallFake(function(platforms, callback) { + callback(false); + }); + var spy = spyOn(shell, 'exec').andCallFake(function(cmd, options, cb) { + cb(0, 'yep'); + }); + cordova.run('android', function() { + expect(spy.mostRecentCall.args[0]).toMatch(/cordova.run"$/gi); + done(); + }); + }); + }); + + + describe('hooks', function() { + var s; + beforeEach(function() { + s = spyOn(hooker.prototype, 'fire').andReturn(true); + }); + + describe('when platforms are added', function() { + beforeEach(function() { + shell.cp('-Rf', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir, 'platforms')); + process.chdir(tempDir); + }); + afterEach(function() { + process.chdir(cwd); + }); + + it('should fire before hooks through the hooker module', function() { + + spyOn(shell, 'exec'); + cordova.run(); + expect(hooker.prototype.fire).toHaveBeenCalledWith('before_run'); + }); + it('should fire after hooks through the hooker module', function(done) { + spyOn(shell, 'exec').andCallFake(function(cmd, options, callback) { + callback(0, 'fucking eh'); + }); + cordova.run('android', function() { + expect(hooker.prototype.fire).toHaveBeenCalledWith('after_run'); + done(); + }); + }); + }); + + describe('with no platforms added', function() { + beforeEach(function() { + process.chdir(tempDir); + }); + afterEach(function() { + process.chdir(cwd); + }); + it('should not fire the hooker', function() { + spyOn(shell, 'exec'); + expect(function() { + cordova.run(); + }).toThrow(); + expect(s).not.toHaveBeenCalledWith('before_run'); + expect(s).not.toHaveBeenCalledWith('after_run'); + }); + }); + }); +}); http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/05196b36/spec/platform-script/android/android.spec.js ---------------------------------------------------------------------- diff --git a/spec/platform-script/android/android.spec.js b/spec/platform-script/android/android.spec.js index 2433c0a..8890276 100644 --- a/spec/platform-script/android/android.spec.js +++ b/spec/platform-script/android/android.spec.js @@ -61,16 +61,6 @@ describe('Test:', function() { shell.rm('-rf', tempDir); cordova.create(tempDir); shell.cp('-rf', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir, 'platforms')); - it('should shell out to run command on Android', function() { - var proj_spy = spyOn(android_parser.prototype, 'update_project'); - var s = spyOn(require('shelljs'), 'exec'); - spyOn(require('plugman'), 'prepare'); - cordova.emulate('android'); - proj_spy.mostRecentCall.args[1](); // update_project fake - expect(s).toHaveBeenCalled(); - var emulate_cmd = path.join('android', 'cordova', 'run'); - expect(s.mostRecentCall.args[0]).toContain(emulate_cmd); - }); it('should call android_parser\'s update_project', function() { spyOn(require('shelljs'), 'exec'); spyOn(android_parser.prototype, 'update_project'); http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/05196b36/spec/platform-script/ios/ios.spec.js ---------------------------------------------------------------------- diff --git a/spec/platform-script/ios/ios.spec.js b/spec/platform-script/ios/ios.spec.js index 04ae4bf..2723b83 100644 --- a/spec/platform-script/ios/ios.spec.js +++ b/spec/platform-script/ios/ios.spec.js @@ -62,16 +62,6 @@ describe('Test:', function() { shell.rm('-rf', tempDir); cordova.create(tempDir); shell.cp('-rf', path.join(cordova_project, 'platforms', 'ios'), path.join(tempDir, 'platforms')); - it('should shell out to run command on ios', function() { - var proj_spy = spyOn(ios_parser.prototype, 'update_project'); - var s = spyOn(require('shelljs'), 'exec'); - spyOn(require('plugman'), 'prepare'); - cordova.emulate('ios'); - proj_spy.mostRecentCall.args[1](); // update_project fake - expect(s).toHaveBeenCalled(); - var emulate_cmd = path.join('ios', 'cordova', 'run'); - expect(s.mostRecentCall.args[0]).toContain(emulate_cmd); - }); it('should call ios_parser\'s update_project', function() { spyOn(require('shelljs'), 'exec'); spyOn(ios_parser.prototype, 'update_project'); http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/05196b36/src/compile.js ---------------------------------------------------------------------- diff --git a/src/compile.js b/src/compile.js index 1f550f8..8d9d217 100644 --- a/src/compile.js +++ b/src/compile.js @@ -27,15 +27,8 @@ var cordova_util = require('./util'), n = require('ncallbacks'); -function shell_out_to_debug(projectRoot, platform, callback) { - var cmd = path.join(projectRoot, 'platforms', platform); - // TODO: this is bb10 only for now - // TODO: PLATFORM LIBRARY INCONSISTENCY - if (platform == 'blackberry') { - cmd = 'ant -f "' + path.join(cmd, 'build.xml') + '" qnx load-device'; - } else { - cmd = '"' + path.join(cmd, 'cordova', 'build') + '"'; - } +function shell_out_to_build(projectRoot, platform, callback) { + var cmd = '"' + path.join(projectRoot, 'platforms', platform, 'cordova', 'build') + '"'; events.emit('log', 'Compiling platform "' + platform + '" with command "' + cmd + '" (output to follow)...'); shell.exec(cmd, {silent:true, async:true}, function(code, output) { events.emit('log', output); @@ -96,6 +89,6 @@ module.exports = function compile(platformList, callback) { // Iterate over each added platform platformList.forEach(function(platform) { - shell_out_to_debug(projectRoot, platform, end); + shell_out_to_build(projectRoot, platform, end); }); }; http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/05196b36/src/create.js ---------------------------------------------------------------------- diff --git a/src/create.js b/src/create.js index 5cced50..be9966c 100644 --- a/src/create.js +++ b/src/create.js @@ -78,6 +78,7 @@ module.exports = function create (dir, id, name) { shell.mkdir(path.join(hooks, 'after_plugin_ls')); shell.mkdir(path.join(hooks, 'after_plugin_rm')); shell.mkdir(path.join(hooks, 'after_prepare')); + shell.mkdir(path.join(hooks, 'after_run')); shell.mkdir(path.join(hooks, 'before_build')); shell.mkdir(path.join(hooks, 'before_compile')); shell.mkdir(path.join(hooks, 'before_docs')); @@ -89,6 +90,7 @@ module.exports = function create (dir, id, name) { shell.mkdir(path.join(hooks, 'before_plugin_ls')); shell.mkdir(path.join(hooks, 'before_plugin_rm')); shell.mkdir(path.join(hooks, 'before_prepare')); + shell.mkdir(path.join(hooks, 'before_run')); // Write out .cordova/config.json file with a simple json manifest fs.writeFileSync(path.join(dotCordova, 'config.json'), JSON.stringify({ http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/05196b36/src/emulate.js ---------------------------------------------------------------------- diff --git a/src/emulate.js b/src/emulate.js index 9ccfc0b..9dd8857 100644 --- a/src/emulate.js +++ b/src/emulate.js @@ -31,11 +31,7 @@ var cordova_util = require('./util'), util = require('util'); function shell_out_to_emulate(root, platform, callback) { - var cmd = '"' + path.join(root, 'platforms', platform, 'cordova', 'run') + '"'; - // TODO: PLATFORM LIBRARY INCONSISTENCY - if (platform == 'blackberry') { - cmd = 'ant -f "' + path.join(root, 'platforms', platform, 'build.xml') + '" qnx load-simulator'; - } + var cmd = '"' + path.join(root, 'platforms', platform, 'cordova', 'emulate') + '"'; events.emit('log', 'Running on emulator for platform "' + platform + '" via command "' + cmd + '" (output to follow)...'); shell.exec(cmd, {silent:true, async:true}, function(code, output) { events.emit('log', output); http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/05196b36/src/run.js ---------------------------------------------------------------------- diff --git a/src/run.js b/src/run.js new file mode 100644 index 0000000..c13e4ab --- /dev/null +++ b/src/run.js @@ -0,0 +1,101 @@ +/** + 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 cordova_util = require('./util'), + path = require('path'), + config_parser = require('./config_parser'), + fs = require('fs'), + shell = require('shelljs'), + et = require('elementtree'), + hooker = require('./hooker'), + events = require('./events'), + n = require('ncallbacks'); + +function shell_out_to_run(projectRoot, platform, callback) { + var cmd = '"' + path.join(projectRoot, 'platforms', platform, 'cordova', 'run') + '"'; + + events.emit('log', 'Running app on platform "' + platform + '" with command "' + cmd + '" (output to follow)...'); + shell.exec(cmd, {silent:true, async:true}, function(code, output) { + events.emit('log', output); + if (code > 0) { + throw new Error('An error occurred while running the ' + platform + ' project. ' + output); + } else { + events.emit('log', 'Platform "' + platform + '" ran successfully.'); + if (callback) callback(); + } + }); +} + +module.exports = function run(platformList, callback) { + var projectRoot = cordova_util.isCordova(process.cwd()); + + if (!projectRoot) { + var err = new Error('Current working directory is not a Cordova-based project.'); + if (callback) callback(err); + else throw err; + return; + } + + var xml = cordova_util.projectConfig(projectRoot); + var cfg = new config_parser(xml); + + if (arguments.length === 0 || (platformList instanceof Array && platformList.length === 0)) { + platformList = cordova_util.listPlatforms(projectRoot); + } else if (typeof platformList == 'string') platformList = [platformList]; + else if (platformList instanceof Function && callback === undefined) { + callback = platformList; + platformList = cordova_util.listPlatforms(projectRoot); + } + + if (platformList.length === 0) { + var err = new Error('No platforms added to this project. Please use `cordova platform add <platform>`.'); + if (callback) callback(err); + else throw err; + return; + } + + var hooks = new hooker(projectRoot); + if (!(hooks.fire('before_run'))) { + var err = new Error('before_run hooks exited with non-zero code. Aborting.'); + if (callback) callback(err); + else throw err; + return; + } + + var end = n(platformList.length, function() { + if (!(hooks.fire('after_run'))) { + var err = new Error('after_run hooks exited with non-zero code. Aborting.'); + if (callback) callback(err); + else throw err; + return; + } + if (callback) callback(); + }); + + // Run a prepare first, then shell out to run + require('../cordova').prepare(platformList, function(err) { + if (err) { + if (callback) callback(err); + else throw err; + } else { + platformList.forEach(function(platform) { + shell_out_to_run(projectRoot, platform, end); + }); + } + }); +};
