added update_www and update_project methods to project parsers. moved native project specifics to project parser modules (such as retrieving BB env config for deployment).
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/0987dbb3 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/tree/0987dbb3 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/diff/0987dbb3 Branch: refs/heads/cordova-client Commit: 0987dbb36f7407f3c69d5023b4b02249e7b3084c Parents: 5755260 Author: Fil Maj <maj....@gmail.com> Authored: Sun Sep 30 23:44:25 2012 -0700 Committer: Fil Maj <maj....@gmail.com> Committed: Sun Sep 30 23:44:25 2012 -0700 ---------------------------------------------------------------------- spec/metadata/android_parser.spec.js | 59 +++++++++++++- spec/metadata/blackberry_parser.spec.js | 113 ++++++++++++++++++++++++++ spec/metadata/ios_parser.spec.js | 93 +++++++++++++++++++++ src/metadata/android_parser.js | 14 +++ src/metadata/blackberry_parser.js | 112 +++++++++++++++++++++++++ src/metadata/ios_parser.js | 17 ++++- 6 files changed, 406 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/blob/0987dbb3/spec/metadata/android_parser.spec.js ---------------------------------------------------------------------- diff --git a/spec/metadata/android_parser.spec.js b/spec/metadata/android_parser.spec.js index ea3e89e..33fb88a 100644 --- a/spec/metadata/android_parser.spec.js +++ b/spec/metadata/android_parser.spec.js @@ -1,11 +1,14 @@ var android_parser = require('../../src/metadata/android_parser'), config_parser = require('../../src/config_parser'), path = require('path'), + shell = require('shelljs'), fs = require('fs'), et = require('elementtree'), cfg_path = path.join(__dirname, '..', 'fixtures', 'projects', 'test', 'www', 'config.xml'), android_path = path.join(__dirname, '..', 'fixtures', 'projects', 'native', 'android'), - android_strings = path.join(android_path, 'res', 'values', 'strings.xml'); + android_strings = path.join(android_path, 'res', 'values', 'strings.xml'), + tempDir = path.join(__dirname, '..', '..', 'temp'), + cordova = require('../../cordova'); var cwd = process.cwd(); @@ -51,4 +54,58 @@ describe('android project parser', function() { }); it('should update the application package name properly'); }); + + describe('update_www method', function() { + var parser, android_platform; + + beforeEach(function() { + shell.rm('-rf', tempDir); + cordova.create(tempDir); + process.chdir(tempDir); + cordova.platform('add', 'android'); + android_platform = path.join(tempDir, 'platforms', 'android'); + parser = new android_parser(android_platform); + }); + afterEach(function() { + process.chdir(cwd); + }); + + it('should update all www assets', function() { + var newFile = path.join(tempDir, 'www', 'somescript.js'); + fs.writeFileSync(newFile, 'alert("sup");', 'utf-8'); + parser.update_www(); + expect(fs.existsSync(path.join(android_platform, 'assets', 'www', 'somescript.js'))).toBe(true); + }); + it('should write out android js to cordova.js', function() { + parser.update_www(); + expect(fs.readFileSync(path.join(android_platform, 'assets', 'www', 'cordova.js'),'utf-8')).toBe(fs.readFileSync(path.join(__dirname, '..', '..', 'lib', 'android', 'framework', 'assets', 'js', 'cordova.android.js'), 'utf-8')); + }); + }); + + describe('update_project method', function() { + var parser, android_platform, cfg; + + beforeEach(function() { + shell.rm('-rf', tempDir); + cordova.create(tempDir); + process.chdir(tempDir); + cordova.platform('add', 'android'); + android_platform = path.join(tempDir, 'platforms', 'android'); + parser = new android_parser(android_platform); + cfg = new config_parser(cfg_path); + }); + afterEach(function() { + process.chdir(cwd); + }); + it('should invoke update_www', function() { + var spyWww = spyOn(parser, 'update_www'); + parser.update_project(cfg); + expect(spyWww).toHaveBeenCalled(); + }); + it('should invoke update_from_config', function() { + var spyConfig = spyOn(parser, 'update_from_config'); + parser.update_project(cfg); + expect(spyConfig).toHaveBeenCalled(); + }); + }); }); http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/blob/0987dbb3/spec/metadata/blackberry_parser.spec.js ---------------------------------------------------------------------- diff --git a/spec/metadata/blackberry_parser.spec.js b/spec/metadata/blackberry_parser.spec.js index c0e7995..7526df2 100644 --- a/spec/metadata/blackberry_parser.spec.js +++ b/spec/metadata/blackberry_parser.spec.js @@ -1,7 +1,11 @@ var blackberry_parser = require('../../src/metadata/blackberry_parser'), config_parser = require('../../src/config_parser'), path = require('path'), + shell = require('shelljs'), + cordova = require('../../cordova'), fs = require('fs'), + tempDir = path.join(__dirname, '..', '..', 'temp'), + tempBb = path.join(tempDir, 'platforms', 'blackberry-10'), cfg_path = path.join(__dirname, '..', 'fixtures', 'projects', 'test', 'www', 'config.xml'), blackberry_path = path.join(__dirname, '..', 'fixtures', 'projects', 'native', 'blackberry'), blackberry_config = path.join(blackberry_path, 'www', 'config.xml'); @@ -49,4 +53,113 @@ describe('blackberry project parser', function() { }); it('should update the application package name properly'); }); + + describe('update_www method', function() { + var s, parser; + beforeEach(function() { + shell.rm('-rf', tempDir); + cordova.create(tempDir); + shell.mkdir('-p', tempBb); + shell.cp('-rf', path.join(blackberry_path, '*'), tempBb); + parser = new blackberry_parser(tempBb); + }); + + it('should update all www assets', function() { + var newFile = path.join(tempDir, 'www', 'somescript.js'); + fs.writeFileSync(newFile, 'alert("sup");', 'utf-8'); + parser.update_www(); + expect(fs.existsSync(path.join(tempBb, 'www', 'somescript.js'))).toBe(true); + }); + it('should write out bb qnx js to cordova.js', function() { + var qnx_dir = path.join(tempBb, 'www', 'qnx'); + var qnx_js_path = path.join(qnx_dir, fs.readdirSync(qnx_dir)[0]); + var qnx_js = fs.readFileSync(qnx_js_path, 'utf-8'); + parser.update_www(); + expect(fs.readFileSync(path.join(tempBb, 'www', 'cordova.js'),'utf-8')).toBe(qnx_js); + }); + it('should not overwrite the blackberry-specific config.xml', function() { + var www_cfg = fs.readFileSync(path.join(tempDir, 'www', 'config.xml'), 'utf-8'); + parser.update_www(); + var bb_cfg = fs.readFileSync(path.join(tempBb, 'www', 'config.xml'), 'utf-8'); + expect(bb_cfg).not.toBe(www_cfg); + }); + it('should inject a reference to webworks.js in index.html', function() { + parser.update_www(); + var index = fs.readFileSync(path.join(tempBb, 'www', 'index.html'), 'utf-8'); + expect(index).toMatch(/<script type="text\/javascript" src="js\/webworks.js">/i); + }); + }); + + describe('update_project method', function() { + var parser, cfg, s, + ioFake = function() { s.mostRecentCall.args[1](null, {}); }; + beforeEach(function() { + shell.rm('-rf', tempDir); + cordova.create(tempDir); + s = spyOn(require('prompt'), 'get').andReturn(true); + shell.mkdir('-p', tempBb); + shell.cp('-rf', path.join(blackberry_path, '*'), tempBb); + parser = new blackberry_parser(tempBb); + cfg = new config_parser(path.join(tempDir, 'www', 'config.xml')); + }); + + it('should invoke update_www', function() { + var spyWww = spyOn(parser, 'update_www'); + parser.update_project(cfg); + ioFake(); + expect(spyWww).toHaveBeenCalled(); + }); + it('should invoke update_from_config', function() { + var spyConfig = spyOn(parser, 'update_from_config'); + parser.update_project(cfg); + ioFake(); + expect(spyConfig).toHaveBeenCalled(); + }); + it('should invoke get_blackberry_environment if .cordova file has no BB config', function() { + var spyEnv = spyOn(parser, 'get_blackberry_environment'); + parser.update_project(cfg); + expect(spyEnv).toHaveBeenCalled(); + }); + it('should not invoke get_blackberry_environment if .cordova file has BB config', function() { + var spyEnv = spyOn(parser, 'get_blackberry_environment'); + fs.writeFileSync(path.join(tempDir, '.cordova'), JSON.stringify({ + blackberry:{ + qnx:{ + } + } + }), 'utf-8'); + parser.update_project(cfg); + expect(spyEnv).not.toHaveBeenCalled(); + }); + it('should write out project properties with no BB config in .cordova', function() { + var spyProps = spyOn(parser, 'write_project_properties'); + var cb = jasmine.createSpy(); + runs(function() { + parser.update_project(cfg, cb); + ioFake(); + }); + waitsFor(function() { return cb.wasCalled; }, 'update project'); + runs(function() { + expect(spyProps).toHaveBeenCalled(); + }); + }); + it('should write out project properties with BB config in .cordova', function() { + var spyProps = spyOn(parser, 'write_project_properties'); + var cb = jasmine.createSpy(); + fs.writeFileSync(path.join(tempDir, '.cordova'), JSON.stringify({ + blackberry:{ + qnx:{ + } + } + }), 'utf-8'); + parser.update_project(cfg, cb); + expect(spyProps).toHaveBeenCalled(); + }); + }); + + describe('write_project_properties method', function() { + }); + + describe('get_blackberry_environment method', function() { + }); }); http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/blob/0987dbb3/spec/metadata/ios_parser.spec.js ---------------------------------------------------------------------- diff --git a/spec/metadata/ios_parser.spec.js b/spec/metadata/ios_parser.spec.js index 967be6e..f7c7fbf 100644 --- a/spec/metadata/ios_parser.spec.js +++ b/spec/metadata/ios_parser.spec.js @@ -1,9 +1,12 @@ var ios_parser = require('../../src/metadata/ios_parser'), config_parser = require('../../src/config_parser'), + cordova = require('../../cordova'), path = require('path'), + shell = require('shelljs'), fs = require('fs'), cfg_path = path.join(__dirname, '..', 'fixtures', 'projects', 'test', 'www', 'config.xml'), ios_path = path.join(__dirname, '..', 'fixtures', 'projects', 'native', 'ios'), + tempDir = path.join(__dirname, '..', '..', 'temp'), ios_pbx = path.join(ios_path, 'balls.xcodeproj', 'project.pbxproj'); var cwd = process.cwd(); @@ -59,4 +62,94 @@ describe('ios project parser', function() { }); it('should update the application package name properly'); }); + + describe('update_www method', function() { + var parser, ios_platform = path.join(tempDir, 'platforms', 'ios'); + + beforeEach(function() { + shell.rm('-rf', tempDir); + cordova.create(tempDir); + process.chdir(tempDir); + }); + afterEach(function() { + process.chdir(cwd); + }); + + it('should update all www assets', function() { + var cb = jasmine.createSpy(); + runs(function() { + cordova.platform('add', 'ios', cb); + }); + waitsFor(function() { return cb.wasCalled; }, 'platform add ios'); + runs(function() { + parser = new ios_parser(ios_platform); + var newFile = path.join(tempDir, 'www', 'somescript.js'); + fs.writeFileSync(newFile, 'alert("sup");', 'utf-8'); + parser.update_www(); + expect(fs.existsSync(path.join(ios_platform, 'www', 'somescript.js'))).toBe(true); + }); + }); + it('should write out ios js to cordova.js', function() { + var cb = jasmine.createSpy(); + runs(function() { + cordova.platform('add', 'ios', cb); + }); + waitsFor(function() { return cb.wasCalled; }, 'platform add ios'); + runs(function() { + parser = new ios_parser(ios_platform); + parser.update_www(); + expect(fs.readFileSync(path.join(ios_platform, 'www', 'cordova.js'),'utf-8')).toBe(fs.readFileSync(path.join(__dirname, '..', '..', 'lib', 'ios', 'CordovaLib', 'javascript', 'cordova.ios.js'), 'utf-8')); + }); + }); + }); + + describe('update_project method', function() { + var parser, ios_platform, cfg; + + beforeEach(function() { + shell.rm('-rf', tempDir); + cordova.create(tempDir); + process.chdir(tempDir); + }); + afterEach(function() { + process.chdir(cwd); + }); + it('should invoke update_www', function() { + var cb = jasmine.createSpy(); + var updatecb = jasmine.createSpy(); + var spyWww; + runs(function() { + cordova.platform('add', 'ios', cb); + }); + waitsFor(function() { return cb.wasCalled; }, 'platform add ios'); + runs(function() { + ios_platform = path.join(tempDir, 'platforms', 'ios'); + parser = new ios_parser(ios_platform); + cfg = new config_parser(cfg_path); + spyWww = spyOn(parser, 'update_www'); + parser.update_project(cfg, updatecb); + }); + waitsFor(function() { return updatecb.wasCalled; }, 'update project callback'); + runs(function() { + expect(spyWww).toHaveBeenCalled(); + }); + }); + it('should invoke update_from_config', function() { + var cb = jasmine.createSpy(); + var updatecb = jasmine.createSpy(); + var spyConfig; + ios_platform = path.join(tempDir, 'platforms', 'ios'); + runs(function() { + cordova.platform('add', 'ios', cb); + }); + waitsFor(function() { return cb.wasCalled; }, 'platform add ios'); + runs(function() { + parser = new ios_parser(ios_platform); + cfg = new config_parser(cfg_path); + spyConfig = spyOn(parser, 'update_from_config'); + parser.update_project(cfg, updatecb); + expect(spyConfig).toHaveBeenCalled(); + }); + }); + }); }); http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/blob/0987dbb3/src/metadata/android_parser.js ---------------------------------------------------------------------- diff --git a/src/metadata/android_parser.js b/src/metadata/android_parser.js index 48d2880..04b8698 100644 --- a/src/metadata/android_parser.js +++ b/src/metadata/android_parser.js @@ -1,6 +1,8 @@ var fs = require('fs'), path = require('path'), et = require('elementtree'), + util = require('../util'), + shell = require('shelljs'), config_parser = require('../config_parser'); module.exports = function android_parser(project) { @@ -20,5 +22,17 @@ module.exports.prototype = { var strings = new et.ElementTree(et.XML(fs.readFileSync(this.strings, 'utf-8'))); strings.find('string[@name="app_name"]').text = name; fs.writeFileSync(this.strings, strings.write({indent: 4}), 'utf-8'); + }, + update_www:function() { + var projectRoot = util.isCordova(process.cwd()); + var www = path.join(projectRoot, 'www'); + var platformWww = path.join(this.path, 'assets'); + shell.cp('-rf', www, platformWww); + var jsPath = path.join(__dirname, '..', '..', 'lib', 'android', 'framework', 'assets', 'js', 'cordova.android.js'); + fs.writeFileSync(path.join(platformWww, 'www', 'cordova.js'), fs.readFileSync(jsPath, 'utf-8'), 'utf-8'); + }, + update_project:function(cfg) { + this.update_from_config(cfg); + this.update_www(); } }; http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/blob/0987dbb3/src/metadata/blackberry_parser.js ---------------------------------------------------------------------- diff --git a/src/metadata/blackberry_parser.js b/src/metadata/blackberry_parser.js index 32bb266..b5ae45d 100644 --- a/src/metadata/blackberry_parser.js +++ b/src/metadata/blackberry_parser.js @@ -1,6 +1,9 @@ var fs = require('fs'), path = require('path'), et = require('elementtree'), + prompt = require('prompt'), + shell = require('shelljs'), + util = require('../util'), config_parser = require('../config_parser'); module.exports = function blackberry_parser(project) { @@ -17,5 +20,114 @@ module.exports.prototype = { } else throw 'update_from_config requires a config_parser object'; this.xml.name(config.name()); + }, + update_project:function(cfg, callback) { + this.update_from_config(cfg); + this.update_www(); + var self = this; + + // Do we have BB config? + var projectRoot = util.isCordova(this.path); + var dotFile = path.join(projectRoot, '.cordova'); + var dot = JSON.parse(fs.readFileSync(dotFile, 'utf-8')); + if (dot.blackberry === undefined || dot.blackberry.qnx === undefined) { + this.get_blackberry_environment(function() { + // Update project.properties + self.write_project_properties(); + + if (callback) callback(); + }); + return; + } + // Write out config stuff to project.properties file + this.write_project_properties(); + if (callback) callback(); + }, + update_www:function() { + var projectRoot = util.isCordova(this.path); + var www = path.join(projectRoot, 'www'); + var platformWww = path.join(this.path, 'www'); + + // Copy everything over except config.xml + var cfg_www = path.join(www, 'config.xml'); + var temp_cfg = path.join(projectRoot, 'config.xml'); + shell.mv(cfg_www, temp_cfg); + shell.cp('-rf', path.join(www, '*'), platformWww); + shell.mv(temp_cfg, cfg_www); + + // Move the js to just cordova.js + shell.mv('-f', path.join(platformWww, 'qnx', 'cordova-*.js'), path.join(platformWww, 'cordova.js')); + + // Add the webworks.js script file + // TODO: assumption that index.html is only file that needs the hot webworks script injection + // TODO: assumption that index.html is entry point to app + var index = path.join(platformWww, 'index.html'); + var contents = fs.readFileSync(index, 'utf-8'); + contents = contents.replace(/<script type="text\/javascript" src="cordova\.js"><\/script>/, '<script type="text/javascript" src="js/webworks.js"></script><script type="text/javascript" src="cordova.js"></script>'); + fs.writeFileSync(index, contents, 'utf-8'); + }, + write_project_properties:function() { + // TODO: eventually support all blackberry sub-platforms + var projectRoot = util.isCordova(this.path); + + var projFile = path.join(this.path, 'project.properties'); + var props = fs.readFileSync(projFile, 'utf-8'); + + var dotFile = path.join(projectRoot, '.cordova'); + var dot = JSON.parse(fs.readFileSync(dotFile, 'utf-8')); + + props = props.replace(/qnx\.bbwp\.dir=.*\n/, 'qnx.bbwp.dir=' + dot.blackberry.qnx.bbwp + '\n'); + props = props.replace(/qnx\.sigtool\.password=.*\n/, 'qnx.sigtool.password=' + dot.blackberry.qnx.signing_password + '\n'); + props = props.replace(/qnx\.device\.ip=.*\n/, 'qnx.device.ip=' + dot.blackberry.qnx.device_ip + '\n'); + props = props.replace(/qnx\.device\.password=.*\n/, 'qnx.device.password=' + dot.blackberry.qnx.device_password + '\n'); + props = props.replace(/qnx\.sim\.ip=.*\n/, 'qnx.sim.ip=' + dot.blackberry.qnx.sim_ip + '\n'); + props = props.replace(/qnx\.sim\.password=.*\n/, 'qnx.sim.password=' + dot.blackberry.qnx.sim_password + '\n'); + fs.writeFileSync(projFile, props, 'utf-8'); + }, + get_blackberry_environment:function(callback) { + // TODO: add other blackberry sub-platforms + var projectRoot = util.isCordova(this.path); + var dotFile = path.join(projectRoot, '.cordova'); + var dot = JSON.parse(fs.readFileSync(dotFile, 'utf-8')); + // Let's save relevant BB SDK + signing info to .cordova + console.log('Looks like we need some of your BlackBerry development environment information. We\'ll just ask you a few questions and we\'ll be on our way to building.'); + prompt.start(); + prompt.get([{ + name:'bbwp', + required:true, + description:'Enter the full path to your BB10 bbwp executable' + },{ + name:'signing_password', + required:true, + description:'Enter your BlackBerry signing password', + hidden:true + },{ + name:'device_ip', + description:'Enter the IP to your BB10 device' + },{ + name:'device_password', + description:'Enter the password for your BB10 device' + },{ + name:'sim_ip', + description:'Enter the IP to your BB10 simulator' + },{ + name:'sim_password', + description:'Enter the password for your BB10 simulator' + } + ], function(err, results) { + if (err) throw 'Error during BlackBerry environment config retrieval'; + // Write out .cordova file + if (dot.blackberry === undefined) dot.blackberry = {}; + if (dot.blackberry.qnx === undefined) dot.blackberry.qnx = {}; + dot.blackberry.qnx.bbwp = results.bbwp; + dot.blackberry.qnx.signing_password = results.signing_password; + dot.blackberry.qnx.device_ip = results.device_ip; + dot.blackberry.qnx.device_password = results.device_password; + dot.blackberry.qnx.sim_ip = results.sim_ip; + dot.blackberry.qnx.sim_password = results.sim_password; + fs.writeFileSync(dotFile, JSON.stringify(dot), 'utf-8'); + console.log('Perfect! If you need to change any of these properties, just edit the .cordova file in the root of your cordova project (it\'s just JSON, you\'ll be OK).'); + if (callback) callback(); + }); } }; http://git-wip-us.apache.org/repos/asf/incubator-cordova-labs/blob/0987dbb3/src/metadata/ios_parser.js ---------------------------------------------------------------------- diff --git a/src/metadata/ios_parser.js b/src/metadata/ios_parser.js index e353ad4..aa9ed31 100644 --- a/src/metadata/ios_parser.js +++ b/src/metadata/ios_parser.js @@ -1,6 +1,8 @@ var fs = require('fs'), path = require('path'), xcode = require('xcode'), + util = require('../util'), + shell = require('shelljs'), config_parser = require('../config_parser'); module.exports = function ios_parser(project) { @@ -13,7 +15,6 @@ module.exports = function ios_parser(project) { } this.path = project; this.pbxproj = path.join(this.xcodeproj, 'project.pbxproj'); - }; module.exports.prototype = { update_from_config:function(config, callback) { @@ -32,5 +33,19 @@ module.exports.prototype = { if (callback) callback(); } }); + }, + update_www:function() { + var projectRoot = util.isCordova(process.cwd()); + var www = path.join(projectRoot, 'www'); + shell.cp('-rf', www, this.path); + var jsPath = path.join(__dirname, '..', '..', 'lib', 'ios', 'CordovaLib', 'javascript', 'cordova.ios.js'); + fs.writeFileSync(path.join(this.path, 'www', 'cordova.js'), fs.readFileSync(jsPath, 'utf-8'), 'utf-8'); + }, + update_project:function(cfg, callback) { + var self = this; + this.update_from_config(cfg, function() { + self.update_www(); + if (callback) callback(); + }); } };