You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by lo...@apache.org on 2013/05/07 17:18:39 UTC
[02/30] git commit: [ios] add custom config-file support
[ios] add custom config-file support
Project: http://git-wip-us.apache.org/repos/asf/cordova-plugman/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugman/commit/375459c3
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugman/tree/375459c3
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugman/diff/375459c3
Branch: refs/heads/future
Commit: 375459c39bd28916a63841907ad30c707b8d1d3f
Parents: e3592a1
Author: Brett Rudd <br...@gmail.com>
Authored: Fri Apr 19 15:28:21 2013 -0700
Committer: Brett Rudd <br...@gmail.com>
Committed: Mon Apr 22 11:42:01 2013 -0700
----------------------------------------------------------------------
platforms/ios.js | 71 +++++++++++++++++++-
test/ios-config-xml-uninstall.js | 20 ++++++
test/plugins/ChildBrowser/plugin-old.xml | 13 ++++
test/plugins/ChildBrowser/plugin.xml | 13 ++++
util/plist-helpers.js | 90 +++++++++++++++++++++++++
5 files changed, 204 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/375459c3/platforms/ios.js
----------------------------------------------------------------------
diff --git a/platforms/ios.js b/platforms/ios.js
index 6473936..8b13d4a 100644
--- a/platforms/ios.js
+++ b/platforms/ios.js
@@ -26,6 +26,8 @@ var path = require('path')
, bplist = require('bplist-parser')
, shell = require('shelljs')
, xml_helpers = require('../util/xml-helpers')
+ , plist_helpers = require('../util/plist-helpers')
+ , getConfigChanges = require('../util/config-changes')
, searchAndReplace = require('../util/search-and-replace')
, getConfigChanges = require('../util/config-changes')
, assetsDir = 'www'; // relative path to project's web assets
@@ -86,7 +88,8 @@ exports.handlePlugin = function (action, project_dir, plugin_dir, plugin_et, var
sourceFiles = platformTag.findall('./source-file'),
headerFiles = platformTag.findall('./header-file'),
resourceFiles = platformTag.findall('./resource-file'),
- frameworks = platformTag.findall('./framework');
+ frameworks = platformTag.findall('./framework'),
+ configChanges = getConfigChanges(platformTag);
// move asset files into www
assets && assets.forEach(function (asset) {
@@ -193,9 +196,17 @@ exports.handlePlugin = function (action, project_dir, plugin_dir, plugin_et, var
// write out xcodeproj file
fs.writeFileSync(pbxPath, xcodeproj.writeSync());
- // add plugin and whitelisted hosts
try {
+ // add plugin and whitelisted hosts
updateConfig(action, config_file, plugin_et);
+
+ // edit custom configuration items
+ Object.keys(configChanges).forEach(function (filename) {
+ var filepaths = glob.sync(path.resolve(xcode_dir, filename));
+ for (var i in filepaths) {
+ updateCustomConfig(action, filepaths[i], configChanges[filename]);
+ }
+ });
} catch(e) {
throw {
name: "ConfigurationError",
@@ -352,7 +363,8 @@ function updateConfigXml(action, config_path, plugin_et) {
throw new Error('failed to remove children from ' + selector + ' in ' + config_path);
}
}
- });
+ delete configChanges[base_config_path][configNode];
+ });
}
output = xmlDoc.write({indent: 4});
@@ -367,7 +379,60 @@ function updateConfig(action, config_path, plugin_et) {
updatePlistFile(action, config_path, plugin_et);
}
}
+
// throws error if last command returns code != 0
function checkLastCommand() {
if(shell.error() != null) throw {name: "ShellError", message: shell.error()};
}
+
+// updates plist file and/or config.xml
+function updateCustomConfig(action, filepath, configNodes) {
+
+ if (path.extname(filepath) == ".xml") {
+ var xmlDoc = xml_helpers.parseElementtreeSync(filepath),
+ output;
+
+ configNodes.forEach(function (configNode) {
+ var selector = configNode.attrib["parent"],
+ children = configNode.findall('*');
+
+ if( action == 'install') {
+ if (!xml_helpers.graftXML(xmlDoc, children, selector)) {
+ throw new Error('failed to add children to ' + filepath);
+ }
+ } else {
+ if (!xml_helpers.pruneXML(xmlDoc, children, selector)) {
+ throw new Error('failed to remove children from' + filepath);
+ }
+ }
+ });
+
+ output = xmlDoc.write({indent: 4});
+ fs.writeFileSync(filepath, output);
+
+ }
+ else { // PLIST
+ var pl = (isBinaryPlist(filepath) ? bplist : plist),
+ plistObj = pl.parseFileSync(filepath);
+
+ configNodes.forEach(function (configNode) {
+
+ var selector = configNode.attrib["parent"],
+ children = configNode.find("./*");
+
+ if( action == 'install') {
+ if (!plist_helpers.graftPLIST(plistObj, children, selector)) {
+ throw new Error('failed to add children to ' + filepath);
+ }
+ } else {
+ if (!plist_helpers.prunePLIST(plistObj, children, selector)) {
+ throw new Error('failed to remove children from' + filepath);
+ }
+ }
+
+ });
+
+ // write out plist
+ fs.writeFileSync(filepath, plist.build(plistObj));
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/375459c3/test/ios-config-xml-uninstall.js
----------------------------------------------------------------------
diff --git a/test/ios-config-xml-uninstall.js b/test/ios-config-xml-uninstall.js
index a2b5885..6b2674e 100644
--- a/test/ios-config-xml-uninstall.js
+++ b/test/ios-config-xml-uninstall.js
@@ -175,6 +175,26 @@ exports['should edit config.xml'] = function (test) {
test.done();
}
+exports['should remove custom config-file elements'] = function (test) {
+ // setting up WebNotification (with config.xml)
+ var dummy_plugin_dir = path.join(test_dir, 'plugins', 'ChildBrowser')
+ var dummy_xml_path = path.join(test_dir, 'plugins', 'ChildBrowser', 'plugin.xml')
+
+ // overriding some params
+ var dummy_plugin_et = new et.ElementTree(et.XML(fs.readFileSync(dummy_xml_path, 'utf-8')));
+
+ // run the platform-specific function
+ ios.handlePlugin('install', test_project_dir, dummy_plugin_dir, dummy_plugin_et, { APP_ID: '1234' });
+ ios.handlePlugin('uninstall', test_project_dir, dummy_plugin_dir, dummy_plugin_et);
+
+ var configPath = path.join(test_project_dir, 'SampleApp', 'SampleApp-Info.plist');
+ var configPList = plist.parseFileSync(configPath);
+
+ test.equal(configPList['AppId'], null);
+ test.equal(configPList['CFBundleURLTypes'], null);
+ test.done();
+}
+
exports['should edit the pbxproj file'] = function (test) {
// run the platform-specific function
ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/375459c3/test/plugins/ChildBrowser/plugin-old.xml
----------------------------------------------------------------------
diff --git a/test/plugins/ChildBrowser/plugin-old.xml b/test/plugins/ChildBrowser/plugin-old.xml
index a3d7643..d145839 100644
--- a/test/plugins/ChildBrowser/plugin-old.xml
+++ b/test/plugins/ChildBrowser/plugin-old.xml
@@ -65,6 +65,19 @@
<resource-file src="ChildBrowser.bundle" />
<resource-file src="ChildBrowserViewController.xib" />
+ <config-file target="*-Info.plist" parent="AppId">
+ <string>$APP_ID</string>
+ </config-file>
+
+ <config-file target="*-Info.plist" parent="CFBundleURLTypes">
+ <array>
+ <dict>
+ <key>PackageName</key>
+ <string>$PACKAGE_NAME</string>
+ </dict>
+ </array>
+ </config-file>
+
<header-file src="ChildBrowserCommand.h" />
<header-file src="ChildBrowserViewController.h" />
<header-file src="preserveDirs/PreserveDirsTest.h" preserve-dirs="true" />
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/375459c3/test/plugins/ChildBrowser/plugin.xml
----------------------------------------------------------------------
diff --git a/test/plugins/ChildBrowser/plugin.xml b/test/plugins/ChildBrowser/plugin.xml
index 7641ec0..fef4bdd 100644
--- a/test/plugins/ChildBrowser/plugin.xml
+++ b/test/plugins/ChildBrowser/plugin.xml
@@ -70,6 +70,19 @@
value="ChildBrowserCommand" />
</config-file>
+ <config-file target="*-Info.plist" parent="AppId">
+ <string>$APP_ID</string>
+ </config-file>
+
+ <config-file target="*-Info.plist" parent="CFBundleURLTypes">
+ <array>
+ <dict>
+ <key>PackageName</key>
+ <string>$PACKAGE_NAME</string>
+ </dict>
+ </array>
+ </config-file>
+
<resource-file src="ChildBrowser.bundle" />
<resource-file src="ChildBrowserViewController.xib" />
http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/375459c3/util/plist-helpers.js
----------------------------------------------------------------------
diff --git a/util/plist-helpers.js b/util/plist-helpers.js
new file mode 100644
index 0000000..9a49feb
--- /dev/null
+++ b/util/plist-helpers.js
@@ -0,0 +1,90 @@
+/*
+ *
+ * Copyright 2013 Brett Rudd
+ *
+ * Licensed 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.
+ *
+*/
+
+// contains PLIST utility functions
+
+var et = require('elementtree'),
+ plist = require('plist');
+
+// adds node to doc at selector
+exports.graftPLIST = function (doc, nodes, selector) {
+ var text = et.tostring(nodes, { xml_declaration: false });
+ obj = plist.parseStringSync("<plist>"+text+"</plist>");
+
+ var node = doc[selector];
+ if (node && Array.isArray(node) && Array.isArray(obj))
+ doc[selector] = node.concat(obj);
+ else
+ doc[selector] = obj;
+
+ return true;
+}
+
+// removes node from doc at selector
+exports.prunePLIST = function(doc, nodes, selector) {
+ var text = et.tostring(nodes, { xml_declaration: false }),
+ obj = plist.parseStringSync("<plist>"+text+"</plist>");
+
+ pruneOBJECT(doc, selector, obj);
+
+ return true;
+}
+
+function pruneOBJECT(doc, selector, fragment) {
+ if (Array.isArray(fragment) && Array.isArray(doc[selector])) {
+ var empty = true;
+ for (i in fragment) {
+ for (j in doc[selector]) {
+ empty = pruneOBJECT(doc[selector], j, fragment[i]) && empty;
+ }
+ }
+ if (empty)
+ {
+ delete doc[selector];
+ return true;
+ }
+ }
+ else if (nodeEqual(doc[selector], fragment)) {
+ delete doc[selector];
+ return true;
+ }
+
+ return false;
+}
+
+function nodeEqual(node1, node2) {
+ if (typeof node1 != typeof node2)
+ return false;
+ else if (typeof node1 == 'string') {
+ node2 = escapeRE(node2).replace(new RegExp("\\$[a-zA-Z0-9-_]+","gm"),"(.*?)");
+ return new RegExp('^' + node2 + '$').test(node1);
+ }
+ else {
+ for (var key in node2) {
+ if (!nodeEqual(node1[key], node2[key])) return false;
+ }
+ return true;
+ }
+}
+
+// escape string for use in regex
+function escapeRE(str) {
+ return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\$&");
+};
+