<commit_before>/// Required Core Modules
var os = require('os');
var cluster = require('cluster');
///
/// External Modules
var SuperTask = require('supertask');
///
/// Internal Modules

///
// No Operation function
function noop() { return null; }
// Log function
function log() {
    var args = Array.prototype.slice.call(arguments);
    // Prepend worker id
    args.unshift('WORKER#' + process.argv.slice(2)[0]);
    console.log.apply(console, args);
}

// Worker //

// Create new master Supertask instance
var ST_INSTANCE = new SuperTask();

process.on('message', function(message) {
    if((!message) || (typeof message !== 'object')) {
        // Invalid STC message
        return;
    }else if(message.type === "STC_KILL_YOURSELF_PLEASE") {
        // Implement Graceful Kill
        // Finish message ticket
        process.send({ ticket: message.ticket, success: true });
    }else if(message.type === 'task') {
        log("ADDING NEW TASK", message.name);
        ST_INSTANCE.addForeign(message.name, message.source, function(error, task) {
            if(error) log("TASK ADD FAILED", message.name, error);
            if(error) return process.send({ ticket: message.ticket, success: false, error: error });
            if(message.isModule) task.module(message.isModule);
            if(message.priority) task.priority(message.priority);
            if(typeof message.defaultContext === 'object') task.context(message.defaultContext || {});
            if(message.access) task.permission(message.access);

            log("TASK ADDED", message.name);
            // Finish message ticket
            process.send({ ticket: message.ticket, success: true });
        });
    }else if(message.type === 'do') {
        log("RUNNING", message.name);
        var args = [message.name];
        args = args.concat(message.args);
        args.push(function WORKER_DO_CALLBACK(error) {
            var args = Array.prototype.slice.call(arguments);
            if(error) log("FAILED", message.ticket);
            if(error) return process.send({ ticket: message.ticket, success: false, error: error.message });
            // Finish message ticket
            log("DONE", message.ticket);
            process.send({ ticket: message.ticket, success: true, args: args });
        });
        ST_INSTANCE.do.apply(ST_INSTANCE, args);
    }
});<commit_msg>Updated Worker debug script<commit_after>/// Required Core Modules
var os = require('os');
var cluster = require('cluster');
///
/// External Modules
var SuperTask = require('supertask');
///
/// Internal Modules
var BufferAllocator = require('./BufferAllocator');
var StorageObject = require('./StorageObject');
///
// No Operation function
function noop() { return null; }
// Log function
function log() {
    var args = Array.prototype.slice.call(arguments);
    // Prepend worker id
    args.unshift('WORKER#' + process.argv.slice(2)[0]);
    console.log.apply(console, args);
}

/* Editing Guidelines
    - Keep the format functional (use functions)
    - Filter message down to the basics in process.on('...')
      and process the message in a function. Try to avoid sharing
      a function that has an if/else statement to distinguish
      between two subparts of a message (create a function for every
      submessage)
     - Don't use process.send as the given callback should be enough
     to pass data back.
*/

// Create new master Supertask instance
var ST_INSTANCE = new SuperTask();
var STC_STORAGE_MAP = new Map();

function STC_WORKER_CALLBACK_CREATOR(ticket) {
    return function STC_WORKER_CALLBACK(error, extension) {
        if(error) {
            log("ERROR::", message.name, error.message, ticket);
            process.send({ ticket: ticket, success: false, error: error.message });
        }else{
            log("DONE", ticket);
            var message = { ticket: ticket, success: true };
            // Merge extension to message
            if(extension) for (var property in extension) { message[property] = extension[property]; }
            // Finish message ticket
            process.send(message);
        }
    };
}

function STC_WORKER_GRACEFUL_KILL(callback) {
    // Implement Graceful Kill
    callback();
}

function STC_WORKER_ADD(message, callback) {
    ST_INSTANCE.addForeign(message.name, message.source, function(error, task) {
        if(error) return callback(error);
        if(message.isModule) task.module(message.isModule);
        if(message.priority) task.priority(message.priority);
        if(typeof message.defaultContext === 'object') task.context(message.defaultContext || {});
        if(message.access) task.permission(message.access);

        callback();
    });
}

function STC_WORKER_DO(message, callback) {
    var args = [message.name];
    args = args.concat(message.args);
    // Process StorageObjects to value
    for(var i = 0; i < args.length; i++) {
        if(StorageObject.is(args[i])) {
            args[i] = StorageObject.toValue(STC_STORAGE_MAP, args[i]);
        }
    }
    args.push(function WORKER_DO_CALLBACK(error) {
        var args = Array.prototype.slice.call(arguments);
        if(error) return callback(error);
        // Finish message ticket
        callback(null, { args: args });
    });
    ST_INSTANCE.do.apply(ST_INSTANCE, args);
}

function STC_WORKER_BUFFER_ALLOCATE(message, callback) {
    STC_STORAGE_MAP.set(message.name, new BufferAllocator(message.name, message.size, message.encoding, !message.mutable, message.split));
    // Finish message ticket
    callback();
}

function STC_WORKER_BUFFER_STREAM(message, callback) {
    var buffer = STC_STORAGE_MAP.get(message.name);
    if(message.done) {
        buffer.set(message.data, message.chunk);
        buffer.setDone();
        // Finish Buffer
        callback(null, { ticket: "STC_BUFFER:" + message.name, digest: buffer.digest(), encoding: buffer.encoding })
    }else{
        buffer.set(message.data, message.chunk);
    }
}

process.on('message', function(message) {
    if((!message) || (typeof message !== 'object')) return; // Invalid STC message
    log("MESSAGE RECEIVED", message.name);
    var callback = STC_WORKER_CALLBACK_CREATOR(message.ticket);
    if(message.type === "STC_KILL_YOURSELF_PLEASE") {
        log("KILLING SELF GRACEFULLY");
        STC_WORKER_GRACEFUL_KILL(callback);
    }else if(message.type === 'task') {
        log("ADDING", message.name);
        STC_WORKER_ADD(message, callback);
    }else if(message.type === 'do') {
        log("RUNNING", message.name);
        STC_WORKER_DO(message, callback);
    }else if(message.type === 'buffer') {
        // If Buffer is not allocated
        if(!STC_STORAGE_MAP.has(message.name)) {
            log("ALLOCATING", message.name);
            // Allocate Buffer
            STC_WORKER_BUFFER_ALLOCATE(message, callback);
        }else{
            log("STREAMING TO", message.name);
            // Stream to Buffer
            STC_WORKER_BUFFER_STREAM(message, callback);
        }
    }
});<|endoftext|>


<commit_before>'use strict';
const storageManager = require('./../StorageManager'),
    BlobHttpProperties = require('./../model/BlobHttpProperties'),
    uuid = require('node-uuid');

class PutBlock {
    constructor() {
    }

    process(req, res, containerName, blobName, blockId) {
        const options = {
            blockId: blockId,
            contentLength: req.headers['content-length'],
            fileName: `${containerName}-${blobName}-${blockId}`,
            parent: `${containerName}-${blobName}`,
            httpProps: new BlobHttpProperties(null,
                                              null,
                                              null,
                                              req.headers['x-ms-blob-content-encoding'] || 'utf8',
                                              null,
                                              req.headers['content-mD5'],
                                              false)
        }
        // Content-Length is required. The length of the block content in bytes.
        // The block must be less than or equal to 4 MB in size.
        // When the length is not provided, the operation will fail with the status code 411 (Length Required).
        if (!options.contentLength) {
            res.status(411).send();
            return;
        }
        // Blocks larger than 4MB are not allowed as per specification at
        // https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/put-block
        if (options.contentLength > 4194304) {
            res.status(413).send();
        }
        storageManager.putBlock(containerName, blobName, req.body, options)
            .then((result) => {
                this._addResponseHeaders(res, result);
                res.status(201).send();
            })
            .catch((e) => {
                if (e.name === 'md5') {
                    res.status(400).send(e.message);
                }
            });
    }

    _addResponseHeaders(res, props) {
        res.set({
            'ETag': props.ETag,
            'Last-Modified': props.lastModified,
            'Content-MD5': props['Content-MD5'],
            'x-ms-request-server-encrypted': false,
            'x-ms-version': '2011-08-18',
        });
    }
}

module.exports = new PutBlock();<commit_msg>removed unused package<commit_after>'use strict';
const storageManager = require('./../StorageManager'),
    BlobHttpProperties = require('./../model/BlobHttpProperties');

class PutBlock {
    constructor() {
    }

    process(req, res, containerName, blobName, blockId) {
        const options = {
            blockId: blockId,
            contentLength: req.headers['content-length'],
            fileName: `${containerName}-${blobName}-${blockId}`,
            parent: `${containerName}-${blobName}`,
            httpProps: new BlobHttpProperties(null,
                                              null,
                                              null,
                                              req.headers['x-ms-blob-content-encoding'] || 'utf8',
                                              null,
                                              req.headers['content-mD5'],
                                              false)
        }
        // Content-Length is required. The length of the block content in bytes.
        // The block must be less than or equal to 4 MB in size.
        // When the length is not provided, the operation will fail with the status code 411 (Length Required).
        if (!options.contentLength) {
            res.status(411).send();
            return;
        }
        // Blocks larger than 4MB are not allowed as per specification at
        // https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/put-block
        if (options.contentLength > 4194304) {
            res.status(413).send();
        }
        storageManager.putBlock(containerName, blobName, req.body, options)
            .then((result) => {
                this._addResponseHeaders(res, result);
                res.status(201).send();
            })
            .catch((e) => {
                if (e.name === 'md5') {
                    res.status(400).send(e.message);
                }
            });
    }

    _addResponseHeaders(res, props) {
        res.set({
            'ETag': props.ETag,
            'Last-Modified': props.lastModified,
            'Content-MD5': props['Content-MD5'],
            'x-ms-request-server-encrypted': false,
            'x-ms-version': '2011-08-18',
        });
    }
}

module.exports = new PutBlock();<|endoftext|>


<commit_before>// jshint esnext:true
var koa = require('koa'),
    ZoneRenderer = require('./../../pretty/lib/zone');

module.exports = App;

function App(){
  var blogApp = new koa();
  var zone = new ZoneRenderer();
  console.log('initializing the blog');

  blogApp.use(function* (next) {
    var start = new Date();
    yield next;
    console.log('Rendering blog: ' + (new Date() - start) + 'ms');
  });

  blogApp.use(function* (next){
    var self = this;
    self.body = '';
    var renderer = zone.render('footer');
    yield next;
    renderer.then(function(htmlBuffer) {
      console.log('rendering the footer');
      self.body += htmlBuffer.toString();
    })
  });

  blogApp.use(function* (next){
    var self = this;
    self.body = '';
    var renderer = zone.render('body');
    yield next;
    renderer.then(function(htmlBuffer) {
      console.log('rendering the body');
      self.body += htmlBuffer.toString();
    })
  });

  blogApp.use(function* (next){
    var self = this;
    var renderer = zone.render('header');
    yield next;
    renderer.then(function(htmlBuffer) {
      console.log('rendering the header');
      self.body += htmlBuffer.toString();
    })
  });

  blogApp.use(function* (){

  });

  return blogApp;
}
<commit_msg>fix test<commit_after>// jshint esnext:true
var koa = require('koa'),
    ZoneRenderer = require('./../../pretty/lib/zone');

module.exports = App;

function App(){
  var blogApp = new koa();
  var zone = new ZoneRenderer();
  console.log('initializing the blog');

  blogApp.use(function* (next) {
    var start = new Date();
    yield next;
    console.log('Rendering blog: ' + (new Date() - start) + 'ms');
  });

  blogApp.use(function* (next){
    var self = this;
    self.body = '';
    var renderer = zone.render('footer');
    yield next;
    renderer.then(function(htmlBuffer) {
      console.log('rendering the footer');
      self.body += htmlBuffer.toString();
    });
  });

  blogApp.use(function* (next){
    var self = this;
    self.body = '';
    var renderer = zone.render('body');
    yield next;
    renderer.then(function(htmlBuffer) {
      console.log('rendering the body');
      self.body += htmlBuffer.toString();
    });
  });

  blogApp.use(function* (next){
    var self = this;
    var renderer = zone.render('header');
    yield next;
    renderer.then(function(htmlBuffer) {
      console.log('rendering the header');
      self.body += htmlBuffer.toString();
    });
  });

  blogApp.use(function* (){
    yield {};
  });

  return blogApp;
}
<|endoftext|>


<commit_before>/**
 * ain2 module for writing to syslog
 *
 * 0  emerg    Emergency: system is unusable
 * 1  alert    Alert: action must be taken immediately
 * 2  crit     Critical: critical conditions
 * 3  err      Error: error conditions
 * 4  warn     Warning: warning conditions
 * 5  notice   Notice: normal but significant condition
 * 6  info     Informational: informational messages
 * 7  debug    Debug: debug-level messages
 *
 *
 * Facilities
 *  0  kern    kernel messages
 *  1  user    user-level messages
 *  2  mail    mail system
 *  3  daemon  system daemons
 *  4  auth    security/authorization messages
 *  5  syslog  messages generated internally by syslog daemon
 *  6  lpr     line printer subsystem
 *  7  news    network news subsystem
 *  8  uucp    UUCP subsystem
 *  16  local0  local use 0
 *  17  local1  local use 1
 *  18  local2  local use 2
 *  19  local3  local use 3
 *  20  local4  local use 4
 *  21  local5  local use 5
 *  22  local6  local use 6
 *  23  local7  local use 7
 * @type {SysLogger|exports|*}
 */
var SysLogger   = require('ain2')
  , util        = require('util')
  , log         = {}
  , metalogger  = require('../metalogger');

var _level      = 'debug'
  , _facility   = 'local0'
  , _app_name   = 'app_name';

var levels = {'debug':7, 'info':6, 'notice':5, 'warning':4, 'error':3, 'critical':2, 'alert':1, 'emergency':0};

exports = module.exports = function(level) {

  var logger = {}
    , options = {
      facility: _facility,
      tag:      _app_name
    };

  if ('NODE_LOGGER_FACILITY' in process.env && process.env.NODE_LOGGER_FACILITY) {
    options.facility = process.env.NODE_LOGGER_FACILITY;
  }

  if ('NODE_LOGGER_APPNAME' in process.env && process.env.NODE_LOGGER_APPNAME) {
    options.tag = process.env.NODE_LOGGER_APPNAME;
  }

  if (level in levels) _level = level;

  log = new SysLogger(options);

  for(var level in levels) {
    logger[level] = function(){delegate(level, arguments)};
  }

  return logger;
}

function delegate(method, _args) {

  var call_position = metalogger.callposition();

  if (!metalogger.logLevelAllowedGranular(method)) {
    if (!metalogger.logLevelAllowed(method, _level)) {
      return;
    }
  }

  var args = Array.prototype.slice.call(_args);

  var message = [call_position];
  if(args.length === 1) {
    message.push(util.inspect(args[0], { showHidden: true, depth: null }));
  }

  if(args.length === 2) {
    message.push(args.shift());
    message.push(util.inspect(args[0], { showHidden: true, depth: null }));
  }

  if(args.length > 2) {
    message.push(args.shift());
    message.push(util.format.apply(null, args));
  }

  log.send(message.join(' '), levels[method]);
}<commit_msg>Fixing a problem with my loop logic. #3<commit_after>/**
 * ain2 module for writing to syslog
 *
 * 0  emerg    Emergency: system is unusable
 * 1  alert    Alert: action must be taken immediately
 * 2  crit     Critical: critical conditions
 * 3  err      Error: error conditions
 * 4  warn     Warning: warning conditions
 * 5  notice   Notice: normal but significant condition
 * 6  info     Informational: informational messages
 * 7  debug    Debug: debug-level messages
 *
 *
 * Facilities
 *  0  kern    kernel messages
 *  1  user    user-level messages
 *  2  mail    mail system
 *  3  daemon  system daemons
 *  4  auth    security/authorization messages
 *  5  syslog  messages generated internally by syslog daemon
 *  6  lpr     line printer subsystem
 *  7  news    network news subsystem
 *  8  uucp    UUCP subsystem
 *  16  local0  local use 0
 *  17  local1  local use 1
 *  18  local2  local use 2
 *  19  local3  local use 3
 *  20  local4  local use 4
 *  21  local5  local use 5
 *  22  local6  local use 6
 *  23  local7  local use 7
 * @type {SysLogger|exports|*}
 */
var SysLogger   = require('ain2')
  , util        = require('util')
  , log         = {}
  , metalogger  = require('../metalogger');

var _level      = 'debug'
  , _facility   = 'local0'
  , _app_name   = 'app_name';

var levels = {'debug':7, 'info':6, 'notice':5, 'warning':4, 'error':3, 'critical':2, 'alert':1, 'emergency':0};

exports = module.exports = function(level) {

  var logger = {}
    , options = {
      facility: _facility,
      tag:      _app_name
    };

  if ('NODE_LOGGER_FACILITY' in process.env && process.env.NODE_LOGGER_FACILITY) {
    options.facility = process.env.NODE_LOGGER_FACILITY;
  }

  if ('NODE_LOGGER_APPNAME' in process.env && process.env.NODE_LOGGER_APPNAME) {
    options.tag = process.env.NODE_LOGGER_APPNAME;
  }

  if (level in levels) _level = level;

  log = new SysLogger(options);

  for(var level in levels) {
    logger[level] = (function(level, arguments){
      return function(){
        delegate(level, arguments)
      }
    })(level, arguments);
  }

  return logger;
}

function delegate(method, _args) {

  var call_position = metalogger.callposition();

  if (!metalogger.logLevelAllowedGranular(method)) {
    if (!metalogger.logLevelAllowed(method, _level)) {
      return;
    }
  }

  var args = Array.prototype.slice.call(_args);

  var message = [call_position];
  if(args.length === 1) {
    message.push(util.inspect(args[0], { showHidden: true, depth: null }));
  }

  if(args.length === 2) {
    message.push(args.shift());
    message.push(util.inspect(args[0], { showHidden: true, depth: null }));
  }

  if(args.length > 2) {
    message.push(args.shift());
    message.push(util.format.apply(null, args));
  }

  log.send(message.join(' '), levels[method]);
}<|endoftext|>


<commit_before>"use babel"

class Diff {
  constructor({gitIndex, filePath}) {
    this.gitIndex = gitIndex
    this.filePath = filePath
  }

  // Maps staged data onto a diff of the HEAD -> the working dir
  async getPatch () {
    await this.gitIndex.getStatuses()

    let all = this.gitIndex.getPatch(this.filePath, 'all')
    let staged = this.gitIndex.getPatch(this.filePath, 'staged')

    allPatch = await all
    stagedPatch = await staged

    let allHunks = await this._extractHunks(allPatch)
    let stagedHunks = await this._extractHunks(stagedPatch)

    // This is not really correct. Problematic when there are staged changes,
    // then another change is made in the area of the staged change.
    for(let hunk of allHunks) {
      for(let line of hunk.lines) {
        if(this._lineInHunks(line, stagedHunks)){
          console.log('STAGED', line.oldLineno(), line.newLineno(), line.content().split(/[\r\n]/g)[0])
          line.staged = true
        }
      }
    }

    return {
      entry: {
        path: this.filePath,
        status: 'all'
      },
      patch: new Patch(allPatch, allHunks)
    }
  }

  _lineInHunks(lineToFind, hunks) {
    for(let hunk of hunks) {
      for(let line of hunk.lines) {
        if(this._linesEqual(line, lineToFind))
          return true
      }
    }
  }

  _linesEqual(lineA, lineB) {
    let contentA = lineA.content().split(/[\r\n]/g)[0]
    let contentB = lineB.content().split(/[\r\n]/g)[0]

    return lineA.oldLineno() == lineB.oldLineno() &&
      lineA.newLineno() == lineB.newLineno() &&
      contentA == contentB
  }

  async _extractHunks(patch) {
    let hunks = []
    if (patch) {
      for (let hunk of (await patch.hunks())) {
        let lines = await hunk.lines()
        hunks.push(new Hunk(hunk.header(), lines))
      }
    }
    return hunks
  }
}

class Patch {
  constructor(patch, hunks) {
    this._patch = patch
    this.newPathName = patch.newFile().path()
    this.oldPathName = patch.oldFile().path()
    this.hunks = hunks
    for(let hunk of hunks) {
      hunk.patch = this
    }
  }

  getRaw() {
    return this._patch
  }

  size() {
    return this._patch.size()
  }

  isRenamed() {
    return this._patch.isRenamed()
  }

  isAdded() {
    return this._patch.isAdded()
  }

  isUntracked() {
    return this._patch.isUntracked()
  }

  isDeleted() {
    return this._patch.isDeleted()
  }
}

class Hunk {
  constructor(header, lines) {
    this.header = header
    this.lines = lines
  }
}

module.exports = Diff
<commit_msg>Pass hunk around<commit_after>"use babel"

class Diff {
  constructor({gitIndex, filePath}) {
    this.gitIndex = gitIndex
    this.filePath = filePath
  }

  // Maps staged data onto a diff of the HEAD -> the working dir
  async getPatch () {
    await this.gitIndex.getStatuses()

    let all = this.gitIndex.getPatch(this.filePath, 'all')
    let staged = this.gitIndex.getPatch(this.filePath, 'staged')

    allPatch = await all
    stagedPatch = await staged

    let allHunks = await this._extractHunks(allPatch)
    let stagedHunks = await this._extractHunks(stagedPatch)

    // This is not really correct. Problematic when there are staged changes,
    // then another change is made in the area of the staged change.
    for(let hunk of allHunks) {
      for(let line of hunk.lines) {
        if(this._lineInHunks(line, stagedHunks)){
          console.log('STAGED', line.oldLineno(), line.newLineno(), line.content().split(/[\r\n]/g)[0])
          line.staged = true
        }
      }
    }

    return {
      entry: {
        path: this.filePath,
        status: 'all'
      },
      patch: new Patch(allPatch, allHunks)
    }
  }

  _lineInHunks(lineToFind, hunks) {
    for(let hunk of hunks) {
      for(let line of hunk.lines) {
        if(this._linesEqual(line, lineToFind))
          return true
      }
    }
  }

  _linesEqual(lineA, lineB) {
    let contentA = lineA.content().split(/[\r\n]/g)[0]
    let contentB = lineB.content().split(/[\r\n]/g)[0]

    return lineA.oldLineno() == lineB.oldLineno() &&
      lineA.newLineno() == lineB.newLineno() &&
      contentA == contentB
  }

  async _extractHunks(patch) {
    let hunks = []
    if (patch) {
      for (let hunk of (await patch.hunks())) {
        let lines = await hunk.lines()
        hunks.push(new Hunk(hunk, lines))
      }
    }
    return hunks
  }
}

class Patch {
  constructor(patch, hunks) {
    this._patch = patch
    this.newPathName = patch.newFile().path()
    this.oldPathName = patch.oldFile().path()
    this.hunks = hunks
    for(let hunk of hunks) {
      hunk.patch = this
    }
  }

  getRaw() {
    return this._patch
  }

  size() {
    return this._patch.size()
  }

  isRenamed() {
    return this._patch.isRenamed()
  }

  isAdded() {
    return this._patch.isAdded()
  }

  isUntracked() {
    return this._patch.isUntracked()
  }

  isDeleted() {
    return this._patch.isDeleted()
  }
}

class Hunk {
  constructor(hunk, lines) {
    this._hunk = hunk
    this.header = hunk.header()
    this.lines = lines
  }
}

module.exports = Diff
<|endoftext|>


<commit_before>var event = require('./event');
var context_menu = require('./context_menu');
var context_menu = require('./tab');

var Chrome = chrome;

module.exports = Chrome;

event(Chrome);
Chrome.context_menu = context_menu;
Chrome.tab = tab;

/**
 * properties
 *     tab
 *     context_menu
 *
 * methods
 *     send     @runtime.sendMessage
 *     notify   @notifications.create
 *     set      save persistent data in localStorage
 *     get      retrive persistent data in localStorage
 */

//aliases
Chrome.send = chrome.runtime.sendMessage;

//notification
Chrome.notify = function(opt, callback) {
    opt = {
        type: 'basic',
        title: opt.title || 'Extension',
        message: opt.data,
        iconUrl: opt.icon
    };

    if(callback) {
        return chrome.notifications.create('', opt, callback);
    }

    chrome.notifications.create('', opt, function() {});
};

Chrome.playAudio = function(url) {
    var audio = document.createElement('audio');
    audio.src = url;
    audio.play();
};

Chrome.set = function(key, value) {
    var data = localStorage.data;

    if(!key) {
        return;
    }

    if(!data) {
        data = {};
    }

    try {
        data = JSON.parse(data);
    } catch(e) {
        delete localStorage.data;
        data = {};
    }

    if(!value) {
        var obj = key;
        var keys = Object.keys(obj);

        for(var i = 0; i < keys.length; i++) {
            data[keys[i]] = obj[keys[i]];
        }
    } else {
        data[key] = value;
    }

    localStorage.data = JSON.stringify(data);
};

Chrome.get = function(key) {
    var data = localStorage.data;

    if(!data) {
        data = {};
    }

    try {
        data = JSON.parse(data);
    } catch(e) {
        delete localStorage.data;
        data = {};
    }

    if(!key) {
        return data;
    }

    return data[key];
};<commit_msg>fix tab<commit_after>var event        = require('./event');
var context_menu = require('./context_menu');
var tab          = require('./tab');

var Chrome = chrome;

module.exports = Chrome;

event(Chrome);
Chrome.context_menu = context_menu;
Chrome.tab = tab;

/**
 * properties
 *     tab
 *     context_menu
 *
 * methods
 *     send     @runtime.sendMessage
 *     notify   @notifications.create
 *     set      save persistent data in localStorage
 *     get      retrive persistent data in localStorage
 */

//aliases
Chrome.send = chrome.runtime.sendMessage;

//notification
Chrome.notify = function(opt, callback) {
    opt = {
        type: 'basic',
        title: opt.title || 'Extension',
        message: opt.data,
        iconUrl: opt.icon
    };

    if(callback) {
        return chrome.notifications.create('', opt, callback);
    }

    chrome.notifications.create('', opt, function() {});
};

Chrome.playAudio = function(url) {
    var audio = document.createElement('audio');
    audio.src = url;
    audio.play();
};

Chrome.set = function(key, value) {
    var data = localStorage.data;

    if(!key) {
        return;
    }

    if(!data) {
        data = {};
    }

    try {
        data = JSON.parse(data);
    } catch(e) {
        delete localStorage.data;
        data = {};
    }

    if(!value) {
        var obj = key;
        var keys = Object.keys(obj);

        for(var i = 0; i < keys.length; i++) {
            data[keys[i]] = obj[keys[i]];
        }
    } else {
        data[key] = value;
    }

    localStorage.data = JSON.stringify(data);
};

Chrome.get = function(key) {
    var data = localStorage.data;

    if(!data) {
        data = {};
    }

    try {
        data = JSON.parse(data);
    } catch(e) {
        delete localStorage.data;
        data = {};
    }

    if(!key) {
        return data;
    }

    return data[key];
};<|endoftext|>


<commit_before>/* See license.txt for terms of usage */

"use strict";

const self = require("sdk/self");
const main = require("../main.js");

const { Cu } = require("chrome");
const { Trace, TraceError } = require("../core/trace.js").get(module.id);
const { Locale } = require("../core/locale.js");
const { loadSheet } = require("sdk/stylesheet/utils");
const { emit, on, off } = require("sdk/event/core");
const { Win } = require("../core/window.js");
const { Xul } = require("../core/xul.js");
const { Dom } = require("../core/dom.js");
const { System } = require("../core/system.js");
const { ToolbarButton } = require("../chrome/panelToolbar.js");
const { windows, isDocumentLoaded } = require("sdk/window/utils");
const { prefs } = require("sdk/simple-prefs");

const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const StylesheetUtils = devtools["require"]("sdk/stylesheet/utils");

// XUL Builder
const { BOX } = Xul;

const Theme = {};

/**
* Load firebug theme stylesheets into the toolbox.
*
* @param {@Toolbox} toolbox Reference to the toolbox instance
*/
Theme.registerFirebugTheme = function(options) {
  let skinUrl = "chrome://firebug/skin/";

  // List of styles to load.
  let sharedStyles = [
    skinUrl + "common.css",
    skinUrl + "firebug-theme.css",
    skinUrl + "toolbox.css",
    skinUrl + "toolbars.css",
    skinUrl + "buttons.css",
    skinUrl + "splitter.css",
    skinUrl + "searchbox.css",
    skinUrl + "tabmenu.css",
    skinUrl + "options.css",
    skinUrl + "codemirror-firebug.css",
    skinUrl + "panelbase.css",
    skinUrl + "toggle-sidepanels.css",
    skinUrl + "command-editor.css",
    skinUrl + "webconsole.css",
    skinUrl + "markup-view.css"
  ];

  // List of OS dependent styles are added at the end, so they
  // can override the default (shared) styling.
  // xxxHonza: we might want to automate this. Automatically change
  // URL (add '-os') of every default (shared) stylesheet and append
  // if it exists.
  let osSkinUrl = "chrome://firebug-os/skin/";
  let osStyles = [
    osSkinUrl + "searchbox.css",
  ]

  // Register new developer tools theme.
  gDevTools.registerTheme({
    id: "firebug",
    label: Locale.$STR("options.label.firebugTheme"),
    stylesheets: sharedStyles.concat(osStyles),
    classList: ["theme-light", "theme-firebug"],
    onApply: this.onThemeApply.bind(this),
    onUnapply: this.onThemeUnapply.bind(this),
  });

  this.onPrefChanged = this.onPrefChanged.bind(this);
  gDevTools.on("pref-changed", this.onPrefChanged);

  // Set Firebug theme as the default one if Firebug has been installed
  // or enabled. Downgrade and upgrade is also supported since these
  // changes cause Firebug theme deactivation (when uninstalling the
  // previous version). This way e.g. Firebug reinstallation doesn't
  // deactivatethe theme. There can be some corner cases where Firebug
  // theme is activated while user didn't want to, but in general,
  // if the user is installing Firebug there is good chance he/she wants
  // to see the Firebug theme.
  let reason = options.loadReason;
  if (reason == "install" || reason == "enable" ||
      reason == "upgrade" || reason == "downgrade") {
    // xxxHonza: iterate over all browser windows and tabs and reopen
    // all existing toolboxes in order to properly apply Firebug overlays.
    // TODO: panel overlays (and the toolbox customizations) should be
    // properly applied even on existing panels.
    let browsers = windows("navigator:browser", {includePrivate: true});
    browsers.forEach(browser => {
      let tabBrowser = browser.getBrowser();
      let numTabs = tabBrowser.browsers.length;
      for (let index=0; index<numTabs; index++) {
        reopenToolbox(tabBrowser.mTabs[index]);
      }
    });

    // Remember the default Developer browser edition theme for restoration
    // when Firebug is uninstalled or disabled.
    safeBrowserEditionTheme();

    // Activate Firebug theme.
    this.toggle(true);
  }
}

function reopenToolbox(tab) {
  let target = devtools.TargetFactory.forTab(tab);
  let toolbox = gDevTools.getToolbox(target);
  if (toolbox) {
    toolbox.destroy().then(() => {
      let target = devtools.TargetFactory.forTab(tab);
      gDevTools.showToolbox(target);
    });
  }
}

Theme.unregisterFirebugTheme = function(reason) {
  // Unregister Firebug theme.
  gDevTools.unregisterTheme("firebug");

  if (reason == "uninstall" || reason == "disable") {
    // Synchronize Developer Edition browser theme. If Firebug
    // is uninstalled (or disabled) set back the Developer Edition
    // browser theme.
    restoreBrowserEditionTheme();
  }
}

// Preferences changes callback
Theme.onPrefChanged = function(event, data) {
  if (data.pref != "devtools.theme") {
    return;
  }

  // Synchronize Developer Edition browser theme. If Firebug toolbox
  // theme is applied the dev-browser theme must be switched off, so
  // the default Australis is on.
  // The user can manually change the usage of dev-browser theme in
  // Customize screen by using "Use Firefox Developer Edition Theme"
  // button (only available in Firefox Developer Edition).
  toggleBrowserEditionTheme(data.newValue != "firebug");
},

Theme.onThemeApply = function(win, oldTheme) {
  let documentElement = win.document.documentElement;
  let location = documentElement.ownerDocument.location;

  Trace.sysout("theme.onThemeApply; " + location + ", " +
    documentElement.className, win);

  emit(this, "onThemeApply", win, oldTheme);
}

Theme.onThemeUnapply = function(win, newTheme) {
  let documentElement = win.document.documentElement;
  let location = documentElement.ownerDocument.location;

  Trace.sysout("theme.onThemeUnapply; " + location + ", " +
    documentElement.className, win);

  emit(this, "onThemeUnapply", win, newTheme);
}

Theme.addThemeListeners = function(apply, unapply) {
  on(this, "onThemeApply", apply);
  on(this, "onThemeUnapply", unapply);
}

Theme.removeThemeListeners = function(apply, unapply) {
  off(this, "onThemeApply", apply);
  off(this, "onThemeUnapply", unapply);
}

Theme.getCurrentTheme = function() {
  return Services.prefs.getCharPref("devtools.theme");
}

Theme.isFirebugActive = function() {
  return Theme.getCurrentTheme() == "firebug";
}

Theme.toggle = function(forceFirebug) {
  let oldValue = this.getCurrentTheme();
  let newValue = this.isFirebugActive() ? "light" : "firebug";

  if (forceFirebug) {
    newValue = "firebug";
    if (oldValue == "firebug") {
      oldValue = null;
    }
  }

  Services.prefs.setCharPref("devtools.theme", newValue);

  let data = {
    pref: "devtools.theme",
    newValue: newValue,
    oldValue: oldValue
  };

  gDevTools.emit("pref-changed", data);
}

Theme.customizeSideBarSplitter = function(iframeWin, apply) {
  Win.loaded(iframeWin).then(doc => {
    if (apply) {
      // Create a little box in the splitter, so we can theme its top
      // part located between the main and side panel toolbars.
      // Note that the splitter element is available as soon as
      // the document is loaded.
      if (!doc.querySelector(".devtools-side-splitter > .panelSplitterBox")) {
        let splitter = doc.querySelector(".devtools-side-splitter");
        splitter.setAttribute("valign", "top");
        BOX({"class": "panelSplitterBox"}).build(splitter);
      }
    }
    else {
      // Remove customization
      let splitter = doc.querySelector(".devtools-side-splitter");
      splitter.removeAttribute("valign");
      Dom.clearNode(splitter);
    }
  });
}

// Developer Browser Edition Theme API

function toggleBrowserEditionTheme(enabled) {
  if (!System.isDeveloperBrowser()) {
    return;
  }

  Trace.sysout("theme.toggleBrowserEditionTheme; " + enabled);

  try {
    Services.prefs.setBoolPref("browser.devedition.theme.enabled", enabled);
  } catch (err) {
    Trace.sysout("theme.toggleBrowserEditionTheme; " + err, err);
  }
}

function safeBrowserEditionTheme() {
  if (!System.isDeveloperBrowser()) {
    return;
  }

  try {
    let state = Services.prefs.getBoolPref("browser.devedition.theme.enabled");
    prefs["developerBrowserThemeDefault"] = state;

    Trace.sysout("theme.safeBrowserEditionTheme; " + state);
  } catch (err) {
    Trace.sysout("theme.safeBrowserEditionTheme; " + err, err);
  }
}

function restoreBrowserEditionTheme() {
  if (!System.isDeveloperBrowser()) {
    return;
  }

  try {
    let state = prefs["developerBrowserThemeDefault"];
    Services.prefs.setBoolPref("browser.devedition.theme.enabled", state);

    Trace.sysout("theme.restoreBrowserEditionTheme; " + state);
  } catch (err) {
    Trace.sysout("theme.restoreBrowserEditionTheme; " + err, err);
  }
}

// Exports from this module
exports.Theme = Theme;
<commit_msg>Fix typo<commit_after>/* See license.txt for terms of usage */

"use strict";

const self = require("sdk/self");
const main = require("../main.js");

const { Cu } = require("chrome");
const { Trace, TraceError } = require("../core/trace.js").get(module.id);
const { Locale } = require("../core/locale.js");
const { loadSheet } = require("sdk/stylesheet/utils");
const { emit, on, off } = require("sdk/event/core");
const { Win } = require("../core/window.js");
const { Xul } = require("../core/xul.js");
const { Dom } = require("../core/dom.js");
const { System } = require("../core/system.js");
const { ToolbarButton } = require("../chrome/panelToolbar.js");
const { windows, isDocumentLoaded } = require("sdk/window/utils");
const { prefs } = require("sdk/simple-prefs");

const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
const { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
const StylesheetUtils = devtools["require"]("sdk/stylesheet/utils");

// XUL Builder
const { BOX } = Xul;

const Theme = {};

/**
* Load firebug theme stylesheets into the toolbox.
*
* @param {@Toolbox} toolbox Reference to the toolbox instance
*/
Theme.registerFirebugTheme = function(options) {
  let skinUrl = "chrome://firebug/skin/";

  // List of styles to load.
  let sharedStyles = [
    skinUrl + "common.css",
    skinUrl + "firebug-theme.css",
    skinUrl + "toolbox.css",
    skinUrl + "toolbars.css",
    skinUrl + "buttons.css",
    skinUrl + "splitter.css",
    skinUrl + "searchbox.css",
    skinUrl + "tabmenu.css",
    skinUrl + "options.css",
    skinUrl + "codemirror-firebug.css",
    skinUrl + "panelbase.css",
    skinUrl + "toggle-sidepanels.css",
    skinUrl + "command-editor.css",
    skinUrl + "webconsole.css",
    skinUrl + "markup-view.css"
  ];

  // List of OS dependent styles are added at the end, so they
  // can override the default (shared) styling.
  // xxxHonza: we might want to automate this. Automatically change
  // URL (add '-os') of every default (shared) stylesheet and append
  // if it exists.
  let osSkinUrl = "chrome://firebug-os/skin/";
  let osStyles = [
    osSkinUrl + "searchbox.css",
  ]

  // Register new developer tools theme.
  gDevTools.registerTheme({
    id: "firebug",
    label: Locale.$STR("options.label.firebugTheme"),
    stylesheets: sharedStyles.concat(osStyles),
    classList: ["theme-light", "theme-firebug"],
    onApply: this.onThemeApply.bind(this),
    onUnapply: this.onThemeUnapply.bind(this),
  });

  this.onPrefChanged = this.onPrefChanged.bind(this);
  gDevTools.on("pref-changed", this.onPrefChanged);

  // Set Firebug theme as the default one if Firebug has been installed
  // or enabled. Downgrade and upgrade is also supported since these
  // changes cause Firebug theme deactivation (when uninstalling the
  // previous version). This way e.g. Firebug reinstallation doesn't
  // deactivatethe theme. There can be some corner cases where Firebug
  // theme is activated while user didn't want to, but in general,
  // if the user is installing Firebug there is good chance he/she wants
  // to see the Firebug theme.
  let reason = options.loadReason;
  if (reason == "install" || reason == "enable" ||
      reason == "upgrade" || reason == "downgrade") {
    // xxxHonza: iterate over all browser windows and tabs and reopen
    // all existing toolboxes in order to properly apply Firebug overlays.
    // TODO: panel overlays (and the toolbox customizations) should be
    // properly applied even on existing panels.
    let browsers = windows("navigator:browser", {includePrivate: true});
    browsers.forEach(browser => {
      let tabBrowser = browser.getBrowser();
      let numTabs = tabBrowser.browsers.length;
      for (let index=0; index<numTabs; index++) {
        reopenToolbox(tabBrowser.mTabs[index]);
      }
    });

    // Remember the default Developer browser edition theme for restoration
    // when Firebug is uninstalled or disabled.
    saveBrowserEditionTheme();

    // Activate Firebug theme.
    this.toggle(true);
  }
}

function reopenToolbox(tab) {
  let target = devtools.TargetFactory.forTab(tab);
  let toolbox = gDevTools.getToolbox(target);
  if (toolbox) {
    toolbox.destroy().then(() => {
      let target = devtools.TargetFactory.forTab(tab);
      gDevTools.showToolbox(target);
    });
  }
}

Theme.unregisterFirebugTheme = function(reason) {
  // Unregister Firebug theme.
  gDevTools.unregisterTheme("firebug");

  if (reason == "uninstall" || reason == "disable") {
    // Synchronize Developer Edition browser theme. If Firebug
    // is uninstalled (or disabled) set back the Developer Edition
    // browser theme.
    restoreBrowserEditionTheme();
  }
}

// Preferences changes callback
Theme.onPrefChanged = function(event, data) {
  if (data.pref != "devtools.theme") {
    return;
  }

  // Synchronize Developer Edition browser theme. If Firebug toolbox
  // theme is applied the dev-browser theme must be switched off, so
  // the default Australis is on.
  // The user can manually change the usage of dev-browser theme in
  // Customize screen by using "Use Firefox Developer Edition Theme"
  // button (only available in Firefox Developer Edition).
  toggleBrowserEditionTheme(data.newValue != "firebug");
},

Theme.onThemeApply = function(win, oldTheme) {
  let documentElement = win.document.documentElement;
  let location = documentElement.ownerDocument.location;

  Trace.sysout("theme.onThemeApply; " + location + ", " +
    documentElement.className, win);

  emit(this, "onThemeApply", win, oldTheme);
}

Theme.onThemeUnapply = function(win, newTheme) {
  let documentElement = win.document.documentElement;
  let location = documentElement.ownerDocument.location;

  Trace.sysout("theme.onThemeUnapply; " + location + ", " +
    documentElement.className, win);

  emit(this, "onThemeUnapply", win, newTheme);
}

Theme.addThemeListeners = function(apply, unapply) {
  on(this, "onThemeApply", apply);
  on(this, "onThemeUnapply", unapply);
}

Theme.removeThemeListeners = function(apply, unapply) {
  off(this, "onThemeApply", apply);
  off(this, "onThemeUnapply", unapply);
}

Theme.getCurrentTheme = function() {
  return Services.prefs.getCharPref("devtools.theme");
}

Theme.isFirebugActive = function() {
  return Theme.getCurrentTheme() == "firebug";
}

Theme.toggle = function(forceFirebug) {
  let oldValue = this.getCurrentTheme();
  let newValue = this.isFirebugActive() ? "light" : "firebug";

  if (forceFirebug) {
    newValue = "firebug";
    if (oldValue == "firebug") {
      oldValue = null;
    }
  }

  Services.prefs.setCharPref("devtools.theme", newValue);

  let data = {
    pref: "devtools.theme",
    newValue: newValue,
    oldValue: oldValue
  };

  gDevTools.emit("pref-changed", data);
}

Theme.customizeSideBarSplitter = function(iframeWin, apply) {
  Win.loaded(iframeWin).then(doc => {
    if (apply) {
      // Create a little box in the splitter, so we can theme its top
      // part located between the main and side panel toolbars.
      // Note that the splitter element is available as soon as
      // the document is loaded.
      if (!doc.querySelector(".devtools-side-splitter > .panelSplitterBox")) {
        let splitter = doc.querySelector(".devtools-side-splitter");
        splitter.setAttribute("valign", "top");
        BOX({"class": "panelSplitterBox"}).build(splitter);
      }
    }
    else {
      // Remove customization
      let splitter = doc.querySelector(".devtools-side-splitter");
      splitter.removeAttribute("valign");
      Dom.clearNode(splitter);
    }
  });
}

// Developer Browser Edition Theme API

function toggleBrowserEditionTheme(enabled) {
  if (!System.isDeveloperBrowser()) {
    return;
  }

  Trace.sysout("theme.toggleBrowserEditionTheme; " + enabled);

  try {
    Services.prefs.setBoolPref("browser.devedition.theme.enabled", enabled);
  } catch (err) {
    Trace.sysout("theme.toggleBrowserEditionTheme; " + err, err);
  }
}

function saveBrowserEditionTheme() {
  if (!System.isDeveloperBrowser()) {
    return;
  }

  try {
    let state = Services.prefs.getBoolPref("browser.devedition.theme.enabled");
    prefs["developerBrowserThemeDefault"] = state;

    Trace.sysout("theme.saveBrowserEditionTheme; " + state);
  } catch (err) {
    Trace.sysout("theme.saveBrowserEditionTheme; " + err, err);
  }
}

function restoreBrowserEditionTheme() {
  if (!System.isDeveloperBrowser()) {
    return;
  }

  try {
    let state = prefs["developerBrowserThemeDefault"];
    Services.prefs.setBoolPref("browser.devedition.theme.enabled", state);

    Trace.sysout("theme.restoreBrowserEditionTheme; " + state);
  } catch (err) {
    Trace.sysout("theme.restoreBrowserEditionTheme; " + err, err);
  }
}

// Exports from this module
exports.Theme = Theme;
<|endoftext|>


<commit_before>'use strict';

var q = require('q'),
    os = require('os'),
    fs = require('fs'),
    _ = require('lodash'),
    path = require('path'),
    steps = require('../steps'),
    db = require('../utils/mongo'),
    output = require('../utils/output'),
    logger = require('../utils/logger'),
    inquirer = require('inquirer'),
    guid = require('../utils/guid');

module.exports = function(){
    var questions = [{
            type: 'input',
            name: 'name',
            message: 'What is the name of your application?',
            default: 'MyGrasshopperApp'
        }],
        validate = require('../validate');

    logger.statement("Automated Grasshopper setup. Scaffolding will be created for this project and files could be overwritten. \nIf you do not want to install a fresh Grasshopper application then try another command.\nPlease answer a few questions to get started.");

    inquirer.prompt(questions, function( answers ) {
        var appId = answers.name.toLowerCase().replace(/ /g,''),
            config = {
                project: {
                    home: process.cwd(),
                    name: answers.name,
                    main: 'app/' + appId + '.js',
                    installExpress: true
                },
                admin: {
                    buildDirectory : path.join('app', 'public', 'admin'),
                    apiEndpoint : ''
                },
                crypto: {
                    secret: guid()
                },
                assets: {
                    default : 'local',
                    tmpdir : path.join(process.cwd(), 'tmp'),
                    engines: {
                        local : {
                            path : path.join(process.cwd(), 'app', 'public', 'assets'),
                            urlbase : 'http://locahost:3000'
                        }
                    }
                },
                logger: {
                    adapters: [{
                        type: 'console',
                        application: answers.name,
                        machine: os.hostname()
                    },{
                        type: 'file',
                        application: answers.name,
                        machine: os.hostname(),
                        path: path.join(process.cwd(), 'logs/' + appId + '.log')
                    }]
                },
                identities: {},
                db: db.buildConfig('mongodb://localhost/' + appId)
            };

        writePackageJson(config)
            .then(writeAdminConfig)
            .then(validate.hasPackageFile)
            .then(steps.scaffolding)
            .then(steps.npms)
            .then(writeConfig)
            .then(installAdmin)
            .then(db.createSampleData)
            .then(writeAppFile)
            .then(function(results){
                output.setupCompleted();
            })
            .catch(function(err){
                logger.error('');
                logger.error('Setup failed!');
                logger.error('Reason: ' + err.message);
            });
    });
};

function writePackageJson(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/package.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'package.json'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function writeConfig(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/core.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'ghapi.json'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function writeAdminConfig(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/admin.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'gha.json'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function writeAppFile(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/server.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'app', 'index.js'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function installAdmin(config){
    var exec = require('child_process').exec,
        cmd = path.join(config.project.home, './node_modules/.bin/grasshopper build'),
        child = exec(cmd, function(err, stdout, stderr){
            if(err) {
                console.log('exec error: ' + err);
            }
        }),
        progress = output.progress({label: 'Building grasshopper-admin. Please wait, this can take a few minutes.'}),
        deferred = q.defer();

    logger.trace('');
    logger.trace('RUNNING: ' + cmd);

    progress.start();

    child.on('error', function(err){
        deferred.reject(err);
    });

    child.on('close', function(code){
        if(code === 0){
            progress.complete();
            deferred.resolve(config);
        }
        else {
            deferred.reject(new Error(code));
        }
    });

    return deferred.promise;
}<commit_msg>Changed question to just be a cancel or continue option and automatically get the name of the current directory for the appName<commit_after>'use strict';

var q = require('q'),
    os = require('os'),
    fs = require('fs'),
    _ = require('lodash'),
    path = require('path'),
    steps = require('../steps'),
    db = require('../utils/mongo'),
    output = require('../utils/output'),
    logger = require('../utils/logger'),
    inquirer = require('inquirer'),
    guid = require('../utils/guid');

module.exports = function(){
    var questions = [{
            type: 'list',
            name: 'start',
            message: 'Do you want to continue?',
            choices: ['Yes', 'No']
        }],
        validate = require('../validate');

    logger.statement("Automated Grasshopper setup. A fresh Grasshopper application will be created in this directory.\nTo ensure that this process goes smoothly please review the prerequisites: https://github.com/Solid-Interactive/grasshopper-cli ");

    inquirer.prompt(questions, function( answers ) {
        var appName = process.cwd().substr((process.cwd().lastIndexOf('/') + 1), (process.cwd().length - process.cwd().lastIndexOf('/'))),
            appId = appName.toLowerCase().replace(/ /g,''),
            config = {
                project: {
                    home: process.cwd(),
                    name: appName,
                    main: 'app/' + appId + '.js',
                    installExpress: true
                },
                admin: {
                    buildDirectory : path.join('app', 'public', 'admin'),
                    apiEndpoint : ''
                },
                crypto: {
                    secret: guid()
                },
                assets: {
                    default : 'local',
                    tmpdir : path.join(process.cwd(), 'tmp'),
                    engines: {
                        local : {
                            path : path.join(process.cwd(), 'app', 'public', 'assets'),
                            urlbase : 'http://locahost:3000'
                        }
                    }
                },
                logger: {
                    adapters: [{
                        type: 'console',
                        application: appName,
                        machine: os.hostname()
                    },{
                        type: 'file',
                        application: appName,
                        machine: os.hostname(),
                        path: path.join(process.cwd(), 'logs/' + appId + '.log')
                    }]
                },
                identities: {},
                db: db.buildConfig('mongodb://localhost/' + appId)
            };

        if(answers.start === 'Yes'){
            writePackageJson(config)
                .then(writeAdminConfig)
                .then(validate.hasPackageFile)
                .then(steps.scaffolding)
                .then(steps.npms)
                .then(writeConfig)
                .then(installAdmin)
                .then(db.createSampleData)
                .then(writeAppFile)
                .then(function(results){
                    output.setupCompleted();
                })
                .catch(function(err){
                    logger.error('');
                    logger.error('Setup failed!');
                    logger.error('Reason: ' + err.message);
                });
        }
        else {
            logger.notice('');
            logger.notice('Quit without installing.');
        }
    });
};

function writePackageJson(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/package.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'package.json'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function writeConfig(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/core.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'ghapi.json'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function writeAdminConfig(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/admin.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'gha.json'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function writeAppFile(config){
    var tpl = _.template(
            fs.readFileSync(path.join(__dirname, '../../templates/server.tpl'), 'utf-8')),
        output = tpl(config),
        deferred = q.defer();

    fs.writeFile(path.join(config.project.home, 'app', 'index.js'), output, 'utf-8', function(err){
        if(err){
            throw err;
        }
        deferred.resolve(config);
    });

    return deferred.promise;
}

function installAdmin(config){
    var exec = require('child_process').exec,
        cmd = path.join(config.project.home, './node_modules/.bin/grasshopper build'),
        child = exec(cmd, function(err, stdout, stderr){
            if(err) {
                console.log('exec error: ' + err);
            }
        }),
        progress = output.progress({label: 'Building grasshopper-admin. Please wait, this can take a few minutes.'}),
        deferred = q.defer();

    logger.trace('');
    logger.trace('RUNNING: ' + cmd);

    progress.start();

    child.on('error', function(err){
        deferred.reject(err);
    });

    child.on('close', function(code){
        if(code === 0){
            progress.complete();
            deferred.resolve(config);
        }
        else {
            deferred.reject(new Error(code));
        }
    });

    return deferred.promise;
}<|endoftext|>


<commit_before>'use strict';

var cli = require('commander');
var request = require('request');
var _ = require('lodash');
require('colors');

var Config = require('../config').Config;

//Trace Command
var runCmd = cli.command('run <projectName> <path>');
runCmd
    .description('Run 28.io query.')
    .action(function(projectName, path){
        projectName = projectName || Config.getDefaultProject();
        return Config.refreshTokens(projectName).then(function(){
            var url = Config.getProjectEndpoint(projectName) + '/_queries';
            path = path.indexOf('?') === -1 ? (path + '?') : path;
            path = path[0] === '/' ? path : ('/' + path);
            url += path + '&trace&_token=' + encodeURIComponent(Config.getProjectToken(projectName));
            request({
                uri: url,
                method: 'POST'
            }, function(error, response, body){
                if(error) {
                    console.error(error);
                    return;
                }
                _.forEach(response.headers, function(value, name){
                    console.log((name + ': ' + value).grey);
                });
                try {
                    body = JSON.stringify(JSON.parse(body), null, 2);
                } catch(e) {}
                console.log(body);
                var traceFile = response.headers['x-28msec-trace'];
                setTimeout(function(){
                    request({
                        uri: traceFile,
                        method: 'GET'
                    }, function(error, response, body){
                        if(body) {
                            console.log(body.green);
                        }
                    });
                }, 1000);
            });
        });
    });<commit_msg>Update run.js<commit_after>'use strict';

var cli = require('commander');
var request = require('request');
var _ = require('lodash');
require('colors');

var Config = require('../config').Config;

//Trace Command
var runCmd = cli.command('run <projectName> <path>');
runCmd
    .description('Run 28.io query.')
    .action(function(projectName, path){
        projectName = projectName || Config.getDefaultProject();
        return Config.refreshTokens(projectName).then(function(){
            var url = Config.getProjectEndpoint(projectName) + '/_queries';
            path = path.indexOf('?') === -1 ? (path + '?') : path;
            path = path[0] === '/' ? path : ('/' + path);
            url += path + '&trace&_token=' + encodeURIComponent(Config.getProjectToken(projectName));
            request({
                uri: url,
                method: 'GET'
            }, function(error, response, body){
                if(error) {
                    console.error(error);
                    return;
                }
                _.forEach(response.headers, function(value, name){
                    console.log((name + ': ' + value).grey);
                });
                try {
                    body = JSON.stringify(JSON.parse(body), null, 2);
                } catch(e) {}
                console.log(body);
                var traceFile = response.headers['x-28msec-trace'];
                setTimeout(function(){
                    request({
                        uri: traceFile,
                        method: 'GET'
                    }, function(error, response, body){
                        if(body) {
                            console.log(body.green);
                        }
                    });
                }, 1000);
            });
        });
    });
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

'use strict';

const _ = require('lodash');
const fs = require('fs');
const path = require('path');
const util = require('util');
const async = require('async');
const csv = require('csv-parse');
const cli = require('cli');
const YAML = require('yaml-js');
const moment = require('moment');
const chalk = require('chalk');
const defaultOptions = require('rc')('artillery');
const validate = require('artillery-core').validate;
const debug = require('debug')('commands:run');

const createRunner = require('../runner');

module.exports = run;

function run(scriptPath, options) {
  let logfile;

  // is the destination a directory that exists?
  let isDir = false;
  if (options.output && options.output !== defaultOptions.output) {
    try {
      isDir = fs.statSync(options.output).isDirectory();
    } catch (err) {
      // ENOENT, don't need to do anything
    }
  }

  const defaultFormat = '[artillery_report_]YMMDD_HHmmSS[.json]';
  if (!isDir && options.output) {
    // -o is set with a filename (existing or not)
    logfile = options.output;
  } else if (!isDir && !options.output) {
    // no -o set
    logfile = moment().format(defaultOptions.output ||
                              defaultFormat);
  } else {
    // -o is set with a directory
    logfile = path.join(options.output, moment().format(defaultOptions.output ||
                                                        defaultFormat));
  }

  function log() {
    if (options.quiet) { return; }
    console.log.apply(console, arguments);
  }

  async.waterfall([
    async.constant(scriptPath),
    readScript,
    parseScript,
    checkTimersBug,
    checkIfXPathIsUsed,
    function(script, callback) {
      return callback(null, script, scriptPath, options);
    },
    checkConfig,
    readPayload
  ], function done(err, script) {
    if (err) {
      console.log(err.message);
      process.exit(1);
    }

    script.config.statsInterval = script.config.statsInterval || 10;

    log('Log file: %s', logfile);

      var spinnerOn = function() {
        if (!options.quiet && process.stdout.isTTY) {
          cli.spinner('');
        }
      };
      var spinnerOff = function() {
        if (!options.quiet && process.stdout.isTTY) {
          cli.spinner('', true);
        }
      };

      let runner = createRunner(script,
                                script.payload,
                                {
                                  environment: options.environment,
                                  // This is used in the worker to resolve
                                  // the path to the processor module
                                  scriptPath: scriptPath
                                });
      let intermediates = [];

      runner.events.on('phaseStarted', function(phase) {
        spinnerOff();
        log(
          'Phase %s%s started - duration: %ss',
          phase.index,
          (phase.name ? ' (' + phase.name + ')' : ''),
          phase.duration || phase.think);
        spinnerOn();
      });

      runner.events.on('stats', function(stats) {
        let report = stats.report();
        intermediates.push(report);
        spinnerOff();
        log('Report for the previous %ss @ %s',
            script.config.statsInterval,
            report.timestamp);
        if (!options.quiet) {
          printReport(report);
        }
        spinnerOn();
      });

      runner.events.on('done', function(allStats) {
        let report = allStats.report();
        delete report.concurrency; // doesn't make sense in this context
        delete report.pendingRequests;

        spinnerOff();
        log('all scenarios completed');
        log('Complete report @ %s', report.timestamp);

        if (!options.quiet) {
          printReport(report, { showScenarioCounts: true });
        }
        report.phases = _.get(script, 'config.phases', []);
        delete report.latencies;

        fs.writeFileSync(
          logfile, JSON.stringify({
            aggregate: report,
            intermediate: intermediates
          }, null, 2),
          {flag: 'w'});

        if (script.config.ensure) {
          const latency = report.latency;
          _.each(script.config.ensure, function(max, k) {

            let bucket = k === 'p50' ? 'median' : k;
            if (latency[bucket]) {
              if (latency[bucket] > max) {
                const msg = util.format(
                  'ensure condition failed: ensure.%s < %s', bucket, max);
                log(msg);
                process.exit(1);
              }
            }
          });
        }
      });

      spinnerOn();
      runner.run();

      let shuttingDown = false;
      process.once('SIGINT', gracefulShutdown);
      process.once('SIGTERM', gracefulShutdown);

      function gracefulShutdown() {
        if (shuttingDown) {
          return;
        }

        shuttingDown = true;
        debug('Graceful shutdown initiated');
        spinnerOff();
        //console.error('Artillery shutting down...');
        runner.shutdown(function() {
          process.exit(0);
        });
      }
  });
}

function printReport(report, opts) {
  opts = opts || {};

  console.log('  Scenarios launched:  %s', report.scenariosCreated);
  console.log('  Scenarios completed: %s', report.scenariosCompleted);
  console.log('  Requests completed:  %s', report.requestsCompleted);

  // Final report does not have concurrency
  if (report.concurrency) {
    console.log('  Concurrent users:    %s', report.concurrency);
  }

  console.log('  RPS sent: %s', report.rps.mean);
  console.log('  Request latency:');
  console.log('    min: %s', report.latency.min);
  console.log('    max: %s', report.latency.max);
  console.log('    median: %s', report.latency.median);
  console.log('    p95: %s', report.latency.p95);
  console.log('    p99: %s', report.latency.p99);

  console.log('  Scenario duration:');
  console.log('    min: %s', report.scenarioDuration.min);
  console.log('    max: %s', report.scenarioDuration.max);
  console.log('    median: %s', report.scenarioDuration.median);
  console.log('    p95: %s', report.scenarioDuration.p95);
  console.log('    p99: %s', report.scenarioDuration.p99);

  // We only want to show this for the aggregate report
  if (opts.showScenarioCounts && report.scenarioCounts) {
    console.log('  Scenario counts:');
    _.each(report.scenarioCounts, function(count, name) {
      let percentage = Math.round(count / report.scenariosCreated * 100 * 1000) / 1000;
      console.log('    %s: %s (%s\%)', name, count, percentage);
    });
  }

  if (_.size(report.customStats) > 0) {
    console.log('Custom stats:');
    _.each(report.customStats, function(r, n) {
      console.log('  %s:', n);
      console.log('    min: %s', r.min);
      console.log('    max: %s', r.max);
      console.log('    median: %s', r.median);
      console.log('    p95: %s', r.p95);
      console.log('    p99: %s', r.p99);
    });
  }

  if (_.keys(report.codes).length !== 0) {
    console.log('  Codes:');
    _.each(report.codes, function(count, code) {
      console.log('    %s: %s', code, count);
    });
  }
  if (_.keys(report.errors).length !== 0) {
    console.log('  Errors:');
    _.each(report.errors, function(count, code) {
      console.log('    %s: %s', code, count);
    });
  }
}

function readScript(scriptPath, callback) {
  fs.readFile(scriptPath, 'utf-8', function(err, data) {
    if (err) {
      const msg = util.format('File not found: %s', scriptPath);
      return callback(new Error(msg), null);
    }

    return callback(null, data, scriptPath);
  });
}

function parseScript(data, scriptPath, callback) {
  let script;
  let fileFormat;

  try {
    if (/\.ya?ml$/.test(path.extname(scriptPath))) {
      fileFormat = 'YAML';
      script = YAML.load(data);
    } else {
      fileFormat = 'JSON';
      script = JSON.parse(data);
    }
  } catch (e) {
    const msg2 = `File ${scriptPath} does not appear to be valid ${fileFormat}: (${e.message})`;
    return callback(new Error(msg2), null);
  }

  return callback(null, script);
}

function checkConfig(script, scriptPath, options, callback) {
  if (options.environment) {
    debug('environment specified: %s', options.environment);
    if (script.config.environments[options.environment]) {
      _.merge(script.config, script.config.environments[options.environment]);
      debug(script.config.payload);
    } else {
      console.log(`WARNING: environment ${options.environment} is set but is not defined in the script`);
    }
  }

  if (options.target && script.config) {
    script.config.target = options.target;
  }

  if (!script.config.target && !options.environment) {
    const msg4 = 'No target specified and no environment chosen';
    return callback(new Error(msg4), null);
  }

  //
  // Override/set config.tls if needed:
  //
  if (options.insecure) {
    if (script.config.tls) {
      if (script.config.tls.rejectUnauthorized) {
        console.log('WARNING: TLS certificate validation enabled in the ' +
                    'test script, but explicitly disabled with ' +
                    '-k/--insecure.');
      }
      script.config.tls.rejectUnauthorized = false;
    } else {
      script.config.tls = {rejectUnauthorized: false};
    }
  }

  //
  // Turn config.payload into an array:
  //
  if (_.get(script, 'config.payload')) {
    // Is it an object or an array?
    if (_.isArray(script.config.payload)) {
      // an array - nothing to do
    } else if (_.isObject(script.config.payload)) {

      if (options.payload && !_.get(script.config.payload, 'path')) {
        script.config.payload.path = path.resolve(process.cwd(), options.payload);
      } else if (!options.payload && !_.get(script.config.payload, 'path')) {
        console.log('WARNING: config.payload.path not set and payload file not specified with -p');
      } else if (options.payload && _.get(script.config.payload, 'path')) {
        console.log('WARNING - both -p and config.payload.path are set, config.payload.path will be ignored.');
        script.config.payload.path = options.payload;
      } else {
        // no -p but config.payload.path is set - nothing to do
      }

      // Make it an array
      script.config.payload = [script.config.payload];
    } else {
      console.log('Ignoring config.payload, not an object or an array.');
    }
  }

  //
  // Resolve all payload paths to absolute paths now:
  //
  _.forEach(script.config.payload, function(payloadSpec) {
    const absoluteScriptPath = path.resolve(process.cwd(), scriptPath);
    const resolvedPathToPayload = path.resolve(
      path.dirname(absoluteScriptPath), payloadSpec.path);
    payloadSpec.path = resolvedPathToPayload;
  });

  return callback(null, script);
}

function validateSchema(script, callback) {
  let validation = validate(script);
  if (!validation.valid) {
    console.log(validation.errors);
    return callback(new Error('Test script validation error'));
  }
  return callback(null, script);
}

function readPayload(script, callback) {
  async.map(
    script.config.payload,
    function readPayloadFile(payloadSpec, next) {
      let data = fs.readFileSync(payloadSpec.path, 'utf-8');
      csv(data, function(err, parsedData) {
        payloadSpec.data = parsedData;
        return next(err, payloadSpec);
      });
    },
    function done(err, results) {
      if (err) {
        return callback(err, script);
      }
      script.payload = results;
      return callback(null, script);
    }
  );
}

function checkTimersBug(script, callback) {
  // Node.js versions 6.8.1 - 7.2.0 have a bug which can cause the process
  // to hang when rampTo is used.
  // Ref: https://github.com/shoreditch-ops/artillery/issues/210

  // 6.8.1 and 7.0.0 and 7.2.0 but NOT 6.8.0
  let nv = process.version;
  let mj = parseInt(nv.substring(1, 2), 10);
  let mn = parseInt(nv.substring(3, 4), 10);
  let pt = parseInt(nv.substring(5, 6), 10);
  if (mj === 7 && mn < 3 ||
      (mj === 6 && mn > 8) ||
      (mj === 6 && mn === 8 && pt > 0)) {
    let usesRampTo = _.some(script.config.phases, function(phase) {
      return !(_.isUndefined(phase.rampTo));
    });

    if (usesRampTo) {
      console.error(chalk.bold.red(`
You are running Node.js ${nv} which is affected by a bug that can cause
Artillery to hang indefinitely when a rampTo arrival phase is used.

Use Node.js v6.8.0 or lower to avoid the issue.

For more details see: https://github.com/nodejs/node/issues/9756
`));
    }
  }

  return callback(null, script);
}

function checkIfXPathIsUsed(script, callback) {
  let xmlInstalled = null;
  try {
    xmlInstalled = require('artillery-xml-capture');
  } catch (e) {
  }

  let usesXPathCapture = false;
  script.scenarios.forEach(function(scenario) {
    scenario.flow.forEach(function(step) {
      let params = step[_.keys(step)[0]];
      if ((params.capture && params.capture.xpath) ||
          (params.match && params.match.xpath)) {
        usesXPathCapture = true;
      }
    });
  });
  if (usesXPathCapture && !xmlInstalled) {
    console.log(chalk.bold.red('Warning: '), chalk.bold.yellow('your test script is using XPath capture, but artillery-xml-capture does not seem to be installed.'));
    console.log(chalk.bold.yellow('Install it with: npm install -g artillery-xml-capture'));
  }
  return callback(null, script);
}
<commit_msg>Fix: set script._environment to have $environment in user context<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

'use strict';

const _ = require('lodash');
const fs = require('fs');
const path = require('path');
const util = require('util');
const async = require('async');
const csv = require('csv-parse');
const cli = require('cli');
const YAML = require('yaml-js');
const moment = require('moment');
const chalk = require('chalk');
const defaultOptions = require('rc')('artillery');
const validate = require('artillery-core').validate;
const debug = require('debug')('commands:run');

const createRunner = require('../runner');

module.exports = run;

function run(scriptPath, options) {
  let logfile;

  // is the destination a directory that exists?
  let isDir = false;
  if (options.output && options.output !== defaultOptions.output) {
    try {
      isDir = fs.statSync(options.output).isDirectory();
    } catch (err) {
      // ENOENT, don't need to do anything
    }
  }

  const defaultFormat = '[artillery_report_]YMMDD_HHmmSS[.json]';
  if (!isDir && options.output) {
    // -o is set with a filename (existing or not)
    logfile = options.output;
  } else if (!isDir && !options.output) {
    // no -o set
    logfile = moment().format(defaultOptions.output ||
                              defaultFormat);
  } else {
    // -o is set with a directory
    logfile = path.join(options.output, moment().format(defaultOptions.output ||
                                                        defaultFormat));
  }

  function log() {
    if (options.quiet) { return; }
    console.log.apply(console, arguments);
  }

  async.waterfall([
    async.constant(scriptPath),
    readScript,
    parseScript,
    checkTimersBug,
    checkIfXPathIsUsed,
    function(script, callback) {
      return callback(null, script, scriptPath, options);
    },
    checkConfig,
    readPayload
  ], function done(err, script) {
    if (err) {
      console.log(err.message);
      process.exit(1);
    }

    script.config.statsInterval = script.config.statsInterval || 10;

    log('Log file: %s', logfile);

      var spinnerOn = function() {
        if (!options.quiet && process.stdout.isTTY) {
          cli.spinner('');
        }
      };
      var spinnerOff = function() {
        if (!options.quiet && process.stdout.isTTY) {
          cli.spinner('', true);
        }
      };

      let runner = createRunner(script,
                                script.payload,
                                {
                                  environment: options.environment,
                                  // This is used in the worker to resolve
                                  // the path to the processor module
                                  scriptPath: scriptPath
                                });
      let intermediates = [];

      runner.events.on('phaseStarted', function(phase) {
        spinnerOff();
        log(
          'Phase %s%s started - duration: %ss',
          phase.index,
          (phase.name ? ' (' + phase.name + ')' : ''),
          phase.duration || phase.think);
        spinnerOn();
      });

      runner.events.on('stats', function(stats) {
        let report = stats.report();
        intermediates.push(report);
        spinnerOff();
        log('Report for the previous %ss @ %s',
            script.config.statsInterval,
            report.timestamp);
        if (!options.quiet) {
          printReport(report);
        }
        spinnerOn();
      });

      runner.events.on('done', function(allStats) {
        let report = allStats.report();
        delete report.concurrency; // doesn't make sense in this context
        delete report.pendingRequests;

        spinnerOff();
        log('all scenarios completed');
        log('Complete report @ %s', report.timestamp);

        if (!options.quiet) {
          printReport(report, { showScenarioCounts: true });
        }
        report.phases = _.get(script, 'config.phases', []);
        delete report.latencies;

        fs.writeFileSync(
          logfile, JSON.stringify({
            aggregate: report,
            intermediate: intermediates
          }, null, 2),
          {flag: 'w'});

        if (script.config.ensure) {
          const latency = report.latency;
          _.each(script.config.ensure, function(max, k) {

            let bucket = k === 'p50' ? 'median' : k;
            if (latency[bucket]) {
              if (latency[bucket] > max) {
                const msg = util.format(
                  'ensure condition failed: ensure.%s < %s', bucket, max);
                log(msg);
                process.exit(1);
              }
            }
          });
        }
      });

      spinnerOn();
      runner.run();

      let shuttingDown = false;
      process.once('SIGINT', gracefulShutdown);
      process.once('SIGTERM', gracefulShutdown);

      function gracefulShutdown() {
        if (shuttingDown) {
          return;
        }

        shuttingDown = true;
        debug('Graceful shutdown initiated');
        spinnerOff();
        //console.error('Artillery shutting down...');
        runner.shutdown(function() {
          process.exit(0);
        });
      }
  });
}

function printReport(report, opts) {
  opts = opts || {};

  console.log('  Scenarios launched:  %s', report.scenariosCreated);
  console.log('  Scenarios completed: %s', report.scenariosCompleted);
  console.log('  Requests completed:  %s', report.requestsCompleted);

  // Final report does not have concurrency
  if (report.concurrency) {
    console.log('  Concurrent users:    %s', report.concurrency);
  }

  console.log('  RPS sent: %s', report.rps.mean);
  console.log('  Request latency:');
  console.log('    min: %s', report.latency.min);
  console.log('    max: %s', report.latency.max);
  console.log('    median: %s', report.latency.median);
  console.log('    p95: %s', report.latency.p95);
  console.log('    p99: %s', report.latency.p99);

  console.log('  Scenario duration:');
  console.log('    min: %s', report.scenarioDuration.min);
  console.log('    max: %s', report.scenarioDuration.max);
  console.log('    median: %s', report.scenarioDuration.median);
  console.log('    p95: %s', report.scenarioDuration.p95);
  console.log('    p99: %s', report.scenarioDuration.p99);

  // We only want to show this for the aggregate report
  if (opts.showScenarioCounts && report.scenarioCounts) {
    console.log('  Scenario counts:');
    _.each(report.scenarioCounts, function(count, name) {
      let percentage = Math.round(count / report.scenariosCreated * 100 * 1000) / 1000;
      console.log('    %s: %s (%s\%)', name, count, percentage);
    });
  }

  if (_.size(report.customStats) > 0) {
    console.log('Custom stats:');
    _.each(report.customStats, function(r, n) {
      console.log('  %s:', n);
      console.log('    min: %s', r.min);
      console.log('    max: %s', r.max);
      console.log('    median: %s', r.median);
      console.log('    p95: %s', r.p95);
      console.log('    p99: %s', r.p99);
    });
  }

  if (_.keys(report.codes).length !== 0) {
    console.log('  Codes:');
    _.each(report.codes, function(count, code) {
      console.log('    %s: %s', code, count);
    });
  }
  if (_.keys(report.errors).length !== 0) {
    console.log('  Errors:');
    _.each(report.errors, function(count, code) {
      console.log('    %s: %s', code, count);
    });
  }
}

function readScript(scriptPath, callback) {
  fs.readFile(scriptPath, 'utf-8', function(err, data) {
    if (err) {
      const msg = util.format('File not found: %s', scriptPath);
      return callback(new Error(msg), null);
    }

    return callback(null, data, scriptPath);
  });
}

function parseScript(data, scriptPath, callback) {
  let script;
  let fileFormat;

  try {
    if (/\.ya?ml$/.test(path.extname(scriptPath))) {
      fileFormat = 'YAML';
      script = YAML.load(data);
    } else {
      fileFormat = 'JSON';
      script = JSON.parse(data);
    }
  } catch (e) {
    const msg2 = `File ${scriptPath} does not appear to be valid ${fileFormat}: (${e.message})`;
    return callback(new Error(msg2), null);
  }

  return callback(null, script);
}

function checkConfig(script, scriptPath, options, callback) {
  if (options.environment) {
    debug('environment specified: %s', options.environment);
    if (script.config.environments[options.environment]) {
      _.merge(script.config, script.config.environments[options.environment]);
      script._environment = options.environment;
    } else {
      console.log(`WARNING: environment ${options.environment} is set but is not defined in the script`);
    }
  }

  if (options.target && script.config) {
    script.config.target = options.target;
  }

  if (!script.config.target && !options.environment) {
    const msg4 = 'No target specified and no environment chosen';
    return callback(new Error(msg4), null);
  }

  //
  // Override/set config.tls if needed:
  //
  if (options.insecure) {
    if (script.config.tls) {
      if (script.config.tls.rejectUnauthorized) {
        console.log('WARNING: TLS certificate validation enabled in the ' +
                    'test script, but explicitly disabled with ' +
                    '-k/--insecure.');
      }
      script.config.tls.rejectUnauthorized = false;
    } else {
      script.config.tls = {rejectUnauthorized: false};
    }
  }

  //
  // Turn config.payload into an array:
  //
  if (_.get(script, 'config.payload')) {
    // Is it an object or an array?
    if (_.isArray(script.config.payload)) {
      // an array - nothing to do
    } else if (_.isObject(script.config.payload)) {

      if (options.payload && !_.get(script.config.payload, 'path')) {
        script.config.payload.path = path.resolve(process.cwd(), options.payload);
      } else if (!options.payload && !_.get(script.config.payload, 'path')) {
        console.log('WARNING: config.payload.path not set and payload file not specified with -p');
      } else if (options.payload && _.get(script.config.payload, 'path')) {
        console.log('WARNING - both -p and config.payload.path are set, config.payload.path will be ignored.');
        script.config.payload.path = options.payload;
      } else {
        // no -p but config.payload.path is set - nothing to do
      }

      // Make it an array
      script.config.payload = [script.config.payload];
    } else {
      console.log('Ignoring config.payload, not an object or an array.');
    }
  }

  //
  // Resolve all payload paths to absolute paths now:
  //
  _.forEach(script.config.payload, function(payloadSpec) {
    const absoluteScriptPath = path.resolve(process.cwd(), scriptPath);
    const resolvedPathToPayload = path.resolve(
      path.dirname(absoluteScriptPath), payloadSpec.path);
    payloadSpec.path = resolvedPathToPayload;
  });

  return callback(null, script);
}

function validateSchema(script, callback) {
  let validation = validate(script);
  if (!validation.valid) {
    console.log(validation.errors);
    return callback(new Error('Test script validation error'));
  }
  return callback(null, script);
}

function readPayload(script, callback) {
  async.map(
    script.config.payload,
    function readPayloadFile(payloadSpec, next) {
      let data = fs.readFileSync(payloadSpec.path, 'utf-8');
      csv(data, function(err, parsedData) {
        payloadSpec.data = parsedData;
        return next(err, payloadSpec);
      });
    },
    function done(err, results) {
      if (err) {
        return callback(err, script);
      }
      script.payload = results;
      return callback(null, script);
    }
  );
}

function checkTimersBug(script, callback) {
  // Node.js versions 6.8.1 - 7.2.0 have a bug which can cause the process
  // to hang when rampTo is used.
  // Ref: https://github.com/shoreditch-ops/artillery/issues/210

  // 6.8.1 and 7.0.0 and 7.2.0 but NOT 6.8.0
  let nv = process.version;
  let mj = parseInt(nv.substring(1, 2), 10);
  let mn = parseInt(nv.substring(3, 4), 10);
  let pt = parseInt(nv.substring(5, 6), 10);
  if (mj === 7 && mn < 3 ||
      (mj === 6 && mn > 8) ||
      (mj === 6 && mn === 8 && pt > 0)) {
    let usesRampTo = _.some(script.config.phases, function(phase) {
      return !(_.isUndefined(phase.rampTo));
    });

    if (usesRampTo) {
      console.error(chalk.bold.red(`
You are running Node.js ${nv} which is affected by a bug that can cause
Artillery to hang indefinitely when a rampTo arrival phase is used.

Use Node.js v6.8.0 or lower to avoid the issue.

For more details see: https://github.com/nodejs/node/issues/9756
`));
    }
  }

  return callback(null, script);
}

function checkIfXPathIsUsed(script, callback) {
  let xmlInstalled = null;
  try {
    xmlInstalled = require('artillery-xml-capture');
  } catch (e) {
  }

  let usesXPathCapture = false;
  script.scenarios.forEach(function(scenario) {
    scenario.flow.forEach(function(step) {
      let params = step[_.keys(step)[0]];
      if ((params.capture && params.capture.xpath) ||
          (params.match && params.match.xpath)) {
        usesXPathCapture = true;
      }
    });
  });
  if (usesXPathCapture && !xmlInstalled) {
    console.log(chalk.bold.red('Warning: '), chalk.bold.yellow('your test script is using XPath capture, but artillery-xml-capture does not seem to be installed.'));
    console.log(chalk.bold.yellow('Install it with: npm install -g artillery-xml-capture'));
  }
  return callback(null, script);
}
<|endoftext|>


<commit_before>// run.js
//

'use strict';

var createError  = require('../createError');
var logErrorExit = require('../logErrorExit');
var pkg = require('../../package.json');

var fs    = require('fs');
var path  = require('path');
var spawn = require('child_process').spawn;

var docopt = require('docopt').docopt;

var cwd = process.cwd();
var colliderFile = path.join(cwd, 'project', '.collider');

// RUN
//

var doc = 'usage: collider run';

module.exports = function (argv) {

  var args = docopt(doc, {
    argv: argv,
    version: `Collider CLI ${pkg.version}`,
  });

  // If a Collider-file exists in the CWD, then spin up Collider.
  fs.access(colliderFile, fs.F_OK, function (err) {
    if (err) {
      var err = createError("a Collider-file could not be found.");
      logErrorExit(err, true);
    } else {
      spawn('./node_modules/.bin/gulp', ['default'], { stdio: 'inherit' });
    }
  });

};
<commit_msg>Refactor `run` to use colliderfile module<commit_after>// run.js
//

'use strict';

var createError  = require('../createError');
var logErrorExit = require('../logErrorExit');
var colliderfile = require('../colliderfile');
var pkg = require('../../package.json');

var spawn = require('child_process').spawn;

var docopt = require('docopt').docopt;

// RUN
//

var doc = 'usage: collider run';

module.exports = function (argv) {

  var args = docopt(doc, {
    argv: argv,
    version: `Collider CLI ${pkg.version}`,
  });

  // If a Collider-file exists in the CWD, then spin up Collider.
  colliderfile.existsIn('./project', function (err) {
    if (err) {
      var err = createError('a Collider-file could not be found.');
      logErrorExit(err, true);
    }

    spawn('./node_modules/.bin/gulp', ['default'], { stdio: 'inherit' });
  });

};
<|endoftext|>


<commit_before>/* Gets the previous message to a message
 *
 * @param  message {DOM Element} - the message to get the previous message of
 *
 * @return void
 */
function getPreviousMessage(message) {
	let prevMessage = $(message).prev();
	// check wether the last one was the historic messages block
	// and returns its last child if
	if(prevMessage.attr('id') === 'historic_messages'){
		return $('#historic_messages div.line:last-child');
	}
	else{
		return prevMessage;
	}
}

/* Gets the sender name to a message
 *
 * @param  message {DOM Element} - the message
 *
 * @return senderName {String}
 */
function getSender(message) {
	// drop the last :
	return $(message).find('.sender').text().slice(0, -1)
}

/* Gets the message type
 *
 * @param  message {DOM Element} - the message
 *
 * @return senderName {String}
 */
function getMessageType(message) {
	return $(message).attr('ltype');
}

/* Hides the Sender of a message
 *
 * @param message {DOM Element} - the message
 *
 * @return vooid
 */
function hideSenderAndTime(message) {
	// hide sender
	$(message).find('.sender').css({
		display: 'none'
	});
	// hide time
	$(message).find('.time').css({
		display: 'none'
	});
}
<commit_msg>Fixed a bug, where the "mark" div hindered the finding of the correct previous Message<commit_after>/* Gets the previous message to a message
 *
 * @param  message {DOM Element} - the message to get the previous message of
 *
 * @return void
 */
function getPreviousMessage(message) {
	let prevMessage = $(message).prev();
	// check wether the last one was the historic messages block
	// and returns its last child if
	if(prevMessage.attr('id') === 'historic_messages'){
		return $('#historic_messages div.line:last-child');
	}
	else if(prevMessage.attr('id') === 'mark'){
		return getPreviousMessage(prevMessage);
	}
	else{
		return prevMessage;
	}
}

/* Gets the sender name to a message
 *
 * @param  message {DOM Element} - the message
 *
 * @return senderName {String}
 */
function getSender(message) {
	// drop the last :
	return $(message).find('.sender').text().slice(0, -1)
}

/* Gets the message type
 *
 * @param  message {DOM Element} - the message
 *
 * @return senderName {String}
 */
function getMessageType(message) {
	return $(message).attr('ltype');
}

/* Hides the Sender of a message
 *
 * @param message {DOM Element} - the message
 *
 * @return vooid
 */
function hideSenderAndTime(message) {
	// hide sender
	$(message).find('.sender').css({
		display: 'none'
	});
	// hide time
	$(message).find('.time').css({
		display: 'none'
	});
}
<|endoftext|>


<commit_before>var utl = require('util');
var pronto = require('pronto');
var mongo = require('mongodb');

module.exports = UseMongo;

function UseMongo() {

}
pronto.inheritsCommand(UseMongo);

/**
 * Connect to a named Mongo DB.
 *
 * Params:
 * - host: The hostname of the server, defaults to localhost
 * - port: The port upon which MongoDB listens; defaults to 27017
 * - serverOpts: an object containing server options, as defined in the MongoDB package.
 *    - auto_reconnect: Reconnect when a connection dies (false)
 *    - poolSize: The max number of connections in the pool (1)
 * - dbName: The name of the database. REQUIRED.
 * - dbOpts: MongoDB options, as defined in the MongoDB package.
 * - poolSize: Overrides serverOpts[poolSize].
 * - autoReconnect: Overrides serverOpts[auto_reconnect]
 */
UseMongo.prototype.execute = function(cxt, params) {

  this.required(params, ['dbName']);

  var host = params.host || 'localhost';
  var port = params.port || 27017;
  var serverOpts = params.serverOpts || {};
  var dbName = params.dbName || null;
  var dbOpts = params.dbOpts || {};

  if (params.poolSize) {
    serverOpts['poolSize'] = params.poolSize;
  }
  if (params.autoReconnect) {
    serverOpts['auto_reconnect'] = params.autoReconnect;
  }

  if (dbName == null || dbName.length == 0) {
    this.emit('error', new Error('The dbName parameter is required.'));
    return;
  }

  var server = new mongo.Server(host, port, serverOpts);
  var mongodb = new mongo.Db(dbName, server, dbOpts);

  //this.on('error', function(e) {console.log(e)});

  var cmd = this;
  mongodb.open(function (err, db) {
    if (err != null) {
      //console.log(err)
      cxt.log(err.stack, 'error');
      cmd.emit('error', err);
      return;
    }
    cxt.addDatasource(dbName, db);

    var cn = dbName + ' at ' + host + ':' + port;
    cxt.log('Opened MongoDB connection to ' + cn, 'info');
    cmd.done(dbName);
  });
}<commit_msg>Fixed bug in Use command.<commit_after>var utl = require('util');
var pronto = require('pronto');
var mongo = require('mongodb');

module.exports = UseMongo;

function UseMongo() {

}
pronto.inheritsCommand(UseMongo);

/**
 * Connect to a named Mongo DB.
 *
 * Params:
 * - host: The hostname of the server, defaults to localhost
 * - port: The port upon which MongoDB listens; defaults to 27017
 * - serverOpts: an object containing server options, as defined in the MongoDB package.
 *    - auto_reconnect: Reconnect when a connection dies (false)
 *    - poolSize: The max number of connections in the pool (1)
 * - dbName: The name of the database. REQUIRED.
 * - dbOpts: MongoDB options, as defined in the MongoDB package.
 * - poolSize: Overrides serverOpts[poolSize].
 * - autoReconnect: Overrides serverOpts[auto_reconnect]
 */
UseMongo.prototype.execute = function(cxt, params) {

  this.required(params, ['dbName']);

  var host = params.host || 'localhost';
  var port = params.port || 27017;
  var serverOpts = params.serverOpts || {};
  var dbName = params.dbName || null;
  var dbOpts = params.dbOpts || {};

  if (params.poolSize) {
    serverOpts['poolSize'] = params.poolSize;
  }
  if (params.autoReconnect) {
    serverOpts['auto_reconnect'] = params.autoReconnect;
  }

  if (dbName == null || dbName.length == 0) {
    this.emit('error', new Error('The dbName parameter is required.'));
    return;
  }

  var server = new mongo.Server(host, port, serverOpts);
  var mongodb = new mongo.Db(dbName, server, dbOpts);

  //this.on('error', function(e) {console.log(e)});

  var cmd = this;
  mongodb.open(function (err, db) {
    if (err instanceof Error) {
      //console.log(err)
      cxt.log(err.stack, 'error');
      cmd.emit('error', err);
      return;
    }
    cxt.addDatasource(dbName, db);

    var cn = dbName + ' at ' + host + ':' + port;
    cxt.log('Opened MongoDB connection to ' + cn, 'info');
    cmd.done(dbName);
  });
}<|endoftext|>