Return-Path: X-Original-To: apmail-cordova-commits-archive@www.apache.org Delivered-To: apmail-cordova-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E5DEEF172 for ; Wed, 20 Mar 2013 22:55:49 +0000 (UTC) Received: (qmail 9999 invoked by uid 500); 20 Mar 2013 22:55:49 -0000 Delivered-To: apmail-cordova-commits-archive@cordova.apache.org Received: (qmail 9954 invoked by uid 500); 20 Mar 2013 22:55:49 -0000 Mailing-List: contact commits-help@cordova.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: callback-dev@cordova.apache.org Delivered-To: mailing list commits@cordova.apache.org Received: (qmail 9854 invoked by uid 99); 20 Mar 2013 22:55:49 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 20 Mar 2013 22:55:49 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 4E8003E954; Wed, 20 Mar 2013 22:55:49 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: anis@apache.org To: commits@cordova.apache.org Date: Wed, 20 Mar 2013 22:55:52 -0000 Message-Id: <2eb5eb9cd4684b9c910c25c46c6faddd@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [4/6] git commit: Variable substitution on standard config files 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 Authored: Tue Mar 12 21:50:28 2013 -0700 Committer: Brett Rudd 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 --plugin \n'); + console.log('Add a plugin:\n\t' + package.name + ' --platform <'+ platforms +'> --project --variable ="" --plugin \n'); console.log('Remove a plugin:\n\t' + package.name + ' --remove --platform <'+ platforms +'> --project --plugin \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 @@ + + + + + + CFBundleIcons + + CFBundlePrimaryIcon + + CFBundleIconFiles + + icon.png + icon@2x.png + icon-72.png + icon-72@2x.png + + UIPrerenderedIcon + + + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + icon.png + CFBundleIdentifier + com.example.friendstring + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + + NSMainNibFile~ipad + + + 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 @@ + + + + + + CFBundleIcons + + CFBundlePrimaryIcon + + CFBundleIconFiles + + icon.png + icon@2x.png + icon-72.png + icon-72@2x.png + + UIPrerenderedIcon + + + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + icon.png + CFBundleIdentifier + com.example.friendstring + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + + NSMainNibFile~ipad + + + 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 @@ + + + + + + CFBundleIcons + + CFBundlePrimaryIcon + + CFBundleIconFiles + + icon.png + icon@2x.png + icon-72.png + icon-72@2x.png + + UIPrerenderedIcon + + + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + icon.png + CFBundleIdentifier + com.example.friendstring + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + + NSMainNibFile~ipad + + + 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 @@ + + + + + + CFBundleIcons + + CFBundlePrimaryIcon + + CFBundleIconFiles + + icon.png + icon@2x.png + icon-72.png + icon-72@2x.png + + UIPrerenderedIcon + + + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + icon.png + CFBundleIdentifier + com.example.friendstring + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + + NSMainNibFile~ipad + + + 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