alloy
Version:
TiDev Titanium MVC Framework
209 lines (182 loc) • 6.12 kB
JavaScript
var fs = require('fs'),
path = require('path'),
XMLSerializer = require('@xmldom/xmldom').XMLSerializer,
pkg = require('../package'),
U = require('./utils'),
CONST = require('./common/constants'),
logger = require('./logger');
var DEFAULT_TIAPP = path.join('.', 'tiapp.xml');
var tiapp = {},
tiappFile, doc;
// initialize the project folder
tiapp.init = function(file) {
tiappFile = file || DEFAULT_TIAPP;
doc = tiapp.parse(tiappFile);
};
// Return an XML document object representing the tiapp.xml file
tiapp.parse = function(file) {
file = file || tiappFile;
if (!fs.existsSync(file)) {
U.die('tiapp.xml file does not exist at "' + file + '"');
}
return U.XML.parseFromFile(file);
};
// Get the Titanium SDK version as a string
// Get the Titanium SDK version as a string
tiapp.getSdkVersion = function() {
var elems = doc.documentElement.getElementsByTagName('sdk-version');
if (elems && elems.length > 0) {
return U.XML.getNodeText(elems.item(elems.length - 1));
} else {
if (process.env.sdk) {
return process.env.sdk;
} else {
return getSdkSelectVersion();
}
}
};
function getSdkSelectVersion() {
var homeDir = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'],
file = path.join(homeDir, '.titanium', 'config.json');
if (!fs.existsSync(file)) {
U.die('Titanium configuration file does not exist at "' + file + '"');
}
var ticonfig = JSON.parse(fs.readFileSync(file, {encoding: 'utf8'}));
return ticonfig.sdk.selected;
}
// Get the value of a property from the tiapp.xml
tiapp.getProperty = function(name) {
var props = doc.documentElement.getElementsByTagName('property');
for (var i = 0; i < props.length; i++) {
if (props.item(i).getAttribute('name') === name) {
return props.item(i);
}
}
return null;
};
// Add a module to the tiapp.xml
tiapp.installModule = function(opts) {
install('module', opts);
};
// Add a plugin to the tiapp.xml
tiapp.installPlugin = function(opts) {
install('plugin', opts);
};
// make sure the target TiSDK version meets the minimum for Alloy
tiapp.validateSdkVersion = function() {
var tiVersion = tiapp.getSdkVersion();
if (tiVersion === null) {
logger.warn('Unable to determine Titanium SDK version from tiapp.xml.');
logger.warn('Your app may have unexpected behavior. Make sure your tiapp.xml is valid.');
} else if (tiapp.version.lt(tiVersion, CONST.MINIMUM_TI_SDK)) {
logger.error('Alloy ' + pkg.version + ' requires Titanium SDK ' +
CONST.MINIMUM_TI_SDK + ' or higher.');
logger.error('"' + tiVersion + '" was found in the "sdk-version" field of your tiapp.xml.');
logger.error('If you are building with the legacy titanium.py script and are specifying ');
logger.error('an SDK version as a CLI argument that is different than the one in your ');
logger.error('tiapp.xml, please change the version in your tiapp.xml file.');
process.exit(1);
}
};
// version comparison functions
tiapp.version = {
compare: function(v1, v2) {
// use the tiapp.xml version if v2 is not specified
if (typeof v2 === 'undefined') {
v2 = v1;
v1 = tiapp.getSdkVersion();
}
var parts1 = (v1 || '').split('.'),
parts2 = (v2 || '').split('.');
for (var i = 0; i < 3; i++) {
var p1 = parseInt(parts1[i] || 0, 10),
p2 = parseInt(parts2[i] || 0, 10);
if (p1 > p2) {
return 1;
} else if (p1 < p2) {
return -1;
}
}
return 0;
},
eq: function(v1, v2) { return tiapp.version.compare(v1, v2) === 0; },
gt: function(v1, v2) { return tiapp.version.compare(v1, v2) === 1; },
gte: function(v1, v2) { return tiapp.version.compare(v1, v2) !== -1; },
lt: function(v1, v2) { return tiapp.version.compare(v1, v2) === -1; },
lte: function(v1, v2) { return tiapp.version.compare(v1, v2) !== 1; },
neq: function(v1, v2) { return tiapp.version.compare(v1, v2) !== 0; }
};
tiapp.getDeploymentTargets = function() {
var deployment = doc.documentElement.getElementsByTagName('deployment-targets'),
results = [];
if (deployment.length > 0) {
var targets = deployment.item(0).getElementsByTagName('target');
for (var i = 0, j = targets.length; i < j; i++) {
var target = targets.item(i);
if (U.XML.getNodeText(target) === 'true') {
var platform = target.getAttribute('device');
if (platform === 'iphone' || platform === 'ipad') {
platform = 'ios';
}
if (results.indexOf(platform) === -1) {
results.push(platform);
}
}
}
}
return results;
};
function install(type, opts) {
type = type || 'module';
opts = opts || {};
var err = 'Project creation failed. Unable to install ' + type + ' "' +
(opts.name || opts.id) + '"';
// read the tiapp.xml file
var collection = doc.documentElement.getElementsByTagName(type + 's');
var found = false;
// Determine if the module or plugin is already installed
if (collection.length > 0) {
var items = collection.item(0).getElementsByTagName(type);
if (items.length > 0) {
for (var c = 0; c < items.length; c++) {
var theItem = items.item(c);
var theItemText = U.XML.getNodeText(theItem);
if (theItemText == opts.id) {
found = true;
break;
}
}
}
}
// install module or plugin
if (!found) {
// create the node to be inserted
var node = doc.createElement(type);
var text = doc.createTextNode(opts.id);
if (opts.platform) {
node.setAttribute('platform', opts.platform);
}
if (opts.version) {
node.setAttribute('version', opts.version);
}
node.appendChild(text);
// add the node into tiapp.xml
var pna = null;
if (collection.length === 0) {
var pn = doc.createElement(type + 's');
doc.documentElement.appendChild(pn);
doc.documentElement.appendChild(doc.createTextNode('\n'));
pna = pn;
} else {
pna = collection.item(0);
}
pna.appendChild(node);
pna.appendChild(doc.createTextNode('\n'));
// serialize the xml and write to tiapp.xml
var serializer = new XMLSerializer();
var newxml = serializer.serializeToString(doc);
fs.writeFileSync(tiappFile, newxml, 'utf8');
logger.info('Installed "' + opts.id + '" ' + type + ' to ' + tiappFile);
}
}
module.exports = tiapp;