You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by mw...@apache.org on 2013/05/15 22:36:10 UTC
[31/37] Add WP7 and WP8 support to cordova-cli.
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/platform-script/wp8/wp8.spec.js
----------------------------------------------------------------------
diff --git a/spec/platform-script/wp8/wp8.spec.js b/spec/platform-script/wp8/wp8.spec.js
new file mode 100644
index 0000000..998094c
--- /dev/null
+++ b/spec/platform-script/wp8/wp8.spec.js
@@ -0,0 +1,99 @@
+var cordova = require('../../../cordova'),
+ shell = require('shelljs'),
+ path = require('path'),
+ fs = require('fs'),
+ wp8_parser = require('../../../src/metadata/wp8_parser'),
+ tempDir = path.join(__dirname, '..', '..', '..', 'temp'),
+ fixtures = path.join(__dirname, '..', '..', 'fixtures'),
+ cordova_project = path.join(fixtures, 'projects', 'cordova');
+
+var cwd = process.cwd();
+
+describe('Test:', function() {
+ afterEach(function() {
+ process.chdir(cwd);
+ });
+
+ describe('\'platform add wp8\'', function() {
+ var sh, cr;
+ var fake_reqs_check = function() {
+ expect(cr.mostRecentCall.args).toBeDefined();
+ cr.mostRecentCall.args[0](false);
+ };
+ var fake_create = function(a_path) {
+ shell.mkdir('-p', a_path);
+ fs.writeFileSync(path.join(a_path, 'wp7Project.csproj'), 'hi', 'utf-8');
+ fs.writeFileSync(path.join(a_path, 'wp7Project.sln'), 'hi', 'utf-8');
+ sh.mostRecentCall.args[2](0, '');
+ };
+ beforeEach(function() {
+ sh = spyOn(shell, 'exec');
+ cr = spyOn(wp8_parser, 'check_requirements');
+ shell.rm('-rf', tempDir);
+ cordova.create(tempDir);
+ process.chdir(tempDir);
+ });
+ afterEach(function() {
+ process.chdir(cwd);
+ });
+ it('should shell out to wp8 /bin/create', function() {
+ cordova.platform('add', 'wp8');
+ fake_reqs_check();
+ var shell_cmd = sh.mostRecentCall.args[0];
+ var create_cmd = path.join('wp8', 'bin', 'create');
+ expect(shell_cmd).toContain(create_cmd);
+ });
+ it('should call wp8_parser\'s update_project', function() {
+ spyOn(wp8_parser.prototype, 'update_project');
+ cordova.platform('add', 'wp8');
+ fake_reqs_check();
+ fake_create(path.join(tempDir, 'platforms', 'wp8'));
+ expect(wp8_parser.prototype.update_project).toHaveBeenCalled();
+ });
+ });
+
+ describe('\'emulate wp8\'', function() {
+ beforeEach(function() {
+ process.chdir(tempDir);
+ });
+ afterEach(function() {
+ process.chdir(cwd);
+ });
+ shell.rm('-rf', tempDir);
+ cordova.create(tempDir);
+ shell.cp('-rf', path.join(cordova_project, 'platforms', 'wp8'), path.join(tempDir, 'platforms'));
+ it('should shell out to run command on wp8', function() {
+ var proj_spy = spyOn(wp8_parser.prototype, 'update_project');
+ var s = spyOn(require('shelljs'), 'exec');
+ cordova.emulate('wp8');
+ proj_spy.mostRecentCall.args[1](); // update_project fake
+ expect(s).toHaveBeenCalled();
+ var emulate_cmd = path.join('wp8', 'cordova', 'run');
+ expect(s.mostRecentCall.args[0]).toContain(emulate_cmd);
+ });
+ it('should call wp8_parser\'s update_project', function() {
+ spyOn(require('shelljs'), 'exec');
+ spyOn(wp8_parser.prototype, 'update_project');
+ cordova.emulate('wp8');
+ expect(wp8_parser.prototype.update_project).toHaveBeenCalled();
+ });
+ });
+
+ describe('\'compile wp8\'', function() {
+ beforeEach(function() {
+ process.chdir(tempDir);
+ });
+ afterEach(function() {
+ process.chdir(cwd);
+ });
+ shell.rm('-rf', tempDir);
+ cordova.create(tempDir);
+ shell.cp('-rf', path.join(cordova_project, 'platforms', 'wp8'), path.join(tempDir, 'platforms'));
+ it('should shell out to build command', function() {
+ var build_cmd = path.join('wp8', 'cordova', 'build');
+ var s = spyOn(require('shelljs'), 'exec').andReturn({code:0});
+ cordova.compile('wp8');
+ expect(s.mostRecentCall.args[0]).toContain(build_cmd);
+ });
+ });
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/platform-script/wp8/wp8_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/platform-script/wp8/wp8_parser.spec.js b/spec/platform-script/wp8/wp8_parser.spec.js
new file mode 100644
index 0000000..5669e02
--- /dev/null
+++ b/spec/platform-script/wp8/wp8_parser.spec.js
@@ -0,0 +1,249 @@
+
+/**
+ 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 wp8_parser = require('../../../src/metadata/wp8_parser'),
+ config_parser = require('../../../src/config_parser'),
+ util = require('../../../src/util'),
+ path = require('path'),
+ shell = require('shelljs'),
+ fs = require('fs'),
+ os = require('os'),
+ et = require('elementtree'),
+ cordova = require('../../../cordova'),
+ projects_path = path.join(__dirname, '..', '..', 'fixtures', 'projects'),
+ wp8_path = path.join(projects_path, 'native', 'wp8_fixture'),
+ project_path = path.join(projects_path, 'cordova'),
+ wp8_project_path = path.join(project_path, 'platforms', 'wp8');
+
+var www_config = util.projectConfig(project_path);
+var original_www_config = fs.readFileSync(www_config, 'utf-8');
+
+describe('wp8 project parser', function() {
+ it('should throw an exception with a path that is not a native wp8 project', function() {
+ expect(function() {
+ var project = new wp8_parser(process.cwd());
+ }).toThrow();
+ });
+ it('should accept a proper native wp8 project path as construction parameter', function() {
+ expect(function() {
+ var project = new wp8_parser(wp8_path);
+ expect(project).toBeDefined();
+ }).not.toThrow();
+ });
+
+ describe('update_from_config method', function() {
+ var config;
+ var project = new wp8_parser(wp8_path);
+
+ var manifest_path = path.join(wp8_path, 'Properties', 'WMAppManifest.xml');
+ var csproj_path = project.csproj_path;
+ var sln_path = project.sln_path;
+ var app_xaml_path = path.join(wp8_path, 'App.xaml');
+ var app_cs_path = path.join(wp8_path, 'App.xaml.cs');
+ var main_xaml_path = path.join(wp8_path, 'MainPage.xaml');
+ var main_cs_path = path.join(wp8_path, 'MainPage.xaml.cs');
+
+
+ var original_manifest = fs.readFileSync(manifest_path, 'utf-8');
+ var original_csproj = fs.readFileSync(csproj_path, 'utf-8');
+ var original_sln = fs.readFileSync(sln_path, 'utf-8');
+ var original_app_xaml = fs.readFileSync(app_xaml_path, 'utf-8');
+ var original_app_cs = fs.readFileSync(app_cs_path, 'utf-8');
+ var original_main_xaml = fs.readFileSync(main_xaml_path, 'utf-8');
+ var original_main_cs = fs.readFileSync(main_cs_path, 'utf-8');
+
+ beforeEach(function() {
+ project = new wp8_parser(wp8_path);
+ config = new config_parser(www_config);
+ });
+ afterEach(function() {
+ fs.writeFileSync(manifest_path, original_manifest, 'utf-8');
+ // csproj file changes name if app changes name
+ fs.unlinkSync(project.csproj_path);
+ fs.unlinkSync(project.sln_path);
+ fs.writeFileSync(csproj_path, original_csproj, 'utf-8');
+ fs.writeFileSync(sln_path, original_sln, 'utf-8');
+ fs.writeFileSync(app_xaml_path, original_app_xaml, 'utf-8');
+ fs.writeFileSync(app_cs_path, original_app_cs, 'utf-8');
+ fs.writeFileSync(main_xaml_path, original_main_xaml, 'utf-8');
+ fs.writeFileSync(main_cs_path, original_main_cs, 'utf-8');
+ });
+ it('should throw an exception if a non config_parser object is passed into it', function() {
+ expect(function() {
+ project.update_from_config({});
+ }).toThrow();
+ });
+ it('should update the application name properly', function() {
+ var test_name = 'bond. james bond.';
+ config.name(test_name);
+ project.update_from_config(config);
+ var raw_manifest = fs.readFileSync(manifest_path, 'utf-8');
+ //Strip three bytes that windows adds (http://www.multiasking.com/2012/11/851)
+ var cleaned_manifest = raw_manifest.replace('\ufeff', '');
+ var manifest = new et.ElementTree(et.XML(cleaned_manifest));
+ var app_name = manifest.find('.//App[@Title]')['attrib']['Title'];
+ expect(app_name).toBe(test_name);
+
+ //check for the proper name of csproj and solution files
+ test_name = test_name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_'); //make it a ligitamate name
+ expect(project.csproj_path).toContain(test_name);
+ expect(project.sln_path).toContain(test_name);
+ });
+ it('should update the application package name properly', function() {
+ var test_package = 'ca.filmaj.dewd'
+ config.packageName(test_package);
+ project.update_from_config(config);
+
+ // check csproj file (use regex instead of elementtree?)
+ var raw_csproj = fs.readFileSync(project.csproj_path, 'utf-8');
+ var cleaned_csproj = raw_csproj.replace(/^\uFEFF/i, '');
+ var csproj = new et.ElementTree(et.XML(cleaned_csproj));
+ expect(csproj.find('.//RootNamespace').text).toEqual(test_package);
+ expect(csproj.find('.//AssemblyName').text).toEqual(test_package);
+ expect(csproj.find('.//XapFilename').text).toEqual(test_package + '.xap');
+ expect(csproj.find('.//SilverlightAppEntry').text).toEqual(test_package + '.App');
+
+ // check app.xaml (use regex instead of elementtree?)
+ var new_app_xaml = fs.readFileSync(app_xaml_path, 'utf-8');
+ var cleaned_app_xaml = new_app_xaml.replace(/^\uFEFF/i, '');
+ var app_xaml = new et.ElementTree(et.XML(cleaned_app_xaml));
+ expect(app_xaml._root.attrib['x:Class']).toEqual(test_package + '.App');
+
+ // check app.xaml.cs
+ var new_app_cs = fs.readFileSync(app_cs_path, 'utf-8');
+ expect(new_app_cs).toContain('namespace ' + test_package);
+
+ // check MainPage.xaml (use regex instead of elementtree?)
+ var new_main_xaml = fs.readFileSync(main_xaml_path, 'utf-8');
+ var cleaned_main_xaml = new_main_xaml.replace(/^\uFEFF/i, '');
+ var main_xaml = new et.ElementTree(et.XML(cleaned_main_xaml));
+ expect(main_xaml._root.attrib['x:Class']).toEqual(test_package + '.MainPage');
+
+ //check MainPage.xaml.cs
+ var new_main_cs = fs.readFileSync(main_cs_path, 'utf-8');
+ expect(new_main_cs).toContain('namespace ' + test_package);
+ });
+ xdescribe('preferences', function() {
+ it('should not change default project preferences and copy over additional project preferences to platform-level config.xml', function() {
+ /*config.preference.add({name:'henrik',value:'sedin'});
+ project.update_from_config(config);
+
+ var native_config = new et.ElementTree(et.XML(fs.readFileSync(android_config, 'utf-8')));
+ var ps = native_config.findall('preference');
+ expect(ps.length).toEqual(7);
+ expect(ps[0].attrib.name).toEqual('useBrowserHistory');
+ expect(ps[0].attrib.value).toEqual('true');
+ expect(ps[6].attrib.name).toEqual('henrik');
+ expect(ps[6].attrib.value).toEqual('sedin');*/
+
+ // TODO : figure out if this is supported
+ //expect(true).toBe(false);
+ });
+ it('should override a default project preference if applicable', function() {
+ /*config.preference.add({name:'useBrowserHistory',value:'false'});
+ project.update_from_config(config);
+
+ var native_config = new et.ElementTree(et.XML(fs.readFileSync(android_config, 'utf-8')));
+ var ps = native_config.findall('preference');
+ expect(ps.length).toEqual(6);
+ expect(ps[0].attrib.name).toEqual('useBrowserHistory');
+ expect(ps[0].attrib.value).toEqual('false');*/
+
+ // TODO : figure out if this is supported
+ //expect(true).toBe(false);
+ });
+ });
+ });
+
+ describe('cross-platform project level methods', function() {
+ var parser, config;
+
+ beforeEach(function() {
+ parser = new wp8_parser(wp8_project_path);
+ config = new config_parser(www_config);
+ });
+ afterEach(function() {
+ });
+ describe('update_www method', function() {
+ it('should update all www assets', function() {
+ var newFile = path.join(util.projectWww(project_path), 'somescript.js');
+ this.after(function() {
+ shell.rm('-f', newFile);
+ });
+ fs.writeFileSync(newFile, 'alert("sup");', 'utf-8');
+ parser.update_www();
+ expect(fs.existsSync(path.join(wp8_project_path, 'www', 'somescript.js'))).toBe(true);
+ });
+ it('should write out windows-phone js to cordova.js', function() {
+ parser.update_www();
+ var raw_version = fs.readFileSync(path.join(util.libDirectory, 'cordova-wp8', 'VERSION'), 'utf-8');
+ var wp8_version = raw_version.replace(/\r\n/,'').replace(/\n/,'');
+ expect(fs.readFileSync(path.join(wp8_project_path, 'www', 'cordova.js'),'utf-8')).toEqual(fs.readFileSync(path.join(util.libDirectory, 'cordova-wp8', 'templates', 'standalone', 'www', 'cordova-' + wp8_version + '.js'), 'utf-8'));
+ });
+ });
+
+ xdescribe('update_overrides method',function() {
+ /*var mergesPath = path.join(util.appDir(project_path), 'merges', 'android');
+ var newFile = path.join(mergesPath, 'merge.js');
+ beforeEach(function() {
+ shell.mkdir('-p', mergesPath);
+ fs.writeFileSync(newFile, 'alert("sup");', 'utf-8');
+ });
+ afterEach(function() {
+ shell.rm('-rf', mergesPath);
+ });
+ it('should copy a new file from merges into www', function() {
+ parser.update_overrides();
+ expect(fs.existsSync(path.join(wp8_project_path, 'assets', 'www', 'merge.js'))).toBe(true);
+ });
+
+ it('should copy a file from merges over a file in www', function() {
+ var newFileWWW = path.join(util.projectWww(project_path), 'merge.js');
+ fs.writeFileSync(newFileWWW, 'var foo=1;', 'utf-8');
+ this.after(function() {
+ shell.rm('-rf', newFileWWW);
+ });
+ parser.update_overrides();
+ expect(fs.existsSync(path.join(wp8_project_path, 'assets', 'www', 'merge.js'))).toBe(true);
+ expect(fs.readFileSync(path.join(wp8_project_path, 'assets', 'www', 'merge.js'),'utf-8')).toEqual('alert("sup");');
+ });*/
+
+ // TODO : figure out if this is supported
+ //expect(true).toBe(false);
+ });
+
+ describe('update_project method', function() {
+ it('should invoke update_www', function() {
+ var spyWww = spyOn(parser, 'update_www');
+ parser.update_project(config);
+ expect(spyWww).toHaveBeenCalled();
+ });
+ it('should invoke update_from_config', function() {
+ var spyConfig = spyOn(parser, 'update_from_config');
+ parser.update_project(config);
+ expect(spyConfig).toHaveBeenCalled();
+ });
+ it('should call out to util.deleteSvnFolders', function() {
+ var spy = spyOn(util, 'deleteSvnFolders');
+ parser.update_project(config);
+ expect(spy).toHaveBeenCalled();
+ });
+ });
+ });
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/src/compile.js
----------------------------------------------------------------------
diff --git a/src/compile.js b/src/compile.js
index 4efbd6b..c88c36e 100644
--- a/src/compile.js
+++ b/src/compile.js
@@ -19,14 +19,11 @@
var cordova_util = require('./util'),
path = require('path'),
config_parser = require('./config_parser'),
- platform = require('./platform'),
fs = require('fs'),
shell = require('shelljs'),
et = require('elementtree'),
hooker = require('./hooker'),
- n = require('ncallbacks'),
- prompt = require('prompt'),
- util = require('util');
+ n = require('ncallbacks');
function shell_out_to_debug(projectRoot, platform, callback) {
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/src/create.js
----------------------------------------------------------------------
diff --git a/src/create.js b/src/create.js
index 0f7c8a6..f1d1792 100644
--- a/src/create.js
+++ b/src/create.js
@@ -45,7 +45,7 @@ module.exports = function create (dir, id, name) {
id = id || DEFAULT_ID;
name = name || DEFAULT_NAME;
- if (!(dir && (dir[0] == '~' || dir[0] == '/'))) {
+ if (!(dir && (dir[0] == '~' || dir[0] == '/' || dir[0] + dir[1] == 'C:'))) {
dir = dir ? path.join(process.cwd(), dir) : process.cwd();
}
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/src/emulate.js
----------------------------------------------------------------------
diff --git a/src/emulate.js b/src/emulate.js
index 7acb441..b396eeb 100644
--- a/src/emulate.js
+++ b/src/emulate.js
@@ -23,6 +23,8 @@ var cordova_util = require('./util'),
android_parser = require('./metadata/android_parser'),
ios_parser = require('./metadata/ios_parser'),
blackberry_parser = require('./metadata/blackberry_parser'),
+ wp7_parser = require('./metadata/wp7_parser'),
+ wp8_parser = require('./metadata/wp8_parser'),
platform = require('./platform'),
fs = require('fs'),
ls = fs.readdirSync,
@@ -33,16 +35,16 @@ var cordova_util = require('./util'),
var parsers = {
"android":android_parser,
"ios":ios_parser,
- "blackberry":blackberry_parser
+ "blackberry":blackberry_parser,
+ "wp7":wp7_parser,
+ "wp8":wp8_parser
};
function shell_out_to_emulate(root, platform, callback) {
- var cmd = '"' + path.join(root, 'platforms', platform, 'cordova', 'emulate') + '"';
+ 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';
- } else if (platform.indexOf('android') > -1) {
- cmd = '"' + path.join(root, 'platforms', platform, 'cordova', 'run') + '"';
}
shell.exec(cmd, {silent:true, async:true}, function(code, output) {
if (code > 0) {
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/src/metadata/wp7_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/wp7_parser.js b/src/metadata/wp7_parser.js
new file mode 100644
index 0000000..289eca0
--- /dev/null
+++ b/src/metadata/wp7_parser.js
@@ -0,0 +1,160 @@
+
+/**
+ 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'),
+ path = require('path'),
+ et = require('elementtree'),
+ util = require('../util'),
+ shell = require('shelljs'),
+ config_parser = require('../config_parser');
+
+module.exports = function wp7_parser(project) {
+ try {
+ // TODO : Check that it's not a wp7 project?
+ var csproj_file = fs.readdirSync(project).filter(function(e) { return e.match(/\.csproj$/i); })[0];
+ if (!csproj_file) throw new Error('The provided path "' + project + '" is not a Windows Phone 8 project.');
+ this.wp7_proj_dir = project;
+ this.csproj_path = path.join(this.wp7_proj_dir, csproj_file);
+ this.sln_path = path.join(this.wp7_proj_dir, csproj_file.replace(/\.csproj/, '.sln'));
+ } catch(e) {
+ throw new Error('The provided path "' + project + '" is not a Windows Phone 8 project.' + e);
+ }
+ this.manifest_path = path.join(this.wp7_proj_dir, 'Properties', 'WMAppManifest.xml');
+};
+
+module.exports.check_requirements = function(callback) {
+ shell.exec(path.join(util.libDirectory, 'cordova-wp7', 'bin', 'check_reqs'), {silent:true, async:true}, function(code, output) {
+ if (code != 0) {
+ callback(output);
+ } else {
+ callback(false);
+ }
+ });
+};
+
+module.exports.prototype = {
+ update_from_config:function(config) {
+ //check config parser
+ if (config instanceof config_parser) {
+ } else throw new Error('update_from_config requires a config_parser object');
+
+ // Update app name by editing app title in Properties\WMAppManifest.xml
+ var name = config.name();
+ var man = fs.readFileSync(this.manifest_path, 'utf-8');
+ //Strip three bytes that windows adds (http://www.multiasking.com/2012/11/851/)
+ var cleanedMan = man.replace('\ufeff', '');
+ var manifest = new et.ElementTree(et.XML(cleanedMan));
+ var prev_name = manifest.find('.//App[@Title]')['attrib']['Title'];
+ if(prev_name != name)
+ {
+ //console.log("Updating app name from " + prev_name + " to " + name);
+ manifest.find('.//App').attrib.Title = name;
+ manifest.find('.//Title').text = name;
+ fs.writeFileSync(this.manifest_path, manifest.write({indent: 4}), 'utf-8');
+
+ //update name of sln and csproj.
+ name = name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_'); //make it a ligitamate name
+ prev_name = prev_name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_');
+ // TODO: might return .sln.user? (generated file)
+ var sln_name = fs.readdirSync(this.wp7_proj_dir).filter(function(e) { return e.match(/\.sln$/i); })[0];
+ var sln_path = path.join(this.wp7_proj_dir, sln_name);
+ var sln_file = fs.readFileSync(sln_path, 'utf-8');
+ var name_regex = new RegExp(prev_name, "g");
+ fs.writeFileSync(sln_path, sln_file.replace(name_regex, name), 'utf-8');
+ shell.mv('-f', this.csproj_path, path.join(this.wp7_proj_dir, name + '.csproj'));
+ this.csproj_path = path.join(this.wp7_proj_dir, name + '.csproj');
+ shell.mv('-f', sln_path, path.join(this.wp7_proj_dir, name + '.sln'));
+ this.sln_path = path.join(this.wp7_proj_dir, name + '.sln');
+ }
+
+ // Update package name by changing:
+ /* - CordovaAppProj.csproj
+ * - MainPage.xaml
+ * - MainPage.xaml.cs
+ * - App.xaml
+ * - App.xaml.cs
+ */
+ var pkg = config.packageName();
+ var raw = fs.readFileSync(this.csproj_path, 'utf-8');
+ var cleanedPage = raw.replace(/^\uFEFF/i, '');
+ var csproj = new et.ElementTree(et.XML(cleanedPage));
+ prev_name = csproj.find('.//RootNamespace').text;
+ if(prev_name != pkg)
+ {
+ //console.log("Updating package name from " + prev_name + " to " + pkg);
+ //CordovaAppProj.csproj
+ csproj.find('.//RootNamespace').text = pkg;
+ csproj.find('.//AssemblyName').text = pkg;
+ csproj.find('.//XapFilename').text = pkg + '.xap';
+ csproj.find('.//SilverlightAppEntry').text = pkg + '.App';
+ fs.writeFileSync(this.csproj_path, csproj.write({indent: 4}), 'utf-8');
+ //MainPage.xaml
+ raw = fs.readFileSync(path.join(this.wp7_proj_dir, 'MainPage.xaml'), 'utf-8');
+ // Remove potential UTF Byte Order Mark
+ cleanedPage = raw.replace(/^\uFEFF/i, '');
+ var mainPageXAML = new et.ElementTree(et.XML(cleanedPage));
+ mainPageXAML._root.attrib['x:Class'] = pkg + '.MainPage';
+ fs.writeFileSync(path.join(this.wp7_proj_dir, 'MainPage.xaml'), mainPageXAML.write({indent: 4}), 'utf-8');
+ //MainPage.xaml.cs
+ var mainPageCS = fs.readFileSync(path.join(this.wp7_proj_dir, 'MainPage.xaml.cs'), 'utf-8');
+ var namespaceRegEx = new RegExp('namespace ' + prev_name);
+ fs.writeFileSync(path.join(this.wp7_proj_dir, 'MainPage.xaml.cs'), mainPageCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
+ //App.xaml
+ raw = fs.readFileSync(path.join(this.wp7_proj_dir, 'App.xaml'), 'utf-8');
+ cleanedPage = raw.replace(/^\uFEFF/i, '');
+ var appXAML = new et.ElementTree(et.XML(cleanedPage));
+ appXAML._root.attrib['x:Class'] = pkg + '.App';
+ fs.writeFileSync(path.join(this.wp7_proj_dir, 'App.xaml'), appXAML.write({indent: 4}), 'utf-8');
+ //App.xaml.cs
+ var appCS = fs.readFileSync(path.join(this.wp7_proj_dir, 'App.xaml.cs'), 'utf-8');
+ fs.writeFileSync(path.join(this.wp7_proj_dir, 'App.xaml.cs'), appCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
+ }
+ },
+ // Returns the platform-specific www directory.
+ www_dir:function() {
+ return path.join(this.wp7_proj_dir, 'www');
+ },
+ // copyies the app www folder into the wp7 project's www folder
+ update_www:function() {
+ var project_www = path.join(this.wp7_proj_dir, '..', '..', util.projectWww());
+ // remove stock platform assets
+ shell.rm('-rf', this.www_dir());
+ // copy over all app www assets
+ shell.cp('-rf', project_www, this.wp7_proj_dir);
+
+ // copy over wp7 lib's cordova.js
+ var raw_version = fs.readFileSync(path.join(util.libDirectory, 'cordova-wp7', 'VERSION'), 'utf-8')
+ var VERSION = raw_version.replace(/\r\n/,'').replace(/\n/,'');
+ var cordovajs_path = path.join(util.libDirectory, 'cordova-wp7', 'templates', 'standalone', 'www', 'cordova-' + VERSION + '.js');
+ fs.writeFileSync(path.join(this.www_dir(), 'cordova.js'), fs.readFileSync(cordovajs_path, 'utf-8'), 'utf-8');
+ },
+ // calls the nessesary functions to update the wp7 project
+ update_project:function(cfg, callback) {
+ //console.log("Updating wp7 project...");
+
+ this.update_from_config(cfg);
+ this.update_www();
+ util.deleteSvnFolders(this.www_dir());
+
+ //console.log("Done updating.");
+
+ if (callback) callback();
+ }
+};
+
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/src/metadata/wp8_parser.js
----------------------------------------------------------------------
diff --git a/src/metadata/wp8_parser.js b/src/metadata/wp8_parser.js
new file mode 100644
index 0000000..5ecb6dc
--- /dev/null
+++ b/src/metadata/wp8_parser.js
@@ -0,0 +1,158 @@
+
+/**
+ 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'),
+ path = require('path'),
+ et = require('elementtree'),
+ util = require('../util'),
+ shell = require('shelljs'),
+ config_parser = require('../config_parser');
+
+module.exports = function wp8_parser(project) {
+ try {
+ // TODO : Check that it's not a wp7 project?
+ var csproj_file = fs.readdirSync(project).filter(function(e) { return e.match(/\.csproj$/i); })[0];
+ if (!csproj_file) throw new Error('The provided path "' + project + '" is not a Windows Phone 8 project.');
+ this.wp8_proj_dir = project;
+ this.csproj_path = path.join(this.wp8_proj_dir, csproj_file);
+ this.sln_path = path.join(this.wp8_proj_dir, csproj_file.replace(/\.csproj/, '.sln'));
+ } catch(e) {
+ throw new Error('The provided path "' + project + '" is not a Windows Phone 8 project.' + e);
+ }
+ this.manifest_path = path.join(this.wp8_proj_dir, 'Properties', 'WMAppManifest.xml');
+};
+
+module.exports.check_requirements = function(callback) {
+ shell.exec(path.join(util.libDirectory, 'cordova-wp8', 'bin', 'check_reqs'), {silent:true, async:true}, function(code, output) {
+ if (code != 0) {
+ callback(output);
+ } else {
+ callback(false);
+ }
+ });
+};
+
+module.exports.prototype = {
+ update_from_config:function(config) {
+ //check config parser
+ if (config instanceof config_parser) {
+ } else throw new Error('update_from_config requires a config_parser object');
+
+ // Update app name by editing app title in Properties\WMAppManifest.xml
+ var name = config.name();
+ var man = fs.readFileSync(this.manifest_path, 'utf-8');
+ //Strip three bytes that windows adds (http://www.multiasking.com/2012/11/851/)
+ var cleanedMan = man.replace('\ufeff', '');
+ var manifest = new et.ElementTree(et.XML(cleanedMan));
+ var prev_name = manifest.find('.//App[@Title]')['attrib']['Title'];
+ if(prev_name != name)
+ {
+ //console.log("Updating app name from " + prev_name + " to " + name);
+ manifest.find('.//App').attrib.Title = name;
+ manifest.find('.//Title').text = name;
+ fs.writeFileSync(this.manifest_path, manifest.write({indent: 4}), 'utf-8');
+
+ //update name of sln and csproj.
+ name = name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_'); //make it a ligitamate name
+ prev_name = prev_name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_');
+ var sln_path = path.join(this.wp8_proj_dir, prev_name + '.sln');
+ var sln_file = fs.readFileSync(sln_path, 'utf-8');
+ var name_regex = new RegExp(prev_name, "g");
+ fs.writeFileSync(sln_path, sln_file.replace(name_regex, name), 'utf-8');
+ shell.mv('-f', this.csproj_path, path.join(this.wp8_proj_dir, name + '.csproj'));
+ this.csproj_path = path.join(this.wp8_proj_dir, name + '.csproj');
+ shell.mv('-f', sln_path, path.join(this.wp8_proj_dir, name + '.sln'));
+ this.sln_path = path.join(this.wp8_proj_dir, name + '.sln');
+ }
+
+ // Update package name by changing:
+ /* - CordovaAppProj.csproj
+ * - MainPage.xaml
+ * - MainPage.xaml.cs
+ * - App.xaml
+ * - App.xaml.cs
+ */
+ var pkg = config.packageName();
+ var raw = fs.readFileSync(this.csproj_path, 'utf-8');
+ var cleanedPage = raw.replace(/^\uFEFF/i, '');
+ var csproj = new et.ElementTree(et.XML(cleanedPage));
+ prev_name = csproj.find('.//RootNamespace').text;
+ if(prev_name != pkg)
+ {
+ //console.log("Updating package name from " + prev_name + " to " + pkg);
+ //CordovaAppProj.csproj
+ csproj.find('.//RootNamespace').text = pkg;
+ csproj.find('.//AssemblyName').text = pkg;
+ csproj.find('.//XapFilename').text = pkg + '.xap';
+ csproj.find('.//SilverlightAppEntry').text = pkg + '.App';
+ fs.writeFileSync(this.csproj_path, csproj.write({indent: 4}), 'utf-8');
+ //MainPage.xaml
+ raw = fs.readFileSync(path.join(this.wp8_proj_dir, 'MainPage.xaml'), 'utf-8');
+ // Remove potential UTF Byte Order Mark
+ cleanedPage = raw.replace(/^\uFEFF/i, '');
+ var mainPageXAML = new et.ElementTree(et.XML(cleanedPage));
+ mainPageXAML._root.attrib['x:Class'] = pkg + '.MainPage';
+ fs.writeFileSync(path.join(this.wp8_proj_dir, 'MainPage.xaml'), mainPageXAML.write({indent: 4}), 'utf-8');
+ //MainPage.xaml.cs
+ var mainPageCS = fs.readFileSync(path.join(this.wp8_proj_dir, 'MainPage.xaml.cs'), 'utf-8');
+ var namespaceRegEx = new RegExp('namespace ' + prev_name);
+ fs.writeFileSync(path.join(this.wp8_proj_dir, 'MainPage.xaml.cs'), mainPageCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
+ //App.xaml
+ raw = fs.readFileSync(path.join(this.wp8_proj_dir, 'App.xaml'), 'utf-8');
+ cleanedPage = raw.replace(/^\uFEFF/i, '');
+ var appXAML = new et.ElementTree(et.XML(cleanedPage));
+ appXAML._root.attrib['x:Class'] = pkg + '.App';
+ fs.writeFileSync(path.join(this.wp8_proj_dir, 'App.xaml'), appXAML.write({indent: 4}), 'utf-8');
+ //App.xaml.cs
+ var appCS = fs.readFileSync(path.join(this.wp8_proj_dir, 'App.xaml.cs'), 'utf-8');
+ fs.writeFileSync(path.join(this.wp8_proj_dir, 'App.xaml.cs'), appCS.replace(namespaceRegEx, 'namespace ' + pkg), 'utf-8');
+ }
+ },
+ // Returns the platform-specific www directory.
+ www_dir:function() {
+ return path.join(this.wp8_proj_dir, 'www');
+ },
+ // copyies the app www folder into the wp8 project's www folder
+ update_www:function() {
+ var project_www = path.join(this.wp8_proj_dir, '..', '..', util.projectWww());
+ // remove stock platform assets
+ shell.rm('-rf', this.www_dir());
+ // copy over all app www assets
+ shell.cp('-rf', project_www, this.wp8_proj_dir);
+
+ // copy over wp8 lib's cordova.js
+ var raw_version = fs.readFileSync(path.join(util.libDirectory, 'cordova-wp8', 'VERSION'), 'utf-8')
+ var VERSION = raw_version.replace(/\r\n/,'').replace(/\n/,'');
+ var cordovajs_path = path.join(util.libDirectory, 'cordova-wp8', 'templates', 'standalone', 'www', 'cordova-' + VERSION + '.js');
+ fs.writeFileSync(path.join(this.www_dir(), 'cordova.js'), fs.readFileSync(cordovajs_path, 'utf-8'), 'utf-8');
+ },
+ // calls the nessesary functions to update the wp8 project
+ update_project:function(cfg, callback) {
+ //console.log("Updating wp8 project...");
+
+ this.update_from_config(cfg);
+ this.update_www();
+ util.deleteSvnFolders(this.www_dir());
+
+ //console.log("Done updating.");
+
+ if (callback) callback();
+ }
+};
+
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/src/platform.js
----------------------------------------------------------------------
diff --git a/src/platform.js b/src/platform.js
index 00f2157..15285fb 100644
--- a/src/platform.js
+++ b/src/platform.js
@@ -26,12 +26,16 @@ var config_parser = require('./config_parser'),
android_parser = require('./metadata/android_parser'),
ios_parser = require('./metadata/ios_parser'),
blackberry_parser = require('./metadata/blackberry_parser'),
+ wp7_parser = require('./metadata/wp7_parser'),
+ wp8_parser = require('./metadata/wp8_parser'),
shell = require('shelljs');
var parsers = {
"android":android_parser,
"ios":ios_parser,
- "blackberry":blackberry_parser
+ "blackberry":blackberry_parser,
+ "wp7":wp7_parser,
+ "wp8":wp8_parser
};
module.exports = function platform(command, targets, callback) {
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/src/plugin.js
----------------------------------------------------------------------
diff --git a/src/plugin.js b/src/plugin.js
index 8997f97..b6d9911 100644
--- a/src/plugin.js
+++ b/src/plugin.js
@@ -108,6 +108,7 @@ module.exports = function plugin(command, targets, callback) {
intersection.forEach(function(platform) {
var cmd = util.format('%s --platform %s --project "%s" --plugin "%s"', cli, platform, path.join(projectRoot, 'platforms', platform), target);
var plugin_cli = shell.exec(cmd, {silent:true});
+ if(!plugin_cli) throw new Error('Plugman command failed to execute for ' + platform + '.');
if (plugin_cli.code > 0) throw new Error('An error occured during plugin installation for ' + platform + '. ' + plugin_cli.output);
});
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/src/plugin_loader.js
----------------------------------------------------------------------
diff --git a/src/plugin_loader.js b/src/plugin_loader.js
index 3798e2f..b4730b4 100644
--- a/src/plugin_loader.js
+++ b/src/plugin_loader.js
@@ -25,6 +25,8 @@ var path = require('path'),
android_parser = require('./metadata/android_parser'),
blackberry_parser= require('./metadata/blackberry_parser'),
ios_parser = require('./metadata/ios_parser'),
+ wp7_parser = require('./metadata/wp7_parser'),
+ wp8_parser = require('./metadata/wp8_parser'),
exec = require('child_process').exec,
et = require('elementtree');
@@ -88,6 +90,13 @@ module.exports = function plugin_loader(platform) {
case 'blackberry':
parser = new blackberry_parser(path.join(projectRoot, 'platforms', 'blackberry'));
break;
+ case 'wp7':
+ parser = new wp7_parser(path.join(projectRoot, 'platforms', 'wp7'));
+ break;
+ case 'wp8':
+ parser = new wp8_parser(path.join(projectRoot, 'platforms', 'wp8'));
+ break;
+
}
plugins && plugins.forEach(function(plugin) {
http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/src/util.js
----------------------------------------------------------------------
diff --git a/src/util.js b/src/util.js
index 7ebbb17..cd34533 100644
--- a/src/util.js
+++ b/src/util.js
@@ -76,5 +76,11 @@ module.exports = {
}
return plugins;
+ },
+ projectWww: function(projectDir) {
+ return path.join(projectDir, 'www');
+ },
+ projectConfig: function(projectDir) {
+ return path.join(projectDir, 'www', 'config.xml');
}
};