<commit_before>/**
 * @fileoverview Service for setting and getting cookies
 *
 * Once installed a "cookies" service is available that exposes
 * get(name, default) and set(name, value, options)
 * methods. The options object can contain the following keys:
 *  - path - Path to scope to cookie to.
 *  - domain - Allows you to scope cookies to a subdomain.
 *  - expires - Date object or timestamp.
 *  - secure - Whether the cookie should only be sent over secure channels.
 *  - httpOnly - Tells the browser to only use the cookie on the HTTP protocol,
 *    i.e. not to client side scripts.
 *
 * @author dan@pupi.us (Daniel Pupius)
 */

module.exports = CookieService

/**
 * @param {Object} req the http request
 * @param {Object} res the http response
 * @constructor
 */
function CookieService(req, res) {
  this.req = req
  this.res = res
  this.parsedCookies_ = null
}

/**
 * Fetches a cookie from the request headers.
 * @param {string} name The cookie's name to fetch.
 * @param {string} opt_default Default value to return if the cookie is not set.
 * @return {string} The cookie's value.
 */
CookieService.prototype.get = function(name, opt_default) {
  var cookies = this.parseCookies_()
  var cookie = cookies[name]
  return typeof cookie !== 'undefined' ? cookie : opt_default
}

/**
 * Sets a cookie.
 * @param {string} name The cookie's name.
 * @param {string} value The value to set.
 * @param {Object=} options Optional options object containing some of the
 *    following: expires, path, domain, secure, httpOnly.
 */
CookieService.prototype.set = function(name, value, options) {
  if (options && options.secure && !this.res.socket.encrypted) {
    throw Error('Can not to set secure cookie on unencrypted socket.')
  }
  var cookies = this.res.getHeader('Set-Cookie') || []
  if (typeof cookies == 'string') {
    cookies = [cookies]
  }
  cookies.push(new Cookie(name, value, options).toString())
  this.res.setHeader('Set-Cookie', cookies)
}

CookieService.prototype.parseCookies_ = function() {
  if (!this.parsedCookies_) {
    var cookies = this.parsedCookies_ = {}
    if (this.req.headers.cookie) {
      this.req.headers.cookie.split(';').forEach(function(cookie) {
        var parts = cookie.split('=')
        var name = parts[0].trim()
        // If multiple cookie's path match the client will send all of them. We
        // only consider the first, since it will be most specific. In the rare
        // case someone cares about all values, they can parse the header
        // themselves.
        if (!cookies[name]) {
          cookies[name] = (parts[1] || '').trim()
        }
      })
    }
  }
  return this.parsedCookies_
}

/**
 * @constructor
 */
function Cookie(name, value, options) {
  this.name = name
  this.value = value
  this.options = options || {}
}

Cookie.prototype.toString = function() {
  var str = this.name + '=' + this.value
  if (this.options.maxAge) {
    str += '; expires=' + new Date(this.options.maxAge + Date.now()).toUTCString()
  } else if (this.options.expires) {
    str += '; expires=' + new Date(this.options.expires).toUTCString()
  }
  if (this.options.path) {
    str += '; path=' + this.options.path
  }
  if (this.options.domain) {
    str += '; domain=' + this.options.domain
  }
  if (this.options.secure) {
    str += '; secure'
  }
  if (this.options.httpOnly) {
    str += '; httponly'
  }
  return str
}
<commit_msg>== to ===<commit_after>/**
 * @fileoverview Service for setting and getting cookies
 *
 * Once installed a "cookies" service is available that exposes
 * get(name, default) and set(name, value, options)
 * methods. The options object can contain the following keys:
 *  - path - Path to scope to cookie to.
 *  - domain - Allows you to scope cookies to a subdomain.
 *  - expires - Date object or timestamp.
 *  - secure - Whether the cookie should only be sent over secure channels.
 *  - httpOnly - Tells the browser to only use the cookie on the HTTP protocol,
 *    i.e. not to client side scripts.
 *
 * @author dan@pupi.us (Daniel Pupius)
 */

module.exports = CookieService

/**
 * @param {Object} req the http request
 * @param {Object} res the http response
 * @constructor
 */
function CookieService(req, res) {
  this.req = req
  this.res = res
  this.parsedCookies_ = null
}

/**
 * Fetches a cookie from the request headers.
 * @param {string} name The cookie's name to fetch.
 * @param {string} opt_default Default value to return if the cookie is not set.
 * @return {string} The cookie's value.
 */
CookieService.prototype.get = function(name, opt_default) {
  var cookies = this.parseCookies_()
  var cookie = cookies[name]
  return typeof cookie !== 'undefined' ? cookie : opt_default
}

/**
 * Sets a cookie.
 * @param {string} name The cookie's name.
 * @param {string} value The value to set.
 * @param {Object=} options Optional options object containing some of the
 *    following: expires, path, domain, secure, httpOnly.
 */
CookieService.prototype.set = function(name, value, options) {
  if (options && options.secure && !this.res.socket.encrypted) {
    throw Error('Can not to set secure cookie on unencrypted socket.')
  }
  var cookies = this.res.getHeader('Set-Cookie') || []
  if (typeof cookies === 'string') {
    cookies = [cookies]
  }
  cookies.push(new Cookie(name, value, options).toString())
  this.res.setHeader('Set-Cookie', cookies)
}

CookieService.prototype.parseCookies_ = function() {
  if (!this.parsedCookies_) {
    var cookies = this.parsedCookies_ = {}
    if (this.req.headers.cookie) {
      this.req.headers.cookie.split(';').forEach(function(cookie) {
        var parts = cookie.split('=')
        var name = parts[0].trim()
        // If multiple cookie's path match the client will send all of them. We
        // only consider the first, since it will be most specific. In the rare
        // case someone cares about all values, they can parse the header
        // themselves.
        if (!cookies[name]) {
          cookies[name] = (parts[1] || '').trim()
        }
      })
    }
  }
  return this.parsedCookies_
}

/**
 * @constructor
 */
function Cookie(name, value, options) {
  this.name = name
  this.value = value
  this.options = options || {}
}

Cookie.prototype.toString = function() {
  var str = this.name + '=' + this.value
  if (this.options.maxAge) {
    str += '; expires=' + new Date(this.options.maxAge + Date.now()).toUTCString()
  } else if (this.options.expires) {
    str += '; expires=' + new Date(this.options.expires).toUTCString()
  }
  if (this.options.path) {
    str += '; path=' + this.options.path
  }
  if (this.options.domain) {
    str += '; domain=' + this.options.domain
  }
  if (this.options.secure) {
    str += '; secure'
  }
  if (this.options.httpOnly) {
    str += '; httponly'
  }
  return str
}
<|endoftext|>


<commit_before>"use strict";

const ccxt = require ('../../ccxt.js')

console.log ('CCXT Version:', ccxt.version)

async function main () {

    const exchange = new ccxt.binance({
            'apiKey': 'YOUR_API_KEY',
            'secret': 'YOUR_SECRET',
            'options': {
                'defaultType': 'margin',
            },
        })

        , markets = await exchange.loadMarkets ()

    // exchange.verbose = true // uncomment for debugging purposes if necessary

        , symbol = 'BTC/USDT'
        , type = 'limit'
        , side = 'buy'
        , amount = YOUR_AMOUNT_HERE
        , price = YOUR_LIMIT_PRICE_HERE
        , params = {
            'stopPrice': YOUR_STOP_PRICE_HERE,
        }

        try {
            const order = await exchange.createOrder (symbol, type, side, amount, price, params)
            console.log (order)
        } catch (e) {
            console.log (e.constructor.name, e.message)
        }
}

main ()
<commit_msg>examples/js/binance-margin-stop-order.js #9971<commit_after>"use strict";

const ccxt = require ('../../ccxt.js')

console.log ('CCXT Version:', ccxt.version)

async function main () {

    const exchange = new ccxt.binance({
            'apiKey': 'YOUR_API_KEY',
            'secret': 'YOUR_SECRET',
            'options': {
                'defaultType': 'margin',
            },
        })

        , markets = await exchange.loadMarkets ()

        // exchange.verbose = true // uncomment for debugging purposes if necessary

        , symbol = 'BTC/USDT'
        , type = 'limit'
        , side = 'buy'
        , amount = YOUR_AMOUNT_HERE
        , price = YOUR_LIMIT_PRICE_HERE
        , params = {
            'stopPrice': YOUR_STOP_PRICE_HERE,
        }

        try {
            const order = await exchange.createOrder (symbol, type, side, amount, price, params)
            console.log (order)
        } catch (e) {
            console.log (e.constructor.name, e.message)
        }
}

main ()
<|endoftext|>


<commit_before>/**
* Copyright (c) 2009 Chris Leonello
* This software is licensed under the GPL version 2.0 and MIT licenses.
*/
(function($) {

    /**
     * Class: $.jqplot.Dragable
     * Plugin to make plotted points dragable by the user.
     */
    $.jqplot.Dragable = function(options) {
        // Group: Properties

        // prop: markerRenderer
        // Renderer used to draw the markers of the point being dragged.
	    this.markerRenderer = new $.jqplot.MarkerRenderer({shadow:false});
	    this.shapeRenderer = new $.jqplot.ShapeRenderer();
	    this.isDragging = false;
	    this._ctx;
	    this._elem;
	    this._point;
	    this._gridData;
	    // prop: color
	    // CSS color spec for the dragged point (and adjacent line segment or bar).
	    this.color;
	    // prop: contstrainTo
	    // Constrain dragging motion to an axis or to none.
	    // Allowable values are 'none', 'x', 'y'
	    this.contstrainTo = 'none';  // 'x', 'y', or 'none';

	    $.extend(true, this, options);
	};

	function DragCanvas() {
	    $.jqplot.GenericCanvas.call(this);
	    this.isDragging = false;
	    this._neighbor;
	    this._cursor;
	}

	DragCanvas.prototype = new $.jqplot.GenericCanvas();
	DragCanvas.prototype.constructor = DragCanvas;

    // // called with scope of plot
    // $.jqplot.Dragable.init = function (target, data, options){
    //     // add a dragable attribute to the plot
    //     this.dragable = new $.jqplot.Dragable(options.dragable);
    // };

	// called within scope of series
	$.jqplot.Dragable.parseOptions = function (defaults, opts) {
	    var options = opts || {};
	    this.plugins.dragable = new $.jqplot.Dragable(options.dragable);
	    this.isDragable = true;
	};

	// called within context of plot
	// create a canvas which we can draw on.
	// insert it before the eventCanvas, so eventCanvas will still capture events.
	// add a new DragCanvas object to the plot plugins to handle drawing on this new canvas.
	$.jqplot.Dragable.postPlotDraw = function() {
	    this.plugins.dragable = {};
	    this.plugins.dragable.dragCanvas = new DragCanvas();

        this.eventCanvas._elem.before(this.plugins.dragable.dragCanvas.createElement(this._gridPadding, 'jqplot-dragable-canvas', this._plotDimensions));
        var dctx = this.plugins.dragable.dragCanvas.setContext();
	};

	//$.jqplot.preInitHooks.push($.jqplot.Dragable.init);
	$.jqplot.preParseSeriesOptionsHooks.push($.jqplot.Dragable.parseOptions);
	$.jqplot.postDrawHooks.push($.jqplot.Dragable.postPlotDraw);
	$.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]);
	$.jqplot.eventListenerHooks.push(['jqplotMouseDown', handleDown]);
	$.jqplot.eventListenerHooks.push(['jqplotMouseUp', handleUp]);

    function initDragPoint(plot, neighbor) {
        var s = plot.series[neighbor.seriesIndex];
        var drag = s.plugins.dragable;

        // first, init the mark renderer for the dragged point
        var smr = s.markerRenderer;
        var mr = drag.markerRenderer;
        mr.style = smr.style;
        mr.lineWidth = smr.lineWidth + 2.5;
        mr.size = smr.size + 5;
        var rgba = $.jqplot.getColorComponents(smr.color);
        var newrgb = [rgba[0], rgba[1], rgba[2]];
        var alpha = (rgba[3] >= 0.6) ? rgba[3]*0.6 : rgba[3]*(2-rgba[3]);
        var color = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+alpha+')';
        drag.color = color;
        mr.color = color;
        mr.init();

        var start = (neighbor.pointIndex > 0) ? neighbor.pointIndex - 1 : 0;
        var end = neighbor.pointIndex+2;
        drag._gridData = s.gridData.slice(start, end);
    }

	function handleMove(ev, gridpos, datapos, neighbor, plot) {
	    if (plot.plugins.dragable.dragCanvas.isDragging) {
	        var dc = plot.plugins.dragable.dragCanvas;
	        var dp = dc._neighbor;
	        var s = plot.series[dp.seriesIndex];
	        var drag = s.plugins.dragable;
	        var gd = s.gridData;

	        // compute the new grid position with any constraints.
	        var x = (drag.constrainTo == 'y') ? dp.gridData[0] : gridpos.x;
	        var y = (drag.constrainTo == 'x') ? dp.gridData[1] : gridpos.y;

	        // compute data values for any listeners.
            var xu = s._xaxis.series_p2u(x);
            var yu = s._yaxis.series_p2u(y);

	        // clear the canvas then redraw effect at new position.
	        var ctx = dc._ctx;
	        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

	        // adjust our gridData for the new mouse position
	        if (dp.pointIndex > 0) {
	            drag._gridData[1] = [x, y];
	        }
	        else {
	            drag._gridData[0] = [x, y];
	        }
	        plot.series[dp.seriesIndex].draw(dc._ctx, {gridData:drag._gridData, shadow:false, preventJqPlotSeriesDrawTrigger:true, color:drag.color});
	        dc._elem.trigger('jqplotSeriesPointChange', [dp.seriesIndex, dp.pointIndex, [xu,yu], [x,y]]);
	    }
	}

	function handleDown(ev, gridpos, datapos, neighbor, plot) {
	    var dc = plot.plugins.dragable.dragCanvas;
	    dc._cursor = ev.target.style.cursor;
	    if (neighbor != null) {
	        var s = plot.series[neighbor.seriesIndex];
	        var drag = s.plugins.dragable;
	        if (s.isDragable && !dc.isDragging) {
	            dc._neighbor = neighbor;
    	        dc.isDragging = true;
    	        initDragPoint(plot, neighbor);
    	        drag.markerRenderer.draw(s.gridData[neighbor.pointIndex][0], s.gridData[neighbor.pointIndex][1], dc._ctx);
    	        ev.target.style.cursor = "move";
            }
	    }
	    // Just in case of a hickup, we'll clear the drag canvas and reset.
	    else {
	       var ctx = dc._ctx;
	       ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
	       dc.isDragging = false;
	    }
	}

	function handleUp(ev, gridpos, datapos, neighbor, plot) {
	    if (plot.plugins.dragable.dragCanvas.isDragging) {
	        var dc = plot.plugins.dragable.dragCanvas;
	        // clear the canvas
	        var ctx = dc._ctx;
	        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
	        dc.isDragging = false;
	        // redraw the series canvas at the new point.
	        var dp = dc._neighbor;
	        var s = plot.series[dp.seriesIndex];
	        var drag = s.plugins.dragable;
	        // compute the new grid position with any constraints.
	        var x = (drag.constrainTo == 'y') ? dp.data[0] : datapos[s.xaxis];
	        var y = (drag.constrainTo == 'x') ? dp.data[1] : datapos[s.yaxis];
            // var x = datapos[s.xaxis];
            // var y = datapos[s.yaxis];
            s.data[dp.pointIndex] = [x,y];
            plot.drawSeries(plot.seriesCanvas._ctx, {preventJqPlotSeriesDrawTrigger:true});
	        dc._neighbor = null;
	        ev.target.style.cursor = dc._cursor;
	    }
	}
})(jQuery);<commit_msg>Added cursor changes when mousing near a dragable point.<commit_after>/**
* Copyright (c) 2009 Chris Leonello
* This software is licensed under the GPL version 2.0 and MIT licenses.
*/
(function($) {

    /**
     * Class: $.jqplot.Dragable
     * Plugin to make plotted points dragable by the user.
     */
    $.jqplot.Dragable = function(options) {
        // Group: Properties

        // prop: markerRenderer
        // Renderer used to draw the markers of the point being dragged.
	    this.markerRenderer = new $.jqplot.MarkerRenderer({shadow:false});
	    this.shapeRenderer = new $.jqplot.ShapeRenderer();
	    this.isDragging = false;
	    this.isOver = false;
	    this._ctx;
	    this._elem;
	    this._point;
	    this._gridData;
	    // prop: color
	    // CSS color spec for the dragged point (and adjacent line segment or bar).
	    this.color;
	    // prop: contstrainTo
	    // Constrain dragging motion to an axis or to none.
	    // Allowable values are 'none', 'x', 'y'
	    this.contstrainTo = 'none';  // 'x', 'y', or 'none';

	    $.extend(true, this, options);
	};

	function DragCanvas() {
	    $.jqplot.GenericCanvas.call(this);
	    this.isDragging = false;
	    this.isOver = false;
	    this._neighbor;
	    this._cursors = [];
	}

	DragCanvas.prototype = new $.jqplot.GenericCanvas();
	DragCanvas.prototype.constructor = DragCanvas;

	// called within scope of series
	$.jqplot.Dragable.parseOptions = function (defaults, opts) {
	    var options = opts || {};
	    this.plugins.dragable = new $.jqplot.Dragable(options.dragable);
	    this.isDragable = true;
	};

	// called within context of plot
	// create a canvas which we can draw on.
	// insert it before the eventCanvas, so eventCanvas will still capture events.
	// add a new DragCanvas object to the plot plugins to handle drawing on this new canvas.
	$.jqplot.Dragable.postPlotDraw = function() {
	    this.plugins.dragable = {previousCursor:'auto', isOver:false};
	    this.plugins.dragable.dragCanvas = new DragCanvas();

        this.eventCanvas._elem.before(this.plugins.dragable.dragCanvas.createElement(this._gridPadding, 'jqplot-dragable-canvas', this._plotDimensions));
        var dctx = this.plugins.dragable.dragCanvas.setContext();
	};

	//$.jqplot.preInitHooks.push($.jqplot.Dragable.init);
	$.jqplot.preParseSeriesOptionsHooks.push($.jqplot.Dragable.parseOptions);
	$.jqplot.postDrawHooks.push($.jqplot.Dragable.postPlotDraw);
	$.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]);
	$.jqplot.eventListenerHooks.push(['jqplotMouseDown', handleDown]);
	$.jqplot.eventListenerHooks.push(['jqplotMouseUp', handleUp]);

    function initDragPoint(plot, neighbor) {
        var s = plot.series[neighbor.seriesIndex];
        var drag = s.plugins.dragable;

        // first, init the mark renderer for the dragged point
        var smr = s.markerRenderer;
        var mr = drag.markerRenderer;
        mr.style = smr.style;
        mr.lineWidth = smr.lineWidth + 2.5;
        mr.size = smr.size + 5;
        var rgba = $.jqplot.getColorComponents(smr.color);
        var newrgb = [rgba[0], rgba[1], rgba[2]];
        var alpha = (rgba[3] >= 0.6) ? rgba[3]*0.6 : rgba[3]*(2-rgba[3]);
        var color = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+alpha+')';
        drag.color = color;
        mr.color = color;
        mr.init();

        var start = (neighbor.pointIndex > 0) ? neighbor.pointIndex - 1 : 0;
        var end = neighbor.pointIndex+2;
        drag._gridData = s.gridData.slice(start, end);
    }

	function handleMove(ev, gridpos, datapos, neighbor, plot) {
	    if (plot.plugins.dragable.dragCanvas.isDragging) {
	        var dc = plot.plugins.dragable.dragCanvas;
	        var dp = dc._neighbor;
	        var s = plot.series[dp.seriesIndex];
	        var drag = s.plugins.dragable;
	        var gd = s.gridData;

	        // compute the new grid position with any constraints.
	        var x = (drag.constrainTo == 'y') ? dp.gridData[0] : gridpos.x;
	        var y = (drag.constrainTo == 'x') ? dp.gridData[1] : gridpos.y;

	        // compute data values for any listeners.
            var xu = s._xaxis.series_p2u(x);
            var yu = s._yaxis.series_p2u(y);

	        // clear the canvas then redraw effect at new position.
	        var ctx = dc._ctx;
	        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

	        // adjust our gridData for the new mouse position
	        if (dp.pointIndex > 0) {
	            drag._gridData[1] = [x, y];
	        }
	        else {
	            drag._gridData[0] = [x, y];
	        }
	        plot.series[dp.seriesIndex].draw(dc._ctx, {gridData:drag._gridData, shadow:false, preventJqPlotSeriesDrawTrigger:true, color:drag.color});
	        dc._elem.trigger('jqplotSeriesPointChange', [dp.seriesIndex, dp.pointIndex, [xu,yu], [x,y]]);
	    }
	    else if (neighbor != null) {
    	    var series = plot.series[neighbor.seriesIndex];
    	    if (series.isDragable) {
        	    var dc = plot.plugins.dragable.dragCanvas;
        	    if (!dc.isOver) {
        	        dc._cursors.push(ev.target.style.cursor);
        	        ev.target.style.cursor = "pointer";
        	    }
        	    dc.isOver = true;
    	    }
	    }
	    else if (neighbor == null) {
	        var dc = plot.plugins.dragable.dragCanvas;
	        if (dc.isOver) {
        	    ev.target.style.cursor = dc._cursors.pop();
        	    dc.isOver = false;
	        }
	    }
	}

	function handleDown(ev, gridpos, datapos, neighbor, plot) {
	    var dc = plot.plugins.dragable.dragCanvas;
	    dc._cursors.push(ev.target.style.cursor);
	    if (neighbor != null) {
	        var s = plot.series[neighbor.seriesIndex];
	        var drag = s.plugins.dragable;
	        if (s.isDragable && !dc.isDragging) {
	            dc._neighbor = neighbor;
    	        dc.isDragging = true;
    	        initDragPoint(plot, neighbor);
    	        drag.markerRenderer.draw(s.gridData[neighbor.pointIndex][0], s.gridData[neighbor.pointIndex][1], dc._ctx);
    	        ev.target.style.cursor = "move";
            }
	    }
	    // Just in case of a hickup, we'll clear the drag canvas and reset.
	    else {
	       var ctx = dc._ctx;
	       ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
	       dc.isDragging = false;
	    }
	}

	function handleUp(ev, gridpos, datapos, neighbor, plot) {
	    if (plot.plugins.dragable.dragCanvas.isDragging) {
	        var dc = plot.plugins.dragable.dragCanvas;
	        // clear the canvas
	        var ctx = dc._ctx;
	        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
	        dc.isDragging = false;
	        // redraw the series canvas at the new point.
	        var dp = dc._neighbor;
	        var s = plot.series[dp.seriesIndex];
	        var drag = s.plugins.dragable;
	        // compute the new grid position with any constraints.
	        var x = (drag.constrainTo == 'y') ? dp.data[0] : datapos[s.xaxis];
	        var y = (drag.constrainTo == 'x') ? dp.data[1] : datapos[s.yaxis];
            // var x = datapos[s.xaxis];
            // var y = datapos[s.yaxis];
            s.data[dp.pointIndex] = [x,y];
            plot.drawSeries(plot.seriesCanvas._ctx, {preventJqPlotSeriesDrawTrigger:true});
	        dc._neighbor = null;
	        ev.target.style.cursor = dc._cursors.pop();
	    }
	}
})(jQuery);<|endoftext|>


<commit_before>/*
 * Logspace
 * Copyright (c) 2015 Indoqa Software Design und Beratung GmbH. All rights reserved.
 * This program and the accompanying materials are made available under the terms of
 * the Eclipse Public License Version 1.0, which accompanies this distribution and
 * is available at http://www.eclipse.org/legal/epl-v10.html.
 */
import React from 'react';
import shallowEqual from 'react/lib/shallowEqual';

/**
 * PureRenderMixin replacement for React component ES6 classes.
 * https://github.com/facebook/react/blob/ed3e6ecb9b86b97c09428f40deb8c3ed695e73e8/src/addons/ReactComponentWithPureRenderMixin.js
 */
export default class PureComponent extends React.Component {

  shouldComponentUpdate(nextProps, nextState) {
    return !shallowEqual(this.props, nextProps) ||
           !shallowEqual(this.state, nextState);
  }

}
<commit_msg>remove deprecated purecomponent.js<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

/**
 * Go over all packages and estimate quality for all.
 * (C) 2014 Alex Fernández.
 */

// requires
require('prototypes');
var config = require('../config.js');
var db = require('../lib/db.js');
var estimator = require('../lib/estimation.js');
var async = require('async');
var moment = require('moment');
var Log = require('log');

// globals
var log = new Log(config.logLevel);
//var githubApiRemainingCalls;
//var githubApiResetLimit;
var limit = config.limit;
var packagesCollection;

/**
 * Go over all the packages in all.json and update mongo.
 * There are two constraints:
 *   - Github only allows 5000 requests per hour.
 *   - We should use config.limit to avoid RangeErrors in the stack size
 * @param offset[optional]: offset over the all.json file. Defaults to zero.
 * @param callback[required]: a function(error, result) with the results of the process
 */
exports.goOver = function(offset, callback)
{
	if (typeof offset === 'function') {
		callback = offset;
		offset = 0;
	}
	var all;
	log.info('loading all.json...');
	try
	{
		all = require('../all.json');
		delete all._updated;
	}
	catch(exception)
	{
		return callback('Could not parse all.json: ' + exception);
	}
	log.info('all.json loaded');
	var names = Object.keys(all);
	log.info('All packages: ' + names.length);
	if (offset)
	{
		log.info('Offset ' + offset);
		for (var i=0; i<offset; i++)
		{
			delete all[names.shift()];
		}
	}
	var numberOfPackages = names.length;
	log.info('All packages after offset: ' + numberOfPackages);
	limit = (limit === null) || (numberOfPackages < limit) ? numberOfPackages : limit;
	var chunks = [];
	for (var j = 0; j < Math.ceil(numberOfPackages/limit); j++)
	{
		chunks.push([]);
	}
	var packageCount = 0;
	for (var name in all)
	{
		var entry = all[name];
		var index = Math.floor(packageCount/limit);
		chunks[index].push(getEstimator(entry));
		packageCount++;
		delete all[name];
	}
	log.debug('number of chunks: ' + chunks.length);
	db.addCallback(function(error, result)
	{
        if (error) {
            return callback(error);
        }
        packagesCollection = result.collection(config.packagesCollection);
        var series = [];
        while (chunks.length)
		{
			series.push(getChunkProcessor(chunks.shift()));
		}
		async.series(series, function(error)
		{
			if (error)
			{
				callback(error);
			}
			callback(null, series.length);
		});
	});
};

function getEstimator(entry)
{
	return function(callback)
	{
		estimator.estimate(entry, callback);
	};
}

function getChunkProcessor(chunk)
{
	return function(callback)
	{
		log.info('About to process chunk.');
		async.parallel(chunk, function(error, estimations)
		{
			if (error)
			{
				return callback(error);
			}
			log.info('Chunk processed.');
			// Adjust pending, remaining calls, etc
			var pendings = [];
			var githubApiRemainingCalls = 9999999;
			var githubApiResetLimit;
			estimations.forEach(function (estimation)
			{
				if (estimation.githubApiRemainingCalls < githubApiRemainingCalls)
				{
					githubApiRemainingCalls = estimation.githubApiRemainingCalls;
					githubApiResetLimit = estimation.githubApiResetLimit;
				}
				delete estimation.githubApiRemainingCalls;
				delete estimation.githubApiResetLimit;
				if (estimation.pending)
				{
					var item = {
						pending: estimation.pending
					};
					delete estimation.pending;
					item.previousEstimation = estimation;
					pendings.push(item);
				}
				else
				{
					// add to db!!
					var finalEstimation = estimator.addQuality(estimation);
					packagesCollection.update({name: finalEstimation.name}, {'$set':finalEstimation}, {upsert: true}, function(error)
					{
						if (error)
						{
							log.error('Package ' + finalEstimation.name + ' could not be upserted in the database: ' + JSON.stringify(error));
						}
						return callback(null);
					});
				}
			});
			// stream the pending stuff
			if (pendings.length > 0)
			{
				var pendingStream = [];
				pendings.forEach(function (pendingItem)
				{
					// only pending issues so far
					pendingStream.push(function (callback)
					{
						log.info('Processing pending for ' + pendingItem.previousEstimation.name);
						// function to process pending item
						function processPendingItem(pendingItem)
						{
							estimator.pending(pendingItem.pending, function (error, pendingEstimation)
							{
								githubApiRemainingCalls = pendingEstimation.githubApiRemainingCalls;
								githubApiResetLimit = pendingEstimation.githubApiResetLimit;
								delete pendingEstimation.githubApiRemainingCalls;
								delete pendingEstimation.githubApiResetLimit;
								var finalEstimation = estimator.addQuality(pendingItem.previousEstimation.concat(pendingEstimation));
								packagesCollection.update({name: finalEstimation.name}, {'$set':finalEstimation}, {upsert: true}, function(error)
								{
									if (error)
									{
										log.error('Package ' + finalEstimation.name + ' could not be upserted in the database: ' + JSON.stringify(error));
									}
									return callback(null);
								});
							});
						}
						// pending API calls
						var apiCallsForThisPending = pendingItem.pending[0].pages[1] - pendingItem.pending[0].pages[0] + 1;
						// check remaining api calls.
						if (githubApiRemainingCalls < apiCallsForThisPending)
						{
							var now = moment().unix();
							if (githubApiResetLimit > now)
							{
								var millisecondsToWait = (githubApiResetLimit - now) * 1000;
								log.info('Waiting in pendings ' + millisecondsToWait + ' milliseconds until next pending');
								setTimeout(function()
								{
									processPendingItem(pendingItem);
								}, millisecondsToWait);
							}
							else
							{
								processPendingItem(pendingItem);
							}
						}
						else
						{
							processPendingItem(pendingItem);
						}
					});
				});
				// run pending stream
				async.series(pendingStream, function()
				{
					// check remaining api calls.
					if (githubApiRemainingCalls < limit)
					{
						var now = moment().unix();
						if (githubApiResetLimit > now)
						{
							var millisecondsToWait = (githubApiResetLimit - now) * 1000;
							log.info('Waiting ' + millisecondsToWait + ' milliseconds until next chunk');
							setTimeout(function()
							{
								return callback(null);
							}, millisecondsToWait);
						}
						else
						{
							return callback(null);
						}
					}
					else
					{
						return callback(null);
					}
				});
			}
		});
	};
}

// run script if invoked directly
if (__filename == process.argv[1])
{
	var offset = process.argv[2];
	exports.goOver(offset, function(error, result)
	{
		if (error)
		{
			log.error('Could not evaluate all: %s', error);
			return db.close(function () {
				log.info('DB closed');
				process.exit(1);
			});
		}
		log.info('Processed ' + result + ' chunks of approx ' + limit + ' elements each.');
		db.close(function () {
			log.info('DB closed');
			process.exit(0);
		});
	});
}

<commit_msg>added error trace at chunk processing<commit_after>#!/usr/bin/env node
'use strict';

/**
 * Go over all packages and estimate quality for all.
 * (C) 2014 Alex Fernández.
 */

// requires
require('prototypes');
var config = require('../config.js');
var db = require('../lib/db.js');
var estimator = require('../lib/estimation.js');
var async = require('async');
var moment = require('moment');
var Log = require('log');

// globals
var log = new Log(config.logLevel);
//var githubApiRemainingCalls;
//var githubApiResetLimit;
var limit = config.limit;
var packagesCollection;

/**
 * Go over all the packages in all.json and update mongo.
 * There are two constraints:
 *   - Github only allows 5000 requests per hour.
 *   - We should use config.limit to avoid RangeErrors in the stack size
 * @param offset[optional]: offset over the all.json file. Defaults to zero.
 * @param callback[required]: a function(error, result) with the results of the process
 */
exports.goOver = function(offset, callback)
{
	if (typeof offset === 'function') {
		callback = offset;
		offset = 0;
	}
	var all;
	log.info('loading all.json...');
	try
	{
		all = require('../all.json');
		delete all._updated;
	}
	catch(exception)
	{
		return callback('Could not parse all.json: ' + exception);
	}
	log.info('all.json loaded');
	var names = Object.keys(all);
	log.info('All packages: ' + names.length);
	if (offset)
	{
		log.info('Offset ' + offset);
		for (var i=0; i<offset; i++)
		{
			delete all[names.shift()];
		}
	}
	var numberOfPackages = names.length;
	log.info('All packages after offset: ' + numberOfPackages);
	limit = (limit === null) || (numberOfPackages < limit) ? numberOfPackages : limit;
	var chunks = [];
	for (var j = 0; j < Math.ceil(numberOfPackages/limit); j++)
	{
		chunks.push([]);
	}
	var packageCount = 0;
	for (var name in all)
	{
		var entry = all[name];
		var index = Math.floor(packageCount/limit);
		chunks[index].push(getEstimator(entry));
		packageCount++;
		delete all[name];
	}
	log.debug('number of chunks: ' + chunks.length);
	db.addCallback(function(error, result)
	{
        if (error) {
            return callback(error);
        }
        packagesCollection = result.collection(config.packagesCollection);
        var series = [];
        while (chunks.length)
		{
			series.push(getChunkProcessor(chunks.shift()));
		}
		async.series(series, function(error)
		{
			if (error)
			{
				callback(error);
			}
			callback(null, series.length);
		});
	});
};

function getEstimator(entry)
{
	return function(callback)
	{
		estimator.estimate(entry, callback);
	};
}

function getChunkProcessor(chunk)
{
	return function(callback)
	{
		log.info('About to process chunk.');
		async.parallel(chunk, function(error, estimations)
		{
			if (error)
			{
				log.error('Chunck processed with error ', error);
				return callback(error);
			}
			log.info('Chunk processed.');
			// Adjust pending, remaining calls, etc
			var pendings = [];
			var githubApiRemainingCalls = 9999999;
			var githubApiResetLimit;
			estimations.forEach(function (estimation)
			{
				if (estimation.githubApiRemainingCalls < githubApiRemainingCalls)
				{
					githubApiRemainingCalls = estimation.githubApiRemainingCalls;
					githubApiResetLimit = estimation.githubApiResetLimit;
				}
				delete estimation.githubApiRemainingCalls;
				delete estimation.githubApiResetLimit;
				if (estimation.pending)
				{
					var item = {
						pending: estimation.pending
					};
					delete estimation.pending;
					item.previousEstimation = estimation;
					pendings.push(item);
				}
				else
				{
					// add to db!!
					var finalEstimation = estimator.addQuality(estimation);
					packagesCollection.update({name: finalEstimation.name}, {'$set':finalEstimation}, {upsert: true}, function(error)
					{
						if (error)
						{
							log.error('Package ' + finalEstimation.name + ' could not be upserted in the database: ' + JSON.stringify(error));
						}
						return callback(null);
					});
				}
			});
			// stream the pending stuff
			if (pendings.length > 0)
			{
				var pendingStream = [];
				pendings.forEach(function (pendingItem)
				{
					// only pending issues so far
					pendingStream.push(function (callback)
					{
						log.info('Processing pending for ' + pendingItem.previousEstimation.name);
						// function to process pending item
						function processPendingItem(pendingItem)
						{
							estimator.pending(pendingItem.pending, function (error, pendingEstimation)
							{
								githubApiRemainingCalls = pendingEstimation.githubApiRemainingCalls;
								githubApiResetLimit = pendingEstimation.githubApiResetLimit;
								delete pendingEstimation.githubApiRemainingCalls;
								delete pendingEstimation.githubApiResetLimit;
								var finalEstimation = estimator.addQuality(pendingItem.previousEstimation.concat(pendingEstimation));
								packagesCollection.update({name: finalEstimation.name}, {'$set':finalEstimation}, {upsert: true}, function(error)
								{
									if (error)
									{
										log.error('Package ' + finalEstimation.name + ' could not be upserted in the database: ' + JSON.stringify(error));
									}
									return callback(null);
								});
							});
						}
						// pending API calls
						var apiCallsForThisPending = pendingItem.pending[0].pages[1] - pendingItem.pending[0].pages[0] + 1;
						// check remaining api calls.
						if (githubApiRemainingCalls < apiCallsForThisPending)
						{
							var now = moment().unix();
							if (githubApiResetLimit > now)
							{
								var millisecondsToWait = (githubApiResetLimit - now) * 1000;
								log.info('Waiting in pendings ' + millisecondsToWait + ' milliseconds until next pending');
								setTimeout(function()
								{
									processPendingItem(pendingItem);
								}, millisecondsToWait);
							}
							else
							{
								processPendingItem(pendingItem);
							}
						}
						else
						{
							processPendingItem(pendingItem);
						}
					});
				});
				// run pending stream
				async.series(pendingStream, function()
				{
					// check remaining api calls.
					if (githubApiRemainingCalls < limit)
					{
						var now = moment().unix();
						if (githubApiResetLimit > now)
						{
							var millisecondsToWait = (githubApiResetLimit - now) * 1000;
							log.info('Waiting ' + millisecondsToWait + ' milliseconds until next chunk');
							setTimeout(function()
							{
								return callback(null);
							}, millisecondsToWait);
						}
						else
						{
							return callback(null);
						}
					}
					else
					{
						return callback(null);
					}
				});
			}
		});
	};
}

// run script if invoked directly
if (__filename == process.argv[1])
{
	var offset = process.argv[2];
	exports.goOver(offset, function(error, result)
	{
		if (error)
		{
			log.error('Could not evaluate all: %s', error);
			return db.close(function () {
				log.info('DB closed');
				process.exit(1);
			});
		}
		log.info('Processed ' + result + ' chunks of approx ' + limit + ' elements each.');
		db.close(function () {
			log.info('DB closed');
			process.exit(0);
		});
	});
}

<|endoftext|>


<commit_before>#!/usr/bin/env node
var Avrgirl = require('../avrgirl-arduino');
var boards = require('../boards');
var parseArgs = require('minimist');
var path = require('path');

var args = (process.argv.slice(2));
var argv = parseArgs(args, {});
var userAction = argv._[0];
var help = 'Usage:\n' +
  '  avrgirl-arduino flash -f <file> -a <arduino name> [-p <port>] [-v]\n' +
  '  avrgirl-arduino boards\n' +
  '  avrgirl-arduino list';

function showHelp() {
  console.log(help);
}

function flash(file, options) {
  var avrgirl = new Avrgirl(options);
  var filepath = path.resolve(process.cwd(), file);

  avrgirl.flash(filepath, function(error) {
    if (error) {
      console.error(error);
      process.exit(1);
    } else {
      process.exit();
    }
  });
}

function handleInput(action, argz) {
  switch (action) {
    case 'flash': {
      if (!argz.f || !argz.a) {
        showHelp();
        process.exit(1);
      } else if (!boards.byName[argz.a]) {
        console.error(new Error('Oops! That board is not supported, sorry.'));
        process.exit(1);
      } else {
        // run flash function here if all is well
        var options = {
          board: argz.a,
          port: argz.p || '',
          debug: argz.v || false
        };

        flash(argz.f, options);
      }

      break;
    }

    case 'boards': {
      var boardNames = Object.keys(boards.byName).sort();
      console.log('Supported Boards:\n - ' + boardNames.join('\n - '));
      break;
    }

    case 'list': {
      Avrgirl.listPorts(function(err, ports) {
        console.log(ports);
      });

      break;
    }

    case 'help': {
      showHelp();
      process.exit();
      break;
    }

    default: {
      // Invalid or no argument specified, show help and exit with an error status
      showHelp();
      process.exit(9);
      break;
    }
  }
}

handleInput(userAction, argv);
<commit_msg>don't end flash process if it's already ending on a success<commit_after>#!/usr/bin/env node
var Avrgirl = require('../avrgirl-arduino');
var boards = require('../boards');
var parseArgs = require('minimist');
var path = require('path');

var args = (process.argv.slice(2));
var argv = parseArgs(args, {});
var userAction = argv._[0];
var help = 'Usage:\n' +
  '  avrgirl-arduino flash -f <file> -a <arduino name> [-p <port>] [-v]\n' +
  '  avrgirl-arduino boards\n' +
  '  avrgirl-arduino list';

function showHelp() {
  console.log(help);
}

function flash(file, options) {
  var avrgirl = new Avrgirl(options);
  var filepath = path.resolve(process.cwd(), file);

  avrgirl.flash(filepath, function(error) {
    if (error) {
      console.error(error);
      process.exit(1);
    }
  });
}

function handleInput(action, argz) {
  switch (action) {
    case 'flash': {
      if (!argz.f || !argz.a) {
        showHelp();
        process.exit(1);
      } else if (!boards.byName[argz.a]) {
        console.error(new Error('Oops! That board is not supported, sorry.'));
        process.exit(1);
      } else {
        // run flash function here if all is well
        var options = {
          board: argz.a,
          port: argz.p || '',
          debug: argz.v || false
        };

        flash(argz.f, options);
      }

      break;
    }

    case 'boards': {
      var boardNames = Object.keys(boards.byName).sort();
      console.log('Supported Boards:\n - ' + boardNames.join('\n - '));
      break;
    }

    case 'list': {
      Avrgirl.listPorts(function(err, ports) {
        console.log(ports);
      });

      break;
    }

    case 'help': {
      showHelp();
      process.exit();
      break;
    }

    default: {
      // Invalid or no argument specified, show help and exit with an error status
      showHelp();
      process.exit(9);
      break;
    }
  }
}

handleInput(userAction, argv);
<|endoftext|>


<commit_before>#!/usr/bin/env node

var trek = require('../');<commit_msg>cli: add usage info, parse args and initiate migrations<commit_after>#!/usr/bin/env node

var usage = [
		'migrate data',
		'',
		'Usage:',
		// TODO: add a -g option for generating an empty migration file
		'$0 [-p <path>] [<migration> | up | down | latest]',
		'',
		'Options:',
		'<path>',
		'	path to application root.  path should contain a trek directory with the migrations.',
		'	default is current working directory.',
		'<migration>',
		'	the sequence number of the specific migration to migrate to.',
		'up',
		'	migrate up to next migration',
		'down',
		'	migrate down from current migration',
		'latest',
		'	migrate to the migration with the largest sequence number.',
		'	this is the default behavior if no othe migration is specified'
	].join('\n'),
	argv = require('optimist')
		.usage(usage)
		['default']('p', process.cwd())
		.argv,
	path = require('path'),
	trekDir = path.join(argv.p, 'trek'),
	migrationSpec = argv._[0] || 'latest',
	// NODE_ENV can be used to switch configuration.  default is 'dev'
	env = process.env.NODE_ENV || 'dev',
	// use the config for this environment
	config = require(path.join(trekDir, 'config'))[env],
	trek = require('../');

// migrate the data
trek.hike(trekDir, migrationSpec, config);<|endoftext|>


<commit_before>#!/usr/bin/env node

require('babel-polyfill');

var cli = require('../lib/cli');
cli.run(process);
<commit_msg>Use `.default` to access exported function<commit_after>#!/usr/bin/env node

require('babel-polyfill');

var cli = require('../lib/cli');
cli.default.run(process);
<|endoftext|>


<commit_before>#!/usr/bin/env node

var path      = require('path');
var fs        = require('fs');
var program   = require('commander');
var log       = console.log;

var pack = 'electrify package';

program
  .usage('[command] [options]')
  .version(require('../package.json').version)
  .on('--help', function(){
    log('  Examples:\n');
    log('    ' + [
      'electrify',
      pack,
      pack +' --output /dist/dir',
      pack +' --output /dist/dir -settings file.json',
      pack +' --input /app/dir --output /dist/dir --settings dev.json',
      pack +' --input /app/dir --output /dist/dir --settings dev.json --plugins electrify-es'
    ].join('\n    ') + '\n');
  });

program
  .option('--settings <path>', 'json file with meteor\'s settings')
  .option('--input   <path>', 'meteor app dir (default = .)')
  .option('--output  <path>', 'output dir (default = .electrify/.dist)')
  .option('--plugins  <a,b>', 'comma separated list of plugins to use');
  // TODO: enable building of client only
  // .option('--server <url>', 'if informed, build client only');

program
  .command('run')
  .description('start meteor app within electrify context')
  .action(function(){
    electrify().app.run();
  });

program
  .command('bundle')
  .description('bundle everything as an electron project at `.electrify` dir')
  .action(function(){
    electrify().app.bundle(/* server_url */);
  });

program
  .command('package')
  .description('bundle and package app to `--output` dir')
  .action(function(){
    electrify().app.package(/* server_url */);
  });

program.parse(process.argv);

if(process.argv.length <= 2)
  electrify().app.run();

// helpers

function electrify() {
  var input, error_msg, meteor_dir;

  // validates input dir (app-root folder)
  if(program.input && !fs.existsSync(program.input)) {
    error_msg = 'Input folder doesn\'t exist: ' + program.input;
    throw new Error(error_msg);
  }

  input = program.input || process.cwd();

  // validates meteor project
  meteor_dir = path.join(input, '.meteor');

  if(!fs.existsSync(meteor_dir)) {
    error_msg = 'Not a meteor app: ' + meteor_dir;
    throw new Error(error_msg);
  }

  if(program.output && !fs.existsSync(program.output)) {
    error_msg = 'Output folder doesn\'t exist: ' + program.output;
    throw new Error(error_msg);
  }

  return require('../lib')(input, program.output, meteor_settings());
}

function meteor_settings() {
  if(!program.settings) return {};

  var relative = path.join(process.cwd(), program.settings);
  var absolute = path.resolve(program.settings);
  var settings = (absolute == program.settings ? absolute : relative);

  if(!fs.existsSync(settings)) {
    log('settings file not found: ', relative);
    process.exit();
  }

  return require(settings);
}<commit_msg>evolving options, improving docs<commit_after>#!/usr/bin/env node

var path      = require('path');
var fs        = require('fs');
var program   = require('commander');
var log       = console.log;

program
  .usage('[command] [options]')
  .version(require('../package.json').version)
  .on('--version', function(){
    return require('../package.json').version;
  })
  .on('--help', function(){
    log('  Examples:\n');
    log('    ' + [
      '# `electrify` without a command defaults to `electrify run`',
      '',
      'electrify',
      'electrify run',
      'electrify package',
      'electrify package -o /dist/dir',
      'electrify package -o /dist/dir -s file.json',
      'electrify package -i /app/dir -o /dist/dir -s dev.json',
      'electrify package -i /app/dir -o /dist/dir -s dev.json -c config.json'
    ].join('\n    ') + '\n');
  });

program
  .option('-i, --input    <path>', 'meteor app dir (default=.)')
  .option('-o, --output   <path>', 'output dir (default=.electrify/.dist)')
  .option('-c, --config   <path>', 'electrify config file (default=.electrify/electrify.json)')
  .option('-s, --settings <path>', 'meteor settings file (optional, default=null)');

program
  .command('run')
  .description('start meteor app within electrify context')
  .action(function(){
    electrify().app.run();
  });

program
  .command('bundle')
  .description('bundle everything as an electron project at `.electrify` dir')
  .action(function(){
    electrify().app.bundle(/* server_url */);
  });

program
  .command('package')
  .description('bundle and package `.electrify` electron app to `--output` dir')
  .action(function(){
    electrify().app.package(/* server_url */);
  });

program.parse(process.argv);

// default command = run
var cmd = process.argv[2];
if(process.argv.length == 2 || -1 == 'run|bundle|package'.indexOf(cmd))
  electrify().app.run();

// helpers
function electrify() {
  var input, error_msg, meteor_dir;

  // validates input dir (app-root folder)
  if(program.input && !fs.existsSync(program.input)) {
    error_msg = 'Input folder doesn\'t exist: ' + program.input;
    throw new Error(error_msg);
  }

  input = program.input || process.cwd();

  // validates meteor project
  meteor_dir = path.join(input, '.meteor');

  if(!fs.existsSync(meteor_dir)) {
    error_msg = 'Not a meteor app: ' + meteor_dir;
    throw new Error(error_msg);
  }

  if(program.output && !fs.existsSync(program.output)) {
    error_msg = 'Output folder doesn\'t exist: ' + program.output;
    throw new Error(error_msg);
  }

  var elec_mod = require('../lib');
  return elec_mod(input, program.output, program.config, meteor_settings());
}

function meteor_settings() {
  if(!program.settings) return {};

  var relative = path.join(process.cwd(), program.settings);
  var absolute = path.resolve(program.settings);
  var settings = (absolute == program.settings ? absolute : relative);

  if(!fs.existsSync(settings)) {
    log('settings file not found: ', relative);
    process.exit();
  }

  return require(settings);
}<|endoftext|>


<commit_before>'use strict'

const fs = require('fs')
const opn = require('opn')
const path = require('path')
const exec = require('child_process').exec
const execSync = require('child_process').execSync
const spawn = require('child_process').spawn
const yargs = require('yargs')
const getos = require('getos')
const semver = require('semver')
const version = require('../package').version

class CLI {
  constructor (args) {
    this.args = this.parseArguments(args)
    this.prefix = 'ws://'
    this.devtools = 'chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws='
    this.image = { path: '../extension/icon.png', type: 'image/png' }
    this.index = { path: '../extension/index.html', type: 'text/html' }
    this.caught = false
    this.errors = {
      process: 'Error: You must define a path to a node process directly or within your package.json under "main"',
      nodemon: 'Error: nodemon is not installed'
    }
  }

  get props () {
    return {
      args: this.args
    }
  }

  parseArguments (args) {
    return yargs
      .version()
      .demandCommand(1)
      .usage('rawkit [options] <file ...>')
      .alias('v', 'version')
      .version(version)
      .describe('v', 'show version information')
      .alias('h', 'help')
      .help('help')
      .usage('Usage: $0 -x [num]')
      .showHelpOnFail(false, 'Specify --help for available options')
      .option('executable', {
        alias: 'e',
        describe: 'Specify the name of the executable.',
        default: 'google chrome'
      })
      .option('canary', {
        alias: 'c',
        describe: 'Run the devtools in canary.',
        boolean: true
      })
      .option('nodemon', {
        alias: 'nm',
        describe: 'Use nodemon to automatically reload your application.',
        boolean: true
      })
      .option('inspect-brk', {
        alias: 'brk',
        describe: 'To break on the first line of the application code.',
        boolean: true
      })
      .option('inspect-port', {
        alias: 'p',
        describe: 'The debugger port. Defaults to 9229.',
        type: 'number'
      })
      .option('silent', {
        alias: 's',
        describe: 'Hide stdout/stderr output from child process.',
        boolean: true
      })
      .parse(args)
  }

  parseURL (str) {
    let re = /(\b(ws?|chrome-devtools):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig
    let matches = str.match(re)
    let link = (matches) ? matches[0] : null
    let isNew = link && link.indexOf(this.prefix) >= 0
    return (isNew) ? `${this.devtools}${link.replace(this.prefix, '')}` : link
  }

  exists (cmd) {
    try {
      let stdout = execSync(`command -v ${cmd} 2>/dev/null && { echo >&1 \'${cmd} found\'; exit 0; }`
      )
      return !!stdout
    } catch (error) {
      return false
    }
  }

  path (path) {
    path = path || this.pkg(process.cwd())
    path = (path && fs.lstatSync(path).isDirectory()) ? this.pkg(path) : path
    if (path && fs.lstatSync(path).isFile()) {
      return path
    }
    console.error(this.errors.process)
    process.exit()
  }

  pkg (dir) {
    let file = path.relative(dir, 'package.json')
    if (fs.existsSync(file)) {
      let config = JSON.parse(fs.readFileSync(file, 'utf8'))
      if (config.main) {
        return path.resolve(process.cwd(), config.main)
      }
    }
    console.error(this.errors.process)
    process.exit()
  }

  nodemon (dir) {
    let file = path.relative(dir, 'nodemon.json')
    let cmd = 'nodemon'
    if (!this.exists('nodemon')) {
      console.error(this.errors.nodemon)
      process.exit()
    }
    if (fs.existsSync(file)) {
      let config = JSON.parse(fs.readFileSync(file, 'utf8'))
      return (config && config.execMap) ? config.execMap.js : cmd
    }
    return cmd
  }

  exec () {
    let path = this.path(this.args._[2])
    let o = process.argv
    let legacy = semver.lt(semver.coerce(process.version), '8.0.0')
    let brk = (legacy) ? 'debug-brk' : 'inspect-brk'
    let cmd = (this.args.brk) ? brk : 'inspect'
    let args = o.splice(o.indexOf(path), o.length).join(' ').replace(path, '')
    let binary = (this.args.nodemon) ? this.nodemon(process.cwd()) : 'node'
    if (this.args.inspectPort) {
      let flag = (legacy) ? 'debug' : 'inspect-port'
      cmd += ` --${flag}=${this.args.inspectPort}`
    }
    this.child = exec(`${binary} --${cmd} ${args}`, { shell: true })
    this.child.stdout.on('data', this.handle.bind(this))
    this.child.stderr.on('data', this.handle.bind(this))
    this.child.on('close', _ => process.exit())
    process.on('exit', _ => this.child.kill())
  }

  handle (data) {
    let ref = this.parseURL(data)
    if (!this.caught && ref && !this.args['no-prompt']) {
      this.caught = true
      getos((e, data) => {
        let link = `https://darcyclarke.github.io/rawkit/?rawkit=${encodeURIComponent(ref)}`
        if (!e) {
          if (data.os === 'win32') {
            this.args.executable = 'chrome'
          }
          if (data.os === 'linux') {
            this.args.executable = 'google-chrome'
          }
          if (data.os === 'darwin' && this.args.canary) {
            this.args.executable = 'google chrome canary'
          }
        }
        if (this.exists('chrome-cli')) {
          let chrome = spawn('chrome-cli', [ 'open', ref ])
          execSync(`open -a "/Applications/Google Chrome${this.args.canary ? ' Canary' : ''}.app"`)
          chrome.stdout.on('data', _ => {})
          chrome.stderr.on('data', _ => {})
          chrome.on('close', _ => {})
        } else {
          console.log('link>>>', link)
          let opts = {
            app: this.args.executable,
            wait: false
          }
          opn(link, opts)
            .then(() => {})
            .catch((e) => {})
        }
        if (!this.args.silent) {
          console.log('\x1b[33m%s\x1b[0m', 'Devtools URL:', ref)
        }
      })
    } else if (!this.args.silent) {
      process.stdout.write(data)
    }
  }
}

module.exports = (args) => {
  return new CLI(args)
}
<commit_msg>Fix problem with path-finding<commit_after>'use strict'

const fs = require('fs')
const opn = require('opn')
const path = require('path')
const exec = require('child_process').exec
const execSync = require('child_process').execSync
const spawn = require('child_process').spawn
const yargs = require('yargs')
const getos = require('getos')
const semver = require('semver')
const version = require('../package').version

class CLI {
  constructor (args) {
    this.args = this.parseArguments(args)
    this.options = /^(executable|canary|inspect-port|inspect-brk|silent|nodemon)$/
    this.prefix = 'ws://'
    this.devtools = 'chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws='
    this.image = { path: '../extension/icon.png', type: 'image/png' }
    this.index = { path: '../extension/index.html', type: 'text/html' }
    this.caught = false
    this.errors = {
      process: 'Error: You must define a path to a node process directly or within your package.json under "main"',
      nodemon: 'Error: nodemon is not installed'
    }
  }

  get props () {
    return {
      args: this.args
    }
  }

  parseArguments (args) {
    return yargs
      .version()
      .demandCommand(1)
      .usage('rawkit [options] <file ...>')
      .alias('v', 'version')
      .version(version)
      .describe('v', 'show version information')
      .alias('h', 'help')
      .help('help')
      .usage('Usage: $0 -x [num]')
      .showHelpOnFail(false, 'Specify --help for available options')
      .option('executable', {
        alias: 'e',
        describe: 'Specify the name of the executable.',
        default: 'google chrome'
      })
      .option('canary', {
        alias: 'c',
        describe: 'Run the devtools in canary.',
        boolean: true
      })
      .option('nodemon', {
        alias: 'nm',
        describe: 'Use nodemon to automatically reload your application.',
        boolean: true
      })
      .option('inspect-brk', {
        alias: 'brk',
        describe: 'To break on the first line of the application code.',
        boolean: true
      })
      .option('inspect-port', {
        alias: 'p',
        describe: 'The debugger port. Defaults to 9229.',
        type: 'number'
      })
      .option('silent', {
        alias: 's',
        describe: 'Hide stdout/stderr output from child process.',
        boolean: true
      })
      .parse(args)
  }

  parseURL (str) {
    let re = /(\b(ws?|chrome-devtools):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig
    let matches = str.match(re)
    let link = (matches) ? matches[0] : null
    let isNew = link && link.indexOf(this.prefix) >= 0
    return (isNew) ? `${this.devtools}${link.replace(this.prefix, '')}` : link
  }

  exists (cmd) {
    try {
      let stdout = execSync(`command -v ${cmd} 2>/dev/null && { echo >&1 \'${cmd} found\'; exit 0; }`
      )
      return !!stdout
    } catch (error) {
      return false
    }
  }

  file (location) {
    location = location || this.pkg(process.cwd())
    location = (location && fs.lstatSync(location).isDirectory()) ? this.pkg(location) : location
    if (location && fs.lstatSync(location).isFile()) {
      return location
    }
    console.error(this.errors.process)
    process.exit()
  }

  pkg (location) {
    let file = path.relative(location, 'package.json')
    if (fs.existsSync(file)) {
      let config = JSON.parse(fs.readFileSync(file, 'utf8'))
      if (config.main) {
        return path.resolve(process.cwd(), config.main)
      }
    }
    console.error(this.errors.process)
    process.exit()
  }

  nodemon (location) {
    let file = path.relative(location, 'nodemon.json')
    let cmd = 'nodemon'
    if (!this.exists('nodemon')) {
      console.error(this.errors.nodemon)
      process.exit()
    }
    if (fs.existsSync(file)) {
      let config = JSON.parse(fs.readFileSync(file, 'utf8'))
      return (config && config.execMap) ? config.execMap.js : cmd
    }
    return cmd
  }

  exec () {
    let file = this.file(this.args._[2])
    let o = process.argv
    let legacy = semver.lt(semver.coerce(process.version), '8.0.0')
    let brk = (legacy) ? 'debug-brk' : 'inspect-brk'
    let cmd = (this.args.brk) ? brk : 'inspect'
    let args = o.splice(o.indexOf(file), o.length).join(' ').replace(file, '')
    args = args.split(' ').filter((v) => v.match(this.options)).join(' ')
    let binary = (this.args.nodemon) ? this.nodemon(process.cwd()) : 'node'
    if (this.args.inspectPort) {
      let flag = (legacy) ? 'debug' : 'inspect-port'
      cmd += ` --${flag}=${this.args.inspectPort}`
    }
    this.child = exec(`${binary} --${cmd} ${file} ${args}`, { shell: true })
    this.child.stdout.on('data', this.handle.bind(this))
    this.child.stderr.on('data', this.handle.bind(this))
    this.child.on('close', _ => process.exit())
    process.on('exit', _ => this.child.kill())
  }

  handle (data) {
    let ref = this.parseURL(data)
    if (!this.caught && ref && !this.args['no-prompt']) {
      this.caught = true
      getos((e, data) => {
        let link = `https://darcyclarke.github.io/rawkit/?rawkit=${encodeURIComponent(ref)}`
        if (!e) {
          if (data.os === 'win32') {
            this.args.executable = 'chrome'
          }
          if (data.os === 'linux') {
            this.args.executable = 'google-chrome'
          }
          if (data.os === 'darwin' && this.args.canary) {
            this.args.executable = 'google chrome canary'
          }
        }
        if (this.exists('chrome-cli')) {
          let chrome = spawn('chrome-cli', [ 'open', ref ])
          execSync(`open -a "/Applications/Google Chrome${this.args.canary ? ' Canary' : ''}.app"`)
          chrome.stdout.on('data', _ => {})
          chrome.stderr.on('data', _ => {})
          chrome.on('close', _ => {})
        } else {
          let opts = {
            app: this.args.executable,
            wait: false
          }
          opn(link, opts)
            .then(() => {})
            .catch((e) => {})
        }
        if (!this.args.silent) {
          console.log('\x1b[33m%s\x1b[0m', 'Devtools URL:', ref)
        }
      })
    } else if (!this.args.silent) {
      process.stdout.write(data)
    }
  }
}

module.exports = (args) => {
  return new CLI(args)
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

const program   = require('commander');
const path      = require('path');
const util      = require('util');
const cache     = require('../caching');
const filez     = require('../filez');
const akasha    = require('../index');

process.title = 'akasharender';
program.version('0.4.0');

program
    .command('copy-assets <configFN>')
    .description('Copy assets into output directory')
    .action(async (configFN) => {

        try {
            const config = require(path.join(process.cwd(), configFN));
            await config.copyAssets();
        } catch (e) {
            console.error(`copy-assets command ERRORED ${e.stack}`);
        }

    });

program
    .command('document <configFN> <documentFN>')
    .description('Show information about a document')
    .action(async (configFN, documentFN) => {

        try {
            const config = require(path.join(process.cwd(), configFN));
            let doc = await akasha.readDocument(config, documentFN);
            console.log(`
basedir: ${doc.basedir}
docpath: ${doc.docpath}
fullpath: ${doc.fullpath}
renderer: ${util.inspect(doc.renderer)}
renderpath: ${doc.renderpath}

data: ${doc.data}

metadata: ${util.inspect(doc.metadata)}

text: ${doc.text}

`);
        } catch (e) {
            console.error(`document command ERRORED ${e.stack}`);
        }
    });

program
    .command('render-document <configFN> <documentFN>')
    .description('Render a document into output directory')
    .action(async (configFN, documentFN) => {
        try {
            const config = require(path.join(process.cwd(), configFN));
            let found = await filez.findRendersTo(config.documentDirs, documentFN);
            let result = await akasha.renderDocument(
                        config,
                        found.foundDir,
                        found.foundPathWithinDir,
                        config.renderTo,
                        found.foundMountedOn,
                        {});
            console.log(result);
        } catch (e) {
            console.error(`copy-assets command ERRORED ${e.stack}`);
        }
    });

program
    .command('render <configFN>')
    .description('Render a site into output directory')
    .action(async (configFN) => {
        try {
            const config = require(path.join(process.cwd(), configFN));
            let results = await akasha.render(config);
            for (let result of results) {

                // TODO --- if AKASHARENDER_TRACE_RENDER then output tracing data
                // TODO --- also set process.env.GLOBFS_TRACE=1

                if (result.error) {
                    console.error(result.error);
                } else {
                    console.log(result.result);
                    // console.log(util.inspect(result.result));
                }
            }
        } catch (e) {
            console.error(`render command ERRORED ${e.stack}`);
        }
    });

program.parse(process.argv);

/* const CommandLineInterface = require('cmnd').CommandLineInterface;
const CLI = new CommandLineInterface();

CLI.load(__dirname, '../commands');
CLI.run(process.argv.slice(2)); */
<commit_msg>Change loading of akasharender module<commit_after>#!/usr/bin/env node

'use strict';

const program   = require('commander');
const path      = require('path');
const util      = require('util');
const cache     = require('../caching');
const filez     = require('../filez');

process.title = 'akasharender';
program.version('0.4.0');

program
    .command('copy-assets <configFN>')
    .description('Copy assets into output directory')
    .action(async (configFN) => {
        const akasha    = require('../index');

        try {
            const config = require(path.join(process.cwd(), configFN));
            await config.copyAssets();
        } catch (e) {
            console.error(`copy-assets command ERRORED ${e.stack}`);
        }

    });

program
    .command('document <configFN> <documentFN>')
    .description('Show information about a document')
    .action(async (configFN, documentFN) => {
        const akasha    = require('../index');

        try {
            const config = require(path.join(process.cwd(), configFN));
            let doc = await akasha.readDocument(config, documentFN);
            console.log(`
basedir: ${doc.basedir}
docpath: ${doc.docpath}
fullpath: ${doc.fullpath}
renderer: ${util.inspect(doc.renderer)}
renderpath: ${doc.renderpath}

data: ${doc.data}

metadata: ${util.inspect(doc.metadata)}

text: ${doc.text}

`);
        } catch (e) {
            console.error(`document command ERRORED ${e.stack}`);
        }
    });

program
    .command('render-document <configFN> <documentFN>')
    .description('Render a document into output directory')
    .action(async (configFN, documentFN) => {
        const akasha    = require('../index');
        try {
            const config = require(path.join(process.cwd(), configFN));
            let found = await filez.findRendersTo(config.documentDirs, documentFN);
            let result = await akasha.renderDocument(
                        config,
                        found.foundDir,
                        found.foundPathWithinDir,
                        config.renderTo,
                        found.foundMountedOn,
                        {});
            console.log(result);
        } catch (e) {
            console.error(`copy-assets command ERRORED ${e.stack}`);
        }
    });

program
    .command('render <configFN>')
    .description('Render a site into output directory')
    .action(async (configFN) => {
        const akasha    = require('../index');
        try {
            const config = require(path.join(process.cwd(), configFN));
            let results = await akasha.render(config);
            for (let result of results) {

                // TODO --- if AKASHARENDER_TRACE_RENDER then output tracing data
                // TODO --- also set process.env.GLOBFS_TRACE=1

                if (result.error) {
                    console.error(result.error);
                } else {
                    console.log(result.result);
                    // console.log(util.inspect(result.result));
                }
            }
        } catch (e) {
            console.error(`render command ERRORED ${e.stack}`);
        }
    });

program.parse(process.argv);

/* const CommandLineInterface = require('cmnd').CommandLineInterface;
const CLI = new CommandLineInterface();

CLI.load(__dirname, '../commands');
CLI.run(process.argv.slice(2)); */
<|endoftext|>


<commit_before>#!/usr/bin/env node

// Dependencies
var geddy = require('../lib/geddy')
  , path = require('path')
  , utils = require('utilities')
  , parseopts = require('../lib/parseopts');

// Variables
var cwd = process.cwd()
  , args = process.argv.slice(2)
  , parser
  , optsMap
  , cmds
  , opts
  , usage
  , cmd
  , engineCmd
  , rtCmd
  , modelCmd
  , filepath
  , die
  , jake
  , jakeArgs
  , jakeProgram
  , jakeLoader
  , start;

// Usage dialog
usage = [
    'Geddy web framework for Node.js'
  , ''
  , 'Usage:'
  , '  geddy [options/commands] [arguments]'
  , ''
  , 'Options:'
  , '  --environment, -e   Environment to use'
  , '  --hostname, -b      Host name or IP to bind the server to (default: localhost)'
  , '  --port, -p          Port to bind the server to (default: 4000)'
  , '  --workers, -w       Number of worker processes to start (default: 1)'
  , '  --debug, -d         Sets the log level to output debug messages to'
  , '                        the console'
  , '  --realtime, -rt      When generating or scaffolding, take realtime into account'
  , '  --jade, -j          When generating views this will create Jade'
  , '                        templates(Default: EJS)'
  , '  --handle, -H        When generating views this will create Handlebars'
  , '                        templates(Default: EJS)'
  , '  --mustache, -m      When generating views this will create Mustache'
  , '                        templates(Default: EJS)'
  , '  --help, -h          Output this usage dialog'
  , '  --version, -v       Output the version of Geddy that\'s installed'
  , ''
  , 'Commands:'
  , '  console                     Start up the Geddy REPL'
  , '  app <name>                  Create a new Geddy application'
  , '  resource <name> [attrs]     Create a new resource. A resource includes'
  , '                                a model, controller and route'
  , '  scaffold <name> [attrs]     Create a new scaffolding. Scaffolding includes'
  , '                                the views, a model, controller and route'
  , '  secret                      Generate a new application secret in'
  , '                                `config/secret`'
  , '  controller <name>           Generate a new controller including an index view'
  , '                                and and a route'
  , '  model <name> [attrs]        Generate a new model'
  , '  routes [query]              Shows routes for a given resource route or all '
  , '                                routes if empty'
  , '  auth[:update]               Creates user authentication for you, using Passport.'
  , ''
  , 'Examples:'
  , '  geddy                    Start Geddy on localhost:4000 in development mode'
  , '                             or if the directory isn\'t a Geddy app it\'ll'
  , '                             display this usage dialog'
  , '  geddy -p 3000            Start Geddy on port 3000'
  , '  geddy -e production      Start Geddy in production mode'
  , '  geddy -j scaffold user   Generate a users scaffolding using Jade templates'
  , '  geddy resource user name admin:boolean'
  , '                           Generate a users resource with the model properties'
  , '                             name as a string and admin as a boolean'
  , '  geddy scaffold user name:string:default'
  , '                           Generate a users scaffolding user name as the default'
  , '                             value to display data with'
  , '  geddy routes user        Show all routes for the user resource'
  , '  geddy routes user.index  Show the index route for the user resource'
  , ''
].join('\n');

// Options available
optsMap = [
  { full: 'origins'
  , abbr: 'o'
  , args: true
  , canon: 'origins'
  }
, { full: ['hostname', 'bind']
  , abbr: 'b'
  , args: true
  , canon: 'hostname'
  }
, { full: 'port'
  , abbr: 'p'
  , args: true
  , canon: 'port'
  }
, { full: 'workers'
  , abbr: ['n', 'w']
  , args: true
  , canon: 'workers'
  }
, { full: 'version'
  , abbr: ['v', 'V']
  , args: false
  , canon: 'version'
  }
, { full: 'help'
  , abbr: 'h'
  , args: false
  , canon: 'help'
  }
, { full: 'debug'
  , abbr: 'd'
  , args: true
  , canon: 'debug'
  }
, { full: 'loglevel'
  , abbr: 'l'
  , args: true
  , canon: 'loglevel'
  }
, { full: 'environment'
  , abbr: 'e'
  , args: true
  , canon: 'environment'
  }
, { full: 'spawned'
  , abbr: ['s', 'q', 'Q']
  , args: true
  , canon: 'spawned'
  }
, { full: 'jade'
  , abbr: 'j'
  , args: false
  , canon: 'jade'
  }
, { full: ['handle', 'handlebars']
  , abbr: 'H'
  , args: false
  , canon: 'handlebars'
  }
, { full: ['handle', 'swig']
  , abbr: 'S'
  , args: false
  , canon: 'swig'
  }
, { full: 'mustache'
  , abbr: 'm'
  , args: false
  , canon: 'mustache'
  }
, { full: 'realtime'
  , abbr: 'rt'
  , args: false
  , canon: 'realtime'
  }
];

// Parse optsMap and generate options and cmd commands
parser = new parseopts.Parser(optsMap);
parser.parse(args);
cmds = parser.cmds;
opts = parser.opts;

// Set handlebars option to handle option
opts.handle = opts.handlebars || opts.handle;

// Exit the process with a message
die = function (str) {
  console.log(str);
  process.exit();
};

// Start Geddy with options
start = function () {
  geddy.startCluster(opts);
};

if (opts.help) {
  die(usage);
}
if (opts.version) {
  die(geddy.version);
}

// `geddy app foo` or `geddy resource bar` etc. -- run generators
if (cmds.length) {
  // Get templates Jake file
  filepath = path.normalize(path.join(__dirname, '..', 'templates', 'Jakefile'));

  cmd = '';

  // Some commands take only one arg
  if (!(cmds[0] == 'jake' ||
      cmds[0] == 'secret' ||
      cmds[0] == 'db:init' ||
      cmds[0] == 'auth' ||
      cmds[0] == 'auth:update' ||
      cmds[0] == 'console' ||
      cmds[0] == 'routes')
      && !cmds[1]) {
    throw new Error(cmds[0] + ' command requires another argument.');
  }

  // Add engines to command
  if (opts.jade) {
    engineCmd = ',' + 'jade';
  } else if (opts.handle) {
    engineCmd = ',' + 'handlebars';
  } else if (opts.mustache) {
    engineCmd = ',' + 'mustache';
  } else if (opts.swig) {
    engineCmd = ',' + 'swig';
  } else engineCmd = ',default';

  if (opts.realtime) {
    rtCmd = ',' + 'realtime';
  }
  else {
    rtCmd = ',default';
  }

  // Get the model properties
  if (cmds.slice(2).length > 0) {
    modelCmd = ',' + cmds.slice(2).join('%');
  } else modelCmd = '';

  // Add Jake argument based on commands
  switch (cmds[0]) {
    case 'jake':
      cmd = 'jake';
      jakeArgs = cmds.slice(1);
      break;
    case 'console':
      // Start console
      cmd += 'console:start[' + (cmds[1] || 'development') + ']';
      break;
    case 'auth':
      // Create authentication
      cmd += 'auth:init[' + engineCmd.substr(1) + ']';
      break;
    case 'auth:update':
      // Update authentication
      cmd += 'auth:update';
      break;
    case 'db:init':
      // Create DBs
      cmd += 'db:init';
      break;
    case 'db:createTable':
      // Create DBs
      cmd += 'db:createTable[' + cmds[1].replace(/,/g, '%') + ']';
      break;
    case 'app':
      // Generating application
      cmd += 'gen:app[' + cmds[1] + engineCmd + rtCmd + ']';
      break;
    case 'resource':
      // Generating resource
      cmd += 'gen:resource[' + cmds[1] + modelCmd + ']';
      break;
    case 'scaffold':
      // Generating application
      cmd += 'gen:scaffold[' + cmds[1] + rtCmd + engineCmd + modelCmd + ']';
      break;
    case 'controller':
      // Generating controller
      cmd += 'gen:bareController[' + cmds[1] + engineCmd + ']';
      break;
    case 'model':
      // Generating model
      cmd += 'gen:model[' + cmds[1] + modelCmd + ']';
      break;
    case 'secret':
      // Generating new app secret
      cmd += 'gen:secret';
      break;
    case 'routes':
      // Show routes(Optionally empty)
      cmd += 'routes:show[' + (cmds[1] || '') + ']';
      break;
    default:
      die(cmds[0] + ' is not a Geddy command.');
  }

  jake = require('jake');
  jakeProgram = jake.program;
  jakeLoader = jake.loader;
  // Load Geddy's bundled Jakefile
  jakeLoader.loadFile(filepath);
  if (cmd == 'jake') {
    jakeProgram.parseArgs(jakeArgs);
    // Load Jakefile and jakelibdir files for app
    jakeLoader.loadFile(jakeProgram.opts.jakefile);
    jakeLoader.loadDirectory(jakeProgram.opts.jakelibdir);
    // Prepend env:init to load Geddy env
    jakeProgram.taskNames.unshift('env:init');
  }
  else {
    jakeProgram.init({
      quiet: !opts.debug
    , trace: true
    });
    jakeProgram.setTaskNames([cmd]);
  }
  jakeProgram.run();
}
// Just `geddy` -- start the server
else {
  // Search for 'config' directory in parent directories
  utils.file.searchParentPath('config', function (err, filePath) {
    if (err) {
      die(usage);
    }

    start();
  });
}
<commit_msg>Fixes alignment<commit_after>#!/usr/bin/env node

// Dependencies
var geddy = require('../lib/geddy')
  , path = require('path')
  , utils = require('utilities')
  , parseopts = require('../lib/parseopts');

// Variables
var cwd = process.cwd()
  , args = process.argv.slice(2)
  , parser
  , optsMap
  , cmds
  , opts
  , usage
  , cmd
  , engineCmd
  , rtCmd
  , modelCmd
  , filepath
  , die
  , jake
  , jakeArgs
  , jakeProgram
  , jakeLoader
  , start;

// Usage dialog
usage = [
    'Geddy web framework for Node.js'
  , ''
  , 'Usage:'
  , '  geddy [options/commands] [arguments]'
  , ''
  , 'Options:'
  , '  --environment, -e   Environment to use'
  , '  --hostname, -b      Host name or IP to bind the server to (default: localhost)'
  , '  --port, -p          Port to bind the server to (default: 4000)'
  , '  --workers, -w       Number of worker processes to start (default: 1)'
  , '  --debug, -d         Sets the log level to output debug messages to'
  , '                        the console'
  , '  --realtime, -rt     When generating or scaffolding, take realtime into account'
  , '  --jade, -j          When generating views this will create Jade'
  , '                        templates(Default: EJS)'
  , '  --handle, -H        When generating views this will create Handlebars'
  , '                        templates(Default: EJS)'
  , '  --mustache, -m      When generating views this will create Mustache'
  , '                        templates(Default: EJS)'
  , '  --help, -h          Output this usage dialog'
  , '  --version, -v       Output the version of Geddy that\'s installed'
  , ''
  , 'Commands:'
  , '  console                     Start up the Geddy REPL'
  , '  app <name>                  Create a new Geddy application'
  , '  resource <name> [attrs]     Create a new resource. A resource includes'
  , '                                a model, controller and route'
  , '  scaffold <name> [attrs]     Create a new scaffolding. Scaffolding includes'
  , '                                the views, a model, controller and route'
  , '  secret                      Generate a new application secret in'
  , '                                `config/secret`'
  , '  controller <name>           Generate a new controller including an index view'
  , '                                and and a route'
  , '  model <name> [attrs]        Generate a new model'
  , '  routes [query]              Shows routes for a given resource route or all '
  , '                                routes if empty'
  , '  auth[:update]               Creates user authentication for you, using Passport.'
  , ''
  , 'Examples:'
  , '  geddy                    Start Geddy on localhost:4000 in development mode'
  , '                             or if the directory isn\'t a Geddy app it\'ll'
  , '                             display this usage dialog'
  , '  geddy -p 3000            Start Geddy on port 3000'
  , '  geddy -e production      Start Geddy in production mode'
  , '  geddy -j scaffold user   Generate a users scaffolding using Jade templates'
  , '  geddy resource user name admin:boolean'
  , '                           Generate a users resource with the model properties'
  , '                             name as a string and admin as a boolean'
  , '  geddy scaffold user name:string:default'
  , '                           Generate a users scaffolding user name as the default'
  , '                             value to display data with'
  , '  geddy routes user        Show all routes for the user resource'
  , '  geddy routes user.index  Show the index route for the user resource'
  , ''
].join('\n');

// Options available
optsMap = [
  { full: 'origins'
  , abbr: 'o'
  , args: true
  , canon: 'origins'
  }
, { full: ['hostname', 'bind']
  , abbr: 'b'
  , args: true
  , canon: 'hostname'
  }
, { full: 'port'
  , abbr: 'p'
  , args: true
  , canon: 'port'
  }
, { full: 'workers'
  , abbr: ['n', 'w']
  , args: true
  , canon: 'workers'
  }
, { full: 'version'
  , abbr: ['v', 'V']
  , args: false
  , canon: 'version'
  }
, { full: 'help'
  , abbr: 'h'
  , args: false
  , canon: 'help'
  }
, { full: 'debug'
  , abbr: 'd'
  , args: true
  , canon: 'debug'
  }
, { full: 'loglevel'
  , abbr: 'l'
  , args: true
  , canon: 'loglevel'
  }
, { full: 'environment'
  , abbr: 'e'
  , args: true
  , canon: 'environment'
  }
, { full: 'spawned'
  , abbr: ['s', 'q', 'Q']
  , args: true
  , canon: 'spawned'
  }
, { full: 'jade'
  , abbr: 'j'
  , args: false
  , canon: 'jade'
  }
, { full: ['handle', 'handlebars']
  , abbr: 'H'
  , args: false
  , canon: 'handlebars'
  }
, { full: ['handle', 'swig']
  , abbr: 'S'
  , args: false
  , canon: 'swig'
  }
, { full: 'mustache'
  , abbr: 'm'
  , args: false
  , canon: 'mustache'
  }
, { full: 'realtime'
  , abbr: 'rt'
  , args: false
  , canon: 'realtime'
  }
];

// Parse optsMap and generate options and cmd commands
parser = new parseopts.Parser(optsMap);
parser.parse(args);
cmds = parser.cmds;
opts = parser.opts;

// Set handlebars option to handle option
opts.handle = opts.handlebars || opts.handle;

// Exit the process with a message
die = function (str) {
  console.log(str);
  process.exit();
};

// Start Geddy with options
start = function () {
  geddy.startCluster(opts);
};

if (opts.help) {
  die(usage);
}
if (opts.version) {
  die(geddy.version);
}

// `geddy app foo` or `geddy resource bar` etc. -- run generators
if (cmds.length) {
  // Get templates Jake file
  filepath = path.normalize(path.join(__dirname, '..', 'templates', 'Jakefile'));

  cmd = '';

  // Some commands take only one arg
  if (!(cmds[0] == 'jake' ||
      cmds[0] == 'secret' ||
      cmds[0] == 'db:init' ||
      cmds[0] == 'auth' ||
      cmds[0] == 'auth:update' ||
      cmds[0] == 'console' ||
      cmds[0] == 'routes')
      && !cmds[1]) {
    throw new Error(cmds[0] + ' command requires another argument.');
  }

  // Add engines to command
  if (opts.jade) {
    engineCmd = ',' + 'jade';
  } else if (opts.handle) {
    engineCmd = ',' + 'handlebars';
  } else if (opts.mustache) {
    engineCmd = ',' + 'mustache';
  } else if (opts.swig) {
    engineCmd = ',' + 'swig';
  } else engineCmd = ',default';

  if (opts.realtime) {
    rtCmd = ',' + 'realtime';
  }
  else {
    rtCmd = ',default';
  }

  // Get the model properties
  if (cmds.slice(2).length > 0) {
    modelCmd = ',' + cmds.slice(2).join('%');
  } else modelCmd = '';

  // Add Jake argument based on commands
  switch (cmds[0]) {
    case 'jake':
      cmd = 'jake';
      jakeArgs = cmds.slice(1);
      break;
    case 'console':
      // Start console
      cmd += 'console:start[' + (cmds[1] || 'development') + ']';
      break;
    case 'auth':
      // Create authentication
      cmd += 'auth:init[' + engineCmd.substr(1) + ']';
      break;
    case 'auth:update':
      // Update authentication
      cmd += 'auth:update';
      break;
    case 'db:init':
      // Create DBs
      cmd += 'db:init';
      break;
    case 'db:createTable':
      // Create DBs
      cmd += 'db:createTable[' + cmds[1].replace(/,/g, '%') + ']';
      break;
    case 'app':
      // Generating application
      cmd += 'gen:app[' + cmds[1] + engineCmd + rtCmd + ']';
      break;
    case 'resource':
      // Generating resource
      cmd += 'gen:resource[' + cmds[1] + modelCmd + ']';
      break;
    case 'scaffold':
      // Generating application
      cmd += 'gen:scaffold[' + cmds[1] + rtCmd + engineCmd + modelCmd + ']';
      break;
    case 'controller':
      // Generating controller
      cmd += 'gen:bareController[' + cmds[1] + engineCmd + ']';
      break;
    case 'model':
      // Generating model
      cmd += 'gen:model[' + cmds[1] + modelCmd + ']';
      break;
    case 'secret':
      // Generating new app secret
      cmd += 'gen:secret';
      break;
    case 'routes':
      // Show routes(Optionally empty)
      cmd += 'routes:show[' + (cmds[1] || '') + ']';
      break;
    default:
      die(cmds[0] + ' is not a Geddy command.');
  }

  jake = require('jake');
  jakeProgram = jake.program;
  jakeLoader = jake.loader;
  // Load Geddy's bundled Jakefile
  jakeLoader.loadFile(filepath);
  if (cmd == 'jake') {
    jakeProgram.parseArgs(jakeArgs);
    // Load Jakefile and jakelibdir files for app
    jakeLoader.loadFile(jakeProgram.opts.jakefile);
    jakeLoader.loadDirectory(jakeProgram.opts.jakelibdir);
    // Prepend env:init to load Geddy env
    jakeProgram.taskNames.unshift('env:init');
  }
  else {
    jakeProgram.init({
      quiet: !opts.debug
    , trace: true
    });
    jakeProgram.setTaskNames([cmd]);
  }
  jakeProgram.run();
}
// Just `geddy` -- start the server
else {
  // Search for 'config' directory in parent directories
  utils.file.searchParentPath('config', function (err, filePath) {
    if (err) {
      die(usage);
    }

    start();
  });
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
/**
 * An executable command which will be added to $PATH.
 *
 * @copyright Copyright 2017-2020 Kevin Locke <kevin@kevinlocke.name>
 * @license MIT
 * @module modulename/bin/cmd
 */

'use strict';

const Yargs = require('yargs/yargs');
const packageJson = require('../package.json');
const modulename = require('..');

/** Options for command entry points.
 *
 * @typedef {{
 *   env: !object<string,string>,
 *   stdin: !module:stream.Readable,
 *   stdout: !module:stream.Writable,
 *   stderr: !module:stream.Writable
 * }} CommandOptions
 * @property {!object<string,string>} env Environment variables.
 * @property {!module:stream.Readable} stdin Stream from which input is read.
 * @property {!module:stream.Writable} stdout Stream to which output is
 * written.
 * @property {!module:stream.Writable} stderr Stream to which errors and
 * non-output status messages are written.
 */
// const CommandOptions;

/** Entry point for this command.
 *
 * @param {Array<string>} args Command-line arguments.
 * @param {!CommandOptions} options Options.
 * @param {function(number)} callback Callback with exit code.
 */
function modulenameCmd(args, options, callback) {
  if (typeof callback !== 'function') {
    throw new TypeError('callback must be a function');
  }

  if (args !== undefined
      && args !== null
      && Math.floor(args.length) !== args.length) {
    throw new TypeError('args must be Array-like');
  }

  if (!options || typeof options !== 'object') {
    throw new TypeError('options must be an object');
  }

  if (!options.stdin || typeof options.stdin.on !== 'function') {
    throw new TypeError('options.stdin must be a stream.Readable');
  }
  if (!options.stdout || typeof options.stdout.write !== 'function') {
    throw new TypeError('options.stdout must be a stream.Writable');
  }
  if (!options.stderr || typeof options.stderr.write !== 'function') {
    throw new TypeError('options.stderr must be a stream.Writable');
  }

  if (args.length >= 2) {
    // Strip "node" and script name, ensure args are strings
    args = Array.prototype.slice.call(args, 2).map(String);
  } else {
    args = [];
  }

  const yargs = new Yargs()
    .parserConfiguration({
      'parse-numbers': false,
      'parse-positional-numbers': false,
      'dot-notation': false,
      'duplicate-arguments-array': false,
      'flatten-duplicate-arrays': false,
      'greedy-arrays': false,
    })
    .usage('Usage: $0 [options] [args...]')
    .help()
    .alias('help', 'h')
    .alias('help', '?')
    .option('quiet', {
      alias: 'q',
      describe: 'Print less output',
      count: true,
    })
    .option('verbose', {
      alias: 'v',
      describe: 'Print more output',
      count: true,
    })
    .version(`${packageJson.name} ${packageJson.version}`)
    .alias('version', 'V')
    .strict();
  yargs.parse(args, (errYargs, argOpts, output) => {
    if (errYargs) {
      options.stderr.write(`${output || errYargs}\n`);
      callback(1);
      return;
    }

    if (output) {
      options.stdout.write(`${output}\n`);
    }

    if (argOpts.help || argOpts.version) {
      callback(0);
      return;
    }

    if (argOpts._.length !== 1) {
      options.stderr.write('Error: Exactly one argument is required.\n');
      callback(1);
      return;
    }

    // Parse arguments then call API function with parsed options
    const cmdOpts = {
      files: argOpts._,
      verbosity: argOpts.verbose - argOpts.quiet,
    };
    // eslint-disable-next-line promise/catch-or-return
    modulename.func(cmdOpts)
      .then(
        () => 0,
        (err) => {
          options.stderr.write(`${err}\n`);
          return 1;
        },
      )
      // Note: nextTick for unhandledException (like util.callbackify)
      .then((exitCode) => process.nextTick(callback, exitCode));
  });
}

modulenameCmd.default = modulenameCmd;
module.exports = modulenameCmd;

if (require.main === module) {
  // This file was invoked directly.
  // Note:  Could pass process.exit as callback to force immediate exit.
  modulenameCmd(process.argv, process, (exitCode) => {
    process.exitCode = exitCode;
  });
}
<commit_msg>Don't return aliased or dashed option properties<commit_after>#!/usr/bin/env node
/**
 * An executable command which will be added to $PATH.
 *
 * @copyright Copyright 2017-2020 Kevin Locke <kevin@kevinlocke.name>
 * @license MIT
 * @module modulename/bin/cmd
 */

'use strict';

const Yargs = require('yargs/yargs');
const packageJson = require('../package.json');
const modulename = require('..');

/** Options for command entry points.
 *
 * @typedef {{
 *   env: !object<string,string>,
 *   stdin: !module:stream.Readable,
 *   stdout: !module:stream.Writable,
 *   stderr: !module:stream.Writable
 * }} CommandOptions
 * @property {!object<string,string>} env Environment variables.
 * @property {!module:stream.Readable} stdin Stream from which input is read.
 * @property {!module:stream.Writable} stdout Stream to which output is
 * written.
 * @property {!module:stream.Writable} stderr Stream to which errors and
 * non-output status messages are written.
 */
// const CommandOptions;

/** Entry point for this command.
 *
 * @param {Array<string>} args Command-line arguments.
 * @param {!CommandOptions} options Options.
 * @param {function(number)} callback Callback with exit code.
 */
function modulenameCmd(args, options, callback) {
  if (typeof callback !== 'function') {
    throw new TypeError('callback must be a function');
  }

  if (args !== undefined
      && args !== null
      && Math.floor(args.length) !== args.length) {
    throw new TypeError('args must be Array-like');
  }

  if (!options || typeof options !== 'object') {
    throw new TypeError('options must be an object');
  }

  if (!options.stdin || typeof options.stdin.on !== 'function') {
    throw new TypeError('options.stdin must be a stream.Readable');
  }
  if (!options.stdout || typeof options.stdout.write !== 'function') {
    throw new TypeError('options.stdout must be a stream.Writable');
  }
  if (!options.stderr || typeof options.stderr.write !== 'function') {
    throw new TypeError('options.stderr must be a stream.Writable');
  }

  if (args.length >= 2) {
    // Strip "node" and script name, ensure args are strings
    args = Array.prototype.slice.call(args, 2).map(String);
  } else {
    args = [];
  }

  const yargs = new Yargs()
    .parserConfiguration({
      'parse-numbers': false,
      'parse-positional-numbers': false,
      'dot-notation': false,
      'duplicate-arguments-array': false,
      'flatten-duplicate-arrays': false,
      'greedy-arrays': false,
      'strip-aliased': true,
      'strip-dashed': true,
    })
    .usage('Usage: $0 [options] [args...]')
    .help()
    .alias('help', 'h')
    .alias('help', '?')
    .option('quiet', {
      alias: 'q',
      describe: 'Print less output',
      count: true,
    })
    .option('verbose', {
      alias: 'v',
      describe: 'Print more output',
      count: true,
    })
    .version(`${packageJson.name} ${packageJson.version}`)
    .alias('version', 'V')
    .strict();
  yargs.parse(args, (errYargs, argOpts, output) => {
    if (errYargs) {
      options.stderr.write(`${output || errYargs}\n`);
      callback(1);
      return;
    }

    if (output) {
      options.stdout.write(`${output}\n`);
    }

    if (argOpts.help || argOpts.version) {
      callback(0);
      return;
    }

    if (argOpts._.length !== 1) {
      options.stderr.write('Error: Exactly one argument is required.\n');
      callback(1);
      return;
    }

    // Parse arguments then call API function with parsed options
    const cmdOpts = {
      files: argOpts._,
      verbosity: argOpts.verbose - argOpts.quiet,
    };
    // eslint-disable-next-line promise/catch-or-return
    modulename.func(cmdOpts)
      .then(
        () => 0,
        (err) => {
          options.stderr.write(`${err}\n`);
          return 1;
        },
      )
      // Note: nextTick for unhandledException (like util.callbackify)
      .then((exitCode) => process.nextTick(callback, exitCode));
  });
}

modulenameCmd.default = modulenameCmd;
module.exports = modulenameCmd;

if (require.main === module) {
  // This file was invoked directly.
  // Note:  Could pass process.exit as callback to force immediate exit.
  modulenameCmd(process.argv, process, (exitCode) => {
    process.exitCode = exitCode;
  });
}
<|endoftext|>