You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by an...@apache.org on 2013/03/20 23:55:49 UTC

[1/6] git commit: Add variable command line options

Updated Branches:
  refs/heads/master adb5a88a9 -> ced6703a5


Add variable command line options


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugman/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugman/commit/49a231ea
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugman/tree/49a231ea
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugman/diff/49a231ea

Branch: refs/heads/master
Commit: 49a231ea286b210b5674273f07bbbee3c73c1694
Parents: adb5a88
Author: Brett Rudd <br...@gmail.com>
Authored: Tue Mar 12 21:24:05 2013 -0700
Committer: Brett Rudd <br...@gmail.com>
Committed: Tue Mar 12 21:24:05 2013 -0700

----------------------------------------------------------------------
 plugman.js |   39 ++++++++++++++++++++++++++++++++-------
 1 files changed, 32 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/49a231ea/plugman.js
----------------------------------------------------------------------
diff --git a/plugman.js b/plugman.js
index 9ddcd94..d0cee33 100755
--- a/plugman.js
+++ b/plugman.js
@@ -40,7 +40,8 @@ var known_opts = { 'platform' : [ 'ios', 'android', 'bb10' ,'www' ]
             , 'list' : Boolean
             , 'v' : Boolean
             , 'debug' : Boolean
-            };
+            , 'variable' : Array
+            }, shortHands = { 'var' : 'variable' };
 
 var cli_opts = nopt(known_opts);
 
@@ -70,7 +71,15 @@ else if (cli_opts.remove) {
     handlePlugin('uninstall', cli_opts.platform, cli_opts.project, cli_opts.plugin);
 }
 else {
-    handlePlugin('install', cli_opts.platform, cli_opts.project, cli_opts.plugin);
+    var cli_variables = {}
+	if (cli_opts.variable) {
+		cli_opts.variable.forEach(function (variable) {
+			var tokens = variable.split('=');
+			var key = tokens.shift().toUpperCase();
+			if (/^[\w-_]+$/.test(key)) cli_variables[key] = tokens.join('=');
+		});
+	}
+    handlePlugin('install', cli_opts.platform, cli_opts.project, cli_opts.plugin, cli_variables);
 }
 
 function printUsage() {
@@ -81,18 +90,34 @@ function printUsage() {
     console.log('List plugins:\n\t' + package.name + ' --list\n');
 }
 
-function execAction(action, platform, project_dir, plugin_dir) {
+function execAction(action, platform, project_dir, plugin_dir, cli_variables) {
     var xml_path     = path.join(plugin_dir, 'plugin.xml')
       , xml_text     = fs.readFileSync(xml_path, 'utf-8')
       , plugin_et   = new et.ElementTree(et.XML(xml_text));
     
+
+    if (action == 'install') {
+        prefs = plugin_et.findall('./preference') || [];
+        prefs = prefs.concat(plugin_et.findall('./platform[@name="'+platform+'"]/preference'));
+        var missing_vars = []
+        prefs.forEach(function (pref) {
+            var key = pref.attrib["name"].toUpperCase();
+            if (cli_variables[key] == undefined)
+                missing_vars.push(key)
+        })
+        if (missing_vars.length > 0) {
+            console.log('Variable missing: ' + missing_vars.join(", "));
+            return;
+        }
+    }
+
     // run the platform-specific function
-    platform_modules[platform].handlePlugin(action, project_dir, plugin_dir, plugin_et);
+    platform_modules[platform].handlePlugin(action, project_dir, plugin_dir, plugin_et, cli_variables);
     
     console.log('plugin ' + action + 'ed');
 }
 
-function handlePlugin(action, platform, project_dir, plugin_dir) {
+function handlePlugin(action, platform, project_dir, plugin_dir, cli_variables) {
     var plugin_xml_path, async = false;
 
     // clone from git repository
@@ -106,7 +131,7 @@ function handlePlugin(action, platform, project_dir, plugin_dir) {
         async = true;
         plugins.getPluginInfo(plugin_dir,
             function(plugin_info) {
-                execAction(action, platform, project_dir, plugins.clonePluginGitRepo(plugin_info.url));
+                execAction(action, platform, project_dir, plugins.clonePluginGitRepo(plugin_info.url), cli_variables);
             },
             function(e) {
                 throw new Error(action + ' failed. "' + plugin_xml_path + '" not found');
@@ -120,7 +145,7 @@ function handlePlugin(action, platform, project_dir, plugin_dir) {
 
     // check arguments and resolve file paths
     if(!async) {
-        execAction(action, platform, project_dir, plugin_dir);
+        execAction(action, platform, project_dir, plugin_dir, cli_variables);
     }
 }
 


[5/6] git commit: Tests for variable substitution

Posted by an...@apache.org.
Tests for variable substitution


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugman/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugman/commit/aeac68b2
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugman/tree/aeac68b2
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugman/diff/aeac68b2

Branch: refs/heads/master
Commit: aeac68b207b197148d3a655be980c3cf8611acd5
Parents: 7ef9b8f
Author: Brett Rudd <br...@gmail.com>
Authored: Wed Mar 20 13:09:30 2013 -0700
Committer: Brett Rudd <br...@gmail.com>
Committed: Wed Mar 20 13:09:30 2013 -0700

----------------------------------------------------------------------
 test/android-one-install.js                      |   40 +++++++++++++---
 test/android-two-install.js                      |   16 +++---
 test/ios-install.js                              |   28 ++++++------
 test/ios-uninstall.js                            |    4 +-
 test/plugins/ChildBrowser/plugin.xml             |    4 +-
 test/projects/android_one/AndroidManifest.xml    |    2 +
 test/projects/ios/SampleApp/SampleApp-Info.plist |    2 +
 7 files changed, 62 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/aeac68b2/test/android-one-install.js
----------------------------------------------------------------------
diff --git a/test/android-one-install.js b/test/android-one-install.js
index 79ee275..bb8b2a6 100644
--- a/test/android-one-install.js
+++ b/test/android-one-install.js
@@ -64,14 +64,14 @@ exports['should install webless plugin'] = function (test) {
     var dummy_xml_path = path.join(test_dir, 'plugins', 'WeblessPlugin', 'plugin.xml')
     dummy_plugin_et  = new et.ElementTree(et.XML(fs.readFileSync(dummy_xml_path, 'utf-8')));
 
-    android.handlePlugin('install', test_project_dir, dummy_plugin_dir, dummy_plugin_et);
+    android.handlePlugin('install', test_project_dir, dummy_plugin_dir, dummy_plugin_et, { APP_ID: 12345 });
 
     test.done();
 }
 
 exports['should move the js file'] = function (test) {
     var jsPath = path.join(test_dir, 'projects', 'android_one', 'assets', 'www', 'childbrowser.js');
-    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
     fs.stat(jsPath, function(err, stats) {
         test.ok(!err);
         test.ok(stats.isFile());
@@ -80,7 +80,7 @@ exports['should move the js file'] = function (test) {
 }
 
 exports['should move the directory'] = function (test) {
-    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     var assetPath = path.join(test_dir, 'projects', 'android_one', 'assets', 'www', 'childbrowser');
 
@@ -92,7 +92,7 @@ exports['should move the directory'] = function (test) {
 }
 
 exports['should move the src file'] = function (test) {
-    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     var javaPath = path.join(test_dir, 'projects', 'android_one', 'src', 'com', 'phonegap', 'plugins', 'childBrowser', 'ChildBrowser.java');
     test.ok(fs.statSync(javaPath));
@@ -100,7 +100,7 @@ exports['should move the src file'] = function (test) {
 }
 
 exports['should add ChildBrowser to plugins.xml'] = function (test) {
-    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     var pluginsXmlPath = path.join(test_dir, 'projects', 'android_one', 'res', 'xml', 'plugins.xml');
     var pluginsTxt = fs.readFileSync(pluginsXmlPath, 'utf-8'),
@@ -113,7 +113,7 @@ exports['should add ChildBrowser to plugins.xml'] = function (test) {
 }
 
 exports['should add ChildBrowser to AndroidManifest.xml'] = function (test) {
-    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     var manifestPath = path.join(test_dir, 'projects', 'android_one', 'AndroidManifest.xml');
     var manifestTxt = fs.readFileSync(manifestPath, 'utf-8'),
@@ -132,7 +132,7 @@ exports['should add ChildBrowser to AndroidManifest.xml'] = function (test) {
 }
 
 exports['should add whitelist hosts'] = function (test) {
-	android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+	android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     var pluginsXmlPath = path.join(test_dir, 'projects', 'android_one', 'res', 'xml', 'plugins.xml');
     var pluginsTxt = fs.readFileSync(pluginsXmlPath, 'utf-8'),
@@ -140,6 +140,30 @@ exports['should add whitelist hosts'] = function (test) {
 
     test.equal(pluginsDoc.findall("access").length, 2, "/access");
 	test.equal(pluginsDoc.findall("access")[0].attrib["origin"], "build.phonegap.com")
-    test.equal(pluginsDoc.findall("access")[1].attrib["origin"], "s3.amazonaws.com")
+    test.equal(pluginsDoc.findall("access")[1].attrib["origin"], "12345.s3.amazonaws.com")
+    test.done();
+}
+
+exports['should search/replace plugin.xml'] = function (test) {
+	android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
+
+    var pluginsXmlPath = path.join(test_dir, 'projects', 'android_one', 'res', 'xml', 'plugins.xml');
+    var pluginsTxt = fs.readFileSync(pluginsXmlPath, 'utf-8'),
+        pluginsDoc = new et.ElementTree(et.XML(pluginsTxt));
+
+    test.equal(pluginsDoc.findall("access").length, 2, "/access");
+	test.equal(pluginsDoc.findall("access")[0].attrib["origin"], "build.phonegap.com")
+    test.equal(pluginsDoc.findall("access")[1].attrib["origin"], "12345.s3.amazonaws.com")
+    test.done();
+}
+
+exports['should search/replace manifest.xml files'] = function (test) {
+	android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
+
+    var manifestXmlPath = path.join(test_dir, 'projects', 'android_one', 'AndroidManifest.xml');
+    var manifestTxt = fs.readFileSync(manifestXmlPath, 'utf-8'),
+        manifestDoc = new et.ElementTree(et.XML(manifestTxt));
+
+	test.equal(manifestDoc.findall("appid")[0].attrib["value"], "12345")
     test.done();
 }

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/aeac68b2/test/android-two-install.js
----------------------------------------------------------------------
diff --git a/test/android-two-install.js b/test/android-two-install.js
index b01cbbd..b8b4c9d 100644
--- a/test/android-two-install.js
+++ b/test/android-two-install.js
@@ -65,7 +65,7 @@ exports['should install webless plugin'] = function (test) {
     var dummy_xml_path = path.join(test_dir, 'plugins', 'WeblessPlugin', 'plugin.xml')
     dummy_plugin_et  = new et.ElementTree(et.XML(fs.readFileSync(dummy_xml_path, 'utf-8')));
 
-    android.handlePlugin('install', test_project_dir, dummy_plugin_dir, dummy_plugin_et);
+    android.handlePlugin('install', test_project_dir, dummy_plugin_dir, dummy_plugin_et, { APP_ID: 12345 });
 
     test.done();
 }
@@ -73,7 +73,7 @@ exports['should install webless plugin'] = function (test) {
 exports['should move the js file'] = function (test) {
     var jsPath = path.join(test_dir, 'projects', 'android_two', 'assets', 'www', 'childbrowser.js');
 
-    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
     fs.stat(jsPath, function(err, stats) {
         test.ok(!err);
         test.ok(stats.isFile());
@@ -94,7 +94,7 @@ exports['should move the directory'] = function (test) {
 }
 
 exports['should move the src file'] = function (test) {
-    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     var javaPath = path.join(test_dir, 'projects', 'android_two', 'src', 'com', 'phonegap', 'plugins', 'childBrowser', 'ChildBrowser.java');
     test.ok(fs.statSync(javaPath));
@@ -102,7 +102,7 @@ exports['should move the src file'] = function (test) {
 }
 
 exports['should add ChildBrowser to config.xml'] = function (test) {
-    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     var pluginsXmlPath = path.join(test_dir, 'projects', 'android_two', 'res', 'xml', 'config.xml');
     var pluginsTxt = fs.readFileSync(pluginsXmlPath, 'utf-8'),
@@ -115,7 +115,7 @@ exports['should add ChildBrowser to config.xml'] = function (test) {
 }
 
 exports['should add ChildBrowser to AndroidManifest.xml'] = function (test) {
-    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     var manifestPath = path.join(test_dir, 'projects', 'android_two', 'AndroidManifest.xml');
     var manifestTxt = fs.readFileSync(manifestPath, 'utf-8'),
@@ -136,7 +136,7 @@ exports['should add ChildBrowser to AndroidManifest.xml'] = function (test) {
 exports['should not install a plugin that is already installed'] = function (test) {
     var jsPath = path.join(test_dir, 'projects', 'android_two', 'assets', 'www', 'childbrowser.js');
 
-    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
     
     test.throws(function() {android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);}, /already installed/);
 
@@ -144,7 +144,7 @@ exports['should not install a plugin that is already installed'] = function (tes
 }
 
 exports['should add whitelist hosts'] = function (test) {
-	android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+	android.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     var pluginsXmlPath = path.join(test_dir, 'projects', 'android_two', 'res', 'xml', 'config.xml');
     var pluginsTxt = fs.readFileSync(pluginsXmlPath, 'utf-8'),
@@ -152,6 +152,6 @@ exports['should add whitelist hosts'] = function (test) {
 
     test.equal(pluginsDoc.findall("access").length, 3, "/access");
 	test.equal(pluginsDoc.findall("access")[1].attrib["origin"], "build.phonegap.com")
-    test.equal(pluginsDoc.findall("access")[2].attrib["origin"], "s3.amazonaws.com")
+    test.equal(pluginsDoc.findall("access")[2].attrib["origin"], "12345.s3.amazonaws.com")
     test.done();
 }

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/aeac68b2/test/ios-install.js
----------------------------------------------------------------------
diff --git a/test/ios-install.js b/test/ios-install.js
index e625fe9..438f48f 100644
--- a/test/ios-install.js
+++ b/test/ios-install.js
@@ -65,14 +65,14 @@ exports['should install webless plugin'] = function (test) {
     var dummy_xml_path = path.join(test_dir, 'plugins', 'WeblessPlugin', 'plugin.xml')
     var dummy_plugin_et  = new et.ElementTree(et.XML(fs.readFileSync(dummy_xml_path, 'utf-8')));
 
-    ios.handlePlugin('install', test_project_dir, dummy_plugin_dir, dummy_plugin_et);
+    ios.handlePlugin('install', test_project_dir, dummy_plugin_dir, dummy_plugin_et, { APP_ID: 12345 });
 
     test.done();
 }
 
 exports['should move the js file'] = function (test) {
     // run the platform-specific function
-    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     var jsPath = path.join(test_dir, 'projects', 'ios', 'www', 'childbrowser.js');
     test.ok(fs.existsSync(jsPath));
@@ -81,7 +81,7 @@ exports['should move the js file'] = function (test) {
 
 exports['should move the source files'] = function (test) {
     // run the platform-specific function
-    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     test.ok(fs.existsSync(srcDir + '/ChildBrowserCommand.m'))
     test.ok(fs.existsSync(srcDir + '/ChildBrowserViewController.m'))
@@ -92,7 +92,7 @@ exports['should move the source files'] = function (test) {
 
 exports['should move the header files'] = function (test) {
     // run the platform-specific function
-    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     test.ok(fs.statSync(srcDir + '/ChildBrowserCommand.h'));
     test.ok(fs.statSync(srcDir + '/ChildBrowserViewController.h'));
@@ -103,7 +103,7 @@ exports['should move the header files'] = function (test) {
 
 exports['should move the xib file'] = function (test) {
     // run the platform-specific function
-    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     test.ok(fs.statSync(resDir + '/ChildBrowserViewController.xib'));
     test.done();
@@ -111,7 +111,7 @@ exports['should move the xib file'] = function (test) {
 
 exports['should move the bundle'] = function (test) {
     // run the platform-specific function
-    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     var bundle = fs.statSync(resDir + '/ChildBrowser.bundle');
 
@@ -122,7 +122,7 @@ exports['should move the bundle'] = function (test) {
 
 exports['should edit PhoneGap.plist'] = function (test) {
     // run the platform-specific function
-    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     var plistPath = test_project_dir + '/SampleApp/PhoneGap.plist';
     var obj = plist.parseFileSync(plistPath);
@@ -132,7 +132,7 @@ exports['should edit PhoneGap.plist'] = function (test) {
         
     test.equal(obj.ExternalHosts.length, 2)    
     test.equal(obj.ExternalHosts[0], "build.phonegap.com")
-    test.equal(obj.ExternalHosts[1], "s3.amazonaws.com")
+    test.equal(obj.ExternalHosts[1], "12345.s3.amazonaws.com")
 
     test.done();
 }
@@ -172,7 +172,7 @@ exports['should edit config.xml even when using old <plugins-plist> approach'] =
     var dummy_plugin_et  = new et.ElementTree(et.XML(fs.readFileSync(dummy_xml_path, 'utf-8')));
 
     // run the platform-specific function
-    ios.handlePlugin('install', project_dir, dummy_plugin_dir, dummy_plugin_et);
+    ios.handlePlugin('install', project_dir, dummy_plugin_dir, dummy_plugin_et, { APP_ID: 12345 });
     
     var configXmlPath = path.join(project_dir, 'SampleApp', 'config.xml');
     var pluginsTxt = fs.readFileSync(configXmlPath, 'utf-8'),
@@ -183,14 +183,14 @@ exports['should edit config.xml even when using old <plugins-plist> approach'] =
     test.ok(pluginsDoc.find(expected));
     test.equal(pluginsDoc.findall("access").length, 3, "/access");
     test.equal(pluginsDoc.findall("access")[1].attrib["origin"], "build.phonegap.com")
-    test.equal(pluginsDoc.findall("access")[2].attrib["origin"], "s3.amazonaws.com")
+    test.equal(pluginsDoc.findall("access")[2].attrib["origin"], "12345.s3.amazonaws.com")
 
     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);
+    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     var projPath = test_project_dir + '/SampleApp.xcodeproj/project.pbxproj';
 
@@ -205,7 +205,7 @@ exports['should edit the pbxproj file'] = function (test) {
 
 exports['should add the framework references to the pbxproj file'] = function (test) {
     // run the platform-specific function
-    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
     var projPath = test_project_dir + '/SampleApp.xcodeproj/project.pbxproj',
         projContents = fs.readFileSync(projPath, 'utf8'),
         projLines = projContents.split("\n"),
@@ -225,7 +225,7 @@ exports['should add the framework references to the pbxproj file'] = function (t
 
 exports['should add the framework references with weak option to the pbxproj file'] = function (test) {
     // run the platform-specific function
-    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
     var projPath = test_project_dir + '/SampleApp.xcodeproj/project.pbxproj',
         projContents = fs.readFileSync(projPath, 'utf8'),
         projLines = projContents.split("\n"),
@@ -251,7 +251,7 @@ exports['should add the framework references with weak option to the pbxproj fil
 }
 
 exports['should not install a plugin that is already installed'] = function (test) {
-    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
 
     test.throws(function(){ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et); }, 
                 /already installed/

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/aeac68b2/test/ios-uninstall.js
----------------------------------------------------------------------
diff --git a/test/ios-uninstall.js b/test/ios-uninstall.js
index 4de23a6..8d7692e 100644
--- a/test/ios-uninstall.js
+++ b/test/ios-uninstall.js
@@ -125,7 +125,7 @@ exports['should remove the bundle'] = function (test) {
 
 exports['should edit PhoneGap.plist'] = function (test) {
     // run the platform-specific function
-    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et);
+    ios.handlePlugin('install', test_project_dir, test_plugin_dir, plugin_et, { APP_ID: 12345 });
     ios.handlePlugin('uninstall', test_project_dir, test_plugin_dir, plugin_et);
 
     var plistPath = test_project_dir + '/SampleApp/PhoneGap.plist';
@@ -136,7 +136,7 @@ exports['should edit PhoneGap.plist'] = function (test) {
         
     test.equal(obj.ExternalHosts.length, 2)    
     test.equal(obj.ExternalHosts[0], "build.phonegap.com")
-    test.equal(obj.ExternalHosts[1], "s3.amazonaws.com")
+    test.equal(obj.ExternalHosts[1], "12345.s3.amazonaws.com")
 
     test.done();
 }

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/aeac68b2/test/plugins/ChildBrowser/plugin.xml
----------------------------------------------------------------------
diff --git a/test/plugins/ChildBrowser/plugin.xml b/test/plugins/ChildBrowser/plugin.xml
index 9e87f10..afd4d0b 100644
--- a/test/plugins/ChildBrowser/plugin.xml
+++ b/test/plugins/ChildBrowser/plugin.xml
@@ -28,8 +28,8 @@
     <asset src="www/childbrowser.js" target="childbrowser.js" />
     <asset src="www/childbrowser" target="childbrowser" />
 
-	<access origin="build.phonegap.com" />
-	<access origin="s3.amazonaws.com" />
+	  <access origin="build.phonegap.com" />
+	  <access origin="$APP_ID.s3.amazonaws.com" />
 	
     <!-- android -->
     <platform name="android">

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/aeac68b2/test/projects/android_one/AndroidManifest.xml
----------------------------------------------------------------------
diff --git a/test/projects/android_one/AndroidManifest.xml b/test/projects/android_one/AndroidManifest.xml
index 0c52803..0979b02 100644
--- a/test/projects/android_one/AndroidManifest.xml
+++ b/test/projects/android_one/AndroidManifest.xml
@@ -48,6 +48,8 @@
 
     <uses-feature android:name="android.hardware.camera" />
     <uses-feature android:name="android.hardware.camera.autofocus" />
+    
+    <appid value="$APP_ID" />
 
     <application android:icon="@drawable/icon" android:label="@string/app_name"
     	android:debuggable="true">

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/aeac68b2/test/projects/ios/SampleApp/SampleApp-Info.plist
----------------------------------------------------------------------
diff --git a/test/projects/ios/SampleApp/SampleApp-Info.plist b/test/projects/ios/SampleApp/SampleApp-Info.plist
index 6010b61..08b9ee3 100644
--- a/test/projects/ios/SampleApp/SampleApp-Info.plist
+++ b/test/projects/ios/SampleApp/SampleApp-Info.plist
@@ -74,5 +74,7 @@
 	<string></string>
 	<key>NSMainNibFile~ipad</key>
 	<string></string>
+	<key>AppId</key>
+	<string>$APP_ID</string>
 </dict>
 </plist>


[3/6] git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/cordova-plugman

Posted by an...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/cordova-plugman


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugman/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugman/commit/970bf97b
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugman/tree/970bf97b
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugman/diff/970bf97b

Branch: refs/heads/master
Commit: 970bf97bb47f4a614926ea5b368238e9576d3fdd
Parents: 122b38c adb5a88
Author: Anis Kadri <an...@gmail.com>
Authored: Mon Mar 18 15:33:33 2013 -0700
Committer: Anis Kadri <an...@gmail.com>
Committed: Mon Mar 18 15:33:33 2013 -0700

----------------------------------------------------------------------
 platforms/android.js |    8 +++++++-
 platforms/bb10.js    |    5 ++++-
 platforms/ios.js     |   18 ++++++++++--------
 3 files changed, 21 insertions(+), 10 deletions(-)
----------------------------------------------------------------------



[2/6] git commit: Issue #35 problem with license header and shebang

Posted by an...@apache.org.
Issue #35 problem with license header and shebang


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugman/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugman/commit/122b38ca
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugman/tree/122b38ca
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugman/diff/122b38ca

Branch: refs/heads/master
Commit: 122b38ca44a4285b7f0ef92d5182ad5c17a12c39
Parents: c5f4335
Author: Anis Kadri <an...@gmail.com>
Authored: Wed Mar 13 17:12:41 2013 -0700
Committer: Anis Kadri <an...@gmail.com>
Committed: Wed Mar 13 17:12:41 2013 -0700

----------------------------------------------------------------------
 plugman.js |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/122b38ca/plugman.js
----------------------------------------------------------------------
diff --git a/plugman.js b/plugman.js
index 9f4bdeb..9ddcd94 100644
--- a/plugman.js
+++ b/plugman.js
@@ -1,3 +1,4 @@
+#!/usr/bin/env node
 /*
  *
  * Copyright 2013 Anis Kadri
@@ -17,8 +18,6 @@
  *
 */
 
-#!/usr/bin/env node
-
 // copyright (c) 2013 Andrew Lunny, Adobe Systems
 var fs = require('fs')
   , path = require('path')


[6/6] git commit: Merge branch 'variable-substitution' of https://github.com/phonegap-build/pluginstall

Posted by an...@apache.org.
Merge branch 'variable-substitution' of https://github.com/phonegap-build/pluginstall


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugman/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugman/commit/ced6703a
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugman/tree/ced6703a
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugman/diff/ced6703a

Branch: refs/heads/master
Commit: ced6703a559ca18257df99b362b54122593daeb0
Parents: 970bf97 aeac68b
Author: Anis Kadri <an...@gmail.com>
Authored: Wed Mar 20 15:44:13 2013 -0700
Committer: Anis Kadri <an...@gmail.com>
Committed: Wed Mar 20 15:44:13 2013 -0700

----------------------------------------------------------------------
 platforms/android.js                               |   21 +++--
 platforms/ios.js                                   |   48 ++++++---
 plugman.js                                         |   45 +++++++--
 test/android-one-install.js                        |   40 ++++++--
 test/android-two-install.js                        |   16 ++--
 test/ios-install.js                                |   28 +++---
 test/ios-uninstall.js                              |    4 +-
 test/plugins/ChildBrowser/plugin.xml               |    4 +-
 test/projects/FriendSting-Info.plist               |   78 ++++++++++++++
 test/projects/android_one/AndroidManifest.xml      |    2 +
 test/projects/ios-config-xml/SampleApp-Info.plist  |   78 ++++++++++++++
 .../ios-config-xml/SampleApp/SampleApp-Info.plist  |   78 ++++++++++++++
 test/projects/ios/SampleApp/SampleApp-Info.plist   |   80 +++++++++++++++
 util/search-and-replace.js                         |   37 +++++++
 14 files changed, 495 insertions(+), 64 deletions(-)
----------------------------------------------------------------------



[4/6] git commit: Variable substitution on standard config files

Posted by an...@apache.org.
Variable substitution on standard config files


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugman/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugman/commit/7ef9b8fe
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugman/tree/7ef9b8fe
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugman/diff/7ef9b8fe

Branch: refs/heads/master
Commit: 7ef9b8fead89be6c3b1055bc1c4d860cbbf2997c
Parents: 49a231e
Author: Brett Rudd <br...@gmail.com>
Authored: Tue Mar 12 21:50:28 2013 -0700
Committer: Brett Rudd <br...@gmail.com>
Committed: Tue Mar 19 16:36:09 2013 -0700

----------------------------------------------------------------------
 platforms/android.js                               |   21 +++--
 platforms/ios.js                                   |   48 +++++++---
 plugman.js                                         |   14 ++-
 test/projects/FriendSting-Info.plist               |   78 +++++++++++++++
 test/projects/ios-config-xml/SampleApp-Info.plist  |   78 +++++++++++++++
 .../ios-config-xml/SampleApp/SampleApp-Info.plist  |   78 +++++++++++++++
 test/projects/ios/SampleApp/SampleApp-Info.plist   |   78 +++++++++++++++
 util/search-and-replace.js                         |   37 +++++++
 8 files changed, 405 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/7ef9b8fe/platforms/android.js
----------------------------------------------------------------------
diff --git a/platforms/android.js b/platforms/android.js
index 892f7b0..2f78bf4 100644
--- a/platforms/android.js
+++ b/platforms/android.js
@@ -23,13 +23,13 @@ var fs = require('fs')  // use existsSync in 0.6.x
    , shell = require('shelljs')
    , et = require('elementtree')
    , getConfigChanges = require('../util/config-changes')
+   , searchAndReplace = require('../util/search-and-replace')
+   , xml_helpers = require('../util/xml-helpers')
+   , assetsDir = 'assets/www'
+   , sourceDir = 'src';
 
-   , assetsDir = 'assets/www'  // relative path to project's web assets
-   , sourceDir = 'src'
-   , xml_helpers = require(path.join(__dirname, '..', 'util', 'xml-helpers'));
 
-
-exports.handlePlugin = function (action, project_dir, plugin_dir, plugin_et) {
+exports.handlePlugin = function (action, project_dir, plugin_dir, plugin_et, variables) {
     var plugin_id = plugin_et._root.attrib['id']
       , version = plugin_et._root.attrib['version']
       , external_hosts = []
@@ -39,9 +39,10 @@ exports.handlePlugin = function (action, project_dir, plugin_dir, plugin_et) {
       , platformTag = plugin_et.find('./platform[@name="android"]')
       , sourceFiles = platformTag.findall('./source-file')
       , libFiles = platformTag.findall('./library-file')
-      , PACKAGE_NAME = androidPackageName(project_dir)
       , configChanges = getConfigChanges(platformTag);
 
+    variables = variables || {}
+
 	// get config.xml filename
 	var config_xml_filename = 'res/xml/config.xml';
     if(fs.existsSync(path.resolve(project_dir, 'res/xml/plugins.xml'))) {
@@ -173,9 +174,15 @@ exports.handlePlugin = function (action, project_dir, plugin_dir, plugin_et) {
         });
 
         output = xmlDoc.write({indent: 4});
-        output = output.replace(/\$PACKAGE_NAME/g, PACKAGE_NAME);
         fs.writeFileSync(filepath, output);
     });
+    
+    if (action == 'install') {
+        variables['PACKAGE_NAME'] = androidPackageName(project_dir);
+        searchAndReplace(path.resolve(project_dir, config_xml_filename), variables);
+        searchAndReplace(path.resolve(project_dir, 'AndroidManifest.xml'), variables);
+    }
+    
 }
 
 

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/7ef9b8fe/platforms/ios.js
----------------------------------------------------------------------
diff --git a/platforms/ios.js b/platforms/ios.js
index b0cec42..6290ebc 100644
--- a/platforms/ios.js
+++ b/platforms/ios.js
@@ -25,20 +25,24 @@ var path = require('path')
   , plist = require('plist')
   , bplist = require('bplist-parser')
   , shell = require('shelljs')
-  , xml_helpers = require(path.join(__dirname, '..', 'util', 'xml-helpers'))
-  , getConfigChanges = require(path.join(__dirname, '..', 'util', 'config-changes'))
+  , xml_helpers = require('../util/xml-helpers')
+  , searchAndReplace = require('../util/search-and-replace')
+  , getConfigChanges = require('../util/config-changes')
   , assetsDir = 'www';    // relative path to project's web assets
 
-exports.handlePlugin = function (action, project_dir, plugin_dir, plugin_et) {
+exports.handlePlugin = function (action, project_dir, plugin_dir, plugin_et, variables) {
     var plugin_id = plugin_et._root.attrib['id']
       , version = plugin_et._root.attrib['version']
       , i = 0
       , matched;
+
+    variables = variables || {}
+
     // grab and parse pbxproj
     // we don't want CordovaLib's xcode project
     var project_files = glob.sync(project_dir + '/*.xcodeproj/project.pbxproj');
     
-    if (!project_files.length) throw "does not appear to be an xcode project";
+    if (!project_files.length) throw "does not appear to be an xcode project (no xcode project file)";
     var pbxPath = project_files[0];
 
     var xcodeproj = xcode.project(project_files[0]);
@@ -50,23 +54,30 @@ exports.handlePlugin = function (action, project_dir, plugin_dir, plugin_et) {
                         glob.sync(project_dir + '/**/{PhoneGap,Cordova}.plist')
                        );
 
-    if (!config_files.length) {
-        throw "does not appear to be a PhoneGap project";
-    }
-
     config_files = config_files.filter(function (val) {
         return !(/^build\//.test(val));
     });
 
-    var pluginsDir = path.resolve(config_files[0], '..', 'Plugins');
-    var resourcesDir = path.resolve(config_files[0], '..', 'Resources');
+    if (!config_files.length) {
+        throw "does not appear to be a PhoneGap project";
+    }
 
+    var config_file = config_files[0];
+    var xcode_dir = path.dirname(config_file);
+    var pluginsDir = path.resolve(xcode_dir, 'Plugins');
+    var resourcesDir = path.resolve(xcode_dir, 'Resources');
+    
+    // get project plist for package name
+    var project_plists = glob.sync(xcode_dir + '/*-Info.plist');
+    var projectPListPath = project_plists[0];
+    
     // collision detection 
-    if(action == "install" && pluginInstalled(plugin_et, config_files[0])) {
+    if(action == "install" && pluginInstalled(plugin_et, config_file)) {
         throw "Plugin "+plugin_id+" already installed"
-    } else if(action == "uninstall" && !pluginInstalled(plugin_et, config_files[0])) {
+    } else if(action == "uninstall" && !pluginInstalled(plugin_et, config_file)) {
         throw "Plugin "+plugin_id+" not installed"
     }
+    
     var assets = plugin_et.findall('./asset'),
         platformTag = plugin_et.find('./platform[@name="ios"]'),
         sourceFiles = platformTag.findall('./source-file'),
@@ -161,10 +172,19 @@ exports.handlePlugin = function (action, project_dir, plugin_dir, plugin_et) {
         }
     });
 
-    updateConfig(action, config_files[0], plugin_et);
-
     // write out xcodeproj file
     fs.writeFileSync(pbxPath, xcodeproj.writeSync());
+
+    // add plugin and whitelisted hosts
+    updateConfig(action, config_file, plugin_et);
+    
+    if (action == 'install') {
+        variables['PACKAGE_NAME'] = plist.parseFileSync(projectPListPath).CFBundleIdentifier;
+        searchAndReplace(pbxPath, variables);
+        searchAndReplace(projectPListPath, variables);
+        searchAndReplace(config_file, variables);
+    }
+    
 }
 
 function getRelativeDir(file) {

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/7ef9b8fe/plugman.js
----------------------------------------------------------------------
diff --git a/plugman.js b/plugman.js
index d0cee33..a38b76e 100755
--- a/plugman.js
+++ b/plugman.js
@@ -85,7 +85,7 @@ else {
 function printUsage() {
     platforms = known_opts.platform.join('|');
     console.log('Usage\n---------');
-    console.log('Add a plugin:\n\t' + package.name + ' --platform <'+ platforms +'> --project <directory> --plugin <directory|git-url|name>\n');
+    console.log('Add a plugin:\n\t' + package.name + ' --platform <'+ platforms +'> --project <directory> --variable <preference_name>="<substituion>" --plugin <directory|git-url|name>\n');
     console.log('Remove a plugin:\n\t' + package.name + ' --remove --platform <'+ platforms +'> --project <directory> --plugin <directory|git-url|name>\n');
     console.log('List plugins:\n\t' + package.name + ' --list\n');
 }
@@ -93,26 +93,28 @@ function printUsage() {
 function execAction(action, platform, project_dir, plugin_dir, cli_variables) {
     var xml_path     = path.join(plugin_dir, 'plugin.xml')
       , xml_text     = fs.readFileSync(xml_path, 'utf-8')
-      , plugin_et   = new et.ElementTree(et.XML(xml_text));
-    
+      , plugin_et    = new et.ElementTree(et.XML(xml_text))
+      , filtered_variables = {};
 
     if (action == 'install') {
         prefs = plugin_et.findall('./preference') || [];
         prefs = prefs.concat(plugin_et.findall('./platform[@name="'+platform+'"]/preference'));
-        var missing_vars = []
+        var missing_vars = [];
         prefs.forEach(function (pref) {
             var key = pref.attrib["name"].toUpperCase();
             if (cli_variables[key] == undefined)
                 missing_vars.push(key)
+            else
+                filtered_variables[key] = cli_variables[key]
         })
         if (missing_vars.length > 0) {
             console.log('Variable missing: ' + missing_vars.join(", "));
             return;
         }
     }
-
+    
     // run the platform-specific function
-    platform_modules[platform].handlePlugin(action, project_dir, plugin_dir, plugin_et, cli_variables);
+    platform_modules[platform].handlePlugin(action, project_dir, plugin_dir, plugin_et, filtered_variables);
     
     console.log('plugin ' + action + 'ed');
 }

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/7ef9b8fe/test/projects/FriendSting-Info.plist
----------------------------------------------------------------------
diff --git a/test/projects/FriendSting-Info.plist b/test/projects/FriendSting-Info.plist
new file mode 100644
index 0000000..6010b61
--- /dev/null
+++ b/test/projects/FriendSting-Info.plist
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+#
+# 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.
+#
+-->
+<plist version="1.0">
+<dict>
+	<key>CFBundleIcons</key>
+	<dict>
+		<key>CFBundlePrimaryIcon</key>
+		<dict>
+			<key>CFBundleIconFiles</key>
+			<array>
+                <string>icon.png</string>
+                <string>icon@2x.png</string>
+                <string>icon-72.png</string>
+                <string>icon-72@2x.png</string>
+			</array>
+			<key>UIPrerenderedIcon</key>
+			<false/>
+		</dict>
+	</dict>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+	</array>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDisplayName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIconFile</key>
+	<string>icon.png</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.example.friendstring</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.0</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>NSMainNibFile</key>
+	<string></string>
+	<key>NSMainNibFile~ipad</key>
+	<string></string>
+</dict>
+</plist>

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/7ef9b8fe/test/projects/ios-config-xml/SampleApp-Info.plist
----------------------------------------------------------------------
diff --git a/test/projects/ios-config-xml/SampleApp-Info.plist b/test/projects/ios-config-xml/SampleApp-Info.plist
new file mode 100644
index 0000000..6010b61
--- /dev/null
+++ b/test/projects/ios-config-xml/SampleApp-Info.plist
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+#
+# 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.
+#
+-->
+<plist version="1.0">
+<dict>
+	<key>CFBundleIcons</key>
+	<dict>
+		<key>CFBundlePrimaryIcon</key>
+		<dict>
+			<key>CFBundleIconFiles</key>
+			<array>
+                <string>icon.png</string>
+                <string>icon@2x.png</string>
+                <string>icon-72.png</string>
+                <string>icon-72@2x.png</string>
+			</array>
+			<key>UIPrerenderedIcon</key>
+			<false/>
+		</dict>
+	</dict>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+	</array>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDisplayName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIconFile</key>
+	<string>icon.png</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.example.friendstring</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.0</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>NSMainNibFile</key>
+	<string></string>
+	<key>NSMainNibFile~ipad</key>
+	<string></string>
+</dict>
+</plist>

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/7ef9b8fe/test/projects/ios-config-xml/SampleApp/SampleApp-Info.plist
----------------------------------------------------------------------
diff --git a/test/projects/ios-config-xml/SampleApp/SampleApp-Info.plist b/test/projects/ios-config-xml/SampleApp/SampleApp-Info.plist
new file mode 100644
index 0000000..6010b61
--- /dev/null
+++ b/test/projects/ios-config-xml/SampleApp/SampleApp-Info.plist
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+#
+# 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.
+#
+-->
+<plist version="1.0">
+<dict>
+	<key>CFBundleIcons</key>
+	<dict>
+		<key>CFBundlePrimaryIcon</key>
+		<dict>
+			<key>CFBundleIconFiles</key>
+			<array>
+                <string>icon.png</string>
+                <string>icon@2x.png</string>
+                <string>icon-72.png</string>
+                <string>icon-72@2x.png</string>
+			</array>
+			<key>UIPrerenderedIcon</key>
+			<false/>
+		</dict>
+	</dict>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+	</array>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDisplayName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIconFile</key>
+	<string>icon.png</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.example.friendstring</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.0</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>NSMainNibFile</key>
+	<string></string>
+	<key>NSMainNibFile~ipad</key>
+	<string></string>
+</dict>
+</plist>

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/7ef9b8fe/test/projects/ios/SampleApp/SampleApp-Info.plist
----------------------------------------------------------------------
diff --git a/test/projects/ios/SampleApp/SampleApp-Info.plist b/test/projects/ios/SampleApp/SampleApp-Info.plist
new file mode 100644
index 0000000..6010b61
--- /dev/null
+++ b/test/projects/ios/SampleApp/SampleApp-Info.plist
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+#
+# 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.
+#
+-->
+<plist version="1.0">
+<dict>
+	<key>CFBundleIcons</key>
+	<dict>
+		<key>CFBundlePrimaryIcon</key>
+		<dict>
+			<key>CFBundleIconFiles</key>
+			<array>
+                <string>icon.png</string>
+                <string>icon@2x.png</string>
+                <string>icon-72.png</string>
+                <string>icon-72@2x.png</string>
+			</array>
+			<key>UIPrerenderedIcon</key>
+			<false/>
+		</dict>
+	</dict>
+	<key>UISupportedInterfaceOrientations~ipad</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+	</array>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDisplayName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIconFile</key>
+	<string>icon.png</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.example.friendstring</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.0</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>NSMainNibFile</key>
+	<string></string>
+	<key>NSMainNibFile~ipad</key>
+	<string></string>
+</dict>
+</plist>

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/7ef9b8fe/util/search-and-replace.js
----------------------------------------------------------------------
diff --git a/util/search-and-replace.js b/util/search-and-replace.js
new file mode 100644
index 0000000..dc1f931
--- /dev/null
+++ b/util/search-and-replace.js
@@ -0,0 +1,37 @@
+#!/usr/bin/env node
+/*
+ *
+ * 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.
+ *
+*/
+
+var glob = require('glob'),
+    fs = require('fs');
+
+module.exports = function searchAndReplace(srcGlob, variables) {
+  var files = glob.sync(srcGlob);
+  for (var i in files) {
+    var file = files[i];
+    if (fs.lstatSync(file).isFile()) {
+      var contents = fs.readFileSync(file, "utf-8");
+      for (var key in variables) {
+          var regExp = new RegExp("\\$" + key, "g");
+          contents = contents.replace(regExp, variables[key]);
+      }
+      fs.writeFileSync(file, contents);
+    }
+  }
+}
\ No newline at end of file