<commit_before>const { api, _, Action } = require("../..")
const flat = require("flat")
const promisify = require('util').promisify;
const defer = require('pull-defer')
module.exports = () => {

function hasPerms(peerID,rPeerID,path,cb){

  api.friends.isFriend(peerID,(err,isFriend)=>{
    if(err) return cb(err,false)
    if(isFriend) return cb(null,true)
    api.identities.get(peerID,(err,identity)=>{
      if(err) return cb(err,false)
      if(identity.groups && identity.groups.length >0){
        api.identities.get(rPeerID,function(err,rIdentity){
          if(err) return cb(err,false)

          if(rIdentity.groups && rIdentity.groups.length >0){
            _(identity.groups,_.asycMap(function(g,cb){
              api.groups.get(g,(err,g2)=>{
                if(err) return (null,undefined)
                return cb(null,g2)
              })
            }),_.filter(),_.filter(function(g){
                return g.allow.indexOf(path) ==-1 && rIdentity.groups.indexOf(g) ==-1
            }),_.collect(function(err,groups){
              if(Array.isArray(groups) && groups.length>0)   return cb(null,true)

              return cb(null,false)
            }))
            return
          }
          cb(null,false)

        })
        return
      }
      cb(null,false)
    })
  })
}

  api.actions.call = {

    promise: Action({
      type: "promise",
      input: ["string", "string", "array"],
      desc: "This run a promise action on peerID",
      run: async function (peerID, path, args) {
        if(!this.id)throw new Error("No permission to call " + path + " from "  + api.id +" on " + peerID)
        const has =  await promisify(hasPerms)(this.id,peerID,path)
        if(!has) throw new Error("No permission to call " + path + " from "  + this.id +" on " + peerID)

        for (let k in api.connections) {
          let c = api.connections[k]
          if (c.peerID === peerID && c.peer) {
            const f = flat.flatten(c.peer)
            if (!f[path]) throw new Error("Action " + path + " not found on " + peerID)
            if (f[path].type !== "promise") throw new Error("Action " + path + " type is not a promise on " + peerID)
            return await f[path](...args)
          }

        }
        throw new Error("No Peer with id" + peerID + " found on " + api.id)
      }
    }),
    source: Action({
      type: "source",
      input: ["string", "string", "array"],
      desc: "This run a source stream on peerID",
      run: function(peerID, path, args)  {

        if(!this.id) return _.error(new Error("No permissions to call " + path + " from "  + api.id+" on " + peerID))

        let callSource = (peerID,path,args)=>{
          for (let k in api.connections) {
            let c = api.connections[k]
            if (c.peerID === peerID && c.peer) {
              const f = flat.flatten(c.peer)
              if (!f[path]) return _.error(new Error("Action " + path + " not found on " + peerID))
              if (f[path].type !== "source") return _.error(new Error("Action " + path + " type is not a source on " + peerID))
              return f[path](...args)
            }
          }
          return _.error(new Error("No Peer with id" + peerID + " found on " + api.id))
        }

        const deferred = defer.source();
        const self = this;
        hasPerms(this.id,peerID,path,function(err,has){
          if(has) return deferred.resolve(callSource(peerID,path,args))
          deferred.resolve(_.error(new Error("No permissions to call " + path + " from "  + self.id +" on " + peerID)))
        })

        return deferred
      }

    }),
    duplex: Action({
      type: "source",
      input: ["string", "string", "array"],
      desc: "This run a duplex stream on peerID",
      run: function(peerID, path, args)  {
        const error = (err) => {
          return {
            source: _.error(err),
            sink: (read) => {
              read(err || true, (_err) => { })
            }
          }
        }
        if(!this.id) return error(new Error("No permissions to call " + path + " from "  + api.id +" on " + peerID))

        const callDuplex = (peerID,path,args)=>{
          for (let k in api.connections) {
            let c = api.connections[k]
            if (c.peerID === peerID && c.peer) {
              const f = flat.flatten(c.peer)
              if (!f[path]) return error(new Error("Action " + path + " not found on " + peerID))
              if (f[path].type !== "source") return error(new Error("Action " + path + " type is not a source on " + peerID))
              return f[path](...args)
            }
          }
          return error(new Error("No Peer with id" + peerID + " found on " + api.id))
        }

        const deferred = defer.duplex();
        const self = this;
        hasPerms(this.id,peerID,path,function(err,has){
          if(has) return deferred.resolve(callDuplex(peerID,path,args))
          deferred.resolve(error(new Error("No permissions to call " + path + " from "  + self.id +" on " + peerID)))
        })

        return deferred
      }
    }),
    sink: Action({
      type: "sink",
      input: ["string", "string", "array"],
      desc: "This run a sink stream on peerID",
      run: function(peerID, path, args, cb) {
        args.push(cb)

        const error = (err) => {
          return (read) => {
            read(err || true, (_err) => { cb(err || _err) })
          }
        }

        if(!this.id) return error(new Error("No permissions to call " + path + " from "  + api.id +" on " + peerID))

        const callSink = (peerID,path,args,cb)=>{

        for (let k in api.connections) {
          let c = api.connections[k]
          if (c.peerID === peerID && c.peer) {
            const f = flat.flatten(c.peer)
            if (!f[path]) return error(new Error("Action " + path + " not found on " + peerID))
            if (f[path].type !== "sink") return error(new Error("Action " + path + " type is not a sink on " + peerID))
            return f[path](...args,cb)
          }
        }

        return error(new Error("No Peer with id" + peerID + " found on " + api.id))
      }

      const deferred = defer.sink();
      const self = this;
      hasPerms(this.id,peerID,path,function(err,has){
        if(has) return deferred.resolve(callSink(peerID,path,args,cb))
        deferred.resolve(error(new Error("No permissions to call " + path + " from "  + self.id +" on " + peerID)))
      })

      return deferred

      }
    })

  }

  api.actions.call.async= api.actions.call.sync = Action({
    type: "async",
    input: ["string", "string", "array"],
    desc: "This run a async or sync action on peerID",
    run: function(peerID, path, args, cb)  {
      if(!this.id) return cb(new Error("No permissions to call " + path + " from "  + self.id +" on " + peerID))
      const callAsync = (peerID,path,args,cb)=>{
      let found
      let foundPeer
      for (let k in api.connections) {
        let c = api.connections[k]
        if (c.peerID === peerID && c.peer) {
          const f = flat.flatten(c.peer)
          if(f[path])found = f[path]

          foundPeer=true
        }

      }

      if(!foundPeer) return cb(new Error("No Peer with id" + peerID + " found on " + api.id))
      if (!found) return cb(new Error("Action " + path + " not found on " + peerID))
      if (found.type !== "sync" && found.type !== "async") return cb(new Error("Action " + path + " type is not sync or async on " + peerID))

      return found(...args,cb)

      }

      const self = this;
      hasPerms(this.id,peerID,path,(err,has)=>{
        if(has) return callAsync(peerID,path,args,cb)
        cb(new Error("No permissions to call " + path + " from "  + self.id +" on " + peerID))
      })

    }
  })

}
<commit_msg>fix typo<commit_after>const { api, _, Action } = require("../..")
const flat = require("flat")
const promisify = require('util').promisify;
const defer = require('pull-defer')
module.exports = () => {

function hasPerms(peerID,rPeerID,path,cb){

  api.friends.isFriend(peerID,(err,isFriend)=>{
    if(err) return cb(err,false)
    if(isFriend) return cb(null,true)
    api.identities.get(peerID,(err,identity)=>{
      if(err) return cb(err,false)
      if(identity.groups && identity.groups.length >0){
        api.identities.get(rPeerID,function(err,rIdentity){
          if(err) return cb(err,false)

          if(rIdentity.groups && rIdentity.groups.length >0){
            _(identity.groups,_.asyncMap(function(g,cb){
              api.groups.get(g,(err,g2)=>{
                if(err) return (null,undefined)
                return cb(null,g2)
              })
            }),_.filter(),_.filter(function(g){
                return g.allow.indexOf(path) ==-1 && rIdentity.groups.indexOf(g) ==-1
            }),_.collect(function(err,groups){
              if(Array.isArray(groups) && groups.length>0)   return cb(null,true)

              return cb(null,false)
            }))
            return
          }
          cb(null,false)

        })
        return
      }
      cb(null,false)
    })
  })
}

  api.actions.call = {

    promise: Action({
      type: "promise",
      input: ["string", "string", "array"],
      desc: "This run a promise action on peerID",
      run: async function (peerID, path, args) {
        if(!this.id)throw new Error("No permission to call " + path + " from "  + api.id +" on " + peerID)
        const has =  await promisify(hasPerms)(this.id,peerID,path)
        if(!has) throw new Error("No permission to call " + path + " from "  + this.id +" on " + peerID)

        for (let k in api.connections) {
          let c = api.connections[k]
          if (c.peerID === peerID && c.peer) {
            const f = flat.flatten(c.peer)
            if (!f[path]) throw new Error("Action " + path + " not found on " + peerID)
            if (f[path].type !== "promise") throw new Error("Action " + path + " type is not a promise on " + peerID)
            return await f[path](...args)
          }

        }
        throw new Error("No Peer with id" + peerID + " found on " + api.id)
      }
    }),
    source: Action({
      type: "source",
      input: ["string", "string", "array"],
      desc: "This run a source stream on peerID",
      run: function(peerID, path, args)  {

        if(!this.id) return _.error(new Error("No permissions to call " + path + " from "  + api.id+" on " + peerID))

        let callSource = (peerID,path,args)=>{
          for (let k in api.connections) {
            let c = api.connections[k]
            if (c.peerID === peerID && c.peer) {
              const f = flat.flatten(c.peer)
              if (!f[path]) return _.error(new Error("Action " + path + " not found on " + peerID))
              if (f[path].type !== "source") return _.error(new Error("Action " + path + " type is not a source on " + peerID))
              return f[path](...args)
            }
          }
          return _.error(new Error("No Peer with id" + peerID + " found on " + api.id))
        }

        const deferred = defer.source();
        const self = this;
        hasPerms(this.id,peerID,path,function(err,has){
          if(has) return deferred.resolve(callSource(peerID,path,args))
          deferred.resolve(_.error(new Error("No permissions to call " + path + " from "  + self.id +" on " + peerID)))
        })

        return deferred
      }

    }),
    duplex: Action({
      type: "source",
      input: ["string", "string", "array"],
      desc: "This run a duplex stream on peerID",
      run: function(peerID, path, args)  {
        const error = (err) => {
          return {
            source: _.error(err),
            sink: (read) => {
              read(err || true, (_err) => { })
            }
          }
        }
        if(!this.id) return error(new Error("No permissions to call " + path + " from "  + api.id +" on " + peerID))

        const callDuplex = (peerID,path,args)=>{
          for (let k in api.connections) {
            let c = api.connections[k]
            if (c.peerID === peerID && c.peer) {
              const f = flat.flatten(c.peer)
              if (!f[path]) return error(new Error("Action " + path + " not found on " + peerID))
              if (f[path].type !== "source") return error(new Error("Action " + path + " type is not a source on " + peerID))
              return f[path](...args)
            }
          }
          return error(new Error("No Peer with id" + peerID + " found on " + api.id))
        }

        const deferred = defer.duplex();
        const self = this;
        hasPerms(this.id,peerID,path,function(err,has){
          if(has) return deferred.resolve(callDuplex(peerID,path,args))
          deferred.resolve(error(new Error("No permissions to call " + path + " from "  + self.id +" on " + peerID)))
        })

        return deferred
      }
    }),
    sink: Action({
      type: "sink",
      input: ["string", "string", "array"],
      desc: "This run a sink stream on peerID",
      run: function(peerID, path, args, cb) {
        args.push(cb)

        const error = (err) => {
          return (read) => {
            read(err || true, (_err) => { cb(err || _err) })
          }
        }

        if(!this.id) return error(new Error("No permissions to call " + path + " from "  + api.id +" on " + peerID))

        const callSink = (peerID,path,args,cb)=>{

        for (let k in api.connections) {
          let c = api.connections[k]
          if (c.peerID === peerID && c.peer) {
            const f = flat.flatten(c.peer)
            if (!f[path]) return error(new Error("Action " + path + " not found on " + peerID))
            if (f[path].type !== "sink") return error(new Error("Action " + path + " type is not a sink on " + peerID))
            return f[path](...args,cb)
          }
        }

        return error(new Error("No Peer with id" + peerID + " found on " + api.id))
      }

      const deferred = defer.sink();
      const self = this;
      hasPerms(this.id,peerID,path,function(err,has){
        if(has) return deferred.resolve(callSink(peerID,path,args,cb))
        deferred.resolve(error(new Error("No permissions to call " + path + " from "  + self.id +" on " + peerID)))
      })

      return deferred

      }
    })

  }

  api.actions.call.async= api.actions.call.sync = Action({
    type: "async",
    input: ["string", "string", "array"],
    desc: "This run a async or sync action on peerID",
    run: function(peerID, path, args, cb)  {
      if(!this.id) return cb(new Error("No permissions to call " + path + " from "  + self.id +" on " + peerID))
      const callAsync = (peerID,path,args,cb)=>{
      let found
      let foundPeer
      for (let k in api.connections) {
        let c = api.connections[k]
        if (c.peerID === peerID && c.peer) {
          const f = flat.flatten(c.peer)
          if(f[path])found = f[path]

          foundPeer=true
        }

      }

      if(!foundPeer) return cb(new Error("No Peer with id" + peerID + " found on " + api.id))
      if (!found) return cb(new Error("Action " + path + " not found on " + peerID))
      if (found.type !== "sync" && found.type !== "async") return cb(new Error("Action " + path + " type is not sync or async on " + peerID))

      return found(...args,cb)

      }

      const self = this;
      hasPerms(this.id,peerID,path,(err,has)=>{
        if(has) return callAsync(peerID,path,args,cb)
        cb(new Error("No permissions to call " + path + " from "  + self.id +" on " + peerID))
      })

    }
  })

}
<|endoftext|>


<commit_before>"use strict";

var spawn = require('child_process').spawn
  , path = require('path')
  , _ = require('underscore')._;

/**
 * Configures a new child process spawn that is used to minify files. We use
 * new child processes for this as these kind of operations are CPU heavy and
 * would block the Node.js event loop resulting in slower conversion rates. This
 * setup also allows us to parallel convert code.
 *
 * @param {String} type which command should be spawned
 * @param {Array} flags required configuration flags
 * @param {Object} configuration default configuration
 * @returns {Function} a configured spawn
 * @api public
 */

function compressor (type, flags, configuration) {
  /**
   * Delegrate all the hard core processing to the vendor file.
   *
   * @param {String} extension file extenstion
   * @param {String} content file contents
   * @param {Object} options options
   * @param {Function} fn error first callback
   * @api public
   */

  function compile (extension, content, options, fn) {
    // allow optional options argument
    if (_.isFunction(options)) {
      fn = options;
      options = {};
    }

    var config = _.clone(compile.configuration)
      , args = flags.slice(0)
      , buffer = ''
      , errors = ''
      , compressor;

    if (compile.configuration.type) {
      config.type = extension;
    }

    // generate the --key value options, both the key and the value should added
    // seperately to the `args` array or the child_process will chocke.
    Object.keys(config).filter(function filter (option) {
      return config[option];
    }).forEach(function format (option) {
      var bool = _.isBoolean(config[option]);

      if (!bool || config[option]) {
        args.push('--' + option);
        if (!bool) args.push(config[option]);
      }
    });

    // apply the configuration
    _.extend(config, options);

    // spawn the shit and set the correct encoding
    compressor = spawn(type, args);
    compressor.stdout.setEncoding('utf8');
    compressor.stderr.setEncoding('utf8');

    /**
     * Buffer up the results so we can concat them once the compression is
     * finished.
     *
     * @param {Buffer} chunk
     * @api private
     */

    compressor.stdout.on('data', function data (chunk) {
      buffer += chunk;
    });

    compressor.stderr.on('data', function data (err) {
      errors += err;
    });

    /**
     * The compressor has finished can we now process the data and see if it was
     * a success.
     *
     * @param {Number} code
     * @api private
     */

    compressor.on('close', function exit (code) {
      // invalid states
      if (errors.length) return fn(new Error(errors));
      if (code !== 0) return fn(new Error('process exited with code ' + code));
      if (!buffer.length) return fn(new Error('no data returned ' + type + args));

      // correctly processed the data
      fn(null, buffer);
    });

    // write out the content that needs to be minified
    compressor.stdin.end(content);
  }

  /**
   * Expose the configuration as global so you can configure the process at once
   * instead of sending the same shitload of options each time.
   *
   * @type {Object}
   * @api private
   */

  compile.configuration = configuration;
  return compile;
}
/**
 * The maxium amount of charactures that we allow one single line before line
 * breaks will be injected. We have set this maxium to make it easier to debug
 * minified code so it's easier to narrow down the location of the broken code.
 *
 * @type {Number}
 * @api private
 */

compressor.maximum = 256;

/**
 * The paths of the executables and/or arguments.
 *
 * @type {Object}
 * @api private
 */

compressor.paths = {
    yui: path.join(__dirname, '../../vendor/yui.jar')
  , closure: path.join(__dirname, '../../vendor/closure.jar')
  , uglify: path.join(__dirname, '../../node_modules/.bin/uglifyjs')
};

/**
 * Spawn a new YUI compressor process, this compressor allows you to compile
 * both CSS and JavaScript.
 *
 * @api public
 */

compressor.yui = compressor('java', ['-jar', compressor.paths.yui], {
    'charset': 'ascii'
  , 'type': 'js'
  , 'line-break': compressor.maximum
  , 'verbose': false
});

/**
 * Spawn a new Google Closure compiler process, this compressor only allows you
 * to compile JavaScript, but does a much better job then the YUI compressor in
 * some cases. But this is the slowest compression you could possibly use.
 *
 * @api public
 */

var closure =
compressor.closure = compressor('java', ['-jar', compressor.paths.closure], {
    'charset': 'ascii'
  , 'compilation_level': 'SIMPLE_OPTIMIZATIONS'
  , 'language_in': 'ECMASCRIPT5'
  , 'warning_level': 'QUIET'
  , 'jscomp_off': 'uselessCode'
  , 'summary_detail_level': 0
});

/**
 * Spawn a new Uglify process, this a next generation compressor complete
 * writting in JavaScript that parses the AST from your JavaScript files.
 * Because this is a fairly new compressor there might be some edgecases that
 * could potentially break your code.
 *
 * @api public
 */

compressor.uglifyjs = compressor(compressor.paths.uglify, [], {
    'ascii': true
  , 'unsafe': true
  , 'lift-vars': true
  , 'max-line-length': compressor.maximum
});

/**
 * Expose the compressor interface.
 *
 * @api public
 */

module.exports = compressor;
<commit_msg>[fix] YUI compressor messed up utf-8 encoding. See #52<commit_after>"use strict";

var spawn = require('child_process').spawn
  , path = require('path')
  , _ = require('underscore')._;

/**
 * Configures a new child process spawn that is used to minify files. We use
 * new child processes for this as these kind of operations are CPU heavy and
 * would block the Node.js event loop resulting in slower conversion rates. This
 * setup also allows us to parallel convert code.
 *
 * @param {String} type which command should be spawned
 * @param {Array} flags required configuration flags
 * @param {Object} configuration default configuration
 * @returns {Function} a configured spawn
 * @api public
 */

function compressor (type, flags, configuration) {
  /**
   * Delegrate all the hard core processing to the vendor file.
   *
   * @param {String} extension file extenstion
   * @param {String} content file contents
   * @param {Object} options options
   * @param {Function} fn error first callback
   * @api public
   */

  function compile (extension, content, options, fn) {
    // allow optional options argument
    if (_.isFunction(options)) {
      fn = options;
      options = {};
    }

    var config = _.clone(compile.configuration)
      , args = flags.slice(0)
      , buffer = ''
      , errors = ''
      , compressor;

    if (compile.configuration.type) {
      config.type = extension;
    }

    // generate the --key value options, both the key and the value should added
    // seperately to the `args` array or the child_process will chocke.
    Object.keys(config).filter(function filter (option) {
      return config[option];
    }).forEach(function format (option) {
      var bool = _.isBoolean(config[option]);

      if (!bool || config[option]) {
        args.push('--' + option);
        if (!bool) args.push(config[option]);
      }
    });

    // apply the configuration
    _.extend(config, options);

    // spawn the shit and set the correct encoding
    compressor = spawn(type, args);
    compressor.stdout.setEncoding('utf8');
    compressor.stderr.setEncoding('utf8');

    /**
     * Buffer up the results so we can concat them once the compression is
     * finished.
     *
     * @param {Buffer} chunk
     * @api private
     */

    compressor.stdout.on('data', function data (chunk) {
      buffer += chunk;
    });

    compressor.stderr.on('data', function data (err) {
      errors += err;
    });

    /**
     * The compressor has finished can we now process the data and see if it was
     * a success.
     *
     * @param {Number} code
     * @api private
     */

    compressor.on('close', function exit (code) {
      // invalid states
      if (errors.length) return fn(new Error(errors));
      if (code !== 0) return fn(new Error('process exited with code ' + code));
      if (!buffer.length) return fn(new Error('no data returned ' + type + args));

      // correctly processed the data
      fn(null, buffer);
    });

    // write out the content that needs to be minified
    compressor.stdin.end(content);
  }

  /**
   * Expose the configuration as global so you can configure the process at once
   * instead of sending the same shitload of options each time.
   *
   * @type {Object}
   * @api private
   */

  compile.configuration = configuration;
  return compile;
}
/**
 * The maxium amount of charactures that we allow one single line before line
 * breaks will be injected. We have set this maxium to make it easier to debug
 * minified code so it's easier to narrow down the location of the broken code.
 *
 * @type {Number}
 * @api private
 */

compressor.maximum = 256;

/**
 * The paths of the executables and/or arguments.
 *
 * @type {Object}
 * @api private
 */

compressor.paths = {
    yui: path.join(__dirname, '../../vendor/yui.jar')
  , closure: path.join(__dirname, '../../vendor/closure.jar')
  , uglify: path.join(__dirname, '../../node_modules/.bin/uglifyjs')
};

/**
 * Spawn a new YUI compressor process, this compressor allows you to compile
 * both CSS and JavaScript.
 *
 * @api public
 */

compressor.yui = compressor('java', ['-jar', compressor.paths.yui], {
  // Don't set the 'charset': 'ascii' option for the YUI compressor, it will
  // break utf-8 chars. Other compilers do require this flag, or they will
  // transform escaped utf-8 chars to real utf-8 chars.
    'type': 'js'
  , 'line-break': compressor.maximum
  , 'verbose': false
});

/**
 * Spawn a new Google Closure compiler process, this compressor only allows you
 * to compile JavaScript, but does a much better job then the YUI compressor in
 * some cases. But this is the slowest compression you could possibly use.
 *
 * @api public
 */

var closure =
compressor.closure = compressor('java', ['-jar', compressor.paths.closure], {
    'charset': 'ascii'
  , 'compilation_level': 'SIMPLE_OPTIMIZATIONS'
  , 'language_in': 'ECMASCRIPT5'
  , 'warning_level': 'QUIET'
  , 'jscomp_off': 'uselessCode'
  , 'summary_detail_level': 0
});

/**
 * Spawn a new Uglify process, this a next generation compressor complete
 * writting in JavaScript that parses the AST from your JavaScript files.
 * Because this is a fairly new compressor there might be some edgecases that
 * could potentially break your code.
 *
 * @api public
 */

compressor.uglifyjs = compressor(compressor.paths.uglify, [], {
    'ascii': true
  , 'unsafe': true
  , 'lift-vars': true
  , 'max-line-length': compressor.maximum
});

/**
 * Expose the compressor interface.
 *
 * @api public
 */

module.exports = compressor;
<|endoftext|>


<commit_before>/**
\file restiming.js
Plugin to collect metrics from the W3C Resource Timing API.
For more information about Resource Timing,
see: http://www.w3.org/TR/resource-timing/
*/

(function() {

BOOMR = BOOMR || {};
BOOMR.plugins = BOOMR.plugins || {};

var restricted = {
	redirectStart: "rt_red_st",
	redirectEnd: "rt_red_end",
	domainLookupStart: "rt_dns_st",
	domainLookupEnd: "rt_dns_end",
	connectStart: "rt_con_st",
	connectEnd: "rt_con_end",
	secureConnectionStart: "rt_scon_st",
	requestStart: "rt_req_st",
	responseStart: "rt_res_st"
},

impl = {
	complete: false,
	done: function() {
		var p = BOOMR.window.performance, r, data, i, k;
		if(impl.complete) {
			return;
		}
		BOOMR.removeVar("restiming");
		if(p && typeof p.getEntriesByType === "function") {
			r = p.getEntriesByType("resource");
			if(r) {
				BOOMR.info("Client supports Resource Timing API", "rt");
				data = {
					restiming: new Array(r.length)
				};
				for(i = 0; i < r.length; ++i) {
					data.restiming[i] = {
						rt_name: r[i].name,
						rt_type: r[i].entryType,
						rt_st: r[i].startTime,
						rt_dur: r[i].duration,
						rt_fet_st: r[i].fetchStart,
						rt_res_end: r[i].responseEnd
					};
					for(k in restricted) {
						if(restricted.hasOwnProperty(k) && r[i][k] > 0) {
							data.restiming[i][restricted[k]] = r[i][k];
						}
					}
				}
				BOOMR.addVar(data);
			}
			this.complete = true;
			BOOMR.sendBeacon();
		}
	}
};

BOOMR.plugins.ResourceTiming = {
	init: function() {
		BOOMR.subscribe("page_ready", impl.done, null, impl);
		return this;
	},
	is_complete: function() {
		return impl.complete;
	}
};

}());

<commit_msg>Implement code review feedback for plugins/restiming.<commit_after>/**
\file restiming.js
Plugin to collect metrics from the W3C Resource Timing API.
For more information about Resource Timing,
see: http://www.w3.org/TR/resource-timing/
*/

(function() {

BOOMR = BOOMR || {};
BOOMR.plugins = BOOMR.plugins || {};

var restricted = {
	redirectStart: "rt_red_st",
	redirectEnd: "rt_red_end",
	domainLookupStart: "rt_dns_st",
	domainLookupEnd: "rt_dns_end",
	connectStart: "rt_con_st",
	connectEnd: "rt_con_end",
	secureConnectionStart: "rt_scon_st",
	requestStart: "rt_req_st",
	responseStart: "rt_res_st"
},

impl = {
	complete: false,
	done: function() {
		var p = BOOMR.window.performance, r, data, i, k;
		if(impl.complete) {
			return;
		}
		BOOMR.removeVar("restiming");
		if(p && typeof p.getEntriesByType === "function") {
			r = p.getEntriesByType("resource");
			if(r) {
				BOOMR.info("Client supports Resource Timing API", "restiming");
				data = {
					restiming: new Array(r.length)
				};
				for(i = 0; i < r.length; ++i) {
					data.restiming[i] = {
						rt_name: r[i].name,
						// reinstate this if entryType is ever something other than "resource"
						//rt_type: r[i].entryType,
						rt_st: r[i].startTime,
						rt_dur: r[i].duration,
						rt_fet_st: r[i].fetchStart,
						rt_res_end: r[i].responseEnd
					};
					for(k in restricted) {
						if(restricted.hasOwnProperty(k) && r[i][k] > 0) {
							data.restiming[i][restricted[k]] = r[i][k];
						}
					}
				}
				BOOMR.addVar(data);
			}
			this.complete = true;
			BOOMR.sendBeacon();
		}
	}
};

BOOMR.plugins.ResourceTiming = {
	init: function() {
		BOOMR.subscribe("page_ready", impl.done, null, impl);
		return this;
	},
	is_complete: function() {
		return impl.complete;
	}
};

}());

<|endoftext|>


<commit_before>//Boyan P

//it takes the top games from twitch.tv using their api
//then gets the streamers of those games
//using angular.js

$(document).ready(function(){

  var app = angular.module("popularTwitch", []);

  app.controller("twitchController",["$scope","$http", function($scope,$http){

    $scope.games;
    $scope.streamers = [];

    $http.get("https://api.twitch.tv/kraken/games/top").success(function(topGames){

      //console.log(topGames);

      $scope.games = topGames.top;
      $scope.count=0;

     //console.log($scope.games[0].game.name);
     var gameQuery;
     $scope.games.forEach(function(twitchGame,index){
       gameQuery = twitchGame.game.name.replace(/\s/g,"+");

       //console.log($scope.count);
       $http.get("https://api.twitch.tv/kraken/streams?game="+gameQuery).success(function(streamers){

         $scope.streamers.push({game:streamers.streams[0].game,
                                streams:streamers.streams.slice(0,3)});

       });
      //console.log($scope.streamers[0].game);

    });

    });

  }]);//controller

});//document ready<commit_msg>twitch api doesnt like & symbols<commit_after>//Boyan P

//it takes the top games from twitch.tv using their api
//then gets the streamers of those games
//using angular.js

$(document).ready(function(){

  var app = angular.module("popularTwitch", []);

  app.controller("twitchController",["$scope","$http", function($scope,$http){

    $scope.games;
    $scope.streamers = [];

    $http.get("https://api.twitch.tv/kraken/games/top").success(function(topGames){

      //console.log(topGames);

      $scope.games = topGames.top;
      $scope.count=0;

     //console.log($scope.games[0].game.name);
     var gameQuery;
     $scope.games.forEach(function(twitchGame,index){
       gameQuery = twitchGame.game.name.replace(/\s/g,"+");
			 gameQuery = gameQuery.replace("&","%26");// twitch api doesn't like having & in there.
																								// it doesn't complain about : though

       //console.log($scope.count);
       $http.get("https://api.twitch.tv/kraken/streams?game="+gameQuery).success(function(streamers){

         $scope.streamers.push({game:streamers.streams[0].game,
                                streams:streamers.streams.slice(0,3)});

       });
      //console.log($scope.streamers[0].game);

    });

    });

  }]);//controller

});//document ready<|endoftext|>


<commit_before>'use strict';
module.exports = function() { // eslint-disable-line func-names
  // Global variables
  const plugins = this.opts.plugins,
        config  = this.opts.configs;

  plugins.browserSync.create();

  // Load browsersync with config from browser-sync.json
  plugins.browserSync(require('../helper/config-loader')('browser-sync.json', plugins, config));
};
<commit_msg>Fixed formatting of browser-sync task file<commit_after>'use strict';
module.exports = function() { // eslint-disable-line func-names
  // Global variables
  const plugins = this.opts.plugins,
        config  = this.opts.configs;

  plugins.browserSync.create();

  // Load browsersync with config from browser-sync.json
  plugins.browserSync(
    require('../helper/config-loader')('browser-sync.json', plugins, config)
  );
};
<|endoftext|>


<commit_before>'use strict';
var utils = require('shipit-utils');
var chalk = require('chalk');
var util = require('util');
var path = require('path');
var _ = require('lodash');
var Csproj = require('../../lib/csproj');
var Promise = require('bluebird');
var fs = require("fs-extra");

function build(gruntOrShipit) {
    utils.registerTask(gruntOrShipit, 'deploy:build', task);

    function task() {
        var shipit = utils.getShipit(gruntOrShipit);
        var xbuildOptions = {
            solutionDir: '',
            configuration: 'release'
        };

        if (!xbuildOptions.output) {
            xbuildOptions.output = shipit.config.dirToCopy = shipit.config.dirToCopy || 'output';
        }

        _.assign(xbuildOptions, shipit.config.xbuild);

        return nugetRestore().then(buildProject).then(copyDeployFiles).then(copyDeployBin);

        function nugetRestore() {
            shipit.log('nuget restore "%s"', shipit.config.workspace);
            var exec_command = util.format('nuget restore');
            var cwd = path.resolve(shipit.config.workspace, xbuildOptions.solutionDir);
            return shipit.local(exec_command, {cwd: cwd}).then(function () {
                shipit.log(chalk.green('nuget restore success.'));
            });
        }

        function buildProject() {
            shipit.log('begin mono xbuild repository in "%s"', shipit.config.workspace);
            var cwd = shipit.config.workspace;
            var exec_command = [
                'xbuild',
                xbuildOptions.csprojPath,
                '/p:configuration=' + xbuildOptions.configuration,
            ];

            if(xbuildOptions.framework) {
                exec_command.push('/p:TargetFrameworkVersion=' + xbuildOptions.framework)
            }

            for (var p in xbuildOptions.properties) {
                exec_command.push(['/p:', p, '=', xbuildOptions.properties[p]].join(""));
            }
            exec_command = exec_command.join(' ');

            return shipit.local(exec_command, {cwd: cwd}).then(function () {
                shipit.log(chalk.green('build success.'));
                shipit.emit('builded');
            });
        }

        function copyDeployFiles() {
            shipit.log('cp deploy files in"%s"', shipit.config.workspace);
            var projPath = path.resolve(shipit.config.workspace, xbuildOptions.csprojPath);
            var csproj = new Csproj(projPath);

            var outReleaseDir = path.resolve(shipit.config.workspace, xbuildOptions.output);
            var cwd = path.resolve(shipit.config.workspace, xbuildOptions.solutionDir);

            var promise = new Promise(function (resolve, reject) {
                csproj.getDeployFiles(function (err, items) {
                    if (err) {
                        return reject(err);
                    }
                    resolve(items)
                })
            });

            return promise.mapSeries(function (item) {
                var from = path.resolve(path.dirname(projPath), item);
                var to = path.resolve(outReleaseDir, item);
                var toDir = path.dirname(to);
                fs.ensureDirSync(toDir);
                var exec_command = [
                    'cp',
                    '-f',
                    from,
                    to
                ];

                return shipit.local(exec_command.join(' '), {cwd: cwd}).then(function () {
                    shipit.log(chalk.green('cp content:' + item + ' success.'));
                });
            })

        }

        function copyDeployBin() {
            shipit.log('cp deploy files in"%s"', shipit.config.workspace);
            var projPath = path.resolve(shipit.config.workspace, xbuildOptions.csprojPath);
            var binPath = path.resolve(path.dirname(projPath), 'bin');
            var outputBinPath = path.resolve(shipit.config.workspace, xbuildOptions.output, 'bin');
            var cwd = path.resolve(shipit.config.workspace);
            var exec_command = [
                'cp',
                '-rf',
                binPath,
                outputBinPath
            ];
            return shipit.local(exec_command.join(' '), {cwd: cwd}).then(function () {
                shipit.log(chalk.green('cp bin: ' + binPath + ' success.'));
                shipit.emit('builded');
            });
        }
    }
}

module.exports = build;<commit_msg>fix cp bin bug<commit_after>'use strict';
var utils = require('shipit-utils');
var chalk = require('chalk');
var util = require('util');
var path = require('path');
var _ = require('lodash');
var Csproj = require('../../lib/csproj');
var Promise = require('bluebird');
var fs = require("fs-extra");

function build(gruntOrShipit) {
    utils.registerTask(gruntOrShipit, 'deploy:build', task);

    function task() {
        var shipit = utils.getShipit(gruntOrShipit);
        var xbuildOptions = {
            solutionDir: '',
            configuration: 'release'
        };

        if (!xbuildOptions.output) {
            xbuildOptions.output = shipit.config.dirToCopy = shipit.config.dirToCopy || 'output';
        }

        _.assign(xbuildOptions, shipit.config.xbuild);

        return nugetRestore().then(buildProject).then(copyDeployFiles).then(copyDeployBin);

        function nugetRestore() {
            shipit.log('nuget restore "%s"', shipit.config.workspace);
            var exec_command = util.format('nuget restore');
            var cwd = path.resolve(shipit.config.workspace, xbuildOptions.solutionDir);
            return shipit.local(exec_command, {cwd: cwd}).then(function () {
                shipit.log(chalk.green('nuget restore success.'));
            });
        }

        function buildProject() {
            shipit.log('begin mono xbuild repository in "%s"', shipit.config.workspace);
            var cwd = shipit.config.workspace;
            var exec_command = [
                'xbuild',
                xbuildOptions.csprojPath,
                '/p:configuration=' + xbuildOptions.configuration,
            ];

            if(xbuildOptions.framework) {
                exec_command.push('/p:TargetFrameworkVersion=' + xbuildOptions.framework)
            }

            for (var p in xbuildOptions.properties) {
                exec_command.push(['/p:', p, '=', xbuildOptions.properties[p]].join(""));
            }
            exec_command = exec_command.join(' ');

            return shipit.local(exec_command, {cwd: cwd}).then(function () {
                shipit.log(chalk.green('build success.'));
                shipit.emit('builded');
            });
        }

        function copyDeployFiles() {
            shipit.log('cp deploy files in"%s"', shipit.config.workspace);
            var projPath = path.resolve(shipit.config.workspace, xbuildOptions.csprojPath);
            var csproj = new Csproj(projPath);

            var outReleaseDir = path.resolve(shipit.config.workspace, xbuildOptions.output);
            var cwd = path.resolve(shipit.config.workspace, xbuildOptions.solutionDir);

            var promise = new Promise(function (resolve, reject) {
                csproj.getDeployFiles(function (err, items) {
                    if (err) {
                        return reject(err);
                    }
                    resolve(items)
                })
            });

            return promise.mapSeries(function (item) {
                var from = path.resolve(path.dirname(projPath), item);
                var to = path.resolve(outReleaseDir, item);
                var toDir = path.dirname(to);
                fs.ensureDirSync(toDir);
                var exec_command = [
                    'cp',
                    '-f',
                    from,
                    to
                ];

                return shipit.local(exec_command.join(' '), {cwd: cwd}).then(function () {
                    shipit.log(chalk.green('cp content:' + item + ' success.'));
                });
            })

        }

        function copyDeployBin() {
            shipit.log('cp deploy files in"%s"', shipit.config.workspace);
            var projPath = path.resolve(shipit.config.workspace, xbuildOptions.csprojPath);
            var binPath = path.resolve(path.dirname(projPath), 'bin');
            var outputBinPath = path.resolve(shipit.config.workspace, xbuildOptions.output, 'bin');
            var cwd = path.resolve(shipit.config.workspace);
            var exec_command = [
                'cp',
                '-rf',
                binPath + '/',
                outputBinPath
            ];
            return shipit.local(exec_command.join(' '), {cwd: cwd}).then(function () {
                shipit.log(chalk.green('cp bin: ' + binPath + ' success.'));
                shipit.emit('builded');
            });
        }
    }
}

module.exports = build;<|endoftext|>


<commit_before>/*
 * grunt-jstestdriver-phantomjs
 * https://github.com/tolu/grunt-jstestdriver-phantomjs
 *
 * Copyright (c) 2013 Tobias Lundin
 * Licensed under the MIT license.
 */
'use strict';
module.exports = function (grunt) {

    var JSTDFLAGS_FLAGS = ['tests', 'verbose', 'captureConsole', 'preloadFiles', 'plugins', 'runnerMode', 'testOutput'];

    var taskName = "jstdPhantom";

    // Nodejs libs.
    var path = require('path');
    var Q = require('q');
    var http = require("http");

    // npm lib
    var phantomjs = require('grunt-lib-phantomjs').init(silentGrunt(grunt));

    grunt.registerTask(taskName, 'Grunt task for unit testing using JS Test Driver.', function () {

        var options = this.options({
                tests: 'all',
                timeout: 60000,
                retries: 1,
                port: 1025+Math.round(Math.pow(2, 12)*Math.random()) // [1025-5121]
            }),
            config = grunt.config.get(taskName),
            async = this.async(),
            numberOfConfigs,
            numberOfPassedTests = 0,
            numberOfFailedTests = 0,
            timeouts = [],
            childProcesses = [],
            jarFile = path.join(__dirname, '..', 'lib', 'jstestdriver.jar');

        grunt.verbose.writeflags(options, 'Options');

        function done(success) {
            // Don't let killed child processes do any logging
            grunt.util.hooker.hook(process.stdout, 'write', {
                pre: function(out) {
                    if (/(Running PhantomJS...|ERROR|>>.*0.*\[)/.test(out)) {
                        return grunt.util.hooker.preempt();
                    }
                }
            });
            killChildProcesses().then(function () {
                setTimeout(function() {
                    grunt.util.hooker.unhook(process.stdout, 'write');
                }, 3000);
                if (success === false) {
                    grunt.fail.warn(taskName +" task failed!");
                }
                async.apply(this, arguments);
            });
        }

        function killChildProcesses() {
            var deferred = Q.defer();

            function poll () {
                var killed = true;

                childProcesses.forEach(function (cp) {
                    killed = killed && (cp.killed || cp.exitCode !== null);
                });

                setTimeout(killed ? deferred.resolve : poll, 100);
            }

            // clear all timeouts
            timeouts.map(clearTimeout);

            // kill all child processes
            childProcesses.forEach(function (childProcess) {
                childProcess.kill('SIGKILL');
            });

            // wait for child processes to finish
            poll();

            // wait no more than 10s
            Q.delay(10000).then(deferred.resolve);

            return deferred.promise;
        }

        function taskComplete() {
            grunt.log.writeln('');
            var msg = 'Total Passed: ' + numberOfPassedTests + ', Fails: ' + numberOfFailedTests;

            if (numberOfFailedTests > 0) {
                grunt.log.error(msg);
                done(false);
            } else {
                grunt.log.ok(msg);
                done();
            }
        }

        function runJSTestDriver(configFileLocation, options) {

            function itDidntWork (msg) {
                grunt.log.writeln(msg);
                done(false);
            }

            function getOptionsArray(options) {
                var names, name, i, l, arr = [];

                names = Object.getOwnPropertyNames(options);
                l = names.length;
                for (i = 0; i < l; i += 1) {
                    name = names[i];

                    if (JSTDFLAGS_FLAGS.indexOf(name) !== -1) {
                        arr.push("--" + name);
                        arr.push(options[name]);
                    }
                }

                return arr;
            }

            function startServer () {
                var deferred = Q.defer();

                grunt.log.write('Starting jstd server.');
                deferred.promise.then(function() {
                    grunt.log.writeln("");
                });

                var server = grunt.util.spawn({
                    cmd: 'java',
                    args: [
                        "-jar",
                        jarFile,
                        "--port",
                        options.port
                    ]
                }, function(error, result, code){
                    grunt.verbose.writeln(error);
                });

                childProcesses.push(server);

                function poll () {
                    grunt.log.write(".")

                    var httpOptions = {
                      host: 'localhost',
                      port: options.port,
                      path: '/',
                      method: 'GET'
                    };

                    var req = http.request(httpOptions, function(res) {
                        if (200 === res.statusCode) {
                            timeouts.push(setTimeout(deferred.resolve, 1000));
                        } else {
                            timeouts.push(setTimeout(poll, 100));
                        }
                    });

                    req.on('error', function(e) {
                        timeouts.push(setTimeout(poll, 1000));
                    });

                    // do request
                    req.end();
                }
                poll();

                return deferred.promise;
            }

            function startBrowser () {
                var deferred = Q.defer();

                grunt.log.writeln("Starting PhantomJS...");

                phantomjs.on('onResourceReceived', function(request){

                    if(/\/capture$/.test(request.url) && request.status == 404){
                        itDidntWork('server did not respond');
                    }
                    if(/\/heartbeat$/.test(request.url)){
                        deferred.resolve();
                    }

                });

                var phantom = phantomjs.spawn("http://localhost:" + options.port + "/capture", {
                    options: {},
                    done: function () {}
                });
                childProcesses.push(phantom);

                return deferred.promise;
            }

            function runTests () {
                var deferred = Q.defer();

                grunt.log.writeln("Running tests...\n");

                var jstdCmd = {
                    cmd: 'java',
                    args: ["-jar",
                           jarFile,
                           "--config",
                           configFileLocation,
                           '--reset',
                           '--server',
                           'http://localhost:' + options.port].concat(getOptionsArray(options))
                };

                var runner = grunt.util.spawn(jstdCmd, function (error, result) {
                    if (result && typeof result.stdout === "string") {
                        deferred.resolve(result.stdout);
                    }
                    else {
                        done(false);
                    }
                });

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

                childProcesses.push(runner);

                return deferred.promise;
            }

            function handleTestResults (result) {
                setNumberOfPassesAndFails(result);

                if (hasFailedTests(result)) {
                    grunt.verbose.writeln('   ONE or MORE tests have failed in:');
                }

                processCompleteTests();
            }

            function setNumberOfPassesAndFails(result) {
                var passedReg = /\d+(?=;\sFails)/,
                    failsReg = /\d+(?=;\sErrors)/;

                if (result && result.indexOf('RuntimeException') === -1) {
                    numberOfPassedTests += parseInt(passedReg.exec(result)[0], 10);
                    numberOfFailedTests += parseInt(failsReg.exec(result)[0], 10);
                }
            }

            function hasFailedTests(result) {
                return result.indexOf("Error:") > -1;
            }

            function processCompleteTests() {
                grunt.log.verbose.writeln('>> Finished running file: ' + configFileLocation);
                grunt.log.verbose.writeln('');

                numberOfConfigs -= 1;
                if (numberOfConfigs === 0) {
                    taskComplete();
                }
            }

            function onTimeout () {
                grunt.verbose.writeln("A Timeout has been triggered. Retries left: " + (options.retries-1));
                if (0 === options.retries--) {
                    grunt.log.error("Something took too long");
                    done(false);
                }
                else {
                    killChildProcesses().then(function() {
                        runJSTestDriver(configFileLocation, options)
                    });
                }
            }

            Q.delay(options.timeout).then(onTimeout);

            startServer().then(startBrowser).then(runTests).then(handleTestResults);
        }

        if (typeof config.files === 'string') {
            config.files = [config.files];
        }

        if (options.testOutput) {
            grunt.file.mkdir(options.testOutput);
        }

        numberOfConfigs = config.files.length;

        grunt.util.async.forEach(config.files, function (filename) {
            runJSTestDriver(filename, options);
        }.bind(this));
    });

    function silentGrunt(grunt) {
        var clonedGrunt = {};
        for (var key in grunt) {
            clonedGrunt[key] = grunt[key];
            if ("warn" === key) {
                clonedGrunt[key] = function() {};
            }
        }
        return clonedGrunt;
    }
};
<commit_msg>Using grunt.util._<commit_after>/*
 * grunt-jstestdriver-phantomjs
 * https://github.com/tolu/grunt-jstestdriver-phantomjs
 *
 * Copyright (c) 2013 Tobias Lundin
 * Licensed under the MIT license.
 */
'use strict';
module.exports = function (grunt) {

    var JSTDFLAGS_FLAGS = ['tests', 'verbose', 'captureConsole', 'preloadFiles', 'plugins', 'runnerMode', 'testOutput'];

    var taskName = "jstdPhantom";

    var _ = grunt.util._;

    // Nodejs libs.
    var path = require('path');
    var Q = require('q');
    var http = require("http");

    // npm lib
    var phantomjs = require('grunt-lib-phantomjs').init(silentGrunt(grunt));

    grunt.registerTask(taskName, 'Grunt task for unit testing using JS Test Driver.', function () {

        var options = this.options({
                tests: 'all',
                timeout: 60000,
                retries: 3,
                port: _.random(1025, 5000)
            }),
            config = grunt.config.get(taskName),
            async = this.async(),
            numberOfConfigs,
            numberOfPassedTests = 0,
            numberOfFailedTests = 0,
            timeouts = [],
            childProcesses = [],
            jarFile = path.join(__dirname, '..', 'lib', 'jstestdriver.jar');

        grunt.verbose.writeflags(options, 'Options');

        function done(success) {
            killChildProcesses().then(function () {
                if (success === false) {
                    grunt.fail.warn(taskName +" task failed!");
                }
                async.apply(this, arguments);
            });
        }

        function killChildProcesses() {
            var deferred = Q.defer();

            // Don't let killed child processes do any logging
            grunt.util.hooker.hook(process.stdout, 'write', {
                pre: function(out) {
                    if (/(Running PhantomJS...|ERROR|>>.*0.*\[)/.test(out)) {
                        return grunt.util.hooker.preempt();
                    }
                }
            });
            deferred.promise.then(function () {
                setTimeout(function() {
                    grunt.util.hooker.unhook(process.stdout, 'write');
                }, 3000);
            });

            function poll () {
                var success = _.every(childProcesses, function (cp) {
                    return cp.killed || cp.exitCode !== null;
                });

                setTimeout(success ? deferred.resolve : poll, 100);
            }

            // clear all timeouts
            timeouts.map(clearTimeout);

            // kill all child processes
            _.invoke(childProcesses, 'kill', 'SIGKILL');

            // wait for child processes to finish
            poll();

            // wait no more than 10s
            Q.delay(10000).then(deferred.resolve);

            return deferred.promise;
        }

        function taskComplete() {
            grunt.log.writeln('');
            var msg = 'Total Passed: ' + numberOfPassedTests + ', Fails: ' + numberOfFailedTests;

            if (numberOfFailedTests > 0) {
                grunt.log.error(msg);
                done(false);
            } else {
                grunt.log.ok(msg);
                done();
            }
        }

        function runJSTestDriver(configFileLocation, options) {

            function itDidntWork (msg) {
                grunt.log.writeln(msg);
                done(false);
            }

            function getOptionsArray(options) {
                var names, name, i, l, arr = [];

                names = Object.getOwnPropertyNames(options);
                l = names.length;
                for (i = 0; i < l; i += 1) {
                    name = names[i];

                    if (JSTDFLAGS_FLAGS.indexOf(name) !== -1) {
                        arr.push("--" + name);
                        arr.push(options[name]);
                    }
                }

                return arr;
            }

            function startServer () {
                var deferred = Q.defer();

                grunt.log.write('Starting jstd server.');
                deferred.promise.then(function() {
                    grunt.log.writeln("");
                });

                var server = grunt.util.spawn({
                    cmd: 'java',
                    args: [
                        "-jar",
                        jarFile,
                        "--port",
                        options.port
                    ]
                }, function(error, result, code){
                    grunt.verbose.writeln(error);
                });

                childProcesses.push(server);

                function poll () {
                    grunt.log.write(".")

                    var httpOptions = {
                      host: 'localhost',
                      port: options.port,
                      path: '/',
                      method: 'GET'
                    };

                    var req = http.request(httpOptions, function(res) {
                        if (200 === res.statusCode) {
                            timeouts.push(setTimeout(deferred.resolve, 1000));
                        } else {
                            timeouts.push(setTimeout(poll, 100));
                        }
                    });

                    req.on('error', function(e) {
                        timeouts.push(setTimeout(poll, 1000));
                    });

                    // do request
                    req.end();
                }
                poll();

                return deferred.promise;
            }

            function startBrowser () {
                var deferred = Q.defer();

                grunt.log.writeln("Starting PhantomJS...");

                phantomjs.on('onResourceReceived', function(request){

                    if(/\/capture$/.test(request.url) && request.status == 404){
                        itDidntWork('server did not respond');
                    }
                    if(/\/heartbeat$/.test(request.url)){
                        deferred.resolve();
                    }

                });

                var phantom = phantomjs.spawn("http://localhost:" + options.port + "/capture", {
                    options: {},
                    done: function () {}
                });
                childProcesses.push(phantom);

                return deferred.promise;
            }

            function runTests () {
                var deferred = Q.defer();

                grunt.log.writeln("Running tests...\n");

                var jstdCmd = {
                    cmd: 'java',
                    args: ["-jar",
                           jarFile,
                           "--config",
                           configFileLocation,
                           '--reset',
                           '--server',
                           'http://localhost:' + options.port].concat(getOptionsArray(options))
                };

                var runner = grunt.util.spawn(jstdCmd, function (error, result) {
                    if (result && typeof result.stdout === "string") {
                        deferred.resolve(result.stdout);
                    }
                    else {
                        done(false);
                    }
                });

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

                childProcesses.push(runner);

                return deferred.promise;
            }

            function handleTestResults (result) {
                setNumberOfPassesAndFails(result);

                if (hasFailedTests(result)) {
                    grunt.verbose.writeln('   ONE or MORE tests have failed in:');
                }

                processCompleteTests();
            }

            function setNumberOfPassesAndFails(result) {
                var passedReg = /\d+(?=;\sFails)/,
                    failsReg = /\d+(?=;\sErrors)/;

                if (result && result.indexOf('RuntimeException') === -1) {
                    numberOfPassedTests += parseInt(passedReg.exec(result)[0], 10);
                    numberOfFailedTests += parseInt(failsReg.exec(result)[0], 10);
                }
            }

            function hasFailedTests(result) {
                return result.indexOf("Error:") > -1;
            }

            function processCompleteTests() {
                grunt.log.verbose.writeln('>> Finished running file: ' + configFileLocation);
                grunt.log.verbose.writeln('');

                numberOfConfigs -= 1;
                if (numberOfConfigs === 0) {
                    taskComplete();
                }
            }

            function onTimeout () {
                grunt.verbose.writeln("A Timeout has been triggered. Retries left: " + (options.retries-1));
                if (0 === options.retries--) {
                    grunt.log.error("Something took too long");
                    done(false);
                }
                else {
                    killChildProcesses().then(function() {
                        runJSTestDriver(configFileLocation, options)
                    });
                }
            }

            Q.delay(options.timeout).then(onTimeout);

            startServer().then(startBrowser).then(runTests).then(handleTestResults);
        }

        if (typeof config.files === 'string') {
            config.files = [config.files];
        }

        if (options.testOutput) {
            grunt.file.mkdir(options.testOutput);
        }

        numberOfConfigs = config.files.length;

        grunt.util.async.forEach(config.files, function (filename) {
            runJSTestDriver(filename, options);
        }.bind(this));
    });

    function silentGrunt(grunt) {
        var clonedGrunt = _.clone(grunt);
        clonedGrunt.warn = function() {};
        return clonedGrunt;
    }
};
<|endoftext|>


<commit_before>/*
 * grunt-mincer
 * https://github.com/pirxpilot/grunt-mincer
 *
 * Copyright (c) 2012 Damian Krzeminski
 * Licensed under the MIT license.
 */

var Mincer = require('mincer'),
  path = require('path');

exports.init = function (grunt) {
  'use strict';

  var exports = {};

  var arrayUnique = function (value, index, self) {
    return self.indexOf(value) === index;
  };

  var logicalAssetName = function(environment, filename) {
    var engines = environment.getEngines(),
      resolvedFilename = path.resolve(filename),
      _path, _i, _len;

    for (_i = 0, _len = environment.paths.length; _i < _len; _i++) {
      _path = environment.paths[_i];
      if(_path.slice(-1, 1) !== '/') {
        _path += '/';
      }
      if(resolvedFilename.slice(0, _path.length) === _path) {
        resolvedFilename = resolvedFilename.slice(_path.length);
        break;
      }
    }
    var parts = resolvedFilename.split('.');
    while(engines.hasOwnProperty('.' + parts.slice(-1)[0])) {
      parts.pop();
    }
    return parts.join('.');
  };

  var mince = function (src, options) {
    var environment, asset, err;

    function configureEngine(name) {
      var engine = Mincer[name + 'Engine'] || Mincer[name],
        opts = options.engines[name];
      if (!engine || typeof engine.configure !== 'function') {
        grunt.fail.warn('Invalid Mincer engine ' + name.cyan);
      }
      engine.configure(opts);
    }

    options.configure(Mincer);

    environment = new Mincer.Environment(process.cwd());

    if (options.enable) {
      [].concat(options.enable).forEach(function (configuration) {
        environment.enable(configuration);
      });
    }

    [].concat(options.include).forEach(function (include) {
      environment.appendPath(include);
    });

    Object.keys(options.helpers).forEach(function (key) {
      // Create a bound function which has access to the current Mincer.Environment
      var helper = options.helpers[key].bind({
        environment: environment
      });
      environment.registerHelper(key, helper);
    });

    if (Object.keys(options.engines).some(configureEngine)) {
      return;
    }

    if (options.jsCompressor) {
      environment.jsCompressor = options.jsCompressor;
    }

    if (options.cssCompressor) {
      environment.cssCompressor = options.cssCompressor;
    }

    if (options.manifestPath && options.manifestPath.length > 0) {
      var resolvedAssets = src.map(function(filepath) {
        return logicalAssetName(environment, filepath);
      });

      if ((options.manifestOptions.sourceMaps !== null) && options.manifestOptions.sourceMaps) {
        environment.enable('source_maps');
      }

      var manifest = new Mincer.Manifest(environment, options.manifestPath);
      return manifest.compile(resolvedAssets, options.manifestOptions);
    }

    asset = environment.findAsset(path.basename(src));
    if (!asset) {
      grunt.fail.warn('Cannot find logical path ' + src.cyan);
    }
    return asset.toString();
  };

  exports.compileManifest = function(files, options) {
    var inputFiles = [];

    files.forEach(function(file) {
      inputFiles = inputFiles.concat(file.src.map(function(filepath) {
        return filepath;
      }));
    });

    if (options.banner) {
      grunt.log.warn('Banner option is not supported when compiling to manifest.');
    }

    var assetData = mince(inputFiles.filter(arrayUnique), options);
    if(typeof assetData === 'object') {
      if (options.verbose && assetData.assets) {
        Object.keys(assetData.assets).forEach(function (src) {
          grunt.log.writeln('File ' + src + ' written to: ' + assetData.assets[src]);
        });
      } else {
        grunt.log.writeln('Manifest written to: ' + options.manifestPath.cyan);
      }
    } else {
      grunt.fail.warn('Error compiling manifest:' + options.manifestPath.cyan);
    }
  };

  exports.compileAssets = function(files, options) {
    files.forEach(function (file) {
      var output = [];
      var valid = file.src.filter(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file ' + filepath.cyan + ' not found.');
          return false;
        } else {
          return true;
        }
      });

      valid.forEach(function (file) {
        var assetData = mince(file, options);
        output.push(assetData);
      });

      if (output.length === 0) {
        return grunt.log.warn('Destination not written because compiled output was empty');
      }

      if (options.banner) {
        output.unshift(options.banner + grunt.util.linefeed);
      }

      grunt.file.write(file.dest, output.join(''));
      grunt.log.writeln('File ' + file.dest.cyan + ' created...');
    });
  };

  return exports;
};
<commit_msg>Perform asset concatenation using SourceNode<commit_after>/*
 * grunt-mincer
 * https://github.com/pirxpilot/grunt-mincer
 *
 * Copyright (c) 2012 Damian Krzeminski
 * Licensed under the MIT license.
 */

var Mincer = require('mincer'),
  path = require('path'),
  SourceMapConsumer = require('source-map').SourceMapConsumer,
  SourceMapGenerator = require('source-map').SourceMapGenerator,
  SourceNode = require('source-map').SourceNode;

exports.init = function (grunt) {
  'use strict';

  var exports = {};

  var arrayUnique = function (value, index, self) {
    return self.indexOf(value) === index;
  };

  var logicalAssetName = function(environment, filename) {
    var engines = environment.getEngines(),
      resolvedFilename = path.resolve(filename),
      _path, _i, _len;

    for (_i = 0, _len = environment.paths.length; _i < _len; _i++) {
      _path = environment.paths[_i];
      if(_path.slice(-1, 1) !== '/') {
        _path += '/';
      }
      if(resolvedFilename.slice(0, _path.length) === _path) {
        resolvedFilename = resolvedFilename.slice(_path.length);
        break;
      }
    }
    var parts = resolvedFilename.split('.');
    while(engines.hasOwnProperty('.' + parts.slice(-1)[0])) {
      parts.pop();
    }
    return parts.join('.');
  };

  var mince = function (src, options) {
    var environment, asset, err;

    function configureEngine(name) {
      var engine = Mincer[name + 'Engine'] || Mincer[name],
        opts = options.engines[name];
      if (!engine || typeof engine.configure !== 'function') {
        grunt.fail.warn('Invalid Mincer engine ' + name.cyan);
      }
      engine.configure(opts);
    }

    options.configure(Mincer);

    environment = new Mincer.Environment(process.cwd());
    environment.enable('source_maps');

    if (options.enable) {
      [].concat(options.enable).forEach(function (configuration) {
        environment.enable(configuration);
      });
    }

    [].concat(options.include).forEach(function (include) {
      environment.appendPath(include);
    });

    Object.keys(options.helpers).forEach(function (key) {
      // Create a bound function which has access to the current Mincer.Environment
      var helper = options.helpers[key].bind({
        environment: environment
      });
      environment.registerHelper(key, helper);
    });

    if (Object.keys(options.engines).some(configureEngine)) {
      return;
    }

    if (options.jsCompressor) {
      environment.jsCompressor = options.jsCompressor;
    }

    if (options.cssCompressor) {
      environment.cssCompressor = options.cssCompressor;
    }

    if (options.manifestPath && options.manifestPath.length > 0) {
      var resolvedAssets = src.map(function(filepath) {
        return logicalAssetName(environment, filepath);
      });

      if ((options.manifestOptions.sourceMaps !== null) && options.manifestOptions.sourceMaps) {
        environment.enable('source_maps');
      }

      var manifest = new Mincer.Manifest(environment, options.manifestPath);
      return manifest.compile(resolvedAssets, options.manifestOptions);
    }

    asset = environment.findAsset(path.basename(src));
    if (!asset) {
      grunt.fail.warn('Cannot find logical path ' + src.cyan);
    }
    return asset;
  };

  exports.compileManifest = function(files, options) {
    var inputFiles = [];

    files.forEach(function(file) {
      inputFiles = inputFiles.concat(file.src.map(function(filepath) {
        return filepath;
      }));
    });

    if (options.banner) {
      grunt.log.warn('Banner option is not supported when compiling to manifest.');
    }

    var assetData = mince(inputFiles.filter(arrayUnique), options);
    if(typeof assetData === 'object') {
      if (options.verbose && assetData.assets) {
        Object.keys(assetData.assets).forEach(function (src) {
          grunt.log.writeln('File ' + src + ' written to: ' + assetData.assets[src]);
        });
      } else {
        grunt.log.writeln('Manifest written to: ' + options.manifestPath.cyan);
      }
    } else {
      grunt.fail.warn('Error compiling manifest:' + options.manifestPath.cyan);
    }
  };

  exports.compileAssets = function(files, options) {
    files.forEach(function (file) {
      var output = [];
      var sourceNode = new SourceNode();
      var valid = file.src.filter(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file ' + filepath.cyan + ' not found.');
          return false;
        } else {
          return true;
        }
      });

      valid.forEach(function (file) {
        var assetData = mince(file, options);
        output.push(assetData);
      });

      if (output.length === 0) {
        return grunt.log.warn('Destination not written because compiled output was empty');
      }

      if (options.banner) {
        sourceNode.add(options.banner);
        sourceNode.add(grunt.util.linefeed);
      }

      output.forEach(function(asset) {
        if(asset.sourceMap && asset.sourceMap.mappings !== '') {
          sourceNode.add(SourceNode.fromStringWithSourceMap(asset.toString(), new SourceMapConsumer(asset.sourceMap)));
        } else {
          asset.toString().split('\n').forEach(function(line, j){
            sourceNode.add(new SourceNode(j + 1, 0, asset.relativePath, line + '\n'));
          });
          sourceNode.add('\n');
        }
      });
      grunt.file.write(file.dest, sourceNode.toString());
      grunt.log.writeln('File ' + file.dest.cyan + ' created...');
    });
  };

  return exports;
};
<|endoftext|>


<commit_before>'use strict';

var configFileName = 'toggles.json';

exports._ensureConfigFileExists = function (fileSystem) {
    if (!fileSystem.exists(configFileName)) {
        throw new Error("Could not find the toggles.json file");
    }
};

exports._readToggleConfig = function (fileSystem) {
    return fileSystem.readJSON(configFileName);
};

exports._redactHtmlFiles = function (fileSystem, redactor, workingDirectory, toggleConfig) {
    var htmlFiles = fileSystem.expandMapping('**/*.html', workingDirectory, {cwd: workingDirectory, filter: 'isFile'});

    htmlFiles.forEach(function (file) {
        var filePath = file.dest;

        var body = fileSystem.read(filePath);

        var redactedBody = redactor.redactHtml(body, toggleConfig);

        fileSystem.write(filePath, redactedBody);
    });
};

exports._redactJavaScriptFiles = function (fileSystem, redactor, workingDirectory, toggleConfig) {
    var htmlFiles = fileSystem.expandMapping('**/*.js', workingDirectory, {cwd: workingDirectory, filter: 'isFile'});

    htmlFiles.forEach(function (file) {
        var filePath = file.dest;

        var body = fileSystem.read(filePath);

        var redactedBody = redactor.redactJavascript(body, toggleConfig);

        fileSystem.write(filePath, redactedBody);
    });
};

exports.run = function (grunt, redact) {
    //TODO: test this shit
    //TODO: get workingDirectory from options

    exports._ensureConfigFileExists(grunt.file);
    var toggleConfig = exports._readToggleConfig(grunt.file);
    exports._redactHtmlFiles(grunt.file, redact, 'target/main', toggleConfig);
    exports._redactJavaScriptFiles(grunt.file, redact, 'target/main', toggleConfig);
};
<commit_msg>Renaming variable for clarity purposes<commit_after>'use strict';

var configFileName = 'toggles.json';

exports._ensureConfigFileExists = function (fileSystem) {
    if (!fileSystem.exists(configFileName)) {
        throw new Error("Could not find the toggles.json file");
    }
};

exports._readToggleConfig = function (fileSystem) {
    return fileSystem.readJSON(configFileName);
};

exports._redactHtmlFiles = function (fileSystem, redactor, workingDirectory, toggleConfig) {
    var htmlFiles = fileSystem.expandMapping('**/*.html', workingDirectory, {cwd: workingDirectory, filter: 'isFile'});

    htmlFiles.forEach(function (file) {
        var filePath = file.dest;

        var body = fileSystem.read(filePath);

        var redactedBody = redactor.redactHtml(body, toggleConfig);

        fileSystem.write(filePath, redactedBody);
    });
};

exports._redactJavaScriptFiles = function (fileSystem, redactor, workingDirectory, toggleConfig) {
    var jsFiles = fileSystem.expandMapping('**/*.js', workingDirectory, {cwd: workingDirectory, filter: 'isFile'});

    jsFiles.forEach(function (file) {
        var filePath = file.dest;

        var body = fileSystem.read(filePath);

        var redactedBody = redactor.redactJavascript(body, toggleConfig);

        fileSystem.write(filePath, redactedBody);
    });
};

exports.run = function (grunt, redact) {
    //TODO: test this shit
    //TODO: get workingDirectory from options

    exports._ensureConfigFileExists(grunt.file);
    var toggleConfig = exports._readToggleConfig(grunt.file);
    exports._redactHtmlFiles(grunt.file, redact, 'target/main', toggleConfig);
    exports._redactJavaScriptFiles(grunt.file, redact, 'target/main', toggleConfig);
};
<|endoftext|>


<commit_before>'use strict';

exports.run = function(grunt, taskData) {
    var EC2_INSTANCE_LAUNCH_FAIL = '✗'.red + ' EC2 instance launched failed with %s';
    var EC2_INSTANCE_LAUNCH_SUCCESS = '↗'.yellow + ' EC2 instance(s) launched, instance ids:: %s';
    var EC2_INSTANCE_TAG_FAIL = '✗'.red + ' EC2 instance tagging failed with %s';
    var EC2_INSTANCE_TAG_SUCCESS = '↗'.blue + ' EC2 instance tagged';

    var AWS = taskData.AWS;
    var _ = require("underscore");
    var util = require('util');
    var done = taskData.async();

    if (taskData.data.ec2 !== undefined) {
        var task = taskData.data.ec2;
        var options = _(grunt.config.get('aws.options') || {}).chain()
                .extend(taskData.data.options || {})
                .extend(taskData.data.ec2.options || {})
                .value();
    }
    else {
        var task = taskData;
    }

    var ami;

    var findAMI = function(options, task) {
        if (task.findAMI) {
            var findAMIOptions = _(_.clone(options)).extend(task.findAMI.options || {});
            if (findAMIOptions.region == 'us-standard') {
                findAMIOptions.region = 'us-east-1';
            }
            AWS.config.update(_.pick(findAMIOptions, 'accessKeyId', 'secretAccessKey', 'region'));
            var ec2 = new AWS.EC2(_.pick(findAMIOptions, 'accessKeyId', 'secretAccessKey', 'region'));

            ec2.describeImages(_.pick(task.findAMI, "Owners","ExecutableUsers","Filters"),
                function(err, data) {
                    if (err) {
                        grunt.fail.warn("Fetching AMI info failed. AWS response: "+ JSON.stringify(err));
                    }
                    else {
                        grunt.log.writeln("Fetching AMI info succeded");
                        data.Images.sort(function(a,b){
                            if (a.Name > b.Name) {
                                return -1;
                            }
                            else {
                                return 1;
                            }
                        });
                        ami = data.Images[0].ImageId;

                        grunt.log.writeln("Found latest matching AMI: " + ami + " - \"" +data.Images[0].Name +"\"" );
                        startEC2(options,task);
                    }
            });
        }
        else {
            startEC2(options,task);
        }
    };

    var startEC2 = function(options, task) {
        if (task.startEC2) {
            var startEC2Options = _(_.clone(options)).extend(task.startEC2.options || {});
            if (startEC2Options.region == 'us-standard') {
                startEC2Options.region = 'us-east-1';
            }
            task.startEC2['UserData'] = new Buffer(JSON.stringify(task.startEC2['UserData'])).toString('base64');
            AWS.config.update(_.pick(startEC2Options, 'accessKeyId', 'secretAccessKey', 'region'));
            var ec2 = new AWS.EC2(_.pick(startEC2Options, 'accessKeyId', 'secretAccessKey', 'region'));
            task.startEC2['ImageId'] = (task.startEC2['ImageId'] || ami);

            ec2.runInstances(_.pick(task.startEC2, "ImageId", "MinCount", "MaxCount",
                                                   "KeyName", "InstanceType", "UserData",
                                                   "Placement", "SecurityGroups"), function(err, data) {
                if (err) {
                    grunt.fail.warn(util.format(EC2_INSTANCE_LAUNCH_FAIL, JSON.stringify(err)));
                    done();
                }
                else {
                    var instances = grunt.config('launched_ec2_instance_ids') || new Array();
                    for (var i = 0; i<data.Instances.length; i++) {
                        instances.push(data.Instances[i].InstanceId);
                    }

                    grunt.config.set('launched_ec2_instance_ids', instances);

                    grunt.log.writeln(util.format(EC2_INSTANCE_LAUNCH_SUCCESS, instances.join(", ")));

                    if (task.startEC2.Tags !== undefined) {
                        tagInstances(instances, startEC2Options, task.startEC2.Tags);
                    }
                    else {
                        done();
                    }
                }
            });
        }
    }

    var tagInstances = function(instances, options, tags, max_retries) {
        if (max_retries === undefined) {
            max_retries = 5;
        }

        if (tags) {
            var ec2 = new AWS.EC2(_.pick(options, 'accessKeyId', 'secretAccessKey', 'region'));
            ec2.createTags({Resources: instances, Tags: tags},
                function(err, data) {
                    if (err) {
                        if (max_retries > 0) {
                            tagInstances(instances, options, tags, max_retries - 1);
                        } else {
                            grunt.fail.warn(util.format(EC2_INSTANCE_TAG_FAIL, JSON.stringify(err)));
                        }
                    }
                    else {
                        grunt.log.writeln(EC2_INSTANCE_TAG_SUCCESS);
                    }
                    done();
            });
        }
    }

    var terminateEC2 = function(options, task) {
        if (task.terminateEC2) {
            var terminateEC2Options = _(_.clone(options)).extend(task.terminateEC2.options || {});
            if (terminateEC2Options.region == 'us-standard') {
                terminateEC2Options.region = 'us-east-1';
            }
            AWS.config.update(_.pick(terminateEC2Options, 'accessKeyId', 'secretAccessKey', 'region'));
            var ec2 = new AWS.EC2(_.pick(terminateEC2Options, 'accessKeyId', 'secretAccessKey', 'region'));

            ec2.terminateInstances(_.pick(task.terminateEC2, "InstanceIds"),
                function(err, data) {
                    if (err) {
                        grunt.fail.warn("Terminating EC2 intances failed. AWS response: \n"+ JSON.stringify(err));
                    }
                    else {
                        grunt.log.writeln(JSON.stringify(data));
                    }
            });
        }
    }

    findAMI(options,task);
    //removeFromAmi(options,task);
    //addToAMI(options,task);
    //terminateEC2(options,task);
};
<commit_msg>testing<commit_after>'use strict';

exports.run = function(grunt, taskData) {
    var EC2_INSTANCE_LAUNCH_FAIL = '✗'.red + ' EC2 instance launched failed with %s';
    var EC2_INSTANCE_LAUNCH_SUCCESS = '↗'.yellow + ' EC2 instance(s) launched, instance ids:: %s';
    var EC2_INSTANCE_TAG_FAIL = '✗'.red + ' EC2 instance tagging failed with %s';
    var EC2_INSTANCE_TAG_SUCCESS = '↗'.blue + ' EC2 instance tagged';

    var AWS = taskData.AWS;
    var _ = require("underscore");
    var util = require('util');
    var done = taskData.async();

    if (taskData.data.ec2 !== undefined) {
        var task = taskData.data.ec2;
        var options = _(grunt.config.get('aws.options') || {}).chain()
                .extend(taskData.data.options || {})
                .extend(taskData.data.ec2.options || {})
                .value();
    }
    else {
        var task = taskData;
    }

    var ami;

    var findAMI = function(options, task) {
        if (task.findAMI) {
            var findAMIOptions = _(_.clone(options)).extend(task.findAMI.options || {});
            if (findAMIOptions.region == 'us-standard') {
                findAMIOptions.region = 'us-east-1';
            }
            AWS.config.update(_.pick(findAMIOptions, 'accessKeyId', 'secretAccessKey', 'region'));
            var ec2 = new AWS.EC2(_.pick(findAMIOptions, 'accessKeyId', 'secretAccessKey', 'region'));

            ec2.describeImages(_.pick(task.findAMI, "Owners","ExecutableUsers","Filters"),
                function(err, data) {
                    if (err) {
                        grunt.fail.warn("Fetching AMI info failed. AWS response: "+ JSON.stringify(err));
                    }
                    else {
                        grunt.log.writeln("Fetching AMI info succeded");
                        data.Images.sort(function(a,b){
                            if (a.Name > b.Name) {
                                return -1;
                            }
                            else {
                                return 1;
                            }
                        });
                        ami = data.Images[0].ImageId;

                        grunt.log.writeln("Found latest matching AMI: " + ami + " - \"" +data.Images[0].Name +"\"" );
                        startEC2(options,task);
                    }
            });
        }
        else {
            startEC2(options,task);
        }
    };

    var startEC2 = function(options, task) {
        if (task.startEC2) {
            var startEC2Options = _(_.clone(options)).extend(task.startEC2.options || {});
            if (startEC2Options.region == 'us-standard') {
                startEC2Options.region = 'us-east-1';
            }
            task.startEC2['UserData'] = new Buffer(JSON.stringify(task.startEC2['UserData'])).toString('base64');
            AWS.config.update(_.pick(startEC2Options, 'accessKeyId', 'secretAccessKey', 'region'));
            var ec2 = new AWS.EC2(_.pick(startEC2Options, 'accessKeyId', 'secretAccessKey', 'region'));
            task.startEC2['ImageId'] = (task.startEC2['ImageId'] || ami);

            ec2.runInstances(_.pick(task.startEC2, "ImageId", "MinCount", "MaxCount",
                                                   "KeyName", "InstanceType", "UserData",
                                                   "Placement", "SecurityGroups"), function(err, data) {
                if (err) {
                    grunt.fail.warn(util.format(EC2_INSTANCE_LAUNCH_FAIL, JSON.stringify(err)));
                    done();
                }
                else {
                    var instances = grunt.config('launched_ec2_instance_ids') || new Array();
                    for (var i = 0; i<data.Instances.length; i++) {
                        instances.push(data.Instances[i].InstanceId);
                    }

                    grunt.config.set('launched_ec2_instance_ids', instances);

                    grunt.log.writeln(util.format(EC2_INSTANCE_LAUNCH_SUCCESS, instances.join(", ")));
                    grunt.log.writeln(grunt.config('launched_ec2_instance_ids'));

                    if (task.startEC2.Tags !== undefined) {
                        tagInstances(instances, startEC2Options, task.startEC2.Tags);
                    }
                    else {
                        done();
                    }
                }
            });
        }
    }

    var tagInstances = function(instances, options, tags, max_retries) {
        if (max_retries === undefined) {
            max_retries = 5;
        }

        if (tags) {
            var ec2 = new AWS.EC2(_.pick(options, 'accessKeyId', 'secretAccessKey', 'region'));
            ec2.createTags({Resources: instances, Tags: tags},
                function(err, data) {
                    if (err) {
                        if (max_retries > 0) {
                            tagInstances(instances, options, tags, max_retries - 1);
                        } else {
                            grunt.fail.warn(util.format(EC2_INSTANCE_TAG_FAIL, JSON.stringify(err)));
                        }
                    }
                    else {
                        grunt.log.writeln(EC2_INSTANCE_TAG_SUCCESS);
                    }
                    done();
            });
        }
    }

    var terminateEC2 = function(options, task) {
        if (task.terminateEC2) {
            var terminateEC2Options = _(_.clone(options)).extend(task.terminateEC2.options || {});
            if (terminateEC2Options.region == 'us-standard') {
                terminateEC2Options.region = 'us-east-1';
            }
            AWS.config.update(_.pick(terminateEC2Options, 'accessKeyId', 'secretAccessKey', 'region'));
            var ec2 = new AWS.EC2(_.pick(terminateEC2Options, 'accessKeyId', 'secretAccessKey', 'region'));

            ec2.terminateInstances(_.pick(task.terminateEC2, "InstanceIds"),
                function(err, data) {
                    if (err) {
                        grunt.fail.warn("Terminating EC2 intances failed. AWS response: \n"+ JSON.stringify(err));
                    }
                    else {
                        grunt.log.writeln(JSON.stringify(data));
                    }
            });
        }
    }

    findAMI(options,task);
    //removeFromAmi(options,task);
    //addToAMI(options,task);
    //terminateEC2(options,task);
};
<|endoftext|>