<commit_before>/*eslint strict:0*/
var childProcess = require('child_process');
var os = require('os');
var fs = require('fs');
var net = require('net');
var path = require('path');
var exec = childProcess.exec;

/* App Name */
/* -------- */
// Be sure to change this or your data might be stored
// somewhere you don't want it to be.
var appName = 'GrandView';

var app = require('app'); // Module to control application life.
var BrowserWindow = require('browser-window'); // Module to create native browser window.

var dirname = __dirname;
console.log(dirname); // The name of the directory that the currently executing script resides in.

// Before starting a local server, freePort will find an available port by letting
// the OS find it.
function freePort (callback) {
  var server = net.createServer();
  var port = 0;

  server.on('listening', function () {
    port = server.address().port;
    server.close();
  });
  server.on('close', function () {
    callback(null, port);
  });

  server.listen(0, '127.0.0.1');
}

// Write something about Start method
function start (callback) {
  if (process.env.NODE_ENV === 'development') {
    console.log('Running in Dev mode.');
    callback('http://localhost:3000');
  } else {
    process.stdout.write('Starting production server\n');

    var appPath = '',
        dataPath = '',
        bundlePath = '';
    if (os.platform() === 'darwin') {
      appPath = path.join(process.env.HOME, 'Library/Application Support/', appName, '/');
      dataPath = path.join(appPath, 'data');
      bundlePath = path.join(appPath, 'bundle');
    } else if (os.platform() === 'win32') {
      appPath = path.join(process.env.HOMEPATH, 'AppData/Local/', appName, '/');
      dataPath = path.join(appPath, 'data');
      bundlePath = path.join(appPath, 'bundle');
    } else if (os.platform() === 'linux') {
      appPath = path.join(process.env.HOME, '/.config/', appName, '/');
      dataPath = path.join(appPath, 'data');
      bundlePath = path.join(appPath, 'bundle');
    }

    // If file paths don't yet exist, create them
    if (!fs.existsSync(appPath)) {
      fs.mkdirSync(appPath);
    }

    if (!fs.existsSync(dataPath)) {
      fs.mkdirSync(dataPath);
    }

    if (!fs.existsSync(bundlePath)) {
      fs.mkdirSync(bundlePath);
    }

    freePort(function (err, webPort) {
      freePort(function (err, mongoPort) {
        console.log('MongoPort: ', mongoPort);
        console.log('WebPort: ', webPort);

        // Be sure to change the PURPOSE to be the name of your app
        var command = '';
        if (os.platform() === 'darwin' || os.platform === 'linux') {
          command = 'rm -rf ' + path.join(dataPath, 'mongod.lock');
        } else if (os.platform() === 'win32') {
          childProcess.exec('rm -rf ' + path.join(dataPath, 'mongod.lock'));
        }

        childProcess.exec(command, function (err, stdout, stderr) {

          // Path to mongod command bundled with app.
          var mongodPath = path.join(dirname, 'resources', 'mongod');

          // Arguments passed to mongod command.
          var mongodArgs = ['--bind_ip', '127.0.0.1', '--dbpath', dataPath, '--port', mongoPort, '--unixSocketPrefix', dataPath, '--smallfiles'];
          if (os.platform() === 'win32') {
            mongodArgs = ['--bind_ip', '127.0.0.1', '--dbpath', dataPath, '--port', mongoPort, '--smallfiles'];
          }

          // Start the Mongo process.
          var mongoChild = childProcess.spawn(mongodPath, mongodArgs, {
            env: {
              PURPOSE: 'MY_ELECTROMETEOR_APP'
            }
          });

          mongoChild.stderr.setEncoding('utf8');
          mongoChild.stderr.on('data', function (data) {
            console.log(data);
          });

          var started = false;
          mongoChild.stdout.setEncoding('utf8');
          mongoChild.stdout.on('data', function (data) {
            console.log(data);

            if (data.indexOf('waiting for connections on port ' + mongoPort)) {
              if (!started) {
                started = true;
              } else {
                return;
              }

              console.log('Starting node child...');
              var rootURL = 'http://localhost';
              var userEnv = process.env;
              userEnv.ROOT_URL = rootURL;
              userEnv.PORT = webPort;
              userEnv.BIND_IP = '127.0.0.1';
              userEnv.DB_PATH = dataPath;
              userEnv.MONGO_URL = 'mongodb://localhost:' + mongoPort + '/meteor';
              // user_env.METEOR_SETTINGS = fs.readFileSync(path.join(dirname, 'resources', 'settings.json'), 'utf8');
              userEnv.DIR = dirname;
              userEnv.NODE_ENV = 'production';
              userEnv.NODE_PATH = path.join(dirname, 'node_modules');

              var nodePath = path.join(dirname, 'resources', 'node');
              var nodeArgs = path.join(dirname, 'bundle', 'main.js');
              var nodeChild = childProcess.spawn(nodePath, [nodeArgs], {
                env: userEnv
              });

              var opened = false;

              // listen for errors
              nodeChild.stderr.setEncoding('utf8');
              nodeChild.stderr.on('data', function (nodeData) {
                console.log('stderr: ', nodeData);
              });

              nodeChild.stdout.setEncoding('utf8');
              nodeChild.stdout.on('data', function (nodeData) {
                console.log(nodeData);

                if (data.indexOf(!'Meteor app started.' === -1)) {
                  if (!opened) {
                    opened = true;
                  } else {
                    return;
                  }

                  setTimeout(function () {
                    var fullURL = rootURL + ':' + webPort;
                    callback(fullURL, nodeChild, mongoChild);
                  }, 100);
                }
              });
            }
          });
        });
      });
    });
  }
}

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the javascript object is GCed.

/*global mainWindow:true*/ // <-- This is to let ESLint know that it's ok to have a global and 'true' allows it to be read/write
mainWindow = null;

// Emitted when the application is activated while there is no opened windows.
// It usually happens when a user has closed all of application's windows and then
// click on the application's dock icon.
app.on('activate-with-no-open-windows', function () {
  if (mainWindow) {
    mainWindow.show();
  }

  return false;
});

// Emitted when Electron has done all of the initialization.
app.on('ready', function () {
  start(function (url, nodeChild, mongoChild) {
    console.log('App occupying ', url);
    var cleanup = function () {
      app.quit();
    };
    // Create the browser window.
    var windowOptions = {
      width: 1024,
      height: 800,
      resizeable: true,
      frame: true
    };
    mainWindow = new BrowserWindow(windowOptions);
    mainWindow.focus();
    mainWindow.loadUrl(url);

    process.on('uncaughtException', cleanup);

    // Emitted when all windows have been closed and the application will quit.
    // Calling event.preventDefault() will prevent the default behaviour, which is
    // terminating the application.
    app.on('will-quit', function (event) {
      console.log(event);
      console.log('Cleaning up children.');

      if (nodeChild) {
        console.log('cleaning up node child');
        nodeChild.kill('SIGTERM');
      }

      if (mongoChild) {
        console.log('cleaning up mongo child');
        mongoChild.kill('SIGTERM');
      }

    });

    app.on('window-all-closed', function() {
      cleanup();
    });
  });
});
<commit_msg>Creates a larger app window.<commit_after>/*eslint strict:0*/
var childProcess = require('child_process');
var os = require('os');
var fs = require('fs');
var net = require('net');
var path = require('path');
var exec = childProcess.exec;

/* App Name */
/* -------- */
// Be sure to change this or your data might be stored
// somewhere you don't want it to be.
var appName = 'GrandView';

var app = require('app'); // Module to control application life.
var BrowserWindow = require('browser-window'); // Module to create native browser window.

var dirname = __dirname;
console.log(dirname); // The name of the directory that the currently executing script resides in.

// Before starting a local server, freePort will find an available port by letting
// the OS find it.
function freePort (callback) {
  var server = net.createServer();
  var port = 0;

  server.on('listening', function () {
    port = server.address().port;
    server.close();
  });
  server.on('close', function () {
    callback(null, port);
  });

  server.listen(0, '127.0.0.1');
}

// Write something about Start method
function start (callback) {
  if (process.env.NODE_ENV === 'development') {
    console.log('Running in Dev mode.');
    callback('http://localhost:3000');
  } else {
    process.stdout.write('Starting production server\n');

    var appPath = '',
        dataPath = '',
        bundlePath = '';
    if (os.platform() === 'darwin') {
      appPath = path.join(process.env.HOME, 'Library/Application Support/', appName, '/');
      dataPath = path.join(appPath, 'data');
      bundlePath = path.join(appPath, 'bundle');
    } else if (os.platform() === 'win32') {
      appPath = path.join(process.env.HOMEPATH, 'AppData/Local/', appName, '/');
      dataPath = path.join(appPath, 'data');
      bundlePath = path.join(appPath, 'bundle');
    } else if (os.platform() === 'linux') {
      appPath = path.join(process.env.HOME, '/.config/', appName, '/');
      dataPath = path.join(appPath, 'data');
      bundlePath = path.join(appPath, 'bundle');
    }

    // If file paths don't yet exist, create them
    if (!fs.existsSync(appPath)) {
      fs.mkdirSync(appPath);
    }

    if (!fs.existsSync(dataPath)) {
      fs.mkdirSync(dataPath);
    }

    if (!fs.existsSync(bundlePath)) {
      fs.mkdirSync(bundlePath);
    }

    freePort(function (err, webPort) {
      freePort(function (err, mongoPort) {
        console.log('MongoPort: ', mongoPort);
        console.log('WebPort: ', webPort);

        // Be sure to change the PURPOSE to be the name of your app
        var command = '';
        if (os.platform() === 'darwin' || os.platform === 'linux') {
          command = 'rm -rf ' + path.join(dataPath, 'mongod.lock');
        } else if (os.platform() === 'win32') {
          childProcess.exec('rm -rf ' + path.join(dataPath, 'mongod.lock'));
        }

        childProcess.exec(command, function (err, stdout, stderr) {

          // Path to mongod command bundled with app.
          var mongodPath = path.join(dirname, 'resources', 'mongod');

          // Arguments passed to mongod command.
          var mongodArgs = ['--bind_ip', '127.0.0.1', '--dbpath', dataPath, '--port', mongoPort, '--unixSocketPrefix', dataPath, '--smallfiles'];
          if (os.platform() === 'win32') {
            mongodArgs = ['--bind_ip', '127.0.0.1', '--dbpath', dataPath, '--port', mongoPort, '--smallfiles'];
          }

          // Start the Mongo process.
          var mongoChild = childProcess.spawn(mongodPath, mongodArgs, {
            env: {
              PURPOSE: 'MY_ELECTROMETEOR_APP'
            }
          });

          mongoChild.stderr.setEncoding('utf8');
          mongoChild.stderr.on('data', function (data) {
            console.log(data);
          });

          var started = false;
          mongoChild.stdout.setEncoding('utf8');
          mongoChild.stdout.on('data', function (data) {
            console.log(data);

            if (data.indexOf('waiting for connections on port ' + mongoPort)) {
              if (!started) {
                started = true;
              } else {
                return;
              }

              console.log('Starting node child...');
              var rootURL = 'http://localhost';
              var userEnv = process.env;
              userEnv.ROOT_URL = rootURL;
              userEnv.PORT = webPort;
              userEnv.BIND_IP = '127.0.0.1';
              userEnv.DB_PATH = dataPath;
              userEnv.MONGO_URL = 'mongodb://localhost:' + mongoPort + '/meteor';
              // user_env.METEOR_SETTINGS = fs.readFileSync(path.join(dirname, 'resources', 'settings.json'), 'utf8');
              userEnv.DIR = dirname;
              userEnv.NODE_ENV = 'production';
              userEnv.NODE_PATH = path.join(dirname, 'node_modules');

              var nodePath = path.join(dirname, 'resources', 'node');
              var nodeArgs = path.join(dirname, 'bundle', 'main.js');
              var nodeChild = childProcess.spawn(nodePath, [nodeArgs], {
                env: userEnv
              });

              var opened = false;

              // listen for errors
              nodeChild.stderr.setEncoding('utf8');
              nodeChild.stderr.on('data', function (nodeData) {
                console.log('stderr: ', nodeData);
              });

              nodeChild.stdout.setEncoding('utf8');
              nodeChild.stdout.on('data', function (nodeData) {
                console.log(nodeData);

                if (data.indexOf(!'Meteor app started.' === -1)) {
                  if (!opened) {
                    opened = true;
                  } else {
                    return;
                  }

                  setTimeout(function () {
                    var fullURL = rootURL + ':' + webPort;
                    callback(fullURL, nodeChild, mongoChild);
                  }, 100);
                }
              });
            }
          });
        });
      });
    });
  }
}

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the javascript object is GCed.

/*global mainWindow:true*/ // <-- This is to let ESLint know that it's ok to have a global and 'true' allows it to be read/write
mainWindow = null;

// Emitted when the application is activated while there is no opened windows.
// It usually happens when a user has closed all of application's windows and then
// click on the application's dock icon.
app.on('activate-with-no-open-windows', function () {
  if (mainWindow) {
    mainWindow.show();
  }

  return false;
});

// Emitted when Electron has done all of the initialization.
app.on('ready', function () {
  start(function (url, nodeChild, mongoChild) {
    console.log('App occupying ', url);
    var cleanup = function () {
      app.quit();
    };
    // Create the browser window.
    var windowOptions = {
      width: 1200,
      height: 800,
      resizeable: true,
      frame: true
    };
    mainWindow = new BrowserWindow(windowOptions);
    mainWindow.focus();
    mainWindow.loadUrl(url);

    process.on('uncaughtException', cleanup);

    // Emitted when all windows have been closed and the application will quit.
    // Calling event.preventDefault() will prevent the default behaviour, which is
    // terminating the application.
    app.on('will-quit', function (event) {
      console.log(event);
      console.log('Cleaning up children.');

      if (nodeChild) {
        console.log('cleaning up node child');
        nodeChild.kill('SIGTERM');
      }

      if (mongoChild) {
        console.log('cleaning up mongo child');
        mongoChild.kill('SIGTERM');
      }

    });

    app.on('window-all-closed', function() {
      cleanup();
    });
  });
});
<|endoftext|>


<commit_before>(function (Vue, Clipboard) {

  'use strict';

  var parseArray = function (array, fn) {
    return array.map(fn).join('');
  };

  var parse = function (option) {
    return '
' +
      '
' +
      '
' +
      '
' +
      '        Web Weekly #' + option.number +
      '
' +
      '
' +
      '
' +
      '          Web 组同学们~' +
      '
' +
      '
' +
      '          Web 组第' + option.number + '期周报出炉了~' +
      '
' +
      '
' +
      '          本期热点:' +
      '
' +
      '
' +
      parseArray(option.topics, function (topic) {
        return '
' + topic.title + ' ' + topic.description + '
';
      }) +
      '
' +
      '            ......' +
      '
' +
      '
' +
      '
' +
      '          编辑: ' + option.editor + ';
' +
      '          投稿:' +
      parseArray(option.volunteers, function (volunteer, volunteerIndex) {
        return ' ' + volunteer.name + '' + (
          volunteerIndex === option.volunteers.length - 1 ? '.' : ','
        );
      }) +
      '
' +
      '
' +
      '          点此阅读' +
      '
' +
      '
' +
      '
' +
      '
' + option.body + '
' +
      '
' + option.sender + '
' + option.date + '
' +
      '
' +
      '
' +
      '        长期广告位:' +
      '        周报投稿/建议' +
      '        项目建立/加入' +
      '        提问/分享' +
      '
' +
      '
' +
      '
' +
      '          东岳网络工作室 - Web 组' +
      '
' +
      '
' +
      '          Questions? Email web@dongyue.io' +
      '
' +
      '
' +
      '
' +
      '
' +
      '
';
  };

  Vue.filter('parse', parse);

  var weekly = {
    number: '',
    url: '',
    topics: [{title: '', description: ''}],
    editor: '',
    volunteers: [{name: ''}],
    body: '',
    sender: '',
    date: ''
  };

  new Vue({
    el: '#template-box',
    data: {
      weekly: weekly
    },
    methods: {
      remove: function (array, $index) {
        array.splice($index, 1);
      }
    }
  });

  new Clipboard('#weekly-copy-html', {
    text: function (trigger) {
      trigger.innerText = 'Copied';
      setTimeout(function () {
        trigger.innerText = 'Copy HTML';
      }, 800);
      return parse(weekly);
    }
  });

})(window.Vue, window.Clipboard);
<commit_msg>Remove redunt spaces<commit_after>(function (Vue, Clipboard) {

  'use strict';

  var parseArray = function (array, fn) {
    return array.map(fn).join('');
  };

  var parse = function (option) {
    return '
' +
      '
' +
        '
' +
          '
' +
            'Web Weekly #' + option.number +
          '
' +
          '
' +
            '
Web 组同学们~
' +
            '
Web 组第' + option.number + '期周报出炉了~
' +
            '
本期热点:
' +
            '
' +
              parseArray(option.topics, function (topic) {
                return '
' + topic.title + ' ' + topic.description + '
';
              }) +
              '
......
' +
            '
' +
            '
' +
              '编辑: ' + option.editor + ';
' +
              '投稿:' +
              parseArray(option.volunteers, function (volunteer, volunteerIndex) {
                return ' ' + volunteer.name + '' + (
                  volunteerIndex === option.volunteers.length - 1 ? '.' : ','
                );
              }) +
            '
' +
            '
点此阅读
' +
          '
' +
          '
' +
            '
' + option.body + '
' +
            '
' + option.sender + '
' + option.date + '
' +
          '
' +
          '
' +
            '长期广告位:' +
            '周报投稿/建议' +
            '项目建立/加入' +
            '提问/分享' +
          '
' +
          '
' +
            '
东岳网络工作室 - Web 组
' +
            '
Questions? Email web@dongyue.io
' +
          '
' +
        '
' +
      '
' +
    '
';
  };

  Vue.filter('parse', parse);

  var weekly = {
    number: '',
    url: '',
    topics: [{title: '', description: ''}],
    editor: '',
    volunteers: [{name: ''}],
    body: '',
    sender: '',
    date: ''
  };

  new Vue({
    el: '#template-box',
    data: {
      weekly: weekly
    },
    methods: {
      remove: function (array, $index) {
        array.splice($index, 1);
      }
    }
  });

  new Clipboard('#weekly-copy-html', {
    text: function (trigger) {
      trigger.innerText = 'Copied';
      setTimeout(function () {
        trigger.innerText = 'Copy HTML';
      }, 800);
      return parse(weekly);
    }
  });

})(window.Vue, window.Clipboard);
<|endoftext|>


<commit_before>var request = require('request');
var cheerio = require('cheerio');
var S = require('string');

var self = module.exports;

self.getShows = function(options, callback) {

	request("http://eztv.it/showlist/", function (error, response, body) {

		if (!error && response.statusCode == 200) {

			var list = [];
			var $ = cheerio.load(body);
			var $elements = $("table.forum_header_border tr[name=hover]");
			$elements.each(function(i, e) {

				var show = {};
				show.url = $(e).find("td").eq(0).find("a").attr("href");
				var regex = show.url.match(/\/shows\/(\d+)\/([^\/]+)/);
				show.id = parseInt(regex[1]);
				show.slug = regex[2];

				var title = $(e).find("td").eq(0).text();
				if (S(title).endsWith(", The")) {
					title = "The " + S(title).chompRight(", The").s;
				}
				show.title = title;
				show.status = $(e).find("td").eq(1).find("font").attr("class");

				if (options && options.query) {
					if (show.title.toLowerCase().search(options.query.toLowerCase()) >= 0) {
						//console.log(show.title);
						list.push(show);
					}
				}
				else {
					list.push(show);
				}

			});

			if (callback) callback(null, list);

		}
		else {
			if (callback) callback(new Error("Error getting shows"), null);
		}
	});

};

self.getShowEpisodes = function(showId, callback) {

	request("http://eztv.it/shows/" + showId + "/", function (error, response, body) {

		if (!error && response.statusCode == 200) {

			var list = [];
			var $ = cheerio.load(body);
			var $elements = $("table.forum_header_noborder tr[name=hover]");
			$elements.each(function(i, e) {

				var episode = {};

				episode.url = $(e).find("td").eq(1).find("a").attr("href");
				var urlRegex = episode.url.match(/\/ep\/(\d+)\/.*/);
				episode.id = parseInt(urlRegex[1]);

				episode.title = $(e).find("td").eq(1).find("a").text();
				var titleRegex = episode.title.match(/(.+) S?(\d+)[Ex](\d+)(.*)/);
				if (titleRegex) {
					episode.show = titleRegex[1];
					episode.seasonNumber = parseInt(titleRegex[2]);
					episode.episodeNumber = parseInt(titleRegex[3]);
					episode.extra = titleRegex[4].trim();
				}
				else {
					console.log("unparsed episode: " + episode.title);
				}

				episode.magnet = $(e).find("td").eq(2).find("a.magnet").attr("href");
				episode.torrentURL = $(e).find("td").eq(2).find("a.download_1").attr("href");

				list.push(episode);

			});

			if (callback) callback(null, list);

		}
		else {
			if (callback) callback(new Error("Error getting show episodes"), null);
		}
	});

}

<commit_msg>return show title with episodes<commit_after>var request = require('request');
var cheerio = require('cheerio');
var S = require('string');

var self = module.exports;

self.getShows = function(options, callback) {

	request("http://eztv.it/showlist/", function (error, response, body) {

		if (!error && response.statusCode == 200) {

			var list = [];
			var $ = cheerio.load(body);
			var $elements = $("table.forum_header_border tr[name=hover]");
			$elements.each(function(i, e) {

				var show = {};
				show.url = $(e).find("td").eq(0).find("a").attr("href");
				var regex = show.url.match(/\/shows\/(\d+)\/([^\/]+)/);
				show.id = parseInt(regex[1]);
				show.slug = regex[2];

				var title = $(e).find("td").eq(0).text();
				if (S(title).endsWith(", The")) {
					title = "The " + S(title).chompRight(", The").s;
				}
				show.title = title;
				show.status = $(e).find("td").eq(1).find("font").attr("class");

				if (options && options.query) {
					if (show.title.toLowerCase().search(options.query.toLowerCase()) >= 0) {
						//console.log(show.title);
						list.push(show);
					}
				}
				else {
					list.push(show);
				}

			});

			if (callback) callback(null, list);

		}
		else {
			if (callback) callback(new Error("Error getting shows"), null);
		}
	});

};

self.getShowEpisodes = function(showId, callback) {

	request("http://eztv.it/shows/" + showId + "/", function (error, response, body) {

		if (!error && response.statusCode == 200) {

			var result = {
				episodes: []
			};

			var $ = cheerio.load(body);
			result.title = $("td.section_post_header").eq(0).find("b").text();

			var $episodes = $("table.forum_header_noborder tr[name=hover]");
			$episodes.each(function(i, e) {

				var episode = {};

				episode.url = $(e).find("td").eq(1).find("a").attr("href");
				var urlRegex = episode.url.match(/\/ep\/(\d+)\/.*/);
				episode.id = parseInt(urlRegex[1]);

				episode.title = $(e).find("td").eq(1).find("a").text();
				var titleRegex = episode.title.match(/(.+) S?(\d+)[Ex](\d+)(.*)/);
				if (titleRegex) {
					episode.show = titleRegex[1];
					episode.seasonNumber = parseInt(titleRegex[2]);
					episode.episodeNumber = parseInt(titleRegex[3]);
					episode.extra = titleRegex[4].trim();
				}
				else {
					console.log("unparsed episode: " + episode.title);
				}

				episode.magnet = $(e).find("td").eq(2).find("a.magnet").attr("href");
				episode.torrentURL = $(e).find("td").eq(2).find("a.download_1").attr("href");

				result.episodes.push(episode);

			});

			if (callback) callback(null, result);

		}
		else {
			if (callback) callback(new Error("Error getting show episodes"), null);
		}
	});

}

<|endoftext|>


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

var path     = require('path')
var rc       = require('rc')
var optimist = require('optimist')
var toCC     = require('to-camel-case')
var osenv    = require('osenv')

var home     = osenv.home()
var tmp      = osenv.tmpdir()

var config = module.exports = (function () {
  // *** vvv Copied this stuff out of npmconf **********************
  var uidOrPid = process.getuid ? process.getuid() : process.pid

  if (home) process.env.HOME = home
  else home = path.resolve(temp, "npm-" + uidOrPid)

  var cacheExtra = process.platform === "win32" ? "npm-cache" : ".npm"
  var cacheRoot = process.platform === "win32" && process.env.APPDATA || home
  var cache = path.resolve(cacheRoot, cacheExtra)
  // *** ^^^ Copied this stuff out of npmconf **********************

  var config = rc('npmd', {
    dbPath: path.join(process.env.HOME, '.npmd'),
    debug: true,
    sync: false,
    encoding: 'json',
    registry: 'http://isaacs.iriscouch.com/registry',
    cache: cache,
    "user-agent" : "node/" + process.version
                 + ' ' + process.platform
                 + ' ' + process.arch,
    prefix: (
      process.env.PREFIX ||
      ( process.platform === 'win32' ? path.dirname(process.execPath)
      : path.dirname(path.dirname(process.execPath)))
    ),
    port: 5656
  },
  optimist
    .alias('g', 'global')
    .alias('f', 'force')
    .alias('D', 'saveDev')
    .alias('S', 'save')
    .alias('v', 'version')
    .boolean('global')
    .boolean('online')
    .boolean('offline')
    .boolean('save-dev')
    .boolean('saveDev')
    .boolean('save-peer')
    .boolean('savePeer')
    .boolean('save')
    .argv
  )

  config.bin = config.bin ||
  ( config.global ? path.join(config.prefix, 'bin')
  : path.join(config.path || process.cwd(), 'node_modules', '.bin'))

  if(!config.path && config.global)
    config.path = config.prefix

  for(var k in config)
    config[toCC(k)] = config[k]

  if(config.showConfig)
    console.log(JSON.stringify(config, null, 2))

  return config
})()

if(!module.parent)
  console.log(JSON.stringify(config, null, 2))
<commit_msg>install global modules into $PREFIX/lib like npm<commit_after>#! /usr/bin/env node

var path     = require('path')
var rc       = require('rc')
var optimist = require('optimist')
var toCC     = require('to-camel-case')
var osenv    = require('osenv')

var home     = osenv.home()
var tmp      = osenv.tmpdir()

var config = module.exports = (function () {
  // *** vvv Copied this stuff out of npmconf **********************
  var uidOrPid = process.getuid ? process.getuid() : process.pid

  if (home) process.env.HOME = home
  else home = path.resolve(temp, "npm-" + uidOrPid)

  var cacheExtra = process.platform === "win32" ? "npm-cache" : ".npm"
  var cacheRoot = process.platform === "win32" && process.env.APPDATA || home
  var cache = path.resolve(cacheRoot, cacheExtra)
  // *** ^^^ Copied this stuff out of npmconf **********************

  var config = rc('npmd', {
    dbPath: path.join(process.env.HOME, '.npmd'),
    debug: true,
    sync: false,
    encoding: 'json',
    registry: 'http://isaacs.iriscouch.com/registry',
    cache: cache,
    "user-agent" : "node/" + process.version
                 + ' ' + process.platform
                 + ' ' + process.arch,
    prefix: (
      process.env.PREFIX ||
      ( process.platform === 'win32' ? path.dirname(process.execPath)
      : path.dirname(path.dirname(process.execPath)))
    ),
    port: 5656
  },
  optimist
    .alias('g', 'global')
    .alias('f', 'force')
    .alias('D', 'saveDev')
    .alias('S', 'save')
    .alias('v', 'version')
    .boolean('global')
    .boolean('online')
    .boolean('offline')
    .boolean('save-dev')
    .boolean('saveDev')
    .boolean('save-peer')
    .boolean('savePeer')
    .boolean('save')
    .argv
  )

  config.bin = config.bin ||
  ( config.global ? path.join(config.prefix, 'bin')
  : path.join(config.path || process.cwd(), 'node_modules', '.bin'))

  if(!config.path && config.global)
    config.path = path.join(config.prefix, 'lib')

  for(var k in config)
    config[toCC(k)] = config[k]

  if(config.showConfig)
    console.log(JSON.stringify(config, null, 2))

  return config
})()

if(!module.parent)
  console.log(JSON.stringify(config, null, 2))
<|endoftext|>


<commit_before>var fs = require('fs')
  , spawn = require('child_process').spawn;

/**
 * Create a log parser.
 *
 * @param {String} format
 * @api public
 */

var Parser = module.exports = function (format) {
    this.parser = format;
    this.directives = {};

    var directive = /\$([a-z_]+)(.)?([^\$]+)?/g
      , match, regex, boundary, i = 1;

    while ((match = directive.exec(format))) {
        this.directives[match[1]] = i++;
        if (match[2]) {
            boundary = this.escape(match[2]);
            regex = '([^' + boundary + ']+)' + boundary;
            if (match[3]) {
                regex += this.escape(match[3]);
            }
        } else {
            regex = '(.+)$';
        }
        this.parser = this.parser.replace(match[0], regex);
    }

    this.parser = new RegExp(this.parser);
};

/**
 * Parse a log file.
 *
 * @param {String} path
 * @param {Object} options (optional)
 * @param {Function} callback
 * @api public
 */

Parser.prototype.read = function (path, options, callback) {
    if (!path || path === '-') {
        return this.stdin(callback);
    } else if (options.tail) {
        return this.tail(path, callback);
    }
    return this.stream(fs.createReadStream(path), callback);
};

/**
 * Parse a log file and watch it for changes.
 *
 * @param {String} path
 * @param {Function} callback
 * @api public
 */

Parser.prototype.tail = function (path, callback) {
    var stream = spawn('tail', [ '-F', '-c', '+0', path]).stdout;
    return this.stream(stream, callback);
};

/**
 * Parse a log stream from STDIN.
 *
 * @param {Function} callback
 * @api public
 */

Parser.prototype.stdin = function (callback) {
    return this.stream(process.stdin, callback);
};

/**
 * Parse a log stream.
 *
 * @param {ReadableStream} stream
 * @param {Function} callback
 * @api public
 */

Parser.prototype.stream = function (stream, callback) {
    var self = this, overflow = new Buffer(0);
    stream.on('data', function (data) {
        var buffer = overflow.concat(data), newline = 0;
        for (var i = 0, len = buffer.length; i < len; i++) {
            if (buffer[i] === 10) {
                self.parseLine(buffer.slice(newline, i), callback, stream);
                newline = i + 1;
            }
        }
        overflow = buffer.slice(newline);
    });
    stream.on('end', function () {
        if (overflow.length) {
            self.parseLine(overflow, callback, stream);
        }
    });
    process.nextTick(function () {
        stream.resume();
    });
    return stream;
};

/**
 * Parse a log line.
 *
 * @param {Buffer|String} line
 * @param {Function} callback
 * @api private
 */

Parser.prototype.parseLine = function (line, callback) {
    var match = line.toString().match(this.parser)

    if (!match) return;

    var row = {
        msec: null
      , time_iso8601: null
      , remote_addr: null
      , query_string: null
      , http_x_forwarded_for: null
      , http_user_agent: null
      , http_referer: null
      , time_local: null
      , request: null
      , status: null
      , request_time: null
      , request_length: null
      , pipe: null
      , connection: null
      , bytes_sent: null
      , body_bytes_sent: null

      , date: null
      , timestamp: null
      , ip: null
      , ip_str: null
    };

    for (var key in this.directives) {
        row[key] = match[this.directives[key]];
        if (row[key] === '-') {
            row[key] = null;
        }
    }

    //Parse the timestamp
    if (row.time_iso8601) {
        row.date = new Date(row.time_iso8601);
    } else if (row.msec) {
        row.date = new Date(Number(row.msec.replace('.', '')));
    }
    if (row.date) {
        row.timestamp = row.date.getTime();
    }

    //Parse the user's IP
    if (row.http_x_forwarded_for) {
        row.ip_str = row.http_x_forwarded_for;
    } else if (row.remote_addr) {
        row.ip_str = row.remote_addr;
    }
    if (row.ip_str) {
        var ip = row.ip_str.split('.', 4);
        row.ip = Number(ip[0]) * (2 << 23)
               + Number(ip[1]) * (2 << 15)
               + Number(ip[2]) * (2 << 7)
               + Number(ip[3]);
    }

    callback(row);
};

/**
 * Escape regular expression tokens.
 *
 * @param {String} str
 * @return {String}
 * @api private
 */

Parser.prototype.escape = function (str) {
    return str.replace(new RegExp('[.*+?|()\\[\\]{}]', 'g'), '\\$&');
};

<commit_msg>Lint and cleanup<commit_after>var fs = require('fs')
  , spawn = require('child_process').spawn;

/**
 * Create a log parser.
 *
 * @param {String} format
 */

var Parser = module.exports = function (format) {
    this.parser = format;
    this.directives = {};

    var directive = /\$([a-z_]+)(.)?([^\$]+)?/g
      , match, regex, boundary, i = 1;

    while ((match = directive.exec(format))) {
        this.directives[match[1]] = i++;
        if (match[2]) {
            boundary = this.escape(match[2]);
            regex = '([^' + boundary + ']+)' + boundary;
            if (match[3]) {
                regex += this.escape(match[3]);
            }
        } else {
            regex = '(.+)$';
        }
        this.parser = this.parser.replace(match[0], regex);
    }

    this.parser = new RegExp(this.parser);
};

/**
 * Parse a log file.
 *
 * @param {String} path
 * @param {Object} options (optional)
 * @param {Function} callback
 */

Parser.prototype.read = function (path, options, callback) {
    if (!path || path === '-') {
        return this.stdin(callback);
    } else if (options.tail) {
        return this.tail(path, callback);
    }
    return this.stream(fs.createReadStream(path), callback);
};

/**
 * Parse a log file and watch it for changes.
 *
 * @param {String} path
 * @param {Function} callback
 */

Parser.prototype.tail = function (path, callback) {
    var stream = spawn('tail', [ '-F', '-c', '+0', path]).stdout;
    return this.stream(stream, callback);
};

/**
 * Parse a log stream from STDIN.
 *
 * @param {Function} callback
 */

Parser.prototype.stdin = function (callback) {
    return this.stream(process.stdin, callback);
};

/**
 * Parse a log stream.
 *
 * @param {ReadableStream} stream
 * @param {Function} callback
 */

Parser.prototype.stream = function (stream, callback) {
    var self = this, overflow = new Buffer(0);
    stream.on('data', function (data) {
        var buffer = overflow.concat(data), newline = 0;
        for (var i = 0, len = buffer.length; i < len; i++) {
            if (buffer[i] === 10) {
                self.parseLine(buffer.slice(newline, i), callback, stream);
                newline = i + 1;
            }
        }
        overflow = buffer.slice(newline);
    });
    stream.on('end', function () {
        if (overflow.length) {
            self.parseLine(overflow, callback, stream);
        }
    });
    process.nextTick(function () {
        stream.resume();
    });
    return stream;
};

/**
 * Parse a log line.
 *
 * @param {Buffer|String} line
 * @param {Function} callback
 */

Parser.prototype.parseLine = function (line, callback) {
    var match = line.toString().match(this.parser);
    if (!match) {
        return;
    }

    var row = {
        msec: null
      , time_iso8601: null
      , remote_addr: null
      , query_string: null
      , http_x_forwarded_for: null
      , http_user_agent: null
      , http_referer: null
      , time_local: null
      , request: null
      , status: null
      , request_time: null
      , request_length: null
      , pipe: null
      , connection: null
      , bytes_sent: null
      , body_bytes_sent: null

      , date: null
      , timestamp: null
      , ip: null
      , ip_str: null
    };

    for (var key in this.directives) {
        row[key] = match[this.directives[key]];
        if (row[key] === '-') {
            row[key] = null;
        }
    }

    //Parse the timestamp
    if (row.time_iso8601) {
        row.date = new Date(row.time_iso8601);
    } else if (row.msec) {
        row.date = new Date(Number(row.msec.replace('.', '')));
    }
    if (row.date) {
        row.timestamp = row.date.getTime();
    }

    //Parse the user's IP
    if (row.http_x_forwarded_for) {
        row.ip_str = row.http_x_forwarded_for;
    } else if (row.remote_addr) {
        row.ip_str = row.remote_addr;
    }
    if (row.ip_str) {
        var ip = row.ip_str.split('.', 4);
        row.ip = Number(ip[0]) * (2 << 23) +
            Number(ip[1]) * (2 << 15) +
            Number(ip[2]) * (2 << 7) +
            Number(ip[3]);
    }

    callback(row);
};

/**
 * Escape regular expression tokens.
 *
 * @param {String} str
 * @return {String}
 */

Parser.prototype.escape = function (str) {
    return str.replace(new RegExp('[.*+?|()\\[\\]{}]', 'g'), '\\$&');
};
<|endoftext|>


<commit_before>require('colors');

var SpecReporter = function(baseReporterDecorator, formatError) {
  baseReporterDecorator(this);

  // colorize output of BaseReporter functions
  this.USE_COLORS = true;
  this.SPEC_FAILURE = '%s %s FAILED'.red + '\n';
  this.SPEC_SLOW = '%s SLOW %s: %s'.yellow + '\n';
  this.ERROR = '%s ERROR'.red + '\n';
  this.FINISHED_ERROR = ' ERROR'.red;
  this.FINISHED_SUCCESS = ' SUCCESS'.green;
  this.FINISHED_DISCONNECTED = ' DISCONNECTED'.red;
  this.X_FAILED = ' (%d FAILED)'.red;
  this.TOTAL_SUCCESS = 'TOTAL: %d SUCCESS'.green + '\n';
  this.TOTAL_FAILED = 'TOTAL: %d FAILED, %d SUCCESS'.red + '\n';

  this.onRunComplete = function(browsers, results) {
    // the renderBrowser function is defined in karma/reporters/Base.js
    this.writeCommonMsg(browsers.map(this.renderBrowser).join('\n') + '\n');

    if (browsers.length > 1 && !results.disconnected && !results.error) {
      if (!results.failed) {
        this.write(this.TOTAL_SUCCESS, results.success);
      } else {
        this.write(this.TOTAL_FAILED, results.failed, results.success);
      }
    }

    this.write("\n");
  };

  this.currentSuite = [];
  this.writeSpecMessage = function(status) {
    return (function(browser, result) {
      var suite = result.suite
      var indent = "  ";
      suite.forEach(
        // beware, this in the context of a foreach loop is not what you expect!
        // To be sure, we bind this explicitly
        (function(value, index) {
          if (index >= this.currentSuite.length || this.currentSuite[index] != value) {
            if (index == 0) {
              this.writeCommonMsg('\n');
            }
            this.writeCommonMsg(indent + value + '\n');
            this.currentSuite = [];
          }
          indent += "  ";
        }).bind(this)
      );
      this.currentSuite = suite;

      var specName = result.description;
      //TODO: add timing information
      var msg = indent + status + specName, specName

      result.log.forEach(function(log) {
        msg += formatError(log, '\t');
      });

      this.writeCommonMsg(msg + '\n');

      // other useful properties
      browser.id;
      browser.fullName;
      result.time;
      result.skipped;
      result.success;
    }).bind(this);
  };

  this.specSuccess = this.writeSpecMessage('✓ '.green);
  this.specSkipped = this.writeSpecMessage('- '.grey);
  this.specFailure = this.writeSpecMessage('✗ '.red);
};

SpecReporter.$inject = ['baseReporterDecorator', 'formatError'];

module.exports = {
  'reporter:spec': ['type', SpecReporter]
};
<commit_msg>add new line before render browser<commit_after>require('colors');

var SpecReporter = function(baseReporterDecorator, formatError) {
  baseReporterDecorator(this);

  // colorize output of BaseReporter functions
  this.USE_COLORS = true;
  this.SPEC_FAILURE = '%s %s FAILED'.red + '\n';
  this.SPEC_SLOW = '%s SLOW %s: %s'.yellow + '\n';
  this.ERROR = '%s ERROR'.red + '\n';
  this.FINISHED_ERROR = ' ERROR'.red;
  this.FINISHED_SUCCESS = ' SUCCESS'.green;
  this.FINISHED_DISCONNECTED = ' DISCONNECTED'.red;
  this.X_FAILED = ' (%d FAILED)'.red;
  this.TOTAL_SUCCESS = 'TOTAL: %d SUCCESS'.green + '\n';
  this.TOTAL_FAILED = 'TOTAL: %d FAILED, %d SUCCESS'.red + '\n';

  this.onRunComplete = function(browsers, results) {
    // the renderBrowser function is defined in karma/reporters/Base.js
    this.writeCommonMsg('\n' + browsers.map(this.renderBrowser).join('\n') + '\n');

    if (browsers.length > 1 && !results.disconnected && !results.error) {
      if (!results.failed) {
        this.write(this.TOTAL_SUCCESS, results.success);
      } else {
        this.write(this.TOTAL_FAILED, results.failed, results.success);
      }
    }

    this.write("\n");
  };

  this.currentSuite = [];
  this.writeSpecMessage = function(status) {
    return (function(browser, result) {
      var suite = result.suite
      var indent = "  ";
      suite.forEach(
        // beware, this in the context of a foreach loop is not what you expect!
        // To be sure, we bind this explicitly
        (function(value, index) {
          if (index >= this.currentSuite.length || this.currentSuite[index] != value) {
            if (index == 0) {
              this.writeCommonMsg('\n');
            }
            this.writeCommonMsg(indent + value + '\n');
            this.currentSuite = [];
          }
          indent += "  ";
        }).bind(this)
      );
      this.currentSuite = suite;

      var specName = result.description;
      //TODO: add timing information
      var msg = indent + status + specName, specName

      result.log.forEach(function(log) {
        msg += formatError(log, '\t');
      });

      this.writeCommonMsg(msg + '\n');

      // other useful properties
      browser.id;
      browser.fullName;
      result.time;
      result.skipped;
      result.success;
    }).bind(this);
  };

  this.specSuccess = this.writeSpecMessage('✓ '.green);
  this.specSkipped = this.writeSpecMessage('- '.grey);
  this.specFailure = this.writeSpecMessage('✗ '.red);
};

SpecReporter.$inject = ['baseReporterDecorator', 'formatError'];

module.exports = {
  'reporter:spec': ['type', SpecReporter]
};
<|endoftext|>


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

var fs = require('fs');
var os = require('os');
var path = require('path');
var resolve = require('resolve').sync;
var spawn = require('child_process').spawn;
var glob = require("glob");
var async = require("async");

var VERSION = require('./package.json').version;
var LOCATION = __filename;

function errorFromExitCode(exitCode) {
  return new Error('clang-format exited with exit code ' + exitCode + '.');
}

/**
 * Start a child process running the native clang-format binary.
 * @param file a Vinyl virtual file reference
 * @param enc the encoding to use for reading stdout
 * @param style valid argument to clang-format's '-style' flag
 * @param done callback invoked when the child process terminates
 * @returns {stream.Readable} the formatted code as a Readable stream
 */
function clangFormat(file, enc, style, done) {
  var args = ['-style=' + style, file.path];
  var result = spawnClangFormat(args, done, ['ignore', 'pipe', process.stderr]);
  if (result) { // must be ChildProcess
    result.stdout.setEncoding(enc);
    return result.stdout;
  } else {
    // We shouldn't be able to reach this line, because it's not possible to
    // set the --glob arg in this function.
    throw new Error('Can\'t get output stream when --glob flag is set');
  }
}

/**
 * Spawn the clang-format binary with given arguments.
 */
function spawnClangFormat(args, done, stdio) {
  // WARNING: This function's interface should stay stable across versions for the cross-version
  // loading below to work.
  if (args.indexOf('-version') !== -1 || args.indexOf('--version') !== -1) {
    // Print our version.
    // This makes it impossible to format files called '-version' or '--version'. That's a feature.
    // minimist & Co don't support single dash args, which we need to match binary clang-format.
    console.log('clang-format NPM version', VERSION, 'at', LOCATION);
    // To be consistent with other code paths, we use setImmediate to call `done` asynchronously.
    setImmediate(done);
    return;
  }
  var nativeBinary;
  if (os.platform() === 'win32') {
    nativeBinary = __dirname + '/bin/win32/clang-format.exe';
  } else {
    nativeBinary = __dirname + '/bin/' + os.platform() + "_" + os.arch() + '/clang-format';
  }
  if (!fs.existsSync(nativeBinary)) {
    message = "This module doesn't bundle the clang-format executable for your platform. " +
              "(" + os.platform() + "_" + os.arch() + ")\n" +
              "Consider installing it with your native package manager instead.\n";
    setImmediate(done.bind(new Error(message)));
    return;
  }

  // extract glob, if present
  var filesGlob = args.filter(function(arg){return arg.indexOf('--glob=') === 0;})
                    .map(function(arg){return arg.replace('--glob=', '');})
                    .shift();

  if (filesGlob) {
    // remove glob from arg list
    args = args.filter(function(arg){return arg.indexOf('--glob=') === -1;});

    glob(filesGlob, function(err, files) {
      if (err) {
        done(err);
        return;
      }

      // split file array into chunks of 30
      var i,j, chunks = [], chunkSize = 30;
      for (i=0,j=files.length; i<j; i+=chunkSize) {
          chunks.push( files.slice(i,i+chunkSize));
      }

      // launch a new process for each chunk
      async.series(
        chunks.map(function(chunk) {
          return function(callback) {
            var clangFormatProcess = spawn(nativeBinary,
                                          args.concat(chunk),
                                          {stdio: stdio}).stdout;
            clangFormatProcess.on('close', function(exit) {
              if (exit !== 0) callback(errorFromExitCode(exit));
              else callback();
            });
          };
        }),
        function(err) {
          if (err) {
            done(err);
            return;
          }
          console.log('\n');
          console.log('ran clang-format on',
                      files.length,
                      files.length === 1 ? 'file' : 'files');
          done();
        });
    });
  } else {
    var clangFormatProcess = spawn(nativeBinary, args, {stdio: stdio});
    clangFormatProcess.on('close', function(exit) {
      if (exit) done(errorFromExitCode(exit));
      else done();
    });
    return clangFormatProcess;
  }
}

function main() {
  // Find clang-format in node_modules of the project of the .js file, or cwd.
  var nonDashArgs = process.argv.filter(function(arg, idx) { return idx > 1 && arg[0] != '-' });
  // Using the last file makes it less likely to collide with clang-format's argument parsing.
  var lastFileArg = nonDashArgs[nonDashArgs.length - 1];
  var basedir = lastFileArg ? path.dirname(lastFileArg) :  // relative to the last .js file given.
                    process.cwd();                         // or relative to the cwd()
  var resolvedClangFormat;
  var clangFormatLocation;
  try {
    clangFormatLocation = resolve('clang-format', {basedir: basedir});
    resolvedClangFormat = require(clangFormatLocation);
  } catch (e) {
    // Ignore and use the clang-format that came with this package.
  }
  var actualSpawnFn;
  if (!resolvedClangFormat) {
    actualSpawnFn = spawnClangFormat;
  } else if (resolvedClangFormat.spawnClangFormat) {
    actualSpawnFn = resolvedClangFormat.spawnClangFormat;
  } else {
    throw new Error('Incompatible clang-format loaded from ' + clangFormatLocation);
  }
  // Run clang-format.
  try {
    // Pass all arguments to clang-format, including e.g. -version etc.
    actualSpawnFn(process.argv.slice(2), process.exit, 'inherit');
  } catch (e) {
    process.stdout.write(e.message);
    process.exit(1);
  }
}

module.exports = clangFormat;
module.exports.version = VERSION;
module.exports.location = LOCATION;
module.exports.spawnClangFormat = spawnClangFormat;

if (require.main === module) main();
<commit_msg>Fix an error introduced in the previous commit.<commit_after>#!/usr/bin/env node
'use strict';

var fs = require('fs');
var os = require('os');
var path = require('path');
var resolve = require('resolve').sync;
var spawn = require('child_process').spawn;
var glob = require("glob");
var async = require("async");

var VERSION = require('./package.json').version;
var LOCATION = __filename;

function errorFromExitCode(exitCode) {
  return new Error('clang-format exited with exit code ' + exitCode + '.');
}

/**
 * Start a child process running the native clang-format binary.
 * @param file a Vinyl virtual file reference
 * @param enc the encoding to use for reading stdout
 * @param style valid argument to clang-format's '-style' flag
 * @param done callback invoked when the child process terminates
 * @returns {stream.Readable} the formatted code as a Readable stream
 */
function clangFormat(file, enc, style, done) {
  var args = ['-style=' + style, file.path];
  var result = spawnClangFormat(args, done, ['ignore', 'pipe', process.stderr]);
  if (result) { // must be ChildProcess
    result.stdout.setEncoding(enc);
    return result.stdout;
  } else {
    // We shouldn't be able to reach this line, because it's not possible to
    // set the --glob arg in this function.
    throw new Error('Can\'t get output stream when --glob flag is set');
  }
}

/**
 * Spawn the clang-format binary with given arguments.
 */
function spawnClangFormat(args, done, stdio) {
  // WARNING: This function's interface should stay stable across versions for the cross-version
  // loading below to work.
  if (args.indexOf('-version') !== -1 || args.indexOf('--version') !== -1) {
    // Print our version.
    // This makes it impossible to format files called '-version' or '--version'. That's a feature.
    // minimist & Co don't support single dash args, which we need to match binary clang-format.
    console.log('clang-format NPM version', VERSION, 'at', LOCATION);
    // To be consistent with other code paths, we use setImmediate to call `done` asynchronously.
    setImmediate(done);
    return;
  }
  var nativeBinary;
  if (os.platform() === 'win32') {
    nativeBinary = __dirname + '/bin/win32/clang-format.exe';
  } else {
    nativeBinary = __dirname + '/bin/' + os.platform() + "_" + os.arch() + '/clang-format';
  }
  if (!fs.existsSync(nativeBinary)) {
    message = "This module doesn't bundle the clang-format executable for your platform. " +
              "(" + os.platform() + "_" + os.arch() + ")\n" +
              "Consider installing it with your native package manager instead.\n";
    setImmediate(done.bind(new Error(message)));
    return;
  }

  // extract glob, if present
  var filesGlob = args.filter(function(arg){return arg.indexOf('--glob=') === 0;})
                    .map(function(arg){return arg.replace('--glob=', '');})
                    .shift();

  if (filesGlob) {
    // remove glob from arg list
    args = args.filter(function(arg){return arg.indexOf('--glob=') === -1;});

    glob(filesGlob, function(err, files) {
      if (err) {
        done(err);
        return;
      }

      // split file array into chunks of 30
      var i,j, chunks = [], chunkSize = 30;
      for (i=0,j=files.length; i<j; i+=chunkSize) {
          chunks.push( files.slice(i,i+chunkSize));
      }

      // launch a new process for each chunk
      async.series(
          chunks.map(function(chunk) {
            return function(callback) {
              var clangFormatProcess = spawn(nativeBinary, args.concat(chunk), {stdio: stdio});
              clangFormatProcess.on('close', function(exit) {
                if (exit !== 0)
                  callback(errorFromExitCode(exit));
                else
                  callback();
              });
            };
          }),
          function(err) {
            if (err) {
              done(err);
              return;
            }
            console.log('\n');
            console.log('ran clang-format on', files.length, files.length === 1 ? 'file' : 'files');
            done();
          });
    });
  } else {
    var clangFormatProcess = spawn(nativeBinary, args, {stdio: stdio});
    clangFormatProcess.on('close', function(exit) {
      if (exit) done(errorFromExitCode(exit));
      else done();
    });
    return clangFormatProcess;
  }
}

function main() {
  // Find clang-format in node_modules of the project of the .js file, or cwd.
  var nonDashArgs = process.argv.filter(function(arg, idx) { return idx > 1 && arg[0] != '-' });
  // Using the last file makes it less likely to collide with clang-format's argument parsing.
  var lastFileArg = nonDashArgs[nonDashArgs.length - 1];
  var basedir = lastFileArg ? path.dirname(lastFileArg) :  // relative to the last .js file given.
                    process.cwd();                         // or relative to the cwd()
  var resolvedClangFormat;
  var clangFormatLocation;
  try {
    clangFormatLocation = resolve('clang-format', {basedir: basedir});
    resolvedClangFormat = require(clangFormatLocation);
  } catch (e) {
    // Ignore and use the clang-format that came with this package.
  }
  var actualSpawnFn;
  if (!resolvedClangFormat) {
    actualSpawnFn = spawnClangFormat;
  } else if (resolvedClangFormat.spawnClangFormat) {
    actualSpawnFn = resolvedClangFormat.spawnClangFormat;
  } else {
    throw new Error('Incompatible clang-format loaded from ' + clangFormatLocation);
  }
  // Run clang-format.
  try {
    // Pass all arguments to clang-format, including e.g. -version etc.
    actualSpawnFn(process.argv.slice(2), process.exit, 'inherit');
  } catch (e) {
    process.stdout.write(e.message);
    process.exit(1);
  }
}

module.exports = clangFormat;
module.exports.version = VERSION;
module.exports.location = LOCATION;
module.exports.spawnClangFormat = spawnClangFormat;

if (require.main === module) main();
<|endoftext|>


<commit_before>'use strict';

var skynet = require('skynet');
var util = require('util');
var _ = require('lodash');
var EventEmitter = require('events').EventEmitter;
var DeviceManager = require('./device-manager');

var Gatenu = function(config) {
  var self = this;
  var skynetConnection = skynet.createConnection({ uuid: config.uuid, token: config.token, server: config.server, port: config.port });
  var deviceManager = new DeviceManager({
    uuid: config.uuid,
    token: config.token,
    devicePath: config.devicePath,
    tmpPath: config.tmpPath,
    nodePath: config.nodePath,
    server:  config.server,
    port:    config.port
  });

  deviceManager.on('stderr', function(data, device){
    self.emit('stderr', data, device);
  });

  deviceManager.on('stdout', function(data, device){
    self.emit('stdout', data, device);
  });

  deviceManager.on('update', function(devices){
    self.emit('update', devices);
  });

  var refreshDevices = function(callback) {
    self.emit('refresh');
    skynetConnection.whoami({}, function(data){
      deviceManager.refreshDevices(data.devices, callback);
    });
  };

  var updateType = function(){
    skynetConnection.update({uuid: config.uuid, type: 'device:gateblu'});
  };

  deviceManager.on('start', function(device){
    skynetConnection.subscribe({uuid: device.uuid})
    self.emit('device:start', device);
  });

  skynetConnection.on('notReady', function(data) {
    console.error('notReady', data);
    if (!config.uuid) {
      skynetConnection.register({}, function(data){
        skynetConnection.identify({uuid: data.uuid, token: data.token});
      });
    }
  });

  skynetConnection.on('ready', function(data){
    config.uuid  = data.uuid;
    config.token = data.token;
    self.emit('config', config);
    updateType();
    refreshDevices(function(error){
      if (error) {
        self.emit('error', error);
      }
    });
  });

  skynetConnection.on('message', function(message){
    if (message.topic === 'refresh') {
      refreshDevices();
    }
    if (message.topic === 'device-status') {
      self.emit('device:status', {online: message.payload.online, uuid: message.fromUuid});
    }
    if( deviceManager[message.topic] ) {
      deviceManager[message.topic](message.payload);
    }
  });

  this.cleanup = _.once(function() {
    process.stdin.resume();

    deviceManager.stopDevices(function(error, uuids){
      process.exit();
    });
  });

  this.stopDevice = deviceManager.stopDevice;
  this.startDevice = deviceManager.startDevice;

};

util.inherits(Gatenu, EventEmitter);
module.exports = Gatenu;
<commit_msg>update device config<commit_after>'use strict';

var skynet = require('skynet');
var util = require('util');
var _ = require('lodash');
var EventEmitter = require('events').EventEmitter;
var DeviceManager = require('./device-manager');

var Gatenu = function(config) {
  var self = this;
  var skynetConnection = skynet.createConnection({ uuid: config.uuid, token: config.token, server: config.server, port: config.port });
  var deviceManager = new DeviceManager({
    uuid: config.uuid,
    token: config.token,
    devicePath: config.devicePath,
    tmpPath: config.tmpPath,
    nodePath: config.nodePath,
    server:  config.server,
    port:    config.port
  });

  deviceManager.on('stderr', function(data, device){
    self.emit('stderr', data, device);
  });

  deviceManager.on('stdout', function(data, device){
    self.emit('stdout', data, device);
  });

  deviceManager.on('update', function(devices){
    self.emit('update', devices);
  });

  var refreshDevices = function(callback) {
    self.emit('refresh');
    skynetConnection.whoami({}, function(data){
      deviceManager.refreshDevices(data.devices, callback);
    });
  };

  var updateType = function(){
    skynetConnection.update({uuid: config.uuid, type: 'device:gateblu'});
  };

  deviceManager.on('start', function(device){
    skynetConnection.subscribe({uuid: device.uuid, token: device.token})
    self.emit('device:start', device);
  });

  skynetConnection.on('notReady', function(data) {
    console.error('notReady', data);
    if (!config.uuid) {
      skynetConnection.register({}, function(data){
        skynetConnection.identify({uuid: data.uuid, token: data.token});
      });
    }
  });

  skynetConnection.on('ready', function(data){
    config.uuid  = data.uuid;
    config.token = data.token;
    self.emit('gateblu:config', config);
    updateType();
    refreshDevices(function(error){
      if (error) {
        self.emit('error', error);
      }
    });
  });

  skynetConnection.on('config', function(data){
    if (data.uuid !== config.uuid) {
      self.emit('device:config', data);
    }
  });

  skynetConnection.on('message', function(message){
    if (message.topic === 'refresh') {
      refreshDevices();
    }
    if (message.topic === 'device-status') {
      self.emit('device:status', {online: message.payload.online, uuid: message.fromUuid});
    }
    if( deviceManager[message.topic] ) {
      deviceManager[message.topic](message.payload);
    }
  });

  this.cleanup = _.once(function() {
    process.stdin.resume();

    deviceManager.stopDevices(function(error, uuids){
      process.exit();
    });
  });

  this.stopDevice = deviceManager.stopDevice;
  this.startDevice = deviceManager.startDevice;

};

util.inherits(Gatenu, EventEmitter);
module.exports = Gatenu;
<|endoftext|>


<commit_before>var serverRoute = require('./server/routes/server');

export default function (kibana) {
  return new kibana.Plugin({
    name: 'logtrail',
    require: ['kibana', 'elasticsearch'],
    uiExports: {
      app: {
        title: 'LogTrail',
        description: 'Plugin to view, search & tail logs in Kibana',
        main: 'plugins/logtrail/app'
      },
      hacks: [
      ]
    },
    init: function (server) {
      // register feature
      console.log(JSON.stringify(server.plugins));
      const xpackMainPlugin = server.plugins.xpack_main;
      console.log(`****** xpackMainPlugin - ${xpackMainPlugin}`);
      if (xpackMainPlugin) {
        xpackMainPlugin.registerFeature({
          id: 'logtrail',
          name: 'LogTrail',
          app: ['logtrail','kibana'],
          catalogue: [],
          privileges: {
            all: {
              api: [],
              savedObject: {
                all: [],
                read: [],
              },
              ui: ['show'],
            },
            read: {
              api: [],
              savedObject: {
                all: [],
                read: [],
              },
              ui: ['show'],
            },
          },
        });
      }
      // Add server routes and initalize the plugin here
      serverRoute(server);
    }

  });
};
<commit_msg>remove temp changes related x-pack feature<commit_after>var serverRoute = require('./server/routes/server');

export default function (kibana) {
  return new kibana.Plugin({
    name: 'logtrail',
    require: ['kibana', 'elasticsearch'],
    uiExports: {
      app: {
        title: 'LogTrail',
        description: 'Plugin to view, search & tail logs in Kibana',
        main: 'plugins/logtrail/app'
      },
      hacks: [
      ]
    },
    init: function (server) {
      // Add server routes and initalize the plugin here
      serverRoute(server);
    }

  });
};
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016 Kam Low
 *
 * @license MIT
 **/

var fs = require('fs'),
    path = require('path'),
    Promise = require('bluebird'),
    tmp = require('tmp'),
    grunt = require('grunt'),
    package = require('./package'),
    _ = require('lodash');

// Ensures temporary files are cleaned up on program close, even if errors are encountered.
tmp.setGracefulCleanup();

var defaults = {
    silent: false,
    port: 4400,
    targetDir: path.resolve(process.cwd(), 'public'),
    targetFile: 'index.html',
    appDir: path.resolve(__dirname, 'app'),
    configFile: path.resolve(__dirname, 'app/lib/config.js'),
    cacheDir: tmp.dirSync({ unsafeCleanup: true, prefix: 'spectacle-' }).name
};
function resolveOptions(options) {
    var opts = _.extend({}, defaults, options);

    // Replace some absolute paths
    if (opts.specFile && opts.specFile.indexOf('test/fixtures') === 0)
        opts.specFile = path.resolve(__dirname, opts.specFile);
    if (opts.logoFile && opts.logoFile.indexOf('test/fixtures') === 0)
        opts.logoFile = path.resolve(__dirname, opts.logoFile);

    return opts;
}

/**
 * Run Spectacle and configured tasks
 **/
module.exports = function (options) {
    var opts = resolveOptions(options);

    //
    //= Load the specification and init configuration

    function loadData() {
        var specPath = path.resolve(opts.specFile);
        delete require.cache[specPath];
        return require(path.resolve(opts.appDir + '/lib/preprocessor'))(
                                    options, require(specPath));
    }

    var config = require(path.resolve(opts.configFile))(grunt, opts, loadData());

    //
    //= Setup Grunt to do the heavy lifting

    grunt.initConfig(_.merge({ pkg: package }, config));
    if(opts.silent) {
        grunt.log.writeln = function() {}
        grunt.log.write = function() {}
        grunt.log.header = function() {}
        grunt.log.ok = function() {}
    }

    var cwd = process.cwd(); // change CWD for loadNpmTasks global install
    var exists = grunt.file.exists(path.join(path.resolve('node_modules'),
                                             'grunt-contrib-concat',
                                             'package.json'));
    if (!exists)
        process.chdir(__dirname);

    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-compile-handlebars');
    grunt.loadNpmTasks('grunt-prettify');
    grunt.loadNpmTasks('grunt-sass');

    process.chdir(cwd);

    grunt.registerTask('predentation', 'Remove indentation from generated <pre> tags.', function() {
        var html = fs.readFileSync(opts.cacheDir + '/' + opts.targetFile, 'utf8');
        html = html.replace(/<pre.*?><code.*?>([\s\S]*?)<\/code><\/pre>/gmi, function(x, y) {
            var lines = x.split('\n'), level = null;
            if (lines) {

                // Determine the level of indentation
                lines.forEach(function(line) {
                    if (line[0] === '<') return;
                    var wsp = line.search(/\S/);
                    level = (level === null || (wsp < line.length && wsp < level)) ? wsp : level;
                });

                // Remove indentation
                var regex = new RegExp('^\\s{' + level + '}');
                lines.forEach(function(line, index, lines) {
                    lines[index] = line.replace(regex, '');
                });
            }
            return lines.join('\n');
        });
        fs.writeFileSync(opts.cacheDir + '/' + opts.targetFile, html);
    });

    grunt.registerTask('stylesheets', ['sass:scss', 'concat:css', 'cssmin']);
    grunt.registerTask('javascripts', ['concat:js', 'uglify']);
    grunt.registerTask('templates', ['clean:html', 'compile-handlebars', 'predentation', 'prettify']);
    grunt.registerTask('foundation', ['sass:foundation_scss', 'concat:foundation_css']); // 'concat:foundation_js'
    grunt.registerTask('default', ['stylesheets', 'javascripts', 'foundation', 'templates']);
    grunt.registerTask('server', ['connect']);
    grunt.registerTask('develop', ['server', 'watch']);

    // Reload template data when watch files change
    grunt.event.on('watch', function(action, filepath) {
        // if (filepath == config.specFile)
        grunt.config.set('compile-handlebars.compile.templateData', loadData());
    });

    // Report, etc when all tasks have completed.
    var donePromise = new Promise(function(resolve, reject) {
      grunt.task.options({
          error: function(e) {
              if(!opts.silent) {
                  console.warn('Task error:', e);
              }
              // TODO: fail here or push on?
              reject(e);
          },
          done: function() {
              if(!opts.silent) {
                  console.log('All tasks complete');
              }
              resolve();
          }
      });
    });

    //
    //= Run the shiz

    if (opts.startServer) {
        grunt.task.run('server');
    }
    else {
        if (!opts.disableCss) {
            grunt.task.run(['foundation', 'stylesheets']);
        }
        if (!opts.disableJs) {
            grunt.task.run('javascripts');
        }
        grunt.task.run('copy:images');
        grunt.task.run('copy:package');
        if (opts.logoFile) {
            grunt.task.run('copy:logo');
        }
        grunt.task.run('templates');
        if (opts.developmentMode) {
            grunt.task.run('develop');
        }
    }

    grunt.task.start();

    return donePromise;
};
<commit_msg>Sacada tarea package de la build<commit_after>/**
 * Copyright (c) 2016 Kam Low
 *
 * @license MIT
 **/

var fs = require('fs'),
    path = require('path'),
    Promise = require('bluebird'),
    tmp = require('tmp'),
    grunt = require('grunt'),
    package = require('./package'),
    _ = require('lodash');

// Ensures temporary files are cleaned up on program close, even if errors are encountered.
tmp.setGracefulCleanup();

var defaults = {
    silent: false,
    port: 4400,
    targetDir: path.resolve(process.cwd(), 'public'),
    targetFile: 'index.html',
    appDir: path.resolve(__dirname, 'app'),
    configFile: path.resolve(__dirname, 'app/lib/config.js'),
    cacheDir: tmp.dirSync({ unsafeCleanup: true, prefix: 'spectacle-' }).name
};
function resolveOptions(options) {
    var opts = _.extend({}, defaults, options);

    // Replace some absolute paths
    if (opts.specFile && opts.specFile.indexOf('test/fixtures') === 0)
        opts.specFile = path.resolve(__dirname, opts.specFile);
    if (opts.logoFile && opts.logoFile.indexOf('test/fixtures') === 0)
        opts.logoFile = path.resolve(__dirname, opts.logoFile);

    return opts;
}

/**
 * Run Spectacle and configured tasks
 **/
module.exports = function (options) {
    var opts = resolveOptions(options);

    //
    //= Load the specification and init configuration

    function loadData() {
        var specPath = path.resolve(opts.specFile);
        delete require.cache[specPath];
        return require(path.resolve(opts.appDir + '/lib/preprocessor'))(
                                    options, require(specPath));
    }

    var config = require(path.resolve(opts.configFile))(grunt, opts, loadData());

    //
    //= Setup Grunt to do the heavy lifting

    grunt.initConfig(_.merge({ pkg: package }, config));
    if(opts.silent) {
        grunt.log.writeln = function() {}
        grunt.log.write = function() {}
        grunt.log.header = function() {}
        grunt.log.ok = function() {}
    }

    var cwd = process.cwd(); // change CWD for loadNpmTasks global install
    var exists = grunt.file.exists(path.join(path.resolve('node_modules'),
                                             'grunt-contrib-concat',
                                             'package.json'));
    if (!exists)
        process.chdir(__dirname);

    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-compile-handlebars');
    grunt.loadNpmTasks('grunt-prettify');
    grunt.loadNpmTasks('grunt-sass');

    process.chdir(cwd);

    grunt.registerTask('predentation', 'Remove indentation from generated <pre> tags.', function() {
        var html = fs.readFileSync(opts.cacheDir + '/' + opts.targetFile, 'utf8');
        html = html.replace(/<pre.*?><code.*?>([\s\S]*?)<\/code><\/pre>/gmi, function(x, y) {
            var lines = x.split('\n'), level = null;
            if (lines) {

                // Determine the level of indentation
                lines.forEach(function(line) {
                    if (line[0] === '<') return;
                    var wsp = line.search(/\S/);
                    level = (level === null || (wsp < line.length && wsp < level)) ? wsp : level;
                });

                // Remove indentation
                var regex = new RegExp('^\\s{' + level + '}');
                lines.forEach(function(line, index, lines) {
                    lines[index] = line.replace(regex, '');
                });
            }
            return lines.join('\n');
        });
        fs.writeFileSync(opts.cacheDir + '/' + opts.targetFile, html);
    });

    grunt.registerTask('stylesheets', ['sass:scss', 'concat:css', 'cssmin']);
    grunt.registerTask('javascripts', ['concat:js', 'uglify']);
    grunt.registerTask('templates', ['clean:html', 'compile-handlebars', 'predentation', 'prettify']);
    grunt.registerTask('foundation', ['sass:foundation_scss', 'concat:foundation_css']); // 'concat:foundation_js'
    grunt.registerTask('default', ['stylesheets', 'javascripts', 'foundation', 'templates']);
    grunt.registerTask('server', ['connect']);
    grunt.registerTask('develop', ['server', 'watch']);

    // Reload template data when watch files change
    grunt.event.on('watch', function(action, filepath) {
        // if (filepath == config.specFile)
        grunt.config.set('compile-handlebars.compile.templateData', loadData());
    });

    // Report, etc when all tasks have completed.
    var donePromise = new Promise(function(resolve, reject) {
      grunt.task.options({
          error: function(e) {
              if(!opts.silent) {
                  console.warn('Task error:', e);
              }
              // TODO: fail here or push on?
              reject(e);
          },
          done: function() {
              if(!opts.silent) {
                  console.log('All tasks complete');
              }
              resolve();
          }
      });
    });

    //
    //= Run the shiz

    if (opts.startServer) {
        grunt.task.run('server');
    }
    else {
        if (!opts.disableCss) {
            grunt.task.run(['foundation', 'stylesheets']);
        }
        if (!opts.disableJs) {
            grunt.task.run('javascripts');
        }
        grunt.task.run('copy:images');
        if (opts.logoFile) {
            grunt.task.run('copy:logo');
        }
        grunt.task.run('templates');
        if (opts.developmentMode) {
            grunt.task.run('develop');
        }
    }

    grunt.task.start();

    return donePromise;
};
<|endoftext|>


<commit_before>'use strict';

 /**
 * Compares two specificity vectors, returning the winning one.
 *
 * @param {Array} vector a
 * @param {Array} vector b
 * @return {Array}
 * @api public
 */

function compare(a, b) {
    for (var i = 0; i < 4; i++) {
        if (a[i] === b[i]) {
            continue;
        }
        if (a[i] > b[i]) {
            return a;
        }
        return b;
    }

    return b;
}

/**
 * CSS property constructor.
 *
 * @param {String} property
 * @param {String} value
 * @param {Selector} selector the property originates from
 * @api public
 */

function Property(prop, value, selector) {
    this.prop = prop;
    this.value = value;
    this.selector = selector;
}

/**
 * Compares with another Property based on Selector#specificity.
 *
 * @api public
 */

Property.prototype.compare = function (property) {
    var a = this.selector.specificity(),
        b = property.selector.specificity(),
        winner = compare(a, b);

    if (winner === a && a !== b) {
        return this;
    }
    return property;
};

/**
 * Returns CSS property
 *
 * @api public
 */

Property.prototype.toString = function () {
    return this.prop + ': ' + this.value.replace(/['"]+/g, '') + ';';
};

module.exports = exports = Property;
<commit_msg>Fix eslint issues.<commit_after>'use strict';

 /**
 * Compares two specificity vectors, returning the winning one.
 *
 * @param {Array} vector a
 * @param {Array} vector b
 * @return {Array}
 * @api public
 */

function compare(a, b) {
    var i;

    for (i = 0; i < 4; i++) {
        if (a[i] === b[i]) {
            continue;
        }
        if (a[i] > b[i]) {
            return a;
        }
        return b;
    }

    return b;
}

/**
 * CSS property constructor.
 *
 * @param {String} property
 * @param {String} value
 * @param {Selector} selector the property originates from
 * @api public
 */

function Property(prop, value, selector) {
    this.prop = prop;
    this.value = value;
    this.selector = selector;
}

/**
 * Compares with another Property based on Selector#specificity.
 *
 * @api public
 */

Property.prototype.compare = function (property) {
    var a = this.selector.specificity(),
        b = property.selector.specificity(),
        winner = compare(a, b);

    if (winner === a && a !== b) {
        return this;
    }
    return property;
};

/**
 * Returns CSS property
 *
 * @api public
 */

Property.prototype.toString = function () {
    return this.prop + ': ' + this.value.replace(/['"]+/g, '') + ';';
};

module.exports = exports = Property;
<|endoftext|>


<commit_before>var npa = require('npm-package-arg');
var guessVersion = require('./lib/guessVersion.js');
var Promise = require('bluebird');

module.exports = buildGraph;
module.exports.isRemote = isRemote;

function buildGraph(http, url) {
  url = url || 'http://registry.npmjs.org/';
  if (url[url.length - 1] !== '/') {
    throw new Error('registry url is supposed to end with /');
  }
  var progress;
  var cache = Object.create(null);

  return {
    createNpmDependenciesGraph: createNpmDependenciesGraph,
    notifyProgress: function (cb) {
      progress = cb;
    }
  };

  function createNpmDependenciesGraph(packageName, graph, version) {
    if (!packageName) throw new Error('Initial package name is required');
    if (!graph) throw new Error('Graph data structure is required');
    if (!version) version = 'latest';

    var queue = [];
    var processed = Object.create(null);

    queue.push({
      name: packageName,
      version: version,
      parent: null
    });

    return processQueue(graph);

    function processQueue(graph) {
      if (typeof progress === 'function') {
        progress(queue.length);
      }

      var work = queue.pop();

      var cached = cache[work.name];
      if (cached) {
        return new Promise(function(resolve) {
          resolve(processRegistryResponse(cached));
        });
      }

      if (isRemote(work.version)) {
        // TODO: This will not download remote dependnecies (e.g. git-based)
        return new Promise(function(resolve) {
          resolve(processRegistryResponse({data: {}}));
        });
      }

      var escapedName = npa(work.name).escapedName;
      if (!escapedName) {
        throw new Error('TODO: Escaped name is missing for ' + work.name);
      }

      return http(url + escapedName).then(processRegistryResponse);

      function processRegistryResponse(res) {
        cache[work.name] = res;
        traverseDependencies(work, res.data);

        if (queue.length) {
          // continue building the graph
          return processQueue(graph);
        }

        return graph;
      }
    }

    function traverseDependencies(work, packageJson) {
      var version, pkg, id;
      if (isRemote(work.version)) {
        version = '';
        pkg = packageJson;
        id = work.version;
      } else {
        version = guessVersion(work.version, packageJson);
        pkg = packageJson.versions[version];
        id = pkg._id;
      }

      if (processed[id]) return;
      processed[id] = true;

      // TODO: here is a good place to address https://github.com/anvaka/npmgraph.an/issues/4
      var dependencies = pkg.dependencies;

      graph.beginUpdate();

      graph.addNode(id, pkg);

      if (work.parent && !graph.hasLink(work.parent, id)) {
        graph.addLink(work.parent, id);
      }

      graph.endUpdate();

      if (dependencies) {
        Object.keys(dependencies).forEach(addToQueue);
      }

      function addToQueue(name) {
          queue.push({
            name: name,
            version: dependencies[name],
            parent: id
          })
        }
    }
  }
}

function isRemote(version) {
  return typeof version === 'string' && (
    (version.indexOf('git') === 0) ||
    (version.indexOf('http') === 0) ||
    (version.indexOf('file') === 0)
  );
}
<commit_msg>Properly handle remote packages cache<commit_after>var npa = require('npm-package-arg');
var guessVersion = require('./lib/guessVersion.js');
var Promise = require('bluebird');

module.exports = buildGraph;
module.exports.isRemote = isRemote;

function buildGraph(http, url) {
  url = url || 'http://registry.npmjs.org/';
  if (url[url.length - 1] !== '/') {
    throw new Error('registry url is supposed to end with /');
  }
  var progress;
  var cache = Object.create(null);

  return {
    createNpmDependenciesGraph: createNpmDependenciesGraph,
    notifyProgress: function (cb) {
      progress = cb;
    }
  };

  function createNpmDependenciesGraph(packageName, graph, version) {
    if (!packageName) throw new Error('Initial package name is required');
    if (!graph) throw new Error('Graph data structure is required');
    if (!version) version = 'latest';

    var queue = [];
    var processed = Object.create(null);

    queue.push({
      name: packageName,
      version: version,
      parent: null
    });

    return processQueue(graph);

    function processQueue(graph) {
      if (typeof progress === 'function') {
        progress(queue.length);
      }

      var work = queue.pop();

      var cached = cache[getCacheKey(work)];
      if (cached) {
        return new Promise(function(resolve) {
          resolve(processRegistryResponse(cached));
        });
      }

      if (isRemote(work.version)) {
        // TODO: This will not download remote dependnecies (e.g. git-based)
        return new Promise(function(resolve) {
          resolve(processRegistryResponse({data: {}}));
        });
      }

      var escapedName = npa(work.name).escapedName;
      if (!escapedName) {
        throw new Error('TODO: Escaped name is missing for ' + work.name);
      }

      return http(url + escapedName).then(processRegistryResponse);

      function processRegistryResponse(res) {
        cache[getCacheKey(work)] = res;
        traverseDependencies(work, res.data);

        if (queue.length) {
          // continue building the graph
          return processQueue(graph);
        }

        return graph;
      }
    }

    function getCacheKey(work) {
      var packageIsRemote = isRemote(work.version);
      var cacheKey = work.name;
      return packageIsRemote ? cacheKey + work.version : cacheKey
    }

    function traverseDependencies(work, packageJson) {
      var version, pkg, id;
      if (isRemote(work.version)) {
        version = '';
        pkg = packageJson;
        id = work.version;
      } else {
        version = guessVersion(work.version, packageJson);
        pkg = packageJson.versions[version];
        id = pkg._id;
      }

      if (processed[id]) return;
      processed[id] = true;

      // TODO: here is a good place to address https://github.com/anvaka/npmgraph.an/issues/4
      var dependencies = pkg.dependencies;

      graph.beginUpdate();

      graph.addNode(id, pkg);

      if (work.parent && !graph.hasLink(work.parent, id)) {
        graph.addLink(work.parent, id);
      }

      graph.endUpdate();

      if (dependencies) {
        Object.keys(dependencies).forEach(addToQueue);
      }

      function addToQueue(name) {
          queue.push({
            name: name,
            version: dependencies[name],
            parent: id
          })
        }
    }
  }
}

function isRemote(version) {
  return typeof version === 'string' && (
    (version.indexOf('git') === 0) ||
    (version.indexOf('http') === 0) ||
    (version.indexOf('file') === 0)
  );
}
<|endoftext|>