// MUST use for running batch files
// you can use this for other commands but spawn is better
// as it handles IO better
var q = require('q');
var log = require('./log');
var child_process = require('child_process');

var defaultOptions = {
    cwd: process.cwd(),
};

var doExecFile = function(cmd, args, opts) {
  var deferred = q.defer();
  child_process.execFile(cmd, args, opts, function(error, stdout, stderr) {
    if (error) {
      return deferred.reject({
        error: error,
        stderr: stderr,
        stdout: stdout
      });
    }
    deferred.resolve(stdout);
  });
  return deferred.promise;
};

var trim = function(data) {
  return ('' + (data || '')).trim();
};

var isWarning = function(str) {
  return str.indexOf(' WARN ') > -1;
};

var isError = function(str) {
  return str.indexOf(' ERROR ') > -1;
};

var printLines = function(data) {
  var lines = trim(data).split('\n');
  lines.forEach(function(line) {
    line = trim(line);
    if (isError(line)) {
      log.error(line);
    } else if (isWarning(line)) {
      log.warning(line);
    } else {
      log.info(line);
    }
  });
};

var doSpawn = function(cmd, args, opts) {
  var deferred = q.defer();
  var cmdArgs = ['/c', cmd];
  cmdArgs.push.apply(cmdArgs, args);
  log.suppressTimeStamps();
  var proc = child_process.spawn('cmd.exe', cmdArgs, opts);
  proc.stdout.on('data', function(data) {
    printLines(data);
  });
  proc.stderr.on('data', function(data) {
    log.error(trim(data));
  });
  proc.on('close', function(code) {
    log.showTimeStamps();
    if (code) {
      deferred.reject({ error: new Error('Exit code ' + code) });
    } else {
      deferred.resolve();
    }
  });
  proc.on('error', function(err) {
    log.showTimeStamps();
    log.error('failed to start process');
    log.error(err);
    deferred.reject({ error: err });
  });
  return deferred.promise;
};

var doExec = function(cmd, args, opts) {
  return (opts._useExecFile) ? doExecFile(cmd, args, opts) : doSpawn(cmd, args, opts);
};

var exec = function(cmd, args, opts) {
    var deferred = q.defer();
    args = args || [];
    opts = opts || defaultOptions;
    opts.maxBuffer = Number.MAX_SAFE_INTEGER;
    return doExec(cmd, args, opts);
};

module.exports = exec;

@@ -235,18 +235,16 @@
 ons = %7B%0A
-  
   cwd: p
@@ -2046,40 +2046,8 @@
 ) %7B%0A
-    var deferred = q.defer();%0A  
   ar
@@ -2069,24 +2069,32 @@
 ;%0A  
- 
- 
 opts = 
-opts %7C%7C
+Object.assign(%7B%7D,
  def
@@ -2104,20 +2104,25 @@
 tOptions
+, opts)
 ;%0A
-  
   opts.m
@@ -2157,18 +2157,16 @@
 NTEGER;%0A
-  
   return

Improve exec module options handling