Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apache Cordova : use different settings in config.xml for debug and release

Tags:

cordova

I am looking for a way to use different settings in the config.xml file : some settings for a debug build and other settings for a release build.

For example I need to use this for a debug build :

<content src="https://staging.mywebsite.com" />

And change to this for a release build :

<content src="https://www.mywebsite.com" />

I also need to change values in some <preference /> and <variable /> tags

Cordova-CLI's build command doesn't seem to have any parameter to specify a config.xml to use for the build

For the moment, the only way I can find to do this is to rename my config.xml to config-debug.xml, duplicate it to config-release.xml and change some values in it. And when I need to build, rename the xml I want to use to config.xml

This is not very convenient :/

like image 374
Clemorphy Avatar asked Sep 16 '16 18:09

Clemorphy


2 Answers

If you use different environments that are defined in command line, you could create a template config.xml (the file is config.tpl.xml) and a before_prepare cordova hook to replace the variables in the template with the correct values and save the generated content in config.xml.

The hook is:

#!/usr/bin/env node
var fs = require('fs');
var path = require('path');
var compile = require('es6-template-strings/compile');
var resolveToString = require('es6-template-strings/resolve-to-string');

var ROOT_DIR = process.argv[2];
var FILES = {
    SRC: "config.tpl.xml",
    DEST: "config.xml"
};

var env = process.env.NODE_ENV || 'dev';
var envFile = 'src/environments/environment.' + env + '.json';

var srcFileFull = path.join(ROOT_DIR, FILES.SRC);
var destFileFull = path.join(ROOT_DIR, FILES.DEST);
var configFileFull = path.join(ROOT_DIR, envFile);

var templateData = fs.readFileSync(srcFileFull, 'utf8');

var configData = fs.readFileSync(configFileFull, 'utf8');
var config = JSON.parse(configData);

var compiled = compile(templateData);
var content = resolveToString(compiled, config);

fs.writeFileSync(destFileFull, content);

I use the environment variable as NODE_ENV here, if you use another (like APP_ENV) just do the corresponding changes in the hook above. The hook loads a json from src/environments/environment.[env].json, like environment.dev.json or environment.prod.json (it can be changed in the hook above).

In config.tpl.xml:

<content src="${CONTENT_URL}" />

It would turn into ${CONTENT_URL} into the correct url, based on the environment file used (you need to have a property CONTENT_URL in the environment json files).

For more info, see https://stackoverflow.com/a/46345926/4850646

like image 53
Lucas Basquerotto Avatar answered Oct 15 '22 22:10

Lucas Basquerotto


UPDATE: Ok this IS working for me. I just needed to update the paths to load common.xml and write config.xml.

I am toying around with using one of the hooks, probably the before_prepare and before_run. I need to test it out but this could suffice

I placed my config.xml into a subfolder I created so it doesn't get overwritten, or you can just rename it. And then I use xml2js to load, parse, and also rebuild back to xml.

#!/usr/bin/env node
const xml2js = require('xml2js');
const fs = require('fs');

const parseString = xml2js.parseString;
const builder = new xml2js.Builder();

const stagingDeploymentKey = "YOU_STAGING_KEY";
const productionDeploymentKey = "YOU_PROD_KEY";

/************************************************************
 * load our commong config xml and parse it into a JS object
 */
var commonXML = fs.readFileSync(__dirname + '/../configs/common.xml').toString();
var commonObj;
parseString(commonXML, function (err, result) {
  commonObj = result;
});


module.exports = function(context) {
  // default to staging key
  var CodePushDeploymentKey = stagingDeploymentKey;

  // cordova build ios --release
  if (context.opts.options.release === true) {
    // set KEY to production one
    CodePushDeploymentKey = productionDeploymentKey;
  }

  // replace value in with proper environment specific key
  commonObj.widget.platform[1].preference[0].$.value = CodePushDeploymentKey;

  // write the xml file to the root director of the project so cordova can read it
  var xml = builder.buildObject(commonObj);
  fs.writeFileSync(__dirname + '/../config.xml', xml);
};
like image 40
Francisc0 Avatar answered Oct 15 '22 23:10

Francisc0