mongodb-js / mj

#wip mongodb-js tooling
https://github.com/mongodb-js/mj
Apache License 2.0
0 stars 2 forks source link

`mj check` #5

Closed imlucas closed 9 years ago

imlucas commented 9 years ago
var fs = require('fs'),
  async = require('async'),
  glob = require('glob'),
  rimraf = require('rimraf'),
  Joi = require('joi'),
  pkg = require('package.json');

// Checks for required files
var checkRequiredFilesExist = function(done){
  var tasks = [
    'README*',
    'LICENSE',
    'CONTRIBUTING*',
    '.travis.yml',
    '.gitignore',
    '.npmignore',
  ].map(function requireFileExists(pattern){
    return function(cb){
      glob("**/*.js", options, function (err, files) {
        if(err) return cb(err);
        if(files.length === 0) return fn(new Error());
        if(files.length > 1) return fn(new Error('More than one file matched ' + pattern));

        fs.exists(files[0], function(exists){
          if(!exists) return fn(new Error('Missing required file ' + files[0]));
          return fn();
        });
      });
    };
  }));
  async.parallel(tasks, done);
};

// Check package.json conforms
var checkPackage = function(done){
  var schema = Joi.object().keys({
      name: Joi.string().alphanum().min(3).max(30).regex(/^[a-zA-Z0-9][a-zA-Z0-9\.\-_]*$/).required(),
      version: Joi.string().regex(/^[0-9]+\.[0-9]+[0-9+a-zA-Z\.\-]+$/).required(),
      description: Joi.string().max(80).required(),
      license: Joi.string().alphanum().max(10).required(),
      homepage: Joi.string().uri('http').required(),
      repository: Joi.object().keys({
        type: Joi.string().valid('git').required(),
        url: Joi.string().uri('git').regex(/mongodb-js\/[a-zA-Z0-9\.\-_]+/).required()
      }),
      dependencies: Joi.object().required(),
      devDependencies: Joi.object().required()
  });
  Joi.validate(pkg, schema, done);
};

// If I clone this repo and run `npm install && npm test` does it work?
// If there is an `npm start`, run that as well and make sure it stays up 
// for at least 5 seconds.
var checkFirstRun = function(done){
  function run(cmd){
    return function(cb){
      var parts = cmd.split(' '),
        bin = parts.shift(),
        args = parts,
        completed = false;

      var child = spawn(cmd, args)
        .on('error', function(err){
          completed = true;
          console.error(err);
          done(new Error(cmd + ' failed'));
        });

      child.stdout.pipe(process.stdout);
      child.stderr.pipe(process.stderr);

      if(cmd === 'npm start'){
        setTimeout(function(){
          if(completed) return;

          completed = true;
          child.kill('SIGKILL');
          done();
        }, 5000);
      }

      child.on('close', function(code){
        if(completed) return;

        completed = true;

        if(code === 0) return done();

        done(new Error(cmd + ' failed'));
      });
    };
  }

  rimraf('node_modules/**/*', function(err){
    if(err) return done(err);
    var tasks = [
      run('npm install'),
      run('npm test')
    ];

    if(pkg.scripts.start){
      tasks.push(run('npm start'));
    }

    async.series(tasks, function(err){
      if(err) return done(err);
      done();
    });

  });
};

var checks = [
  checkRequiredFilesExist,
  checkPackage,
  checkFirstRun
];

async.parallel(checks, function(err){
  if(err){
    console.error(err);
    return process.exit(1);
  }
  process.exit(0);
});