const fs = require('fs'),
path = require('path');
/*fsx = require("fs-extra"),
_ = require("lodash"),
xml2js = require('xml2js');*/
// injected after from vipera-de-cli
var fsx = undefined;
var _ = undefined;
var xml2js = undefined;
var gradle = undefined;
var Q = undefined;
function parsePrefenceArray(toParse){
if(!toParse){
return [];
}
return _.map(toParse,function(item){
return item.$
});
}
function readFileAsXml(path,callback){
var parser = new xml2js.Parser();
fs.readFile(path, function(err, data) {
if(err){
callback(err,undefined);
return;
}
parser.parseString(data, function (err, result){
if(err){
callback(err,undefined);
return;
}
callback(undefined,result);
});
});
}
function createPlatformPreference(platformFromXml){
console.log("createPlatformPreference");
return _.map(platformFromXml,function(platform){
return {
name: platform.$.name,
preferences: parsePrefenceArray(platform.preference)
}
});
}
function getVariantsByEnv(variantsWrapper){
var variantParam = process.env.CORDOVA_BUILD_VARIANT;
console.info(" >>>> CORDOVA_BUILD_VARIANT: " + variantParam);
var selected=undefined;
if(variantParam){
_.forEach(variantsWrapper.variants.variant,function(single){
if(single.$.name === variantParam){
selected=single;
}
});
}
return selected;
}
function mergeArray(base,patch){
var toAdd = _.filter(patch,function(item){
var pIndex= _.findIndex(base,function(pItem){
return item.$.name === pItem.$.name
});
if(pIndex >= 0){
console.log("patch preference: " + base[pIndex].$.name);
base[pIndex].$.value=item.$.value;
return false;
}
return true
});
_.forEach(toAdd,function(pref){
base[base.length] = pref;
});
}
module.exports = function(context) {
linkViperaCli();
try{
fsx = context.requireCordovaModule('vipera-de-cli').fsx;
_ = context.requireCordovaModule('vipera-de-cli').lodash;
xml2js = context.requireCordovaModule('vipera-de-cli').xml2js;
Q = context.requireCordovaModule('q');
gradle = context.requireCordovaModule('vipera-de-cli').gradle;
} catch(ex) {
fsx = require('vipera-de-cli').fsx;
_ = require('vipera-de-cli').lodash;
xml2js = require('vipera-de-cli').xml2js;
Q = require('q');
gradle = require('vipera-de-cli').gradle;
}
var deferral = new Q.defer();
clearAndroidBuildExtras(context);
console.log("Begin variants hook for build");
var projectRoot = context.opts.projectRoot;
var variantsDir = projectRoot + "/variants";
var platforms = context.opts.platforms;
console.log("platform: ",JSON.stringify(platforms));
var plugins = context.opts.cordova.plugins;
console.log("plugins: ",JSON.stringify(plugins));
//COPY config.xml file
console.log("Copy config.xml to config_original.xml");
fsx.copySync(projectRoot + '/config.xml', projectRoot + '/config_original.xml');
var parser = new xml2js.Parser();
fs.readFile(projectRoot + '/config.xml', function(err, data) {
parser.parseString(data, function (err, result) {
if(err){
console.error(err);
deferral.reject(err);
return;
}
console.log('Loading xml done');
//console.log(JSON.stringify(result, null, "\t"));
//var globalPreferences = parsePrefenceArray(result.widget.preference);
//var platformPreferences = createPlatformPreference(result.widget.platform);
//console.log("globalPreferences: " + JSON.stringify(globalPreferences,null,4));
//console.log("platformPreferences: " + JSON.stringify(platformPreferences,null,4));
//read variants
console.log("Begin loading of variants");
if (!fs.existsSync(variantsDir)) {
console.warn("No variants dir found");
deferral.resolve();
return;
}
var variantsFiles=fs.readdirSync(variantsDir);
console.log("variants files: " + JSON.stringify(variantsFiles));
var currentVariants = variantsFiles[0];
if(currentVariants){
console.log("read variants def file");
readFileAsXml(variantsDir + "/" + currentVariants,function(err,variantsWrapper){
if(err){
console.error("ERROR: variant apply failed");
deferral.reject();
return;
}
var variantObj = getVariantsByEnv(variantsWrapper);
if(!variantObj){
console.log("No variant loaded: use default config.xml");
deferral.resolve();
return;
}
if(!result.widget.preference){
result.widget.preference = [];
}
//check for special preferences (like application.id)
checkForSpecialPrefs(variantObj.preference, 'global', context, result);
// globals
mergeArray(result.widget.preference,variantObj.preference);
_.forEach(variantObj.platform,function(platform){
console.log("Find platform preference for: " + platform.$.name);
var pIndex = _.findIndex(result.widget.platform,function(pItem){
return pItem.$.name === platform.$.name;
});
if(pIndex < 0){
console.error("platform not found in config xml: skipping this platform settings");
}else{
if(!result.widget.platform[pIndex].preference){
result.widget.platform[pIndex].preference = [];
}
//check for special preferences (like application.id)
checkForSpecialPrefs(platform.preference, platform.$.name, context, result);
//for a single platform
mergeArray(result.widget.platform[pIndex].preference,platform.preference);
}
});
//console.log(">>>>>> Complete JSON: \n", JSON.stringify(result, null, 4));
var builder = new xml2js.Builder();
var xml = builder.buildObject(result);
fs.writeFileSync(projectRoot + "/config.xml",xml);
deferral.resolve();
//console.log("xml: \n" + xml);
});
}else{
console.warn("Variant not found -> use preferences in config");
deferral.resolve();
}
});
});
return deferral.promise;
};
function checkForSpecialPrefs(prefs, platform, context, retData){
//console.log(">>>>> context ", JSON.stringify(context, null, 4));
if (!prefs){
return;
}
for (var i=0;i<prefs.length;i++){
try {
var pref = prefs[i];
//Manage the application id
if (pref.$.name === '_application.id'){
if (platform==='global'){
retData.widget.$.id = pref.$.value
} else if (platform==='android') {
addAndroidBuildExtras("android.defaultConfig.applicationId" , pref.$.value, context);
} else if (platform==='ios') {
retData.widget.$["ios-CFBundleIdentifier"] = pref.$.value
}
}
/*
if (pref.$.name === '_archivesBaseName'){
if (platform==='android'){
addAndroidBuildExtras("archivesBaseName" , pref.$.value, context);
}
}
*/
} catch(ex){
console.log("ERROR: ", ex);
throw ex;
}
}
_.remove(prefs, function(item){
var test = ((item.$.name === '_application.id'));
//console.log("remove test for "+item.$.name+" = " + test);
return test;
});
}
function addAndroidBuildExtras(prefName, prefValue, context){
var androidPlatfVer = getAndroidPlatformVersion(context);
if (androidPlatfVer){
var extrasFile = getAndroidBuildExtrasFile(androidPlatfVer, context);
try {
if (!gradle){
throw "The version of DE-CLI that is currently installed does not support this kind of gradle operation [addAndroidBuildExtras]: update the DE-CLI to version 0.0.10 or higher.";
} else {
if (!fs.existsSync(extrasFile)){
//create a new file
fs.closeSync(fs.openSync(extrasFile, 'w'));
}
/*gradle.parseFile(extrasFile).then(function (representation) {
//console.log("1####>>>>>>> Extra Build Before:\n ", JSON.stringify(representation, null, 4));
if (!representation["ext.postBuildExtras"]){
representation["ext.postBuildExtras"] = {};
}
var extras = representation["ext.postBuildExtras"];
extras[prefName] = ""+prefValue+"";
//console.log("2####>>>>>>> Extra Build After:\n ", JSON.stringify(representation, null, 4));
var gradleScript = makeGradleText(representation);
fs.writeFile(extrasFile, gradleScript, function (e, r) {
//console.log(e, r);
//console.log(">>>>> Android Platform version: " + androidPlatfVer + " -> " + extrasFile);
})
});*/
var content = `ext.cdvPluginPostBuildExtras.add({\n ${prefName} = '${prefValue}'\n})`
fs.writeFileSync(extrasFile,content);
}
} catch (ex){
throw "The version of DE-CLI that is currently installed does not support this kind of gradle operation [addAndroidBuildExtras]: update the DE-CLI to version 0.0.10 or higher.";
}
} else {
//android not available
console.log(">>>>> Android Platform NOT AVAILABLE");
}
}
/*
function recusiveTextConvert(obj, k) {
var text = "";
if (Array.isArray(obj)) {
_.each(obj, function (o, key) {
text += k + " " + recusiveTextConvert(o);
})
} else if (typeof obj === 'object' && obj !== null) {
text += k ? k + " = {\n" : ""
_.each(obj, function (o, key) {
text += recusiveTextConvert(o, key)
})
text += k ? "}\n" : ""
} else {
text += k ? k : ""
text += " = '" + obj + "'\n"
}
return text;
}
function makeGradleText(obj) {
return recusiveTextConvert(obj);
}
*/
function getAndroidBuildExtrasFile(platformVer, context){
var prjRoot = context.opts.projectRoot;
let versionParts = platformVer.split("\.");
var filepath = undefined;
if (versionParts && versionParts[0] && parseInt(versionParts[0]) >= 7) {
filepath = path.join(prjRoot, 'platforms', 'android', 'app');
} else {
filepath = path.join(prjRoot, 'platforms', 'android');
}
var filename = path.join(filepath, 'build-extras.gradle');
return filename;
}
function getAndroidPlatformVersion(context){
var androidPlatformPath = getAndroidPlatformPath(context);
var exists = fs.existsSync(androidPlatformPath);
if (exists){
var pkgJson = getProjectJSON(context);
if (pkgJson && pkgJson.dependencies && pkgJson.dependencies["cordova-android"]) {
return pkgJson.dependencies["cordova-android"];
}
if (pkgJson && pkgJson.devDependencies && pkgJson.devDependencies["cordova-android"]) {
return pkgJson.devDependencies["cordova-android"];
}
return undefined;
} else {
return undefined;
}
}
function getAndroidPlatformPath(context){
var platformsPath = getPlatformsPath(context);
var androidPlatformPath = path.join(platformsPath, "android");
return androidPlatformPath;
}
function getPlatformsPath(context){
var prjRoot = context.opts.projectRoot;
var platformsPath = path.join(prjRoot, "platforms");
return platformsPath;
}
function getProjectJSON(context){
Loading ...