Repository: cordova-lib Updated Branches: refs/heads/master f9a81e4f3 -> f802efd1e
CB-6970 Share win project files manipulation code between cordova and plugman github: close #32 Project: http://git-wip-us.apache.org/repos/asf/cordova-lib/repo Commit: http://git-wip-us.apache.org/repos/asf/cordova-lib/commit/f802efd1 Tree: http://git-wip-us.apache.org/repos/asf/cordova-lib/tree/f802efd1 Diff: http://git-wip-us.apache.org/repos/asf/cordova-lib/diff/f802efd1 Branch: refs/heads/master Commit: f802efd1ea46644a5035f1f7f8891a088635af73 Parents: f9a81e4 Author: sgrebnov <[email protected]> Authored: Wed Jun 18 17:05:06 2014 +0400 Committer: Mark Koudritsky <[email protected]> Committed: Wed Jun 18 17:21:11 2014 -0400 ---------------------------------------------------------------------- cordova-lib/spec-plugman/util/csproj.spec.js | 2 +- .../src/cordova/metadata/windows8_parser.js | 33 +-- cordova-lib/src/cordova/metadata/wp8_parser.js | 32 +-- cordova-lib/src/plugman/platforms/windows8.js | 5 +- cordova-lib/src/plugman/platforms/wp8.js | 2 +- cordova-lib/src/plugman/prepare.js | 57 +--- cordova-lib/src/plugman/util/csproj.js | 142 ---------- cordova-lib/src/plugman/util/w8jsproj.js | 257 ------------------ cordova-lib/src/util/windows/csproj.js | 153 +++++++++++ cordova-lib/src/util/windows/jsproj.js | 263 +++++++++++++++++++ 10 files changed, 444 insertions(+), 502 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/f802efd1/cordova-lib/spec-plugman/util/csproj.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-plugman/util/csproj.spec.js b/cordova-lib/spec-plugman/util/csproj.spec.js index 137918b..236f631 100644 --- a/cordova-lib/spec-plugman/util/csproj.spec.js +++ b/cordova-lib/spec-plugman/util/csproj.spec.js @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -var csproj = require('../../src/plugman/util/csproj'), +var csproj = require('../../src/util/windows/csproj'), path = require('path'), os = require('osenv'), et = require('elementtree'), http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/f802efd1/cordova-lib/src/cordova/metadata/windows8_parser.js ---------------------------------------------------------------------- diff --git a/cordova-lib/src/cordova/metadata/windows8_parser.js b/cordova-lib/src/cordova/metadata/windows8_parser.js index b26b22f..5114da8 100644 --- a/cordova-lib/src/cordova/metadata/windows8_parser.js +++ b/cordova-lib/src/cordova/metadata/windows8_parser.js @@ -28,7 +28,8 @@ var fs = require('fs'), CordovaError = require('../../CordovaError'), xml = require('../../util/xml-helpers'), config = require('../config'), - hooker = require('../hooker'); + hooker = require('../hooker'), + jsproj = require('../../util/windows/jsproj'); module.exports = function windows8_parser(project) { try { @@ -226,38 +227,18 @@ module.exports.prototype = { // updates the jsproj file to explicitly list all www content. update_jsproj:function() { - var jsproj_xml = xml.parseElementtreeSync(this.jsproj_path); + var projFile = new jsproj(this.jsproj_path); + // remove any previous references to the www files - var item_groups = jsproj_xml.findall('ItemGroup'); - for (var i = 0, l = item_groups.length; i < l; i++) { - var group = item_groups[i]; - var files = group.findall('Content'); - for (var j = 0, k = files.length; j < k; j++) { - var file = files[j]; - if (file.attrib.Include.substr(0, 3) == 'www') { - // remove file reference - group.remove(0, file); - // remove ItemGroup if empty - var new_group = group.findall('Content'); - if(new_group.length < 1) { - jsproj_xml.getroot().remove(0, group); - } - } - } - } + projFile.removeSourceFile(new RegExp("www\\\\*", "i")); // now add all www references back in from the root www folder - var project_root = util.isCordova(this.windows8_proj_dir); var www_files = this.folder_contents('www', this.www_dir()); for(file in www_files) { - var item = new et.Element('ItemGroup'); - var content = new et.Element('Content'); - content.attrib.Include = www_files[file]; - item.append(content); - jsproj_xml.getroot().append(item); + projFile.addSourceFile(www_files[file]); } // save file - fs.writeFileSync(this.jsproj_path, jsproj_xml.write({indent:4}), 'utf-8'); + projFile.write(); }, // Returns an array of all the files in the given directory with relative paths // - name : the name of the top level directory (i.e all files will start with this in their path) http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/f802efd1/cordova-lib/src/cordova/metadata/wp8_parser.js ---------------------------------------------------------------------- diff --git a/cordova-lib/src/cordova/metadata/wp8_parser.js b/cordova-lib/src/cordova/metadata/wp8_parser.js index 159bd18..c23df95 100644 --- a/cordova-lib/src/cordova/metadata/wp8_parser.js +++ b/cordova-lib/src/cordova/metadata/wp8_parser.js @@ -28,7 +28,8 @@ var fs = require('fs'), CordovaError = require('../../CordovaError'), xml = require('../../util/xml-helpers'), config = require('../config'), - hooker = require('../hooker'); + hooker = require('../hooker'), + csproj = require('../../util/windows/csproj'); module.exports = function wp8_parser(project) { try { @@ -208,37 +209,18 @@ module.exports.prototype = { // updates the csproj file to explicitly list all www content. update_csproj:function() { - var csproj_xml = xml.parseElementtreeSync(this.csproj_path); + var projFile = new csproj(this.csproj_path); + // remove any previous references to the www files - var item_groups = csproj_xml.findall('ItemGroup'); - for (var i = 0, l = item_groups.length; i < l; i++) { - var group = item_groups[i]; - var files = group.findall('Content'); - for (var j = 0, k = files.length; j < k; j++) { - var file = files[j]; - if (file.attrib.Include.substr(0, 3) == 'www') { - // remove file reference - group.remove(0, file); - // remove ItemGroup if empty - var new_group = group.findall('Content'); - if(new_group.length < 1) { - csproj_xml.getroot().remove(0, group); - } - } - } - } + projFile.removeSourceFile(new RegExp("www\\\\*", "i")); // now add all www references back in from the root www folder var www_files = this.folder_contents('www', this.www_dir()); for(file in www_files) { - var item = new et.Element('ItemGroup'); - var content = new et.Element('Content'); - content.attrib.Include = www_files[file]; - item.append(content); - csproj_xml.getroot().append(item); + projFile.addSourceFile(www_files[file]); } // save file - fs.writeFileSync(this.csproj_path, csproj_xml.write({indent:4}), 'utf-8'); + projFile.write(); }, // Returns an array of all the files in the given directory with relative paths // - name : the name of the top level directory (i.e all files will start with this in their path) http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/f802efd1/cordova-lib/src/plugman/platforms/windows8.js ---------------------------------------------------------------------- diff --git a/cordova-lib/src/plugman/platforms/windows8.js b/cordova-lib/src/plugman/platforms/windows8.js index 571ca64..3f2a750 100644 --- a/cordova-lib/src/plugman/platforms/windows8.js +++ b/cordova-lib/src/plugman/platforms/windows8.js @@ -22,11 +22,10 @@ var common = require('./common'), glob = require('glob'), shell = require('shelljs'), fs = require('fs'), - w8jsproj = require('../util/w8jsproj'), + jsproj = require('../../util/windows/jsproj'), events = require('../../events'), xml_helpers = require('../../util/xml-helpers'); - module.exports = { platformName:"windows8", InvalidProjectPathError:'does not appear to be a Windows Store JS project (no .jsproj file)', @@ -42,7 +41,7 @@ module.exports = { if (project_files.length == 0) { throw new Error(this.InvalidProjectPathError); } - return new w8jsproj(path.join(project_dir, project_files[0])); + return new jsproj(path.join(project_dir, project_files[0])); }, "source-file":{ install:function(source_el, plugin_dir, project_dir, plugin_id, project_file) { http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/f802efd1/cordova-lib/src/plugman/platforms/wp8.js ---------------------------------------------------------------------- diff --git a/cordova-lib/src/plugman/platforms/wp8.js b/cordova-lib/src/plugman/platforms/wp8.js index fa14441..185c048 100644 --- a/cordova-lib/src/plugman/platforms/wp8.js +++ b/cordova-lib/src/plugman/platforms/wp8.js @@ -21,7 +21,7 @@ var common = require('./common'), path = require('path'), glob = require('glob'), fs = require('fs'), - csproj = require('../util/csproj'), + csproj = require('../../util/windows/csproj'), events = require('../../events'), xml_helpers = require('../../util/xml-helpers'); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/f802efd1/cordova-lib/src/plugman/prepare.js ---------------------------------------------------------------------- diff --git a/cordova-lib/src/plugman/prepare.js b/cordova-lib/src/plugman/prepare.js index a4d3c79..374e2b5 100644 --- a/cordova-lib/src/plugman/prepare.js +++ b/cordova-lib/src/plugman/prepare.js @@ -73,51 +73,14 @@ module.exports = function handlePrepare(project_dir, platform, plugins_dir, www_ events.emit('verbose', 'Processing configuration changes for plugins.'); config_changes.process(plugins_dir, project_dir, platform); - // for windows phone platform we need to add all www resources to the .csproj file + // for windows phone and windows8 platforms we need to add all www resources to the .csproj(.jsproj) file // first we need to remove them all to prevent duplicates - var wp_csproj; - var item_groups; - var i, j, k, l, file, files, group, new_group; - if(platform == 'wp8') { - wp_csproj = wp8.parseProjectFile(project_dir); - item_groups = wp_csproj.xml.findall('ItemGroup'); - for (i = 0, l = item_groups.length; i < l; i++) { - group = item_groups[i]; - files = group.findall('Content'); - for (j = 0, k = files.length; j < k; j++) { - file = files[j]; - if (file.attrib.Include.substr(0,11) == 'www\\plugins' || file.attrib.Include == 'www\\cordova_plugins.js') { - // remove file reference - group.remove(0, file); - // remove ItemGroup if empty - new_group = group.findall('Content'); - if(new_group.length < 1) { - wp_csproj.xml.getroot().remove(0, group); - } - } - } - } - } - else if(platform == 'windows8') { - wp_csproj = windows8.parseProjectFile(project_dir); - item_groups = wp_csproj.xml.findall('ItemGroup'); - for (i = 0, l = item_groups.length; i < l; i++) { - group = item_groups[i]; - files = group.findall('Content'); - for (j = 0, k = files.length; j < k; j++) { - file = files[j]; - if (file.attrib.Include.substr(0,11) == 'www\\plugins' || file.attrib.Include == 'www\\cordova_plugins.js') { - // remove file reference - group.remove(0, file); - // remove ItemGroup if empty - new_group = group.findall('Content'); - if(new_group.length < 1) { - wp_csproj.xml.getroot().remove(0, group); - } - } - } - } - + var projFile; + if (platform == 'wp8' || platform == 'windows8') { + projFile = (platform == 'wp8') ? wp8.parseProjectFile(project_dir) : + windows8.parseProjectFile(project_dir); + // remove reference to cordova_plugins.js and all files inside plugins folder + projFile.removeSourceFile(new RegExp("^www\\\\(cordova_plugins.js|plugins\\\\)", "i")); } platform_json = config_changes.get_platform_json(plugins_dir, platform); @@ -185,7 +148,7 @@ module.exports = function handlePrepare(project_dir, platform, plugins_dir, www_ scriptContent = 'cordova.define("' + moduleName + '", function(require, exports, module) { ' + scriptContent + '\n});\n'; fs.writeFileSync(path.join(platformPluginsDir, plugin_id, fsPath), scriptContent, 'utf-8'); if(platform == 'wp8' || platform == 'windows8') { - wp_csproj.addSourceFile(path.join('www', 'plugins', plugin_id, fsPath)); + projFile.addSourceFile(path.join('www', 'plugins', plugin_id, fsPath)); } // Prepare the object for cordova_plugins.json. @@ -229,7 +192,7 @@ module.exports = function handlePrepare(project_dir, platform, plugins_dir, www_ fs.writeFileSync(path.join(wwwDir, 'cordova_plugins.js'), final_contents, 'utf-8'); if(platform == 'wp8' || platform == 'windows8') { - wp_csproj.addSourceFile(path.join('www', 'cordova_plugins.js')); - wp_csproj.write(); + projFile.addSourceFile(path.join('www', 'cordova_plugins.js')); + projFile.write(); } }; http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/f802efd1/cordova-lib/src/plugman/util/csproj.js ---------------------------------------------------------------------- diff --git a/cordova-lib/src/plugman/util/csproj.js b/cordova-lib/src/plugman/util/csproj.js deleted file mode 100644 index 52ee040..0000000 --- a/cordova-lib/src/plugman/util/csproj.js +++ /dev/null @@ -1,142 +0,0 @@ -/** - 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 xml_helpers = require('../../util/xml-helpers'), - et = require('elementtree'), - fs = require('fs'), - path = require('path'); - -function csproj(location) { - this.location = location; - this.xml = xml_helpers.parseElementtreeSync(location); - return this; -} - -csproj.prototype = { - write:function() { - fs.writeFileSync(this.location, this.xml.write({indent:4}), 'utf-8'); - }, - - addReference:function(relPath) { - var item = new et.Element('ItemGroup'); - var extName = path.extname(relPath); - - var elem = new et.Element('Reference'); - // add dll file name - elem.attrib.Include = path.basename(relPath, extName); - // add hint path with full path - var hint_path = new et.Element('HintPath'); - hint_path.text = relPath; - elem.append(hint_path); - - if(extName == ".winmd") { - var mdFileTag = new et.Element("IsWinMDFile"); - mdFileTag.text = "true"; - elem.append(mdFileTag); - } - - item.append(elem); - - this.xml.getroot().append(item); - }, - - removeReference:function(relPath) { - var item = new et.Element('ItemGroup'); - var extName = path.extname(relPath); - var includeText = path.basename(relPath,extName); - // <ItemGroup> - // <Reference Include="WindowsRuntimeComponent1"> - var item_groups = this.xml.findall('ItemGroup/Reference[@Include="' + includeText + '"]/..'); - - if(item_groups.length > 0 ) { - this.xml.getroot().remove(0, item_groups[0]); - } - }, - - addSourceFile:function(relative_path) { - relative_path = relative_path.split('/').join('\\'); - // make ItemGroup to hold file. - var item = new et.Element('ItemGroup'); - - var extName = path.extname(relative_path); - // check if it's a .xaml page - if(extName == ".xaml") { - var page = new et.Element('Page'); - var sub_type = new et.Element('SubType'); - - sub_type.text = "Designer"; - page.append(sub_type); - page.attrib.Include = relative_path; - - var gen = new et.Element('Generator'); - gen.text = "MSBuild:Compile"; - page.append(gen); - - var item_groups = this.xml.findall('ItemGroup'); - if(item_groups.length == 0) { - item.append(page); - } else { - item_groups[0].append(page); - } - } - else if (extName == ".cs") { - var compile = new et.Element('Compile'); - compile.attrib.Include = relative_path; - // check if it's a .xaml.cs page that would depend on a .xaml of the same name - if (relative_path.indexOf('.xaml.cs', relative_path.length - 8) > -1) { - var dep = new et.Element('DependentUpon'); - var parts = relative_path.split('\\'); - var xaml_file = parts[parts.length - 1].substr(0, parts[parts.length - 1].length - 3); // Benn, really !? - dep.text = xaml_file; - compile.append(dep); - } - item.append(compile); - } - else { // otherwise add it normally - var compile = new et.Element('Content'); - compile.attrib.Include = relative_path; - item.append(compile); - } - this.xml.getroot().append(item); - }, - - removeSourceFile:function(relative_path) { - relative_path = relative_path.split('/').join('\\'); - var item_groups = this.xml.findall('ItemGroup'); - for (var i = 0, l = item_groups.length; i < l; i++) { - var group = item_groups[i]; - var files = group.findall('Compile').concat(group.findall('Page')).concat(group.findall('Content')); - for (var j = 0, k = files.length; j < k; j++) { - var file = files[j]; - if (file.attrib.Include == relative_path) { - // remove file reference - group.remove(0, file); - // remove ItemGroup if empty - var new_group = group.findall('Compile').concat(group.findall('Page')).concat(group.findall('Content')); - if(new_group.length < 1) { - this.xml.getroot().remove(0, group); - } - return true; - } - } - } - return false; - } -}; - -module.exports = csproj; http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/f802efd1/cordova-lib/src/plugman/util/w8jsproj.js ---------------------------------------------------------------------- diff --git a/cordova-lib/src/plugman/util/w8jsproj.js b/cordova-lib/src/plugman/util/w8jsproj.js deleted file mode 100644 index 6958de0..0000000 --- a/cordova-lib/src/plugman/util/w8jsproj.js +++ /dev/null @@ -1,257 +0,0 @@ -/** - 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. -*/ -/* - Helper for dealing with Windows Store JS app .jsproj files -*/ - - -var xml_helpers = require('../../util/xml-helpers'), - et = require('elementtree'), - fs = require('fs'), - shell = require('shelljs'), - events = require('../../events'), - path = require('path'); - -var WindowsStoreProjectTypeGUID = "{BC8A1FFA-BEE3-4634-8014-F334798102B3}"; // any of the below, subtype -var WinCSharpProjectTypeGUID = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"; // .csproj -var WinVBnetProjectTypeGUID = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"; // who the ef cares? -var WinCplusplusProjectTypeGUID = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; // .vcxproj - - -function jsproj(location) { - events.emit('verbose','creating jsproj from project at : ' + location); - this.location = location; - this.xml = xml_helpers.parseElementtreeSync(location); - return this; -} - -jsproj.prototype = { - location:null, - xml:null, - plugins_dir:"Plugins", - write:function() { - fs.writeFileSync(this.location, this.xml.write({indent:4}), 'utf-8'); - }, - // add/remove the item group for SDKReference - // example : - // <ItemGroup><SDKReference Include="Microsoft.VCLibs, version=12.0" /></ItemGroup> - addSDKRef:function(incText) { - var item_group = new et.Element('ItemGroup'); - var elem = new et.Element('SDKReference'); - elem.attrib.Include = incText; - - item_group.append(elem); - this.xml.getroot().append(item_group); - }, - - removeSDKRef:function(incText) { - var item_group = this.xml.find('ItemGroup/SDKReference[@Include="' + incText + '"]/..'); - if(item_group) { // TODO: error handling - this.xml.getroot().remove(0, item_group); - } - }, - - addReference:function(relPath,src) { - - events.emit('verbose','addReference::' + relPath); - - var item = new et.Element('ItemGroup'); - var extName = path.extname(relPath); - - var elem = new et.Element('Reference'); - // add file name - elem.attrib.Include = path.basename(relPath, extName); - - // add hint path with full path - var hint_path = new et.Element('HintPath'); - hint_path.text = relPath; - - elem.append(hint_path); - - if(extName == ".winmd") { - var mdFileTag = new et.Element("IsWinMDFile"); - mdFileTag.text = "true"; - elem.append(mdFileTag); - } - - item.append(elem); - this.xml.getroot().append(item); - }, - - removeReference:function(relPath) { - events.emit('verbose','removeReference::' + relPath); - - var extName = path.extname(relPath); - var includeText = path.basename(relPath,extName); - // <ItemGroup> - // <Reference Include="WindowsRuntimeComponent1"> - var item_group = this.xml.find('ItemGroup/Reference[@Include="' + includeText + '"]/..'); - - if(item_group) { // TODO: erro handling - this.xml.getroot().remove(0, item_group); - } - }, - - addSourceFile:function(relative_path) { - - relative_path = relative_path.split('/').join('\\'); - // make ItemGroup to hold file. - var item = new et.Element('ItemGroup'); - - var content = new et.Element('Content'); - content.attrib.Include = relative_path; - item.append(content); - - this.xml.getroot().append(item); - }, - - removeSourceFile:function(relative_path) { - - // path.normalize(relative_path);// ?? - relative_path = relative_path.split('/').join('\\'); - // var oneStep = this.xml.findall('ItemGroup/Content[@Include="' + relative_path + '""]/..'); - - var item_groups = this.xml.findall('ItemGroup'); - for (var i = 0, l = item_groups.length; i < l; i++) { - var group = item_groups[i]; - var files = group.findall('Content'); - for (var j = 0, k = files.length; j < k; j++) { - var file = files[j]; - if (file.attrib.Include == relative_path) { - // remove file reference - group.remove(0, file); - // remove ItemGroup if empty - var new_group = group.findall('Content'); - if(new_group.length < 1) { - this.xml.getroot().remove(0, group); - } - return true; - } - } - } - return false; - }, - // relative path must include the project file, so we can determine .csproj, .jsproj, .vcxproj... - addProjectReference:function(relative_path) { - events.emit('verbose','adding project reference to ' + relative_path); - - relative_path = relative_path.split('/').join('\\'); - // read the solution path from the base directory - var solutionPath = shell.ls(path.join(path.dirname(this.location),"*.sln"))[0];// TODO:error handling - // note we may not have a solution, in which case just add a project reference, I guess .. - // get the project extension to figure out project type - var projectExt = path.extname(relative_path); - - var pluginProjectXML = xml_helpers.parseElementtreeSync(relative_path); - // find the guid + name of the referenced project - var projectGuid = pluginProjectXML.find("PropertyGroup/ProjectGuid").text; - var projName = pluginProjectXML.find("PropertyGroup/ProjectName").text; - - var preInsertText = "ProjectSection(ProjectDependencies) = postProject\n\r" + - projectGuid + "=" + projectGuid + "\n\r" + - "EndProjectSection\n\r"; - - // read in the solution file - var solText = fs.readFileSync(solutionPath,{encoding:"utf8"}); - var splitText = solText.split("EndProject"); - if(splitText.length != 2) { - throw new Error("too many projects in solution."); - } - - var projectTypeGuid = null; - if(projectExt == ".vcxproj") { - projectTypeGuid = WinCplusplusProjectTypeGUID; - } - else if(projectExt == ".csproj") { - projectTypeGuid = WinCSharpProjectTypeGUID; - } - - if(!projectTypeGuid) { - throw new Error("unrecognized project type"); - } - - var postInsertText = 'Project("' + projectTypeGuid + '") = "' + - projName + '", "' + relative_path + '",' + - '"' + projectGuid + '"\n\r EndProject\n\r'; - - solText = splitText[0] + preInsertText + "EndProject\n\r" + postInsertText + splitText[1]; - fs.writeFileSync(solutionPath,solText,{encoding:"utf8"}); - - - // Add the ItemGroup/ProjectReference to the cordova project : - // <ItemGroup><ProjectReference Include="blahblah.csproj"/></ItemGroup> - var item = new et.Element('ItemGroup'); - - var projRef = new et.Element('ProjectReference'); - projRef.attrib.Include = relative_path; - item.append(projRef); - this.xml.getroot().append(item); - - }, - removeProjectReference:function(relative_path) { - events.emit('verbose','removing project reference to ' + relative_path); - - // find the guid + name of the referenced project - var pluginProjectXML = xml_helpers.parseElementtreeSync(relative_path); - var projectGuid = pluginProjectXML.find("PropertyGroup/ProjectGuid").text; - var projName = pluginProjectXML.find("PropertyGroup/ProjectName").text; - - // get the project extension to figure out project type - var projectExt = path.extname(relative_path); - // get the project type - var projectTypeGuid = null; - if(projectExt == ".vcxproj") { - projectTypeGuid = WinCplusplusProjectTypeGUID; - } - else if(projectExt == ".csproj") { - projectTypeGuid = WinCSharpProjectTypeGUID; - } - - if(!projectTypeGuid) { - throw new Error("unrecognized project type"); - } - - var preInsertText = "ProjectSection(ProjectDependencies) = postProject\n\r" + - projectGuid + "=" + projectGuid + "\n\r" + - "EndProjectSection\n\r"; - - var postInsertText = 'Project("' + projectTypeGuid + '") = "' + - projName + '", "' + relative_path + '",' + - '"' + projectGuid + '"\n\r EndProject\n\r'; - - // find and read in the solution file - var solutionPath = shell.ls(path.join(path.dirname(this.location),"*.sln"))[0]; // TODO:error handling - var solText = fs.readFileSync(solutionPath,{encoding:"utf8"}); - var splitText = solText.split(preInsertText); - - solText = splitText.join("").split(postInsertText); - solText = solText.join(""); - - fs.writeFileSync(solutionPath,solText,{encoding:"utf8"}); - - // select first ItemsGroups with a ChildNode ProjectReference - // ideally select all, and look for @attrib 'Include'= projectFullPath - var projectRefNodesPar = this.xml.find("ItemGroup/ProjectReference[@Include='" + relative_path + "']/.."); - if(projectRefNodesPar) { - this.xml.getroot().remove(0, projectRefNodesPar); - } - } -}; - -module.exports = jsproj; http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/f802efd1/cordova-lib/src/util/windows/csproj.js ---------------------------------------------------------------------- diff --git a/cordova-lib/src/util/windows/csproj.js b/cordova-lib/src/util/windows/csproj.js new file mode 100644 index 0000000..762c291 --- /dev/null +++ b/cordova-lib/src/util/windows/csproj.js @@ -0,0 +1,153 @@ +/** + 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 xml_helpers = require('../../util/xml-helpers'), + et = require('elementtree'), + fs = require('fs'), + path = require('path'); + +function csproj(location) { + this.location = location; + this.xml = xml_helpers.parseElementtreeSync(location); + return this; +} + +csproj.prototype = { + write:function() { + fs.writeFileSync(this.location, this.xml.write({indent:4}), 'utf-8'); + }, + + addReference:function(relPath) { + var item = new et.Element('ItemGroup'); + var extName = path.extname(relPath); + + var elem = new et.Element('Reference'); + // add dll file name + elem.attrib.Include = path.basename(relPath, extName); + // add hint path with full path + var hint_path = new et.Element('HintPath'); + hint_path.text = relPath; + elem.append(hint_path); + + if(extName == ".winmd") { + var mdFileTag = new et.Element("IsWinMDFile"); + mdFileTag.text = "true"; + elem.append(mdFileTag); + } + + item.append(elem); + + this.xml.getroot().append(item); + }, + + removeReference:function(relPath) { + var item = new et.Element('ItemGroup'); + var extName = path.extname(relPath); + var includeText = path.basename(relPath,extName); + // <ItemGroup> + // <Reference Include="WindowsRuntimeComponent1"> + var item_groups = this.xml.findall('ItemGroup/Reference[@Include="' + includeText + '"]/..'); + + if(item_groups.length > 0 ) { + this.xml.getroot().remove(0, item_groups[0]); + } + }, + + addSourceFile:function(relative_path) { + relative_path = relative_path.split('/').join('\\'); + // make ItemGroup to hold file. + var item = new et.Element('ItemGroup'); + + var extName = path.extname(relative_path); + // check if it's a .xaml page + if(extName == ".xaml") { + var page = new et.Element('Page'); + var sub_type = new et.Element('SubType'); + + sub_type.text = "Designer"; + page.append(sub_type); + page.attrib.Include = relative_path; + + var gen = new et.Element('Generator'); + gen.text = "MSBuild:Compile"; + page.append(gen); + + var item_groups = this.xml.findall('ItemGroup'); + if(item_groups.length == 0) { + item.append(page); + } else { + item_groups[0].append(page); + } + } + else if (extName == ".cs") { + var compile = new et.Element('Compile'); + compile.attrib.Include = relative_path; + // check if it's a .xaml.cs page that would depend on a .xaml of the same name + if (relative_path.indexOf('.xaml.cs', relative_path.length - 8) > -1) { + var dep = new et.Element('DependentUpon'); + var parts = relative_path.split('\\'); + var xaml_file = parts[parts.length - 1].substr(0, parts[parts.length - 1].length - 3); // Benn, really !? + dep.text = xaml_file; + compile.append(dep); + } + item.append(compile); + } + else { // otherwise add it normally + var compile = new et.Element('Content'); + compile.attrib.Include = relative_path; + item.append(compile); + } + this.xml.getroot().append(item); + }, + + removeSourceFile:function(relative_path) { + var isRegexp = relative_path instanceof RegExp; + + if (!isRegexp) { + // path.normalize(relative_path);// ?? + relative_path = relative_path.split('/').join('\\'); + } + + var root = this.xml.getroot(); + // iterate through all ItemGroup/Content elements and remove all items matched + this.xml.findall('ItemGroup').forEach(function(group){ + // matched files in current ItemGroup + var filesToRemove = group.findall('Compile').concat(group.findall('Page')) + .concat(group.findall('Content')).filter(function(item) { + if (!item.attrib.Include) return false; + return isRegexp ? item.attrib.Include.match(relative_path) : + item.attrib.Include == relative_path; + }); + + // nothing to remove, skip.. + if (filesToRemove.length < 1) return; + + filesToRemove.forEach(function(file){ + // remove file reference + group.remove(0, file); + }); + + // remove ItemGroup if empty + if(group.findall('*').length < 1) { + root.remove(0, group); + }; + }); + } +}; + +module.exports = csproj; http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/f802efd1/cordova-lib/src/util/windows/jsproj.js ---------------------------------------------------------------------- diff --git a/cordova-lib/src/util/windows/jsproj.js b/cordova-lib/src/util/windows/jsproj.js new file mode 100644 index 0000000..b9773f9 --- /dev/null +++ b/cordova-lib/src/util/windows/jsproj.js @@ -0,0 +1,263 @@ +/** + 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. +*/ +/* + Helper for dealing with Windows Store JS app .jsproj files +*/ + + +var xml_helpers = require('../../util/xml-helpers'), + et = require('elementtree'), + fs = require('fs'), + shell = require('shelljs'), + events = require('../../events'), + path = require('path'); + +var WindowsStoreProjectTypeGUID = "{BC8A1FFA-BEE3-4634-8014-F334798102B3}"; // any of the below, subtype +var WinCSharpProjectTypeGUID = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"; // .csproj +var WinVBnetProjectTypeGUID = "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}"; // who the ef cares? +var WinCplusplusProjectTypeGUID = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; // .vcxproj + + +function jsproj(location) { + events.emit('verbose','creating jsproj from project at : ' + location); + this.location = location; + this.xml = xml_helpers.parseElementtreeSync(location); + return this; +} + +jsproj.prototype = { + location:null, + xml:null, + plugins_dir:"Plugins", + write:function() { + fs.writeFileSync(this.location, this.xml.write({indent:4}), 'utf-8'); + }, + // add/remove the item group for SDKReference + // example : + // <ItemGroup><SDKReference Include="Microsoft.VCLibs, version=12.0" /></ItemGroup> + addSDKRef:function(incText) { + var item_group = new et.Element('ItemGroup'); + var elem = new et.Element('SDKReference'); + elem.attrib.Include = incText; + + item_group.append(elem); + this.xml.getroot().append(item_group); + }, + + removeSDKRef:function(incText) { + var item_group = this.xml.find('ItemGroup/SDKReference[@Include="' + incText + '"]/..'); + if(item_group) { // TODO: error handling + this.xml.getroot().remove(0, item_group); + } + }, + + addReference:function(relPath,src) { + + events.emit('verbose','addReference::' + relPath); + + var item = new et.Element('ItemGroup'); + var extName = path.extname(relPath); + + var elem = new et.Element('Reference'); + // add file name + elem.attrib.Include = path.basename(relPath, extName); + + // add hint path with full path + var hint_path = new et.Element('HintPath'); + hint_path.text = relPath; + + elem.append(hint_path); + + if(extName == ".winmd") { + var mdFileTag = new et.Element("IsWinMDFile"); + mdFileTag.text = "true"; + elem.append(mdFileTag); + } + + item.append(elem); + this.xml.getroot().append(item); + }, + + removeReference:function(relPath) { + events.emit('verbose','removeReference::' + relPath); + + var extName = path.extname(relPath); + var includeText = path.basename(relPath,extName); + // <ItemGroup> + // <Reference Include="WindowsRuntimeComponent1"> + var item_group = this.xml.find('ItemGroup/Reference[@Include="' + includeText + '"]/..'); + + if(item_group) { // TODO: erro handling + this.xml.getroot().remove(0, item_group); + } + }, + + addSourceFile:function(relative_path) { + + relative_path = relative_path.split('/').join('\\'); + // make ItemGroup to hold file. + var item = new et.Element('ItemGroup'); + + var content = new et.Element('Content'); + content.attrib.Include = relative_path; + item.append(content); + + this.xml.getroot().append(item); + }, + + removeSourceFile: function(relative_path) { + var isRegexp = relative_path instanceof RegExp; + + if (!isRegexp) { + // path.normalize(relative_path);// ?? + relative_path = relative_path.split('/').join('\\'); + } + + var root = this.xml.getroot(); + // iterate through all ItemGroup/Content elements and remove all items matched + this.xml.findall('ItemGroup').forEach(function(group){ + // matched files in current ItemGroup + var filesToRemove = group.findall('Content').filter(function(item) { + if (!item.attrib.Include) return false; + return isRegexp ? item.attrib.Include.match(relative_path) : + item.attrib.Include == relative_path; + }); + + // nothing to remove, skip.. + if (filesToRemove.length < 1) return; + + filesToRemove.forEach(function(file){ + // remove file reference + group.remove(0, file); + }); + // remove ItemGroup if empty + if(group.findall('*').length < 1) { + root.remove(0, group); + }; + }); + }, + + // relative path must include the project file, so we can determine .csproj, .jsproj, .vcxproj... + addProjectReference:function(relative_path) { + events.emit('verbose','adding project reference to ' + relative_path); + + relative_path = relative_path.split('/').join('\\'); + // read the solution path from the base directory + var solutionPath = shell.ls(path.join(path.dirname(this.location),"*.sln"))[0];// TODO:error handling + // note we may not have a solution, in which case just add a project reference, I guess .. + // get the project extension to figure out project type + var projectExt = path.extname(relative_path); + + var pluginProjectXML = xml_helpers.parseElementtreeSync(relative_path); + // find the guid + name of the referenced project + var projectGuid = pluginProjectXML.find("PropertyGroup/ProjectGuid").text; + var projName = pluginProjectXML.find("PropertyGroup/ProjectName").text; + + var preInsertText = "ProjectSection(ProjectDependencies) = postProject\n\r" + + projectGuid + "=" + projectGuid + "\n\r" + + "EndProjectSection\n\r"; + + // read in the solution file + var solText = fs.readFileSync(solutionPath,{encoding:"utf8"}); + var splitText = solText.split("EndProject"); + if(splitText.length != 2) { + throw new Error("too many projects in solution."); + } + + var projectTypeGuid = null; + if(projectExt == ".vcxproj") { + projectTypeGuid = WinCplusplusProjectTypeGUID; + } + else if(projectExt == ".csproj") { + projectTypeGuid = WinCSharpProjectTypeGUID; + } + + if(!projectTypeGuid) { + throw new Error("unrecognized project type"); + } + + var postInsertText = 'Project("' + projectTypeGuid + '") = "' + + projName + '", "' + relative_path + '",' + + '"' + projectGuid + '"\n\r EndProject\n\r'; + + solText = splitText[0] + preInsertText + "EndProject\n\r" + postInsertText + splitText[1]; + fs.writeFileSync(solutionPath,solText,{encoding:"utf8"}); + + + // Add the ItemGroup/ProjectReference to the cordova project : + // <ItemGroup><ProjectReference Include="blahblah.csproj"/></ItemGroup> + var item = new et.Element('ItemGroup'); + + var projRef = new et.Element('ProjectReference'); + projRef.attrib.Include = relative_path; + item.append(projRef); + this.xml.getroot().append(item); + + }, + removeProjectReference:function(relative_path) { + events.emit('verbose','removing project reference to ' + relative_path); + + // find the guid + name of the referenced project + var pluginProjectXML = xml_helpers.parseElementtreeSync(relative_path); + var projectGuid = pluginProjectXML.find("PropertyGroup/ProjectGuid").text; + var projName = pluginProjectXML.find("PropertyGroup/ProjectName").text; + + // get the project extension to figure out project type + var projectExt = path.extname(relative_path); + // get the project type + var projectTypeGuid = null; + if(projectExt == ".vcxproj") { + projectTypeGuid = WinCplusplusProjectTypeGUID; + } + else if(projectExt == ".csproj") { + projectTypeGuid = WinCSharpProjectTypeGUID; + } + + if(!projectTypeGuid) { + throw new Error("unrecognized project type"); + } + + var preInsertText = "ProjectSection(ProjectDependencies) = postProject\n\r" + + projectGuid + "=" + projectGuid + "\n\r" + + "EndProjectSection\n\r"; + + var postInsertText = 'Project("' + projectTypeGuid + '") = "' + + projName + '", "' + relative_path + '",' + + '"' + projectGuid + '"\n\r EndProject\n\r'; + + // find and read in the solution file + var solutionPath = shell.ls(path.join(path.dirname(this.location),"*.sln"))[0]; // TODO:error handling + var solText = fs.readFileSync(solutionPath,{encoding:"utf8"}); + var splitText = solText.split(preInsertText); + + solText = splitText.join("").split(postInsertText); + solText = solText.join(""); + + fs.writeFileSync(solutionPath,solText,{encoding:"utf8"}); + + // select first ItemsGroups with a ChildNode ProjectReference + // ideally select all, and look for @attrib 'Include'= projectFullPath + var projectRefNodesPar = this.xml.find("ItemGroup/ProjectReference[@Include='" + relative_path + "']/.."); + if(projectRefNodesPar) { + this.xml.getroot().remove(0, projectRefNodesPar); + } + } +}; + +module.exports = jsproj;
