cordova-hot-code-push-plugin
Version:
Cordova plugin to perform code updates on the fly
196 lines (162 loc) • 5.86 kB
JavaScript
/**
This hook is executed every time we build the project.
It will populate config.xml with plugin specific options.
If you want to specify for which server to build the project - you can create chcpbuild.options and put your servers like so:
{
"build_name_1": {
"config-file": "https://some/path/to/chcp.json"
},
"build_name_2": {
"config-file": "https://some/other/path/to/chcp.json",
"local-development": {
"enabled": true
}
},
...
}
File contains list of build options in JSON format.
After it is set you can run build command like that:
cordova build -- build_name_1
If no option is provided - hook will use .chcpenv file to build for local development.
More information can be found on https://github.com/nordnet/cordova-hot-code-push.
*/
var chcpBuildOptions = require('./lib/chcpBuildOptions.js');
var chcpConfigXmlReader = require('./lib/chcpConfigXmlReader.js');
var chcpConfigXmlWriter = require('./lib/chcpConfigXmlWriter.js');
var iosWKWebViewEngineSupport = require('./lib/iosWKWebViewEngineSupport.js');
var BUILD_OPTION_PREFIX = 'chcp-';
var RELEASE_BUILD_FLAG = '--release';
function logStart() {
console.log('CHCP plugin after prepare hook:');
}
function printLog(msg) {
var formattedMsg = ' ' + msg;
console.log(formattedMsg);
}
/**
* Read arguments from console.
* We are reading only plugin-related preferences.
*
* @param {Object} ctx - cordova context object
* @return {Object} parsed arguments; if none were provided - default options are returned
*/
function processConsoleOptions(ctx) {
var consoleOptions = ctx.opts.options;
// If we are using Cordova 5.3.3 or lower - arguments are array of strings.
// Will be removed after some time.
if (consoleOptions instanceof Array) {
return processConsoleOptions_cordova_53(consoleOptions);
}
// for newer version of Cordova - they are an object of properties
return processConsoleOptions_cordova_54(consoleOptions);
}
function processConsoleOptions_cordova_53(consoleOptions) {
var parsedOptions = {
isRelease: false,
buildOption: ''
};
// Search for release flag, or plugin-specific build options.
for (var idx in consoleOptions) {
var opt = consoleOptions[idx];
if (opt === RELEASE_BUILD_FLAG) {
parsedOptions.isRelease = true;
break;
} else if (opt.indexOf(BUILD_OPTION_PREFIX) == 0) {
parsedOptions.buildOption = opt.replace(BUILD_OPTION_PREFIX, '');
break;
}
}
return parsedOptions;
}
function isString(s) {
return typeof(s) === 'string' || s instanceof String;
}
function processConsoleOptions_cordova_54(consoleOptions) {
// For now it's like this for backwards capability.
// Will be simplified later, when Cordova 5.4.x will be used more wide.
var parsedOptions = {
isRelease: false,
buildOption: ''
};
// if building for release - save that and exit
if (consoleOptions.hasOwnProperty('release')) {
parsedOptions.isRelease = consoleOptions.release;
return parsedOptions;
}
// search for plugin specific build options
var args = consoleOptions.argv;
for (var idx in args) {
var opt = args[idx];
if (!isString(opt)) {
continue;
}
if (opt.indexOf(BUILD_OPTION_PREFIX) === -1) {
continue;
}
parsedOptions.buildOption = opt.replace(BUILD_OPTION_PREFIX, '');
break;
}
return parsedOptions;
}
/**
* Try to inject build options according to the arguments from the console.
*
* @param {Object} ctx - cordova context object
* @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, chcpXmlOptions) {
if (optionName.length == 0) {
return false;
}
var buildConfig = chcpBuildOptions.getBuildConfigurationByName(ctx, optionName);
if (buildConfig == null) {
console.warn('Build configuration for "' + optionName + '" not found in chcp.options. Ignoring it.');
return false;
}
console.log('Using config from chcp.options:');
console.log(JSON.stringify(buildConfig, null, 2));
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;
}
/**
* Merge build options into current config.xml preferences.
*
* @param {Object} currentXmlOptions - current plugin preferences from config.xml
* @param {Object} buildConfig - build config preferences
*/
function mergeBuildOptions(currentXmlOptions, buildConfig) {
for (var key in buildConfig) {
currentXmlOptions[key] = buildConfig[key];
}
}
module.exports = function(ctx) {
var buildConfig,
chcpXmlOptions;
logStart();
// apply iOS-specific stuff
if (ctx.opts.platforms.indexOf('ios') !== -1) {
iosWKWebViewEngineSupport.setWKWebViewEngineMacro(ctx);
}
// if we are running build with --release option - do nothing
var consoleOptions = processConsoleOptions(ctx);
if (consoleOptions.isRelease) {
printLog('Building for release, not changing config.xml');
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, chcpXmlOptions)) {
return;
}
// if none of the above
if (!chcpXmlOptions['config-file']) {
printLog('config-file preference is not set.');
} else {
printLog('config-file set to ' + chcpXmlOptions['config-file']['url']);
}
};