better handling of cli params. closes #30.
Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/commit/71ab56a4 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/tree/71ab56a4 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/diff/71ab56a4 Branch: refs/heads/cordova-client Commit: 71ab56a4f01d0b343ec49b8b262c20d9af7310d0 Parents: 0d4c2f9 Author: Fil Maj <maj....@gmail.com> Authored: Tue Oct 9 16:10:56 2012 -0700 Committer: Fil Maj <maj....@gmail.com> Committed: Tue Oct 9 16:10:56 2012 -0700 ---------------------------------------------------------------------- bin/cordova | 46 +++++++--- spec/build.spec.js | 12 +-- spec/cli.spec.js | 217 ++++++++++++++++++++++++++++++++++++++++++++++- src/build.js | 22 ++--- src/emulate.js | 22 ++--- src/platform.js | 4 +- 6 files changed, 264 insertions(+), 59 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/blob/71ab56a4/bin/cordova ---------------------------------------------------------------------- diff --git a/bin/cordova b/bin/cordova index dd0156e..6e42147 100755 --- a/bin/cordova +++ b/bin/cordova @@ -1,7 +1,6 @@ #!/usr/bin/env node -var cordova = require('./../cordova') -, cmd = process.argv[2] -, opts = process.argv.slice(3, process.argv.length) +var cordova = require('./../cordova'), + tokens = process.argv.slice(2, process.argv.length); // provide clean output on exceptions rather than dumping a stack trace process.on('uncaughtException', function(err){ @@ -9,20 +8,39 @@ process.on('uncaughtException', function(err){ process.exit(1); }); -if (cmd === undefined) { - console.log(cordova.help()); -} else if (cmd[0] == '-') { - // options - if (cmd[1].toLowerCase() == 'v') { - console.log(require('../package').version); +var cmd, version, debug, current; + +while (current = tokens.shift()) { + if (current[0] == '-') { + if (current.indexOf('v') > -1) version = true; + if (current.indexOf('d') > -1) debug = true; + } else { + cmd = current; + break; } +} + +// TODO figure out how to incorporate -d logging +if (version) { + console.log(require('../package').version); +} else if (cmd === undefined) { + console.log(cordova.help()); } else if (cordova.hasOwnProperty(cmd)) { - try { - var r = cordova[cmd].apply(this, opts); - if (r) console.log(r); - } catch(e) { - console.error(e); + var opts = Array.prototype.slice.call(tokens, 0); + var r; + if (cmd == 'create' || cmd == 'docs') { + r = cordova[cmd].apply(this, opts); + } else if (cmd == 'emulate' || cmd == 'build') { + r = cordova[cmd].call(this, opts); + } else { + // platform or plugin cmds + if (tokens.length > 2) { + opts = [tokens.shift()]; + opts.push(tokens); + } + r = cordova[cmd].apply(this, opts); } + if (r) console.log(r); } else { console.error('Cordova does not know ' + cmd + '; try help for a list of all the available commands.') http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/blob/71ab56a4/spec/build.spec.js ---------------------------------------------------------------------- diff --git a/spec/build.spec.js b/spec/build.spec.js index b2d4112..51b2e0a 100644 --- a/spec/build.spec.js +++ b/spec/build.spec.js @@ -13,12 +13,9 @@ var cordova = require('../cordova'), tempDir = path.join(__dirname, '..', 'temp'); var cwd = process.cwd(); +shell.rm('-rf', tempDir); describe('build command', function() { - beforeEach(function() { - // Make a temp directory - shell.mkdir('-p', tempDir); - }); afterEach(function() { shell.rm('-rf', tempDir); }); @@ -41,11 +38,10 @@ describe('build command', function() { }); var buildcb = jasmine.createSpy(); - var cb = jasmine.createSpy(); cordova.create(tempDir); process.chdir(tempDir); - cordova.platform('add', 'android', cb); + cordova.platform('add', 'android'); var s = spyOn(require('shelljs'), 'exec').andReturn({code:0}); expect(function() { @@ -59,6 +55,7 @@ describe('build command', function() { process.chdir(cwd); }); + shell.mkdir('-p', tempDir); process.chdir(tempDir); expect(function() { @@ -73,7 +70,6 @@ describe('build command', function() { afterEach(function() { process.chdir(cwd); - shell.rm('-rf', tempDir); }); describe('Android', function() { @@ -179,7 +175,6 @@ describe('build command', function() { afterEach(function() { process.chdir(cwd); - shell.rm('-rf', tempDir); }); it('should only build the specified platform (array notation)', function() { var cb = jasmine.createSpy(); @@ -250,7 +245,6 @@ describe('build command', function() { }); afterEach(function() { process.chdir(cwd); - shell.rm('-rf', tempDir); }); describe('when platforms are added', function() { http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/blob/71ab56a4/spec/cli.spec.js ---------------------------------------------------------------------- diff --git a/spec/cli.spec.js b/spec/cli.spec.js index 29404a5..1242f22 100644 --- a/spec/cli.spec.js +++ b/spec/cli.spec.js @@ -1,11 +1,220 @@ var shell = require('shelljs'), - path = require('path'); + path = require('path'), + fs = require('fs'), + cordova = require('../cordova'), + tempDir = path.join(__dirname, '..', 'temp'), + plugins = path.join(__dirname, 'fixtures', 'plugins'), + androidPlugin = path.join(plugins, 'android'), + testPlugin = path.join(plugins, 'test'), + bin = path.join(__dirname, '..', 'bin', 'cordova'); + +var cwd = process.cwd(); describe('cli interface', function() { + beforeEach(function() { + shell.rm('-rf', tempDir); + }); + afterEach(function() { + shell.rm('-rf', tempDir); + }); + it('should print out version with -v', function() { - var bin = path.join(__dirname, '..', 'bin', 'cordova'); - bin += ' -v'; - var output = shell.exec(bin, {silent:true}).output; + var cmd = bin + ' -v'; + var output = shell.exec(cmd, {silent:true}).output; expect(output.indexOf(require('../package').version)).toBe(0); }); + + describe('create', function() { + it('should create a project when only dir is specified', function() { + var cmd = bin + ' create ' + tempDir; + var result = shell.exec(cmd, {silent:true}); + expect(result.code).toEqual(0); + expect(fs.existsSync(path.join(tempDir, '.cordova'))).toBe(true); + }); + it('should create a project when dir + name are specified', function() { + var cmd = bin + ' create ' + tempDir + ' foobar'; + var result = shell.exec(cmd, {silent:true}); + expect(result.code).toEqual(0); + expect(fs.existsSync(path.join(tempDir, '.cordova'))).toBe(true); + expect(fs.readFileSync(path.join(tempDir, 'www', 'config.xml'), 'utf-8')).toMatch(/<name>foobar/i); + }); + it('should create a project when all parameters are specified', function() { + var cmd = bin + ' create ' + tempDir + ' ca.filmaj.foobar foobar'; + var result = shell.exec(cmd, {silent:true}); + expect(result.code).toEqual(0); + expect(fs.existsSync(path.join(tempDir, '.cordova'))).toBe(true); + var config = fs.readFileSync(path.join(tempDir, 'www', 'config.xml'), 'utf-8'); + expect(config).toMatch(/<name>foobar/i); + expect(config).toMatch(/id="ca.filmaj.foobar"/i); + }); + }); + + describe('help', function() { + it('should print out docs as default command', function() { + var result = shell.exec(bin, {silent:true}); + expect(result.code).toEqual(0); + expect(result.output).toMatch(new RegExp(fs.readFileSync(path.join(__dirname, '..', 'doc', 'help.txt'), 'utf-8').split('\n')[0])); + }); + it('should print out docs when explicitly specified', function() { + var result = shell.exec(bin + ' help', {silent:true}); + expect(result.code).toEqual(0); + expect(result.output).toMatch(new RegExp(fs.readFileSync(path.join(__dirname, '..', 'doc', 'help.txt'), 'utf-8').split('\n')[0])); + }); + }); + + describe('platform', function() { + beforeEach(function() { + cordova.create(tempDir); + process.chdir(tempDir); + }); + afterEach(function() { + process.chdir(cwd); + }); + describe('add', function() { + it('should be able to add multiple platforms from a single invocation', function() { + var cmd = bin + ' platform add android ios'; + var result = shell.exec(cmd, {silent:true}); + expect(result.code).toEqual(0); + var platforms = fs.readdirSync(path.join(tempDir, 'platforms')); + expect(platforms.length).toEqual(2); + expect(platforms.indexOf('ios') > -1).toBe(true); + expect(platforms.indexOf('android') > -1).toBe(true); + }); + it('should be able to add a single platform', function() { + var cmd = bin + ' platform add android'; + var result = shell.exec(cmd, {silent:true}); + expect(result.code).toEqual(0); + var platforms = fs.readdirSync(path.join(tempDir, 'platforms')); + expect(platforms.length).toEqual(1); + expect(platforms.indexOf('android') > -1).toBe(true); + }); + }); + describe('remove', function() { + beforeEach(function() { + cordova.platform('add', 'android'); + }); + it('should be able to remove multiple platforms from a single invocation', function() { + var cb = jasmine.createSpy(); + runs(function() { + cordova.platform('add', 'ios', cb); + }); + waitsFor(function() { return cb.wasCalled; }, 'add ios'); + runs(function() { + var result = shell.exec(bin + ' platform rm ios android', {silent:true}); + expect(result.code).toEqual(0); + expect(fs.readdirSync(path.join(tempDir, 'platforms')).length).toEqual(0); + }); + }); + it('should be able to remove a single platform', function() { + var result = shell.exec(bin + ' platform rm android', {silent:true}); + expect(result.code).toEqual(0); + expect(fs.readdirSync(path.join(tempDir, 'platforms')).length).toEqual(0); + }); + }); + describe('ls', function() { + beforeEach(function() { + cordova.platform('add', 'android'); + }); + it('should be able to list platforms with no sub-command specified', function() { + var result = shell.exec(bin + ' platform', {silent:true}); + expect(result.code).toEqual(0); + expect(result.output).toMatch(/android/); + }); + it('should be able to list platforms with sub-command specified', function() { + var result = shell.exec(bin + ' platform ls', {silent:true}); + expect(result.code).toEqual(0); + expect(result.output).toMatch(/android/); + }); + }); + }); + + describe('plugin', function() { + beforeEach(function() { + cordova.create(tempDir); + process.chdir(tempDir); + cordova.platform('add', 'android'); + }); + afterEach(function() { + process.chdir(cwd); + }); + describe('add', function() { + it('should be able to add multiple plugins from a single invocation', function() { + var cmd = bin + ' plugin add ' + testPlugin + ' ' + androidPlugin; + var result = shell.exec(cmd, {silent:true}); + expect(result.code).toEqual(0); + var addedPlugins = fs.readdirSync(path.join(tempDir, 'plugins')); + expect(addedPlugins.length).toEqual(2); + expect(addedPlugins.indexOf('android') > -1).toBe(true); + expect(addedPlugins.indexOf('test') > -1).toBe(true); + }); + it('should be able to add a single plugin', function() { + var cmd = bin + ' plugin add ' + testPlugin; + var result = shell.exec(cmd, {silent:true}); + expect(result.code).toEqual(0); + var addedPlugins = fs.readdirSync(path.join(tempDir, 'plugins')); + expect(addedPlugins.length).toEqual(1); + expect(addedPlugins.indexOf('test') > -1).toBe(true); + }); + }); + describe('remove', function() { + beforeEach(function() { + cordova.plugin('add', [testPlugin, androidPlugin]); + }); + it('should be able to remove multiple plugins from a single invocation', function() { + var cmd = bin + ' plugin rm test android'; + var result = shell.exec(cmd, {silent:true}); + expect(result.code).toEqual(0); + var addedPlugins = fs.readdirSync(path.join(tempDir, 'plugins')); + expect(addedPlugins.length).toEqual(0); + }); + it('should be able to remove a single plugin', function() { + var cmd = bin + ' plugin rm test'; + var result = shell.exec(cmd, {silent:true}); + expect(result.code).toEqual(0); + var addedPlugins = fs.readdirSync(path.join(tempDir, 'plugins')); + expect(addedPlugins.length).toEqual(1); + expect(addedPlugins.indexOf('android') > -1).toBe(true); + }); + }); + describe('ls', function() { + beforeEach(function() { + cordova.plugin('add', androidPlugin); + }); + it('should be able to list plugins with no sub-command specified', function() { + var result = shell.exec(bin + ' plugin', {silent:true}); + expect(result.code).toEqual(0); + expect(result.output).toMatch(/android/); + }); + it('should be able to list plugins with sub-command specified', function() { + var result = shell.exec(bin + ' plugin list', {silent:true}); + expect(result.code).toEqual(0); + expect(result.output).toMatch(/android/); + }); + }); + }); + + describe('build', function() { + beforeEach(function() { + cordova.create(tempDir); + process.chdir(tempDir); + cordova.platform('add', 'android'); + }); + afterEach(function() { + process.chdir(cwd); + }); + it('should be able to build all platforms when none are specified', function() { + var result = shell.exec(bin + ' build', {silent:true}); + expect(result.code).toEqual(0); + var buildContents = fs.readdirSync(path.join(tempDir, 'platforms', 'android', 'bin')); + expect(buildContents.length > 0).toBe(true); + }); + xit('should be able to build a specific single platform'); + xit('should be able to build multiple, specific platforms from a single invocation'); + }); + + describe('emulate', function() { + xit('should be able to emulate all platforms when none are specified'); + xit('should be able to emulate a specific single platform'); + xit('should be able to emulate multiple, specific platforms from a single invocation'); + }); }); http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/blob/71ab56a4/src/build.js ---------------------------------------------------------------------- diff --git a/src/build.js b/src/build.js index 0b78c5d..a977702 100644 --- a/src/build.js +++ b/src/build.js @@ -4,6 +4,7 @@ var cordova_util = require('./util'), platform = require('./platform'), fs = require('fs'), shell = require('shelljs'), + ls = fs.readdirSync, et = require('elementtree'), android_parser= require('./metadata/android_parser'), blackberry_parser= require('./metadata/blackberry_parser'), @@ -35,21 +36,12 @@ module.exports = function build (platforms, callback) { var assets = path.join(projectRoot, 'www'); var cfg = new config_parser(xml); - if (arguments.length === 0) { - platforms = platform('ls'); - } else { - if (arguments[arguments.length-1] instanceof Function) { - // Called through JS, check platforms param - if (platforms instanceof Function) { - callback = platforms; - platforms = platform('ls'); - } else if (!(platforms instanceof Array)) platforms = [platforms]; - } else { - // Called through CLI; no callback - if (arguments[0] instanceof Array) platforms = arguments[0]; - else platforms = Array.prototype.slice.call(arguments, 0); - callback = undefined; - } + if (arguments.length === 0 || (platforms instanceof Array && platforms.length === 0)) { + platforms = ls(path.join(projectRoot, 'platforms')); + } else if (typeof platforms == 'string') platforms = [platforms]; + else if (platforms instanceof Function && callback === undefined) { + callback = platforms; + platforms = ls(path.join(projectRoot, 'platforms')); } if (platforms.length === 0) throw 'No platforms added to this project. Please use `cordova platform add <platform>`.'; http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/blob/71ab56a4/src/emulate.js ---------------------------------------------------------------------- diff --git a/src/emulate.js b/src/emulate.js index 22509de..23bab32 100644 --- a/src/emulate.js +++ b/src/emulate.js @@ -7,6 +7,7 @@ var cordova_util = require('./util'), blackberry_parser = require('./metadata/blackberry_parser'), platform = require('./platform'), fs = require('fs'), + ls = fs.readdirSync, n = require('ncallbacks'), hooker = require('../src/hooker'), util = require('util'); @@ -31,21 +32,12 @@ module.exports = function emulate (platforms, callback) { var xml = path.join(projectRoot, 'www', 'config.xml'); var cfg = new config_parser(xml); - if (arguments.length === 0) { - platforms = platform('ls'); - } else { - if (arguments[arguments.length-1] instanceof Function) { - // Called through JS, check platforms param - if (platforms instanceof Function) { - callback = platforms; - platforms = platform('ls'); - } else if (!(platforms instanceof Array)) platforms = [platforms]; - } else { - // Called through CLI; no callback - if (arguments[0] instanceof Array) platforms = arguments[0]; - else platforms = Array.prototype.slice.call(arguments, 0); - callback = undefined; - } + if (arguments.length === 0 || (platforms instanceof Array && platforms.length === 0)) { + platforms = ls(path.join(projectRoot, 'platforms')); + } else if (platforms instanceof String) platforms = [platforms]; + else if (platforms instanceof Function && callback === undefined) { + callback = platforms; + platforms = ls(path.join(projectRoot, 'platforms')); } if (platforms.length === 0) throw 'No platforms added to this project. Please use `cordova platform add <platform>`.'; http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/blob/71ab56a4/src/platform.js ---------------------------------------------------------------------- diff --git a/src/platform.js b/src/platform.js index 4a7fa2a..291fd3f 100644 --- a/src/platform.js +++ b/src/platform.js @@ -17,12 +17,12 @@ module.exports = function platform(command, targets, callback) { throw 'Current working directory is not a Cordova-based project.'; } - var hooks = new hooker(projectRoot); + var hooks = new hooker(projectRoot), end; if (arguments.length === 0) command = 'ls'; if (targets) { if (!(targets instanceof Array)) targets = [targets]; - var end = n(targets.length, function() { + end = n(targets.length, function() { if (callback) callback(); }); }