From fe29d9faba96e4110549a713aa718bbfb578a348 Mon Sep 17 00:00:00 2001 From: Nikolay Demyankov Date: Wed, 3 Feb 2016 12:40:20 +0100 Subject: [PATCH] Fix for https://github.com/nordnet/cordova-hot-code-push/issues/91 . Need some more cleanup, but should work now. --- scripts/afterPrepareHook.js | 26 ++++++++++++++++------ scripts/lib/chcpBuildOptions.js | 15 +++++++++++-- scripts/lib/chcpConfigXmlReader.js | 19 ++++------------ scripts/lib/chcpConfigXmlWriter.js | 35 +++++++++++------------------- scripts/lib/xmlHelper.js | 17 ++++++++++++--- 5 files changed, 63 insertions(+), 49 deletions(-) diff --git a/scripts/afterPrepareHook.js b/scripts/afterPrepareHook.js index 90f4c8fc..b8af35e4 100644 --- a/scripts/afterPrepareHook.js +++ b/scripts/afterPrepareHook.js @@ -124,7 +124,7 @@ function processConsoleOptions_cordova_54(consoleOptions) { * @param {String} optionName - build option name from console; will be mapped to configuration from chcpbuild.options file * @return {boolean} true - if build option is found and we successfully injected it into config.xml; otherwise - false */ -function prepareWithCustomBuildOption(ctx, optionName) { +function prepareWithCustomBuildOption(ctx, optionName, chcpXmlOptions) { if (optionName.length == 0) { return false; } @@ -137,11 +137,23 @@ function prepareWithCustomBuildOption(ctx, optionName) { console.log('Using config from chcp.options:'); console.log(JSON.stringify(buildConfig, null, 2)); - chcpConfigXmlWriter.writeOptions(ctx, buildConfig); + + mergeBuildOptions(chcpXmlOptions, buildConfig); + + console.log('Resulting config will contain the following preferences:'); + console.log(JSON.stringify(chcpXmlOptions, null, 2)); + + chcpConfigXmlWriter.writeOptions(ctx, chcpXmlOptions); return true; } +function mergeBuildOptions(currentXmlOptions, buildConfig) { + for (var key in buildConfig) { + currentXmlOptions[key] = buildConfig[key]; + } +} + module.exports = function(ctx) { var buildConfig, chcpXmlOptions; @@ -160,18 +172,18 @@ module.exports = function(ctx) { return; } + // read plugin preferences from config.xml + chcpXmlOptions = chcpConfigXmlReader.readOptions(ctx); + // if any build option is provided in console - try to map it with chcpbuild.options - if (prepareWithCustomBuildOption(ctx, consoleOptions.buildOption)) { + if (prepareWithCustomBuildOption(ctx, consoleOptions.buildOption, chcpXmlOptions)) { return; } - // read plugin preferences from config.xml - chcpXmlOptions = chcpConfigXmlReader.readOptions(ctx); - // if none of the above if (chcpXmlOptions['config-file'].length == 0) { printLog('config-file preference is not set.'); } else { - printLog('config-file set to ' + chcpXmlOptions['config-file']); + printLog('config-file set to ' + chcpXmlOptions['config-file']['url']); } }; diff --git a/scripts/lib/chcpBuildOptions.js b/scripts/lib/chcpBuildOptions.js index 09f47e9d..eca80104 100644 --- a/scripts/lib/chcpBuildOptions.js +++ b/scripts/lib/chcpBuildOptions.js @@ -25,7 +25,18 @@ Those options then injected into platform-specific config.xml. return null; } - return chcpBuildOptions[buildName]; + var resultConfig = chcpBuildOptions[buildName]; + + // backwards capability + // TODO: remove this in the next versions + if (resultConfig['config-file'] && !resultConfig['config-file']['url']) { + var url = resultConfig['config-file']; + resultConfig['config-file'] = { + 'url' : url + }; + } + + return resultConfig; } // endregion @@ -53,7 +64,7 @@ Those options then injected into platform-specific config.xml. return objData; } - + // endregion })(); diff --git a/scripts/lib/chcpConfigXmlReader.js b/scripts/lib/chcpConfigXmlReader.js index 529ef3bf..b5e03ea5 100644 --- a/scripts/lib/chcpConfigXmlReader.js +++ b/scripts/lib/chcpConfigXmlReader.js @@ -24,7 +24,7 @@ Helper class to read plugin-specific options from the config.xml. */ function readOptions(ctx) { var configFilePath = path.join(ctx.opts.projectRoot, 'config.xml'), - configXmlContent = xmlHelper.readXmlAsJson(configFilePath); + configXmlContent = xmlHelper.readXmlAsJson(configFilePath, true); return parseConfig(configXmlContent); } @@ -40,22 +40,11 @@ Helper class to read plugin-specific options from the config.xml. * @return {Object} plugin preferences */ function parseConfig(configXmlContent) { - var rootContent = configXmlContent['widget'], - parsedData = { - 'config-file': '' - }; - - // if no tag is found - return empty preferences - if (rootContent['chcp'] == null) { - return parsedData; + if (!configXmlContent.chcp) { + return {}; } - var chcpContent = rootContent.chcp[0]; - if (chcpContent['config-file']) { - parsedData['config-file'] = chcpContent['config-file'][0]['$']['url']; - } - - return parsedData; + return configXmlContent.chcp; } // endregion diff --git a/scripts/lib/chcpConfigXmlWriter.js b/scripts/lib/chcpConfigXmlWriter.js index c4da38a6..ca5dde3a 100644 --- a/scripts/lib/chcpConfigXmlWriter.js +++ b/scripts/lib/chcpConfigXmlWriter.js @@ -128,38 +128,29 @@ We will use it to inject plugin-specific options. return; } - // if config.xml already has chcp preferences - read them - var chcpConfig = {}; - if (configData.widget.hasOwnProperty('chcp') && configData.widget.chcp.lenght > 0) { - chcpConfig = configData.widget.chcp[0]; - } else { - configData.widget['chcp'] = []; - } - // inject new options - injectConfigUrl(chcpConfig, options); + var chcpXmlConfig = {}; + for (var preferenceName in options) { + injectPreference(chcpXmlConfig, preferenceName, options[preferenceName]); + } // write them back to config.xml - configData.widget.chcp[0] = chcpConfig; + configData.widget['chcp'] = []; + configData.widget.chcp.push(chcpXmlConfig); xmlHelper.writeJsonAsXml(configData, configXmlFilePath); }); } /** - * Inject config-file preference if any is set in provided options. + * Inject preference into xml. * - * @param {Object} xml - config.xml data - * @param {Object} options - plugin options to inject + * @param {Object} xml - current xml preferences for the plugin + * @param {String} preferenceName - preference name + * @param {Object} preferenceAttributes - preference attributes */ - function injectConfigUrl(xml, options) { - if (!options.hasOwnProperty('config-file')) { - return; - } - - xml['config-file'] = [{ - '$': { - 'url': options['config-file'] - } + function injectPreference(xml, preferenceName, preferenceAttributes) { + xml[preferenceName] = [{ + '$': preferenceAttributes }]; } diff --git a/scripts/lib/xmlHelper.js b/scripts/lib/xmlHelper.js index 7a2e7849..67ae125a 100644 --- a/scripts/lib/xmlHelper.js +++ b/scripts/lib/xmlHelper.js @@ -4,6 +4,7 @@ Small helper class to read/write from/to xml file. (function() { var fs = require('fs'), + xml2jsProcessors = require('xml2js/lib/processors'), xml2js = require('xml2js'); module.exports = { @@ -17,14 +18,24 @@ Small helper class to read/write from/to xml file. * @param {String} filePath - absolute path to xml file * @return {Object} JSON object with the contents of the xml file */ - function readXmlAsJson(filePath) { + function readXmlAsJson(filePath, simplify) { var xmlData, xmlParser, - parsedData; + parsedData, + parserOptions = {}; + if (simplify) { + parserOptions = { + attrValueProcessors: [xml2jsProcessors.parseNumbers, xml2jsProcessors.parseBooleans], + explicitArray: false, + mergeAttrs: true, + explicitRoot: false + }; + } + + xmlParser = new xml2js.Parser(parserOptions); try { xmlData = fs.readFileSync(filePath); - xmlParser = new xml2js.Parser(); xmlParser.parseString(xmlData, function(err, data) { if (data) { parsedData = data;