afterPrepareHook.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /**
  2. This hook is executed every time we build the project.
  3. It will populate config.xml with plugin specific options.
  4. If you want to specify for which server to build the project - you can create chcpbuild.options and put your servers like so:
  5. {
  6. "build_name_1": {
  7. "config-file": "https://some/path/to/chcp.json"
  8. },
  9. "build_name_2": {
  10. "config-file": "https://some/other/path/to/chcp.json",
  11. "local-development": {
  12. "enabled": true
  13. }
  14. },
  15. ...
  16. }
  17. File contains list of build options in JSON format.
  18. After it is set you can run build command like that:
  19. cordova build -- build_name_1
  20. If no option is provided - hook will use .chcpenv file to build for local development.
  21. More information can be found on https://github.com/nordnet/cordova-hot-code-push.
  22. */
  23. var chcpBuildOptions = require('./lib/chcpBuildOptions.js');
  24. var chcpConfigXmlReader = require('./lib/chcpConfigXmlReader.js');
  25. var chcpConfigXmlWriter = require('./lib/chcpConfigXmlWriter.js');
  26. var iosWKWebViewEngineSupport = require('./lib/iosWKWebViewEngineSupport.js');
  27. var BUILD_OPTION_PREFIX = 'chcp-';
  28. var RELEASE_BUILD_FLAG = '--release';
  29. function logStart() {
  30. console.log('CHCP plugin after prepare hook:');
  31. }
  32. function printLog(msg) {
  33. var formattedMsg = ' ' + msg;
  34. console.log(formattedMsg);
  35. }
  36. /**
  37. * Read arguments from console.
  38. * We are reading only plugin-related preferences.
  39. *
  40. * @param {Object} ctx - cordova context object
  41. * @return {Object} parsed arguments; if none were provided - default options are returned
  42. */
  43. function processConsoleOptions(ctx) {
  44. var consoleOptions = ctx.opts.options;
  45. // If we are using Cordova 5.3.3 or lower - arguments are array of strings.
  46. // Will be removed after some time.
  47. if (consoleOptions instanceof Array) {
  48. return processConsoleOptions_cordova_53(consoleOptions);
  49. }
  50. // for newer version of Cordova - they are an object of properties
  51. return processConsoleOptions_cordova_54(consoleOptions);
  52. }
  53. function processConsoleOptions_cordova_53(consoleOptions) {
  54. var parsedOptions = {
  55. isRelease: false,
  56. buildOption: ''
  57. };
  58. // Search for release flag, or plugin-specific build options.
  59. for (var idx in consoleOptions) {
  60. var opt = consoleOptions[idx];
  61. if (opt === RELEASE_BUILD_FLAG) {
  62. parsedOptions.isRelease = true;
  63. break;
  64. } else if (opt.indexOf(BUILD_OPTION_PREFIX) == 0) {
  65. parsedOptions.buildOption = opt.replace(BUILD_OPTION_PREFIX, '');
  66. break;
  67. }
  68. }
  69. return parsedOptions;
  70. }
  71. function isString(s) {
  72. return typeof(s) === 'string' || s instanceof String;
  73. }
  74. function processConsoleOptions_cordova_54(consoleOptions) {
  75. // For now it's like this for backwards capability.
  76. // Will be simplified later, when Cordova 5.4.x will be used more wide.
  77. var parsedOptions = {
  78. isRelease: false,
  79. buildOption: ''
  80. };
  81. // if building for release - save that and exit
  82. if (consoleOptions.hasOwnProperty('release')) {
  83. parsedOptions.isRelease = consoleOptions.release;
  84. return parsedOptions;
  85. }
  86. // search for plugin specific build options
  87. var args = consoleOptions.argv;
  88. for (var idx in args) {
  89. var opt = args[idx];
  90. if (!isString(opt)) {
  91. continue;
  92. }
  93. if (opt.indexOf(BUILD_OPTION_PREFIX) === -1) {
  94. continue;
  95. }
  96. parsedOptions.buildOption = opt.replace(BUILD_OPTION_PREFIX, '');
  97. break;
  98. }
  99. return parsedOptions;
  100. }
  101. /**
  102. * Try to inject build options according to the arguments from the console.
  103. *
  104. * @param {Object} ctx - cordova context object
  105. * @param {String} optionName - build option name from console; will be mapped to configuration from chcpbuild.options file
  106. * @return {boolean} true - if build option is found and we successfully injected it into config.xml; otherwise - false
  107. */
  108. function prepareWithCustomBuildOption(ctx, optionName, chcpXmlOptions) {
  109. if (optionName.length == 0) {
  110. return false;
  111. }
  112. var buildConfig = chcpBuildOptions.getBuildConfigurationByName(ctx, optionName);
  113. if (buildConfig == null) {
  114. console.warn('Build configuration for "' + optionName + '" not found in chcp.options. Ignoring it.');
  115. return false;
  116. }
  117. console.log('Using config from chcp.options:');
  118. console.log(JSON.stringify(buildConfig, null, 2));
  119. mergeBuildOptions(chcpXmlOptions, buildConfig);
  120. console.log('Resulting config will contain the following preferences:');
  121. console.log(JSON.stringify(chcpXmlOptions, null, 2));
  122. chcpConfigXmlWriter.writeOptions(ctx, chcpXmlOptions);
  123. return true;
  124. }
  125. /**
  126. * Merge build options into current config.xml preferences.
  127. *
  128. * @param {Object} currentXmlOptions - current plugin preferences from config.xml
  129. * @param {Object} buildConfig - build config preferences
  130. */
  131. function mergeBuildOptions(currentXmlOptions, buildConfig) {
  132. for (var key in buildConfig) {
  133. currentXmlOptions[key] = buildConfig[key];
  134. }
  135. }
  136. module.exports = function(ctx) {
  137. var buildConfig,
  138. chcpXmlOptions;
  139. logStart();
  140. // apply iOS-specific stuff
  141. if (ctx.opts.platforms.indexOf('ios') !== -1) {
  142. iosWKWebViewEngineSupport.setWKWebViewEngineMacro(ctx);
  143. }
  144. // if we are running build with --release option - do nothing
  145. var consoleOptions = processConsoleOptions(ctx);
  146. if (consoleOptions.isRelease) {
  147. printLog('Building for release, not changing config.xml');
  148. return;
  149. }
  150. // read plugin preferences from config.xml
  151. chcpXmlOptions = chcpConfigXmlReader.readOptions(ctx);
  152. // if any build option is provided in console - try to map it with chcpbuild.options
  153. if (prepareWithCustomBuildOption(ctx, consoleOptions.buildOption, chcpXmlOptions)) {
  154. return;
  155. }
  156. // if none of the above
  157. if (!chcpXmlOptions['config-file']) {
  158. printLog('config-file preference is not set.');
  159. } else {
  160. printLog('config-file set to ' + chcpXmlOptions['config-file']['url']);
  161. }
  162. };