eiriksm/commit-a-day

View on GitHub
plugins/dependencies.js

Summary

Maintainability
A
3 hrs
Test Coverage
'use strict';
var util = require('util');
var _ = require('underscore');
var WaitGroup = require('waitgroup');
var semver = require('semver');

var log = require('../lib/log');
var requestCache = require('../lib/cache').get;

module.exports = function(data, callback) {
  var config = require('..').config;
  var npm = config.npm || {};

  // @todo: When npm starts supporting CORS again...
  var npmurl = npm.registry || 'http://npm-registry-cors-proxy.herokuapp.com';

  // Try to get the latest info about this package.
  var wg = new WaitGroup();
  var hasUpdate = false;

  // Check both dev and regular dependencies.
  if (!data.packageJson || (!data.packageJson.dependencies && !data.packageJson.devDependencies)) {
    log.d('Skipping dependency lookup for %s', data.repo.full_name);
    // Skip a heartbeat so we are sure that all waitgroups are added in the
    // plugin loop.
    setTimeout(function() {
      callback(null, null);
    }, 0);
    return;
  }
  var packages = [];
  _.each(['dependencies', 'devDependencies'], function(type) {
    if (data.packageJson[type]) {
      _.each(data.packageJson[type], function(i, n) {
        packages.push({
          name: n,
          version: i
        });
      });
    }
  });
  if (packages.length === 0) {
    // Just make the waitgroup execute.
    wg.add();
    wg.done();
  }
  packages.forEach(function(n) {
    wg.add();
    var opts = {
      url: npmurl + '/' + n.name
    };
    requestCache(opts, function(e, r, b) {
      if (e) {
        callback(e);
        wg.done();
        wg.cancel = true;
        return;
      }
      var depPackage;
      try {
        depPackage = JSON.parse(b);
      }
      catch(err) {
        callback(err);
        wg.done();
        wg.cancel = true;
        return;
      }
      // See what this version is.
      var distVersion = depPackage['dist-tags'].latest;
      // Compare with what we are looking for.
      var upAvail;
      log.d('Comparing versions for %s, dependency %s. Wanted version %s, latest version is %s',
            data.packageJson.name,
            n.name,
            n.version,
            distVersion);
      try {
        upAvail = semver.gtr(distVersion, n.version);
      }
      catch(err) {
        // Whatever...
        log.d('%s has specified version %s of %s, which does not validate the comparison against latest version: %s',
              data.packageJson.name,
              n.version,
              n.name,
              distVersion);
      }
      if (upAvail) {
        hasUpdate = true;
        log.d('%s has specified version %s of %s, which is lower than latest version: %s',
              data.packageJson.name,
              n.version,
              n.name,
              distVersion);
      }
      wg.done();
    });
  });
  wg.wait(function() {
    if (!wg.cancel) {
      if (hasUpdate) {
        callback(null, util.format('There are dependencies to be updated in repo %s. How about an update there?', data.repo.full_name));
      }
      else {
        callback(null, null);
      }
    }
  });
};