diff --git a/lib/secrets.js b/lib/secrets.js index 2c2166e259e7ae4377e9a2e74166b8fee3e4a8df..4b854c3436d02d0238fb84823851dad088d367ba 100644 --- a/lib/secrets.js +++ b/lib/secrets.js @@ -20,7 +20,7 @@ function bytesToChars(buf) { for (var i=0; i < buf.length; i++) { str += alphabet.charAt(buf[i] % alphabet.length); } - + return str; } diff --git a/lib/version.js b/lib/version.js new file mode 100644 index 0000000000000000000000000000000000000000..0262c59bf2f7ff346d164789546b87c900ce22f6 --- /dev/null +++ b/lib/version.js @@ -0,0 +1,53 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// determine the software 'version'. This is the 7 char abbrevieated SHA +// we try to read this from ver.txt at the top level, then try to use git, +// then finally fall back to a randomly generated 7 char string +// this version will be used for features like cache busting + +const +fs = require('fs'), +path = require('path'), +logger = require('./logging.js').logger, +spawn = require('child_process').spawn, +secrets = require('./secrets.js'); + +var sha; + +// first try ver.txt which by convention is placed in repo root at +// deployment time +try { + var contents = fs.readFileSync(path.join(__dirname, '..', 'resources', 'static', 'ver.txt')); + sha = contents.toString().split(' ')[0]; + if (sha.length != 7) throw "bad sha in ver.txt"; +} catch(e) { + sha = undefined; + logger.debug('cannot read code version from ver.txt: ' + e); +} + +// now set the SHA to either the read SHA or a random string +module.exports = sha ? sha : secrets.weakGenerate(7); + +// if ver.txt discovery failed, try using git to get the sha. +if (!sha) { + // next try using git + var p = spawn('git', [ 'log', '--pretty=%h', '-1' ]); + var buf = ""; + p.stdout.on('data', function(d) { + buf += d; + }); + p.on('exit', function(code, signal) { + var sha = buf.toString().trim(); + if (sha && sha.length === 7) { + module.exports = sha; + logger.info('code version (via git) is: ' + module.exports); + } else { + logger.warn('code version (randomly generated) is: ' + module.exports); + } + }); +} else { + logger.info('code version (from ver.txt) is: ' + module.exports); +} + diff --git a/tests/software-version-test.js b/tests/software-version-test.js new file mode 100755 index 0000000000000000000000000000000000000000..65b89072b067d890a39f10553d78817d612cd003 --- /dev/null +++ b/tests/software-version-test.js @@ -0,0 +1,32 @@ +#!/usr/bin/env node + +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +require('./lib/test_env.js'); + +const +assert = require('assert'), +vows = require('vows'), +fs = require('fs'), +path = require('path'), +version = require('../lib/version.js'); + +var suite = vows.describe('software-version'); +suite.options.error = false; + + +suite.addBatch({ + "version": { + topic: function() { return version; }, + "works": function(r) { + assert.isString(r); + assert.equal(r.length, 7); + } + } +}); + +// run or export the suite. +if (process.argv[1] === __filename) suite.run(); +else suite.export(module);