version.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. module.exports = version;
  2. module.exports.pin = pin;
  3. var fs = require('fs');
  4. var path = require('path');
  5. var exec = require('child_process').exec;
  6. var root = null;
  7. function pin() {
  8. return version().then(function (v) {
  9. version.pinned = v;
  10. });
  11. }
  12. function version(callback) {
  13. // first find the package.json as this will be our root
  14. var promise = findPackage(path.dirname(module.parent.filename))
  15. .then(function (dir) {
  16. // now try to load the package
  17. var v = require(path.resolve(dir, 'package.json')).version;
  18. if (v && v !== '0.0.0-development') {
  19. return v;
  20. }
  21. root = dir;
  22. // else we're in development, give the commit out
  23. // get the last commit and whether the working dir is dirty
  24. var promises = [
  25. branch().catch(function () { return 'master'; }),
  26. commit().catch(function () { return '<none>'; }),
  27. dirty().catch(function () { return 0; }),
  28. ];
  29. // use the cached result as the export
  30. return Promise.all(promises).then(function (res) {
  31. var branch = res[0];
  32. var commit = res[1];
  33. var dirtyCount = parseInt(res[2], 10);
  34. var curr = branch + ': ' + commit;
  35. if (dirtyCount !== 0) {
  36. curr += ' (' + dirtyCount + ' dirty files)';
  37. }
  38. return curr;
  39. });
  40. }).catch(function (error) {
  41. console.log(error.stack);
  42. throw error;
  43. });
  44. if (callback) {
  45. promise.then(function (res) {
  46. callback(null, res);
  47. }, callback);
  48. }
  49. return promise;
  50. }
  51. function findPackage(dir) {
  52. if (dir === '/') {
  53. return Promise.reject(new Error('package not found'));
  54. }
  55. return new Promise(function (resolve) {
  56. fs.stat(path.resolve(dir, 'package.json'), function (error, exists) {
  57. if (error || !exists) {
  58. return resolve(findPackage(path.resolve(dir, '..')));
  59. }
  60. resolve(dir);
  61. });
  62. });
  63. }
  64. function command(cmd) {
  65. return new Promise(function (resolve, reject) {
  66. exec(cmd, { cwd: root }, function (err, stdout, stderr) {
  67. var error = stderr.trim();
  68. if (error) {
  69. return reject(new Error(error));
  70. }
  71. resolve(stdout.split('\n').join(''));
  72. });
  73. });
  74. }
  75. function commit() {
  76. return command('git rev-parse HEAD');
  77. }
  78. function branch() {
  79. return command('git rev-parse --abbrev-ref HEAD');
  80. }
  81. function dirty() {
  82. return command('expr $(git status --porcelain 2>/dev/null| ' +
  83. 'egrep "^(M| M)" | wc -l)');
  84. }