8/3/2014 - 4:35 PM

[Appcelerator Titans] Auto increment <version> in tiapp.xml

[Appcelerator Titans] Auto increment in tiapp.xml

Chris Barber <cbarber@appcelerator.com>
"Jerry.Porter@gulfstream.com" <Jerry.Porter@gulfstream.com>,
"titans@lists.appcelerator.org" <titans@lists.appcelerator.org>,
04/09/2014 01:21 AM
Re: [Appcelerator Titans] Auto increment <version> in tiapp.xml

Hi Jerry!

Probably the best way to deal with this is to use a node module that
parses the tiapp.xml and updates the version number. This way it works on
all platforms, it's fast, and it feels less hacky by having to subprocess
a brittle script.

I've taken the liberty to code it up for you. You can get it from
http://www.ambientreality.com/files/ti-increment-version.zip. All you need
to do is download it, extract it to your project directory or the global
install directory ("~/Library/Application Support/Titanium" on Mac OS X,
"~/.titanium" on Linux, "C:\ProgramData\Titanium" on Windows), and enable
the plugin in the tiapp.xml:


As for the code, it's pretty simple. First, I had to add a package.json so
that I could "npm install" the "xmldom" dependency. Then in the hooks
directory, the hook looks like this:

var DOMParser = require('xmldom').DOMParser,
    fs = require('fs'),
    path = require('path');

exports.id = 'com.appcelerator.ti-version-increment';
exports.version = require('../package.json').version;
exports.cliVersion = '>=3.2.0';

exports.init = function (logger, config, cli, appc) {
    cli.addHook('build.pre.construct', function (builder) {
        var parser = new DOMParser,
            tiappFile = path.join(builder.projectDir, 'tiapp.xml'),
            dom =
parser.parseFromString(fs.readFileSync(tiappFile).toString(), 'text/xml'),
            doc = dom.documentElement,
            node = doc.firstChild;

        // find the <version> tag in the tiapp.xml
        for (; node; node = node.nextSibling) {
            if (node.nodeType == appc.xml.ELEMENT_NODE && node.tagName ==
'version' && node.firstChild) {
                try {
                    // found the <version> tag, try to parse it
                    var orig = appc.version.format(node.firstChild.data,
                        version = orig.split('.');

                    // increment the 3rd digit
                    version[2] = parseInt(version[2]) + 1;

                    // set both the <version> in the tiapp.xml and the
version in the builder's tiapp which is already loaded
                    node.firstChild.data = builder.tiapp.version = version
= version.join('.');

                    logger.info('Incrementing version number from ' +
String(orig).cyan + ' to ' + String(version).cyan);

                    // write the new tiapp.xml
                    fs.writeFileSync(tiappFile, dom.toString());
                } catch (e) {
                    logger.error('tiapp.xml has a bad version number!');

During the "build.pre.construct" event hook, we load and parse the
tiapp.xml. Then we loop over all elements of the <ti:app> tag. Once we
find the <version>, we parse it, increment it, then we set it back in the
DOM as well as in the builder's tiapp object which was parsed prior to the
"build.pre.construct" event hook.

Feel free to modify the code as you see fit. I assumed you only wanted to
increment only the 3rd digit.

On a side note, it's a good idea to start adding exports.id and
exports.version to your hooks. In 3.3.0, I added some snazzy plugin
conflict detection. :)

Good luck!