Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

gh

Package Overview
Dependencies
Maintainers
4
Versions
136
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gh - npm Package Compare versions

Comparing version 1.12.8 to 1.12.9

lib/default.gh.json

19

bin/gh.js
#!/usr/bin/env node
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -9,18 +9,21 @@ * Code licensed under the BSD License:

*
* @author Eduardo Lundgren <edu@rdo.io>
* @author Henrique Vicente <henriquevicente@gmail.com>
* @author Eduardo Lundgren <eduardo.lundgren@gmail.com>
* @author Zeno Rocha <zno.rocha@gmail.com>
* @author Ryan Garant <ryantgarant@gmail.com>
*/
'use strict';
'use strict'
var verbose = process.argv.indexOf('--verbose') !== -1;
var insane = process.argv.indexOf('--insane') !== -1;
var verbose = process.argv.indexOf('--verbose') !== -1
var insane = process.argv.indexOf('--insane') !== -1
if (verbose || insane) {
process.env.GH_VERBOSE = true;
process.env.GH_VERBOSE = true
}
if (insane) {
process.env.GH_VERBOSE_INSANE = true;
process.env.GH_VERBOSE_INSANE = true
}
require('../lib/cmd.js').run();
require('../lib/cmd.js').run()
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -10,3 +10,3 @@ * Code licensed under the BSD License:

'use strict';
'use strict'

@@ -17,15 +17,14 @@ var configs = require('./configs'),

path = require('path'),
tracker = require('./tracker'),
updateNotifier = require('update-notifier');
updateNotifier = require('update-notifier')
// -- Config -------------------------------------------------------------------
exports.clone = function (o) {
return JSON.parse(JSON.stringify(o));
};
exports.clone = function(o) {
return JSON.parse(JSON.stringify(o))
}
// -- Utils --------------------------------------------------------------------
exports.load = function () {
var config = configs.getConfig();
exports.load = function() {
var config = configs.getConfig()

@@ -37,65 +36,56 @@ exports.github = new Github({

version: config.api.version,
pathPrefix: config.api.pathPrefix
});
};
pathPrefix: config.api.pathPrefix,
})
}
exports.asyncReadPackages = function (callback) {
exports.asyncReadPackages = function(callback) {
function async(err, data) {
if (err) {
throw err;
throw err
}
callback(JSON.parse(data));
callback(JSON.parse(data))
}
fs.readFile(path.join(__dirname, '..', 'package.json'), async);
fs.readFile(path.join(__dirname, '..', 'package.json'), async)
configs.getPlugins().forEach(function (plugin) {
fs.readFile(path.join(
configs.getNodeModulesGlobalPath(), plugin, 'package.json'), async);
});
};
configs.getPlugins().forEach(function(plugin) {
fs.readFile(path.join(configs.getNodeModulesGlobalPath(), plugin, 'package.json'), async)
})
}
exports.notifyVersion = function (pkg) {
var notifier = updateNotifier({pkg: pkg}),
update,
track = 'notify/';
exports.notifyVersion = function(pkg) {
var notifier = updateNotifier({ pkg: pkg })
if (notifier.update) {
update = notifier.update;
track += update.name + '/' + update.latest + '/from/' + update.current;
tracker.track(track);
notifier.notify();
notifier.notify()
}
};
}
exports.checkVersion = function () {
exports.asyncReadPackages(exports.notifyVersion);
};
exports.checkVersion = function() {
exports.asyncReadPackages(exports.notifyVersion)
}
exports.expandAliases = function (options) {
var config = configs.getConfig();
exports.expandAliases = function(options) {
var config = configs.getConfig()
if (config.alias) {
options.fwd = config.alias[options.fwd] || options.fwd;
options.submit = config.alias[options.submit] || options.submit;
options.user = config.alias[options.user] || options.user;
options.fwd = config.alias[options.fwd] || options.fwd
options.submit = config.alias[options.submit] || options.submit
options.user = config.alias[options.user] || options.user
}
};
}
exports.find = function (filepath, opt_pattern) {
return fs.readdirSync(filepath).filter(function (file) {
return (opt_pattern || /.*/).test(file);
});
};
exports.find = function(filepath, opt_pattern) {
return fs.readdirSync(filepath).filter(function(file) {
return (opt_pattern || /.*/).test(file)
})
}
exports.getUser = function () {
return configs.getConfig().github_user;
};
exports.getUser = function() {
return configs.getConfig().github_user
}
// Export some config methods to allow plugins to access them
exports.getConfig = configs.getConfig;
exports.writeGlobalConfig = configs.writeGlobalConfig;
exports.getConfig = configs.getConfig
exports.writeGlobalConfig = configs.writeGlobalConfig
/*
* Copyright 2015, All Rights Reserved.
* Copyright 2015-2018, All Rights Reserved.
*

@@ -10,88 +10,93 @@ * Code licensed under the BSD License:

'use strict';
'use strict'
function CmdAnonymizer(commandDetails, redaction) {
this.last = null;
this.invoked = [];
this.redaction = redaction;
this.options = commandDetails.options;
this.shorthands = commandDetails.shorthands;
this.last = null
this.invoked = []
this.redaction = redaction
this.options = commandDetails.options
this.shorthands = commandDetails.shorthands
}
CmdAnonymizer.prototype.extractArgument = function (word) {
return word.replace(/-{0,2}/, '');
};
CmdAnonymizer.prototype.extractArgument = function(word) {
return word.replace(/-{0,2}/, '')
}
CmdAnonymizer.prototype.isOptionValue = function (option, value) {
CmdAnonymizer.prototype.isOptionValue = function(option, value) {
var choice = this.options[option],
booleans = ['true', 'false'];
booleans = ['true', 'false']
return ((choice instanceof Array && choice.indexOf(value) !== -1) ||
return (
(choice instanceof Array && choice.indexOf(value) !== -1) ||
(choice === Boolean && booleans.indexOf(value.toLowerCase()) !== -1) ||
(typeof choice === 'string' && choice === value));
};
(typeof choice === 'string' && choice === value)
)
}
CmdAnonymizer.prototype.isValueInOptions = function (options, value) {
CmdAnonymizer.prototype.isValueInOptions = function(options, value) {
if (!(options instanceof Array)) {
return this.isOptionValue(options, value);
return this.isOptionValue(options, value)
}
return options.some(function (each) {
return this.isOptionValue(this.extractArgument(each), value);
}, this);
};
return options.some(function(each) {
return this.isOptionValue(this.extractArgument(each), value)
}, this)
}
CmdAnonymizer.prototype.classify = function (word) {
CmdAnonymizer.prototype.classify = function(word) {
var arg = this.extractArgument(word),
whitelist = ['verbose', 'no-hooks'];
whitelist = ['verbose', 'no-hooks']
if (whitelist.indexOf(arg) === 0) {
this.invoked.push(word);
this.last = arg;
return;
this.invoked.push(word)
this.last = arg
return
}
if (this.shorthands && this.shorthands[arg]) {
this.invoked.push(word);
this.last = this.shorthands[arg];
return;
this.invoked.push(word)
this.last = this.shorthands[arg]
return
}
if (this.options && this.options[arg]) {
this.invoked.push(word);
this.last = arg;
return;
this.invoked.push(word)
this.last = arg
return
}
if (this.options && this.isValueInOptions(this.last, word)) {
this.invoked.push(word);
this.last = undefined;
return;
this.invoked.push(word)
this.last = undefined
return
}
if (this.options && this.options[this.last] instanceof Array &&
this.options[this.last].indexOf(word) !== -1) {
this.invoked.push(word);
this.last = undefined;
return;
if (
this.options &&
this.options[this.last] instanceof Array &&
this.options[this.last].indexOf(word) !== -1
) {
this.invoked.push(word)
this.last = undefined
return
}
this.invoked.push(this.redaction);
this.last = undefined;
};
this.invoked.push(this.redaction)
this.last = undefined
}
CmdAnonymizer.prototype.resolve = function (cmd) {
CmdAnonymizer.prototype.resolve = function(cmd) {
// quasi-strict white list approach (best-effort)
this.invoked.push(cmd.shift());
this.invoked.push(cmd.shift())
cmd.forEach(this.classify, this);
cmd.forEach(this.classify, this)
return this.invoked;
};
return this.invoked
}
CmdAnonymizer.prototype.resolveToString = function (cmd) {
return this.resolve(cmd).join(' ');
};
CmdAnonymizer.prototype.resolveToString = function(cmd) {
return this.resolve(cmd).join(' ')
}
module.exports = CmdAnonymizer;
module.exports = CmdAnonymizer
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -10,7 +10,7 @@ * Code licensed under the BSD License:

'use strict';
'use strict'
// -- Requires -------------------------------------------------------------------------------------
require('babel-polyfill');
require('babel-polyfill')

@@ -25,5 +25,4 @@ var async = require('async'),

path = require('path'),
tracker = require('./tracker'),
User = require('./cmds/user').Impl,
config = configs.getConfig();
config = configs.getConfig()

@@ -34,18 +33,17 @@ // -- Utils ----------------------------------------------------------------------------------------

if (commands) {
return commands.some(function (c) {
return options[c] !== undefined;
});
return commands.some(function(c) {
return options[c] !== undefined
})
}
return false;
return false
}
function invokePayload(options, command, cooked, remain) {
var payload;
var payload
if (command.DETAILS.payload && !hasCommandInOptions(command.DETAILS.commands, options)) {
payload = remain.concat();
payload.shift();
command.DETAILS.payload(payload, options);
payload = remain.concat()
payload.shift()
command.DETAILS.payload(payload, options)
}

@@ -55,29 +53,25 @@ }

function findCommand(name) {
var Command,
commandDir,
commandFiles,
commandPath;
var Command, commandDir, commandFiles, commandPath
commandDir = path.join(__dirname, 'cmds');
commandPath = path.join(commandDir, name + '.js');
commandDir = path.join(__dirname, 'cmds')
commandPath = path.join(commandDir, name + '.js')
if (fs.existsSync(commandPath)) {
Command = require(commandPath).Impl;
}
else {
commandFiles = base.find(commandDir, /\.js$/i);
commandFiles.every(function (file) {
commandPath = path.join(commandDir, file);
Command = require(commandPath).Impl;
Command = require(commandPath).Impl
} else {
commandFiles = base.find(commandDir, /\.js$/i)
commandFiles.every(function(file) {
commandPath = path.join(commandDir, file)
Command = require(commandPath).Impl
if (Command.DETAILS.alias === name) {
return false;
return false
}
Command = null;
return true;
});
Command = null
return true
})
}
return Command;
return Command
}

@@ -87,3 +81,3 @@

var Command = findCommand(name),
plugin;
plugin

@@ -93,19 +87,18 @@ // If command was not found, check if it is registered as a plugin.

try {
plugin = configs.getPlugin(name);
plugin = configs.getPlugin(name)
} catch (e) {
return null
}
catch(e) {
return null;
}
Command = plugin.Impl;
Command = plugin.Impl
// If plugin command exists, register the executed plugin name on
// process.env. This may simplify core plugin infrastructure.
process.env.NODEGH_PLUGIN = name;
process.env.NODEGH_PLUGIN = name
}
return Command;
return Command
}
exports.setUp = function () {
exports.setUp = function() {
var Command,

@@ -117,82 +110,67 @@ iterative,

remain = parsed.argv.remain,
cooked = parsed.argv.cooked;
cooked = parsed.argv.cooked
operations.push(function (callback) {
base.checkVersion();
operations.push(function(callback) {
base.checkVersion()
if (tracker.optOut !== undefined) {
callback();
return;
}
callback()
})
tracker.askPermission(null, function () {
callback();
});
});
operations.push(function(callback) {
var module = remain[0]
operations.push(function (callback) {
var module = remain[0];
if (cooked[0] === '--version' || cooked[0] === '-v') {
module = 'version';
module = 'version'
} else if (!remain.length || cooked.indexOf('-h') >= 0 || cooked.indexOf('--help') >= 0) {
module = 'help'
}
else if (!remain.length ||
(cooked.indexOf('-h') >= 0) ||
(cooked.indexOf('--help') >= 0)) {
module = 'help';
}
Command = loadCommand(module);
Command = loadCommand(module)
if (!Command) {
tracker.trackCommand(remain);
logger.error('Command not found');
return;
logger.error('Command not found')
return
}
options = nopt(
Command.DETAILS.options,
Command.DETAILS.shorthands, process.argv, 2);
options = nopt(Command.DETAILS.options, Command.DETAILS.shorthands, process.argv, 2)
iterative = Command.DETAILS.iterative;
iterative = Command.DETAILS.iterative
cooked = options.argv.cooked;
remain = options.argv.remain;
cooked = options.argv.cooked
remain = options.argv.remain
options.number = options.number || [remain[1]];
options.remote = options.remote || config.default_remote;
options.number = options.number || [remain[1]]
options.remote = options.remote || config.default_remote
if (module === 'help') {
callback();
callback()
} else {
User.login(callback)
}
else {
User.login(callback);
}
});
})
async.series(operations, function () {
async.series(operations, function() {
var iterativeValues,
remoteUrl = git.getRemoteUrl(options.remote);
remoteUrl = git.getRemoteUrl(options.remote)
options.isTTY = {};
options.isTTY.in = Boolean(process.stdin.isTTY);
options.isTTY.out = Boolean(process.stdout.isTTY);
options.loggedUser = base.getUser();
options.remoteUser = git.getUserFromRemoteUrl(remoteUrl);
options.isTTY = {}
options.isTTY.in = Boolean(process.stdin.isTTY)
options.isTTY.out = Boolean(process.stdout.isTTY)
options.loggedUser = base.getUser()
options.remoteUser = git.getUserFromRemoteUrl(remoteUrl)
if (!options.user) {
if (options.repo || options.all) {
options.user = options.loggedUser;
options.user = options.loggedUser
} else {
options.user = options.remoteUser || options.loggedUser
}
else {
options.user = options.remoteUser || options.loggedUser;
}
}
options.repo = options.repo || git.getRepoFromRemoteURL(remoteUrl);
options.currentBranch = options.currentBranch || git.getCurrentBranch();
options.repo = options.repo || git.getRepoFromRemoteURL(remoteUrl)
options.currentBranch = options.currentBranch || git.getCurrentBranch()
base.expandAliases(options);
options.github_host = config.github_host;
options.github_gist_host = config.github_gist_host;
base.expandAliases(options)
options.github_host = config.github_host
options.github_gist_host = config.github_gist_host

@@ -202,42 +180,38 @@ // Try to retrieve iterative values from iterative option key,

// present, assume [undefined] in order to initialize the loop.
iterativeValues = options[iterative] || [undefined];
iterativeValues = options[iterative] || [undefined]
iterativeValues.forEach(function (value) {
options = base.clone(options);
iterativeValues.forEach(function(value) {
options = base.clone(options)
// Value can be undefined when the command doesn't have a iterative
// option.
options[iterative] = value;
options[iterative] = value
invokePayload(options, Command, cooked, remain);
invokePayload(options, Command, cooked, remain)
new Command(options).run();
new Command(options).run()
})
})
}
tracker.trackCommand(options.argv.original, Command.DETAILS);
});
});
};
exports.run = function () {
exports.run = function() {
if (!fs.existsSync(configs.getUserHomePath())) {
configs.createGlobalConfig();
configs.createGlobalConfig()
}
base.load();
configs.getConfig();
base.load()
configs.getConfig()
// If configs.PLUGINS_PATH_KEY is undefined, try to cache it before proceeding.
if (configs.getConfig()[configs.PLUGINS_PATH_KEY] === undefined) {
configs.getNodeModulesGlobalPath();
configs.getNodeModulesGlobalPath()
}
try {
process.env.GH_PATH = path.join(__dirname, '../');
process.env.GH_PATH = path.join(__dirname, '../')
this.setUp();
this.setUp()
} catch (e) {
tracker.track('error');
console.error(e.stack || e);
console.error(e.stack || e)
}
};
}
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -11,3 +11,3 @@ * Code licensed under the BSD License:

'use strict';
'use strict'

@@ -19,3 +19,3 @@ // -- Requires -------------------------------------------------------------------------------------

logger = require('../logger'),
config = base.getConfig();
config = base.getConfig()

@@ -25,3 +25,3 @@ // -- Constructor ----------------------------------------------------------------------------------

function Alias(options) {
this.options = options;
this.options = options
}

@@ -34,83 +34,78 @@

description: 'Create alias for a username.',
commands: [
'add',
'list',
'remove'
],
commands: ['add', 'list', 'remove'],
options: {
'add': String,
'list': Boolean,
'remove': String,
'user': String
add: String,
list: Boolean,
remove: String,
user: String,
},
shorthands: {
'a': ['--add'],
'l': ['--list'],
'r': ['--remove'],
'u': ['--user']
a: ['--add'],
l: ['--list'],
r: ['--remove'],
u: ['--user'],
},
payload: function (payload, options) {
payload: function(payload, options) {
if (payload[0]) {
options.add = payload[0];
options.user = payload[1];
options.add = payload[0]
options.user = payload[1]
} else {
options.list = true
}
else {
options.list = true;
}
}
};
},
}
// -- Commands -------------------------------------------------------------------------------------
Alias.prototype.run = function () {
Alias.prototype.run = function() {
var instance = this,
options = instance.options;
options = instance.options
if (options.add) {
if (!options.user) {
logger.error('You must specify an user, try --user username.');
logger.error('You must specify an user, try --user username.')
}
logger.debug('Creating alias ' + options.add);
instance.add();
logger.debug('Creating alias ' + options.add)
instance.add()
}
if (options.list) {
instance.list(function (err, data) {
var item;
instance.list(function(err, data) {
var item
for (item in data) {
if (data.hasOwnProperty(item)) {
logger.log(logger.colors.cyan(item) + ': ' + logger.colors.magenta(data[item]));
logger.log(logger.colors.cyan(item) + ': ' + logger.colors.magenta(data[item]))
}
}
});
})
}
if (options.remove) {
logger.debug('Removing alias ' + options.remove);
instance.remove();
logger.debug('Removing alias ' + options.remove)
instance.remove()
}
};
}
Alias.prototype.add = function () {
Alias.prototype.add = function() {
var instance = this,
options = instance.options;
options = instance.options
configs.writeGlobalConfig('alias.' + options.add, options.user);
};
configs.writeGlobalConfig('alias.' + options.add, options.user)
}
Alias.prototype.list = function (opt_callback) {
opt_callback && opt_callback(null, config.alias);
};
Alias.prototype.list = function(opt_callback) {
opt_callback && opt_callback(null, config.alias)
}
Alias.prototype.remove = function () {
Alias.prototype.remove = function() {
var instance = this,
options = instance.options;
options = instance.options
delete config.alias[options.remove];
delete config.alias[options.remove]
configs.writeGlobalConfig('alias', config.alias);
};
configs.writeGlobalConfig('alias', config.alias)
}
exports.Impl = Alias;
exports.Impl = Alias
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -12,3 +12,3 @@ * Code licensed under the BSD License:

'use strict';
'use strict'

@@ -22,3 +22,3 @@ // -- Requires -------------------------------------------------------------------------------------

openUrl = require('open'),
config = base.getConfig();
config = base.getConfig()

@@ -28,3 +28,3 @@ // -- Constructor ----------------------------------------------------------------------------------

function Gists(options) {
this.options = options;
this.options = options
}

@@ -38,59 +38,54 @@

iterative: 'delete',
commands: [
'browser',
'delete',
'fork',
'list',
'new'
],
commands: ['browser', 'delete', 'fork', 'list', 'new'],
options: {
'browser': Boolean,
'content': String,
'delete': [String, Array],
'description': String,
'fork': String,
'id': String,
'list': Boolean,
'new': String,
'private': Boolean,
'user': String
browser: Boolean,
content: String,
delete: [String, Array],
description: String,
fork: String,
id: String,
list: Boolean,
new: String,
private: Boolean,
user: String,
},
shorthands: {
'B': ['--browser'],
'c': ['--content'],
'D': ['--delete'],
'd': ['--description'],
'f': ['--fork'],
'i': ['--id'],
'l': ['--list'],
'N': ['--new'],
'p': ['--private'],
'u': ['--user']
B: ['--browser'],
c: ['--content'],
D: ['--delete'],
d: ['--description'],
f: ['--fork'],
i: ['--id'],
l: ['--list'],
N: ['--new'],
p: ['--private'],
u: ['--user'],
},
payload: function (payload, options) {
options.list = true;
}
};
payload: function(payload, options) {
options.list = true
},
}
// -- Commands -------------------------------------------------------------------------------------
Gists.prototype.run = function () {
Gists.prototype.run = function() {
var instance = this,
operations,
options = instance.options;
options = instance.options
instance.config = config;
instance.config = config
if (options.paste) {
logger.error('Sorry, this functionality was removed.');
return;
logger.error('Sorry, this functionality was removed.')
return
}
if (options.browser) {
instance.browser(options.id || options.loggedUser);
instance.browser(options.id || options.loggedUser)
}
if (options.delete) {
hooks.invoke('gists.delete', instance, function (afterHooksCallback) {
logger.log('Deleting gist ' + logger.colors.green(options.loggedUser + '/' + options.delete));
hooks.invoke('gists.delete', instance, function(afterHooksCallback) {
logger.log(
'Deleting gist ' + logger.colors.green(options.loggedUser + '/' + options.delete)
)

@@ -102,145 +97,152 @@ inquirer.prompt(

message: 'Are you sure? This action CANNOT be undone. [y/N]',
name: 'confirmation'
}
], function (answers) {
name: 'confirmation',
},
],
function(answers) {
if (answers.confirmation.toLowerCase() === 'y') {
instance.delete(options.delete, function (err) {
instance.delete(options.delete, function(err) {
if (err) {
logger.error('Can\'t delete gist.');
return;
logger.error("Can't delete gist.")
return
}
});
})
afterHooksCallback();
afterHooksCallback()
} else {
logger.log('Not deleted.')
}
else {
logger.log('Not deleted.');
}
});
});
}
)
})
}
if (options.fork) {
hooks.invoke('gists.fork', instance, function (afterHooksCallback) {
logger.log('Forking gist on ' + logger.colors.green(options.loggedUser));
hooks.invoke('gists.fork', instance, function(afterHooksCallback) {
logger.log('Forking gist on ' + logger.colors.green(options.loggedUser))
instance.fork(options.fork, function (err, gist) {
instance.fork(options.fork, function(err, gist) {
if (err) {
logger.error(JSON.parse(err.message).message);
return;
logger.error(JSON.parse(err.message).message)
return
}
logger.log(gist.html_url);
afterHooksCallback();
});
});
logger.log(gist.html_url)
afterHooksCallback()
})
})
}
if (options.list) {
logger.log('Listing gists for ' + logger.colors.green(options.user));
logger.log('Listing gists for ' + logger.colors.green(options.user))
instance.list(options.user, function (err) {
instance.list(options.user, function(err) {
if (err) {
logger.error('Can\'t list gists for ' + options.user + '.');
return;
logger.error("Can't list gists for " + options.user + '.')
return
}
});
})
}
if (options.new) {
hooks.invoke('gists.new', instance, function (afterHooksCallback) {
var privacy = (options.private) ? 'private' : 'public';
hooks.invoke('gists.new', instance, function(afterHooksCallback) {
var privacy = options.private ? 'private' : 'public'
operations = [];
options.new = options.new;
options.new = options.new
logger.log('Creating ' + logger.colors.magenta(privacy) + ' gist on ' +
logger.colors.green(options.loggedUser));
logger.log(
'Creating ' +
logger.colors.magenta(privacy) +
' gist on ' +
logger.colors.green(options.loggedUser)
)
instance.new(options.new, options.content, function (err, gist) {
instance.new(options.new, options.content, function(err, gist) {
if (gist) {
options.id = gist.id;
options.id = gist.id
}
if (err) {
logger.error('Can\'t create gist. ' + JSON.parse(err.message).message);
return;
logger.error("Can't create gist. " + JSON.parse(err.message).message)
return
}
logger.log(gist.html_url);
logger.log(gist.html_url)
afterHooksCallback();
});
});
afterHooksCallback()
})
})
}
};
}
Gists.prototype.browser = function (gist) {
openUrl(config.github_gist_host + gist);
};
Gists.prototype.browser = function(gist) {
openUrl(config.github_gist_host + gist)
}
Gists.prototype.delete = function (id, opt_callback) {
Gists.prototype.delete = function(id, opt_callback) {
var payload = {
id: id
};
id: id,
}
base.github.gists.delete(payload, opt_callback);
};
base.github.gists.delete(payload, opt_callback)
}
Gists.prototype.fork = function (id, opt_callback) {
Gists.prototype.fork = function(id, opt_callback) {
var payload = {
id: id
};
id: id,
}
base.github.gists.fork(payload, opt_callback);
};
base.github.gists.fork(payload, opt_callback)
}
Gists.prototype.list = function (user, opt_callback) {
Gists.prototype.list = function(user, opt_callback) {
var instance = this,
payload;
payload
payload = {
user: user
};
user: user,
}
base.github.gists.getFromUser(payload, function (err, gists) {
instance.listCallback_(err, gists, opt_callback);
});
};
base.github.gists.getFromUser(payload, function(err, gists) {
instance.listCallback_(err, gists, opt_callback)
})
}
Gists.prototype.listCallback_ = function (err, gists, opt_callback) {
Gists.prototype.listCallback_ = function(err, gists, opt_callback) {
var instance = this,
options = instance.options;
options = instance.options
if (err && !options.all) {
logger.error(logger.getErrorMessage(err));
logger.error(logger.getErrorMessage(err))
}
if (gists && gists.length > 0) {
gists.forEach(function (gist) {
logger.log(logger.colors.yellow(gist.owner.login + '/' + gist.id) +
' ' + logger.getDuration(gist.updated_at));
gists.forEach(function(gist) {
logger.log(
logger.colors.yellow(gist.owner.login + '/' + gist.id) +
' ' +
logger.getDuration(gist.updated_at)
)
if (gist.description) {
logger.log(gist.description);
logger.log(gist.description)
}
logger.log(logger.colors.blue(gist.html_url) + '\n');
});
logger.log(logger.colors.blue(gist.html_url) + '\n')
})
opt_callback && opt_callback(err);
opt_callback && opt_callback(err)
}
};
}
Gists.prototype.new = function (name, content, opt_callback) {
Gists.prototype.new = function(name, content, opt_callback) {
var instance = this,
file = {},
options = instance.options,
payload;
payload
options.description = options.description || '';
options.description = options.description || ''
file[name] = {
content: content
};
content: content,
}

@@ -250,8 +252,8 @@ payload = {

files: file,
public: !options.private
};
public: !options.private,
}
base.github.gists.create(payload, opt_callback);
};
base.github.gists.create(payload, opt_callback)
}
exports.Impl = Gists;
exports.Impl = Gists
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -10,7 +10,7 @@ * Code licensed under the BSD License:

'use strict';
'use strict'
// -- Requires -------------------------------------------------------------------------------------
var logger = require('../logger');
var logger = require('../logger')

@@ -20,3 +20,3 @@ // -- Constructor ----------------------------------------------------------------------------------

function Hello(options) {
this.options = options;
this.options = options
}

@@ -29,31 +29,29 @@

description: 'Hello world example. Copy to start a new command.',
commands: [
'world'
],
commands: ['world'],
options: {
'world': Boolean
world: Boolean,
},
shorthands: {
'w': ['--world']
w: ['--world'],
},
payload: function (payload, options) {
options.world = true;
}
};
payload: function(payload, options) {
options.world = true
},
}
// -- Commands -------------------------------------------------------------------------------------
Hello.prototype.run = function () {
Hello.prototype.run = function() {
var instance = this,
options = instance.options;
options = instance.options
if (options.world) {
instance.world();
instance.world()
}
};
}
Hello.prototype.world = function () {
logger.log('hello world :)');
};
Hello.prototype.world = function() {
logger.log('hello world :)')
}
exports.Impl = Hello;
exports.Impl = Hello
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -11,3 +11,3 @@ * Code licensed under the BSD License:

'use strict';
'use strict'

@@ -22,3 +22,3 @@ // -- Requires -------------------------------------------------------------------------------------

stream = require('stream'),
url = require('url');
url = require('url')

@@ -28,5 +28,3 @@ // -- Constructor ----------------------------------------------------------------------------------

function Help() {
this.options = nopt(
Help.DETAILS.options,
Help.DETAILS.shorthands, process.argv, 2);
this.options = nopt(Help.DETAILS.options, Help.DETAILS.shorthands, process.argv, 2)
}

@@ -39,14 +37,14 @@

options: {
'all': Boolean,
'help': Boolean
all: Boolean,
help: Boolean,
},
shorthands: {
'a': ['--all'],
'h': ['--help']
}
};
a: ['--all'],
h: ['--help'],
},
}
// -- Commands -------------------------------------------------------------------------------------
Help.prototype.run = function () {
Help.prototype.run = function() {
var instance = this,

@@ -58,27 +56,26 @@ commands = [],

options = this.options,
plugins;
plugins
// Remove help from command list
files.splice(files.indexOf('help.js'), 1);
files.splice(files.indexOf('version.js'), 1);
files.splice(files.indexOf('help.js'), 1)
files.splice(files.indexOf('version.js'), 1)
// Get external plugins
plugins = configs.getPlugins();
plugins = configs.getPlugins()
plugins.forEach(function (plugin) {
plugins.forEach(function(plugin) {
try {
files.push(configs.getPluginPath(plugin));
files.push(configs.getPluginPath(plugin))
} catch (e) {
logger.warn("Can't get " + plugin + ' plugin path.')
}
catch (e) {
logger.warn('Can\'t get ' + plugin + ' plugin path.');
}
});
})
filter = options.argv.remain[0];
filter = options.argv.remain[0]
if (filter === 'help') {
filter = options.argv.remain[1];
filter = options.argv.remain[1]
}
files.forEach(function (dir) {
files.forEach(function(dir) {
var cmd = require(path.resolve(cmdDir, dir)),

@@ -88,19 +85,19 @@ alias = cmd.Impl.DETAILS.alias || '',

name = path.basename(dir, '.js').replace(/^gh-/, ''),
offset = 20 - alias.length - name.length;
offset = 20 - alias.length - name.length
if (offset < 1) {
offset = 1;
offset = 1
}
if (offset !== 1 && alias.length === 0) {
offset += 2;
offset += 2
}
if (filter && (filter !== alias) && (filter !== name)) {
return;
if (filter && filter !== alias && filter !== name) {
return
}
if (filter || options.all) {
flags = instance.groupOptions_(cmd.Impl.DETAILS);
offset = 1;
flags = instance.groupOptions_(cmd.Impl.DETAILS)
offset = 1
}

@@ -113,75 +110,77 @@

name: name,
offset: new Array(offset + 1).join(' ')
});
});
offset: new Array(offset + 1).join(' '),
})
})
if (filter && commands.length === 0) {
logger.error('No manual entry for ' + filter);
return;
logger.error('No manual entry for ' + filter)
return
}
logger.log(this.listCommands_(commands));
};
logger.log(this.listCommands_(commands))
}
Help.prototype.listFlags_ = function (command) {
Help.prototype.listFlags_ = function(command) {
var flags = command.flags,
content = '';
content = ''
flags.forEach(function (flag) {
content += ' ';
flags.forEach(function(flag) {
content += ' '
if (flag.shorthand) {
content += '-' + flag.shorthand + ', ';
content += '-' + flag.shorthand + ', '
}
content += '--' + flag.option;
content += '--' + flag.option
if (flag.cmd) {
content += '*';
content += '*'
}
if (flag.type) {
content += logger.colors.cyan(' (' + flag.type + ')');
content += logger.colors.cyan(' (' + flag.type + ')')
}
content += '\n';
});
content += '\n'
})
if (flags.length !== 0) {
content += '\n';
content += '\n'
}
return content;
};
return content
}
Help.prototype.listCommands_ = function (commands) {
Help.prototype.listCommands_ = function(commands) {
var content = 'usage: gh <command> [payload] [--flags] [--verbose] [--no-hooks]\n\n',
pos,
command;
command
content += 'List of available commands:\n';
content += 'List of available commands:\n'
for (pos in commands) {
if (commands.hasOwnProperty(pos)) {
command = commands[pos];
content += ' ';
command = commands[pos]
content += ' '
if (command.alias) {
content += logger.colors.magenta(command.alias) + ', ';
content += logger.colors.magenta(command.alias) + ', '
}
content += logger.colors.magenta(command.name) + command.offset + command.description + '\n';
content +=
logger.colors.magenta(command.name) + command.offset + command.description + '\n'
content += this.listFlags_(command);
content += this.listFlags_(command)
}
}
content += '\n(*) Flags that can execute an action.\n' +
'\'gh help\' lists available commands.\n' +
'\'gh help -a\' lists all available subcommands.';
content +=
'\n(*) Flags that can execute an action.\n' +
"'gh help' lists available commands.\n" +
"'gh help -a' lists all available subcommands."
return content;
};
return content
}
Help.prototype.groupOptions_ = function (details) {
Help.prototype.groupOptions_ = function(details) {
var instance = this,

@@ -191,21 +190,20 @@ cmd,

shorthands,
grouped = [];
grouped = []
options = Object.keys(details.options);
shorthands = Object.keys(details.shorthands);
options = Object.keys(details.options)
shorthands = Object.keys(details.shorthands)
options.forEach(function (option) {
var foundShorthand,
type;
options.forEach(function(option) {
var foundShorthand, type
shorthands.forEach(function (shorthand) {
var shorthandValue = details.shorthands[shorthand][0];
shorthands.forEach(function(shorthand) {
var shorthandValue = details.shorthands[shorthand][0]
if (shorthandValue === '--' + option) {
foundShorthand = shorthand;
foundShorthand = shorthand
}
});
})
cmd = instance.isCommand_(details, option);
type = instance.getType_(details.options[option]);
cmd = instance.isCommand_(details, option)
type = instance.getType_(details.options[option])

@@ -216,15 +214,15 @@ grouped.push({

shorthand: foundShorthand,
type: type
});
});
type: type,
})
})
return grouped;
};
return grouped
}
Help.prototype.getType_ = function (type) {
Help.prototype.getType_ = function(type) {
var types,
separator = ', ';
separator = ', '
if (Array.isArray(type)) {
types = type;
types = type

@@ -234,14 +232,14 @@ // Iterative options have an Array reference as the last type

if (type[type.length - 1] === Array) {
type.pop();
type.pop()
}
type = '';
type = ''
types.forEach(function (eachType) {
type += this.getType_(eachType) + separator;
}, this);
types.forEach(function(eachType) {
type += this.getType_(eachType) + separator
}, this)
type = type.substr(0, type.length - separator.length);
type = type.substr(0, type.length - separator.length)
return type;
return type
}

@@ -251,35 +249,35 @@

case String:
type = 'String';
break;
type = 'String'
break
case url:
type = 'Url';
break;
type = 'Url'
break
case Number:
type = 'Number';
break;
type = 'Number'
break
case path:
type = 'Path';
break;
type = 'Path'
break
case stream.Stream:
type = 'Stream';
break;
type = 'Stream'
break
case Date:
type = 'Date';
break;
type = 'Date'
break
case Boolean:
type = 'Boolean';
break;
type = 'Boolean'
break
}
return type;
};
return type
}
Help.prototype.isCommand_ = function (details, option) {
if (details.commands && (details.commands.indexOf(option) > -1)) {
return true;
Help.prototype.isCommand_ = function(details, option) {
if (details.commands && details.commands.indexOf(option) > -1) {
return true
}
return false;
};
return false
}
exports.Impl = Help;
exports.Impl = Help
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -11,3 +11,3 @@ * Code licensed under the BSD License:

'use strict';
'use strict'

@@ -21,3 +21,3 @@ // -- Requires -------------------------------------------------------------------------------------

openUrl = require('open'),
config = base.getConfig();
config = base.getConfig()

@@ -27,6 +27,6 @@ // -- Constructor ----------------------------------------------------------------------------------

function Issue(options) {
this.options = options;
this.options = options
if (!options.repo && !options.all) {
logger.error('You must specify a Git repository with a GitHub remote to run this command');
logger.error('You must specify a Git repository with a GitHub remote to run this command')
}

@@ -41,118 +41,146 @@ }

iterative: 'number',
commands: [
'browser',
'close',
'comment',
'list',
'new',
'open',
'search'
],
commands: ['assign', 'browser', 'close', 'comment', 'list', 'new', 'open', 'search'],
options: {
'all': Boolean,
'assignee': String,
'browser': Boolean,
'close': Boolean,
'comment': String,
'detailed': Boolean,
'label': String,
'list': Boolean,
'message': String,
'milestone': [Number, String],
all: Boolean,
assign: Boolean,
assignee: String,
browser: Boolean,
close: Boolean,
comment: String,
detailed: Boolean,
label: String,
list: Boolean,
link: Boolean,
message: String,
milestone: [Number, String],
'no-milestone': Boolean,
'new': Boolean,
'number': [String, Array],
'open': Boolean,
'remote': String,
'repo': String,
'search': String,
'state': ['open', 'closed'],
'title': String,
'user': String
new: Boolean,
number: [String, Array],
open: Boolean,
remote: String,
repo: String,
search: String,
state: ['open', 'closed'],
title: String,
user: String,
},
shorthands: {
'a': ['--all'],
'A': ['--assignee'],
'B': ['--browser'],
'C': ['--close'],
'c': ['--comment'],
'd': ['--detailed'],
'L': ['--label'],
'l': ['--list'],
'm': ['--message'],
'M': ['--milestone'],
'N': ['--new'],
'n': ['--number'],
'o': ['--open'],
'r': ['--repo'],
's': ['--search'],
'S': ['--state'],
't': ['--title'],
'u': ['--user']
a: ['--all'],
A: ['--assignee'],
B: ['--browser'],
C: ['--close'],
c: ['--comment'],
d: ['--detailed'],
L: ['--label'],
k: ['--link'],
l: ['--list'],
m: ['--message'],
M: ['--milestone'],
N: ['--new'],
n: ['--number'],
o: ['--open'],
r: ['--repo'],
s: ['--search'],
S: ['--state'],
t: ['--title'],
u: ['--user'],
},
payload: function (payload, options) {
payload: function(payload, options) {
if (payload[0]) {
if (/^\d+$/.test(payload[0])) {
options.browser = true;
options.number = payload[0];
return;
options.browser = true
options.number = payload[0]
return
}
options.new = true;
options.title = options.title || payload[0];
options.message = options.message || payload[1];
options.new = true
options.title = options.title || payload[0]
options.message = options.message || payload[1]
} else {
options.list = true
}
else {
options.list = true;
}
}
};
},
}
Issue.STATE_CLOSED = 'closed';
Issue.STATE_OPEN = 'open';
Issue.STATE_CLOSED = 'closed'
Issue.STATE_OPEN = 'open'
// -- Commands -------------------------------------------------------------------------------------
Issue.prototype.run = function () {
Issue.prototype.run = function() {
var instance = this,
options = instance.options;
options = instance.options
instance.config = config;
instance.config = config
options.state = options.state || Issue.STATE_OPEN;
options.state = options.state || Issue.STATE_OPEN
if (options.assign) {
hooks.invoke('issue.assign', instance, function(afterHooksCallback) {
var user
if (options.user) {
user = options.user
} else {
user = options.loggedUser
}
logger.log(
'Assigning issue ' +
logger.colors.green('#' + options.number) +
' on ' +
logger.colors.green(user + '/' + options.repo) +
' to ' +
logger.colors.green(options.assignee)
)
instance.assign(function(err, issue) {
if (err) {
logger.error("Can't assign issue.")
return
}
logger.log(issue.html_url)
afterHooksCallback()
})
})
}
if (options.browser) {
instance.browser(options.user, options.repo, options.number);
instance.browser(options.user, options.repo, options.number)
}
if (options.close) {
hooks.invoke('issue.close', instance, function (afterHooksCallback) {
options.state = Issue.STATE_CLOSED;
hooks.invoke('issue.close', instance, function(afterHooksCallback) {
options.state = Issue.STATE_CLOSED
logger.log('Closing issue ' + logger.colors.green('#' + options.number) +
' on ' + logger.colors.green(options.user + '/' + options.repo));
logger.log(
'Closing issue ' +
logger.colors.green('#' + options.number) +
' on ' +
logger.colors.green(options.user + '/' + options.repo)
)
instance.close(function (err, issue) {
instance.close(function(err, issue) {
if (err) {
logger.error('Can\'t close issue.');
return;
logger.error("Can't close issue.")
return
}
logger.log(issue.html_url);
afterHooksCallback();
});
});
logger.log(issue.html_url)
afterHooksCallback()
})
})
}
if (options.comment) {
logger.log('Adding comment on issue ' + logger.colors.green('#' + options.number));
logger.log('Adding comment on issue ' + logger.colors.green('#' + options.number))
instance.comment(function (err, issue) {
instance.comment(function(err, issue) {
if (err) {
logger.error('Can\'t add comment.');
return;
logger.error("Can't add comment.")
return
}
logger.log(issue.html_url);
});
logger.log(issue.html_url)
})
}

@@ -162,22 +190,29 @@

if (options.all) {
logger.log('Listing ' + logger.colors.green(options.state) + ' issues for ' +
logger.colors.green(options.user));
logger.log(
'Listing ' +
logger.colors.green(options.state) +
' issues for ' +
logger.colors.green(options.user)
)
instance.listFromAllRepositories(function (err) {
instance.listFromAllRepositories(function(err) {
if (err) {
logger.error('Can\'t list issues for ' + options.user + '.');
return;
logger.error("Can't list issues for " + options.user + '.')
return
}
});
}
else {
logger.log('Listing ' + logger.colors.green(options.state) +
' issues on ' + logger.colors.green(options.user + '/' + options.repo));
})
} else {
logger.log(
'Listing ' +
logger.colors.green(options.state) +
' issues on ' +
logger.colors.green(options.user + '/' + options.repo)
)
instance.list(options.user, options.repo, function (err) {
instance.list(options.user, options.repo, function(err) {
if (err) {
logger.error('Can\'t list issues on ' + options.user + '/' + options.repo);
return;
logger.error("Can't list issues on " + options.user + '/' + options.repo)
return
}
});
})
}

@@ -187,92 +222,116 @@ }

if (options.new) {
hooks.invoke('issue.new', instance, function (afterHooksCallback) {
logger.log('Creating a new issue on ' + logger.colors.green(options.user + '/' + options.repo));
hooks.invoke('issue.new', instance, function(afterHooksCallback) {
logger.log(
'Creating a new issue on ' + logger.colors.green(options.user + '/' + options.repo)
)
instance.new(function (err, issue) {
instance.new(function(err, issue) {
if (err) {
logger.error('Can\'t create new issue.');
return;
logger.error("Can't create new issue.")
return
}
if (issue) {
options.number = issue.number;
options.number = issue.number
}
logger.log(issue.html_url);
afterHooksCallback();
});
});
logger.log(issue.html_url)
afterHooksCallback()
})
})
}
if (options.open) {
hooks.invoke('issue.open', instance, function (afterHooksCallback) {
logger.log('Opening issue ' + logger.colors.green('#' + options.number) +
' on ' + logger.colors.green(options.user + '/' + options.repo));
hooks.invoke('issue.open', instance, function(afterHooksCallback) {
logger.log(
'Opening issue ' +
logger.colors.green('#' + options.number) +
' on ' +
logger.colors.green(options.user + '/' + options.repo)
)
instance.open(function (err, issue) {
instance.open(function(err, issue) {
if (err) {
logger.error('Can\'t open issue.');
return;
logger.error("Can't open issue.")
return
}
logger.log(issue.html_url);
afterHooksCallback();
});
});
logger.log(issue.html_url)
afterHooksCallback()
})
})
}
if (options.search) {
var repo = options.repo;
var repo = options.repo
if (options.all) {
repo = undefined;
logger.log('Searching for ' + logger.colors.green(options.search) +
' in issues for ' + logger.colors.green(options.user));
repo = undefined
logger.log(
'Searching for ' +
logger.colors.green(options.search) +
' in issues for ' +
logger.colors.green(options.user)
)
} else {
logger.log('Searching for ' + logger.colors.green(options.search) +
' in issues on ' + logger.colors.green(options.user + '/' + options.repo));
logger.log(
'Searching for ' +
logger.colors.green(options.search) +
' in issues on ' +
logger.colors.green(options.user + '/' + options.repo)
)
}
instance.search(options.user, repo, function (err) {
instance.search(options.user, repo, function(err) {
if (err) {
if (options.all) {
logger.error('Can\'t search issues for ' + options.user);
return;
logger.error("Can't search issues for " + options.user)
return
} else {
logger.error('Can\'t search issues on ' + options.user + '/' + options.repo);
return;
logger.error("Can't search issues on " + options.user + '/' + options.repo)
return
}
}
});
})
}
}
};
Issue.prototype.assign = function(opt_callback) {
var instance = this
Issue.prototype.browser = function (user, repo, number) {
instance.getIssue_(function(err, issue) {
if (err) {
opt_callback && opt_callback(err)
} else {
instance.editIssue_(issue.title, Issue.STATE_OPEN, opt_callback)
}
})
}
Issue.prototype.browser = function(user, repo, number) {
if (!number) {
number = '';
number = ''
}
openUrl(config.github_host + user + '/' + repo + '/issues/' + number);
};
openUrl(config.github_host + user + '/' + repo + '/issues/' + number)
}
Issue.prototype.close = function (opt_callback) {
var instance = this;
Issue.prototype.close = function(opt_callback) {
var instance = this
instance.getIssue_(function (err, issue) {
instance.getIssue_(function(err, issue) {
if (err) {
opt_callback && opt_callback(err);
opt_callback && opt_callback(err)
} else {
instance.editIssue_(issue.title, Issue.STATE_CLOSED, opt_callback)
}
else {
instance.editIssue_(issue.title, Issue.STATE_CLOSED, opt_callback);
}
});
};
})
}
Issue.prototype.comment = function (opt_callback) {
Issue.prototype.comment = function(opt_callback) {
var instance = this,
options = instance.options,
body,
payload;
payload
body = logger.applyReplacements(options.comment, config.replace) + config.signature;
body = logger.applyReplacements(options.comment, config.replace) + config.signature

@@ -283,14 +342,14 @@ payload = {

repo: options.repo,
user: options.user
};
user: options.user,
}
base.github.issues.createComment(payload, opt_callback);
};
base.github.issues.createComment(payload, opt_callback)
}
Issue.prototype.editIssue_ = function (title, state, opt_callback) {
Issue.prototype.editIssue_ = function(title, state, opt_callback) {
var instance = this,
options = instance.options,
payload;
payload
options.label = options.label || [];
options.label = options.label || []

@@ -305,12 +364,12 @@ payload = {

title: title,
user: options.user
};
user: options.user,
}
base.github.issues.edit(payload, opt_callback);
};
base.github.issues.edit(payload, opt_callback)
}
Issue.prototype.getIssue_ = function (opt_callback) {
Issue.prototype.getIssue_ = function(opt_callback) {
var instance = this,
options = instance.options,
payload;
payload

@@ -320,15 +379,15 @@ payload = {

repo: options.repo,
user: options.user
};
user: options.user,
}
base.github.issues.getRepoIssue(payload, opt_callback);
};
base.github.issues.getRepoIssue(payload, opt_callback)
}
Issue.prototype.list = function (user, repo, opt_callback) {
Issue.prototype.list = function(user, repo, opt_callback) {
var instance = this,
options = instance.options,
operations = [],
payload;
payload
options.label = options.label || '';
options.label = options.label || ''

@@ -339,132 +398,148 @@ payload = {

state: options.state,
user: user
};
user: user,
}
if (options['no-milestone']) {
payload.milestone = 'none';
payload.milestone = 'none'
} else if (options.milestone) {
payload.milestone = options.milestone;
payload.milestone = options.milestone
}
if (options.milestone) {
operations.push(function (callback) {
base.github.issues.getAllMilestones({
repo: repo,
user: user
}, function (err, results) {
if (err) {
logger.warn(err.message);
}
results.some(function (milestone) {
if (options.milestone === milestone.title) {
logger.debug('Milestone ' + milestone.title + ' number: ' + milestone.number);
payload.milestone = milestone.number;
return true;
operations.push(function(callback) {
base.github.issues.getAllMilestones(
{
repo: repo,
user: user,
},
function(err, results) {
if (err) {
logger.warn(err.message)
}
});
callback();
});
});
results.some(function(milestone) {
if (options.milestone === milestone.title) {
logger.debug(
'Milestone ' + milestone.title + ' number: ' + milestone.number
)
payload.milestone = milestone.number
return true
}
})
callback()
}
)
})
}
if (options.assignee) {
payload.assignee = options.assignee;
payload.assignee = options.assignee
}
operations.push(function (callback) {
base.github.issues.repoIssues(payload, callback);
});
operations.push(function(callback) {
base.github.issues.repoIssues(payload, callback)
})
async.series(operations, function (err, results) {
var issues = [];
async.series(operations, function(err, results) {
var issues = []
if (err && !options.all) {
logger.error(logger.getErrorMessage(err));
logger.error(logger.getErrorMessage(err))
}
results.forEach(function (result) {
results.forEach(function(result) {
if (result) {
issues = issues.concat(result);
issues = issues.concat(result)
}
});
})
issues.sort(function (a, b) {
return a.number > b.number ? -1 : 1;
});
issues.sort(function(a, b) {
return a.number > b.number ? -1 : 1
})
if (issues && issues.length > 0) {
issues.forEach(function (issue) {
var labels = issue.label || [];
issues.forEach(function(issue) {
var labels = issue.label || []
logger.log(logger.colors.green('#' + issue.number) + ' ' + issue.title + ' ' +
logger.colors.magenta('@' + issue.user.login + ' (' + logger.getDuration(issue.created_at) + ')'));
var headline =
logger.colors.green('#' + issue.number) +
' ' +
issue.title +
' ' +
logger.colors.magenta(
'@' + issue.user.login + ' (' + logger.getDuration(issue.created_at) + ')'
)
if (options.link) {
headline += ' ' + logger.colors.blue(issue.html_url)
}
logger.log(headline)
if (options.detailed) {
if (issue.body) {
logger.log(issue.body);
logger.log(issue.body)
}
labels.forEach(function (label) {
labels.push(label.name);
});
labels.forEach(function(label) {
labels.push(label.name)
})
if (labels.length > 0) {
logger.log(logger.colors.green('label: ') + labels.join(', '));
logger.log(logger.colors.green('label: ') + labels.join(', '))
}
if (issue.milestone) {
logger.log(logger.colors.green('milestone: ') +
issue.milestone.title + ' - ' + issue.milestone.number);
logger.log(
logger.colors.green('milestone: ') +
issue.milestone.title +
' - ' +
issue.milestone.number
)
}
logger.log(logger.colors.blue(issue.html_url));
logger.log(logger.colors.blue(issue.html_url))
}
});
})
opt_callback && opt_callback(err);
opt_callback && opt_callback(err)
}
});
};
})
}
Issue.prototype.listFromAllRepositories = function (opt_callback) {
Issue.prototype.listFromAllRepositories = function(opt_callback) {
var instance = this,
options = instance.options,
payload;
payload
payload = {
type: 'all',
user: options.user
};
user: options.user,
}
base.github.repos.getAll(payload, function (err, repositories) {
base.github.repos.getAll(payload, function(err, repositories) {
if (err) {
opt_callback && opt_callback(err);
opt_callback && opt_callback(err)
} else {
repositories.forEach(function(repository) {
instance.list(repository.owner.login, repository.name, opt_callback)
})
}
else {
repositories.forEach(function (repository) {
instance.list(repository.owner.login, repository.name, opt_callback);
});
}
});
};
})
}
Issue.prototype.new = function (opt_callback) {
Issue.prototype.new = function(opt_callback) {
var instance = this,
options = instance.options,
body,
payload;
payload
if (options.message) {
body = logger.applyReplacements(options.message, config.replace);
body = logger.applyReplacements(options.message, config.replace)
}
if (options.label) {
options.label = options.label.split(',');
options.label = options.label.split(',')
} else {
options.label = []
}
else {
options.label = [];
}

@@ -477,22 +552,21 @@ payload = {

user: options.user,
labels: options.label
};
labels: options.label,
}
base.github.issues.create(payload, opt_callback);
};
base.github.issues.create(payload, opt_callback)
}
Issue.prototype.open = function (opt_callback) {
var instance = this;
Issue.prototype.open = function(opt_callback) {
var instance = this
instance.getIssue_(function (err, issue) {
instance.getIssue_(function(err, issue) {
if (err) {
opt_callback && opt_callback(err);
opt_callback && opt_callback(err)
} else {
instance.editIssue_(issue.title, Issue.STATE_OPEN, opt_callback)
}
else {
instance.editIssue_(issue.title, Issue.STATE_OPEN, opt_callback);
}
});
};
})
}
Issue.prototype.search = function (user, repo, opt_callback) {
Issue.prototype.search = function(user, repo, opt_callback) {
var instance = this,

@@ -502,73 +576,88 @@ options = instance.options,

query = [],
payload;
payload
options.label = options.label || '';
options.label = options.label || ''
if (!options.all) {
query.push('repo:' + repo);
query.push('repo:' + repo)
}
query.push('user:' + user);
query.push(options.search);
query = query.join('+');
query.push('user:' + user)
query.push(options.search)
query = query.join('+')
payload = {
q: query,
type: 'Issues'
};
type: 'Issues',
}
operations.push(function (callback) {
base.github.search.issues(payload, callback);
});
operations.push(function(callback) {
base.github.search.issues(payload, callback)
})
async.series(operations, function (err, results) {
var issues = [];
async.series(operations, function(err, results) {
var issues = []
if (err && !options.all) {
logger.error(logger.getErrorMessage(err));
logger.error(logger.getErrorMessage(err))
}
results[0].items.forEach(function (result) {
results[0].items.forEach(function(result) {
if (result) {
issues = issues.concat(result);
issues = issues.concat(result)
}
});
})
issues.sort(function (a, b) {
return a.number > b.number ? -1 : 1;
});
issues.sort(function(a, b) {
return a.number > b.number ? -1 : 1
})
if (issues && issues.length > 0) {
issues.forEach(function (issue) {
var labels = issue.label || [];
issues.forEach(function(issue) {
var labels = issue.label || []
logger.log(logger.colors.green('#' + issue.number) + ' ' + issue.title + ' ' +
logger.colors.magenta('@' + issue.user.login + ' (' + logger.getDuration(issue.created_at) + ')'));
logger.log(
logger.colors.green('#' + issue.number) +
' ' +
issue.title +
' ' +
logger.colors.magenta(
'@' +
issue.user.login +
' (' +
logger.getDuration(issue.created_at) +
')'
)
)
if (options.detailed) {
if (issue.body) {
logger.log(issue.body);
logger.log(issue.body)
}
labels.forEach(function (label) {
labels.push(label.name);
});
labels.forEach(function(label) {
labels.push(label.name)
})
if (labels.length > 0) {
logger.log(logger.colors.green('label: ') + labels.join(', '));
logger.log(logger.colors.green('label: ') + labels.join(', '))
}
if (issue.milestone) {
logger.log(logger.colors.green('milestone: ') +
issue.milestone.title + ' - ' + issue.milestone.number);
logger.log(
logger.colors.green('milestone: ') +
issue.milestone.title +
' - ' +
issue.milestone.number
)
}
logger.log(logger.colors.blue(issue.html_url));
logger.log(logger.colors.blue(issue.html_url))
}
});
opt_callback && opt_callback(err);
})
opt_callback && opt_callback(err)
}
});
};
})
}
exports.Impl = Issue;
exports.Impl = Issue
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -11,3 +11,3 @@ * Code licensed under the BSD License:

'use strict';
'use strict'

@@ -18,3 +18,3 @@ // -- Requires -------------------------------------------------------------------------------------

base = require('../base'),
logger = require('../logger');
logger = require('../logger')

@@ -24,10 +24,10 @@ // -- Constructor ----------------------------------------------------------------------------------

function Milestone(options) {
this.options = options;
this.options = options
if (options.organization) {
options.all = true;
options.all = true
}
if (!options.repo && !options.all) {
logger.error('You must specify a Git repository with a GitHub remote to run this command');
logger.error('You must specify a Git repository with a GitHub remote to run this command')
}

@@ -42,91 +42,96 @@ }

iterative: 'number',
commands: [
'list',
],
commands: ['list'],
options: {
'all': Boolean,
'organization': String,
'list': Boolean,
all: Boolean,
organization: String,
list: Boolean,
},
shorthands: {
'a': ['--all'],
'o': ['--organization'],
'l': ['--list'],
a: ['--all'],
o: ['--organization'],
l: ['--list'],
},
payload: function (payload, options) {
options.list = true;
}
};
payload: function(payload, options) {
options.list = true
},
}
// -- Commands -------------------------------------------------------------------------------------
Milestone.prototype.run = function () {
Milestone.prototype.run = function() {
var instance = this,
options = instance.options;
options = instance.options
if (options.list) {
if (options.all) {
logger.log('Listing milestones for ' +
logger.colors.green(options.organization || options.user));
logger.log(
'Listing milestones for ' +
logger.colors.green(options.organization || options.user)
)
instance.listFromAllRepositories(function (err) {
instance.listFromAllRepositories(function(err) {
if (err) {
logger.error('Can\'t list milestones for ' + options.user + '.');
return;
logger.error("Can't list milestones for " + options.user + '.')
return
}
});
}
else {
logger.log('Listing milestones on ' + logger.colors.green(options.user + '/' + options.repo));
})
} else {
logger.log(
'Listing milestones on ' + logger.colors.green(options.user + '/' + options.repo)
)
instance.list(options.user, options.repo, function (err) {
instance.list(options.user, options.repo, function(err) {
if (err) {
logger.error('Can\'t list milestones on ' + options.user + '/' + options.repo);
return;
logger.error("Can't list milestones on " + options.user + '/' + options.repo)
return
}
});
})
}
}
};
}
Milestone.prototype.list = function (user, repo, opt_callback) {
Milestone.prototype.list = function(user, repo, opt_callback) {
var instance = this,
options = instance.options,
payload;
payload
payload = {
repo: repo,
user: user
};
user: user,
}
base.github.issues.getAllMilestones(payload, function (err, milestones) {
base.github.issues.getAllMilestones(payload, function(err, milestones) {
if (err && !options.all) {
logger.error(logger.getErrorMessage(err));
logger.error(logger.getErrorMessage(err))
}
milestones.sort(function (a, b) {
return a.due_date > b.due_date ? -1 : 1;
});
milestones.sort(function(a, b) {
return a.due_date > b.due_date ? -1 : 1
})
if (milestones && milestones.length > 0) {
milestones.forEach(function (milestone) {
var due = milestone.due_on ? logger.getDuration(milestone.due_on) : 'n/a';
var description = milestone.description || '';
var prefix = '';
milestones.forEach(function(milestone) {
var due = milestone.due_on ? logger.getDuration(milestone.due_on) : 'n/a'
var description = milestone.description || ''
var prefix = ''
if (options.all) {
prefix = logger.colors.blue(user + '/' + repo + ' ');
prefix = logger.colors.blue(user + '/' + repo + ' ')
}
logger.log(prefix +
logger.colors.green(milestone.title) + ' ' + (description + ' ').trim() +
logger.colors.magenta('@' + milestone.state + ' (due ' + due + ')'));
});
logger.log(
prefix +
logger.colors.green(milestone.title) +
' ' +
(description + ' ').trim() +
logger.colors.magenta('@' + milestone.state + ' (due ' + due + ')')
)
})
}
opt_callback && opt_callback(err);
});
};
opt_callback && opt_callback(err)
})
}
Milestone.prototype.listFromAllRepositories = function (opt_callback) {
Milestone.prototype.listFromAllRepositories = function(opt_callback) {
var instance = this,

@@ -136,30 +141,29 @@ options = instance.options,

op = 'getAll',
payload;
payload
payload = {
type: 'all',
user: options.user
};
user: options.user,
}
if (options.organization) {
op = 'getFromOrg';
payload.org = options.organization;
op = 'getFromOrg'
payload.org = options.organization
}
base.github.repos[op](payload, function (err, repositories) {
base.github.repos[op](payload, function(err, repositories) {
if (err) {
opt_callback && opt_callback(err);
opt_callback && opt_callback(err)
} else {
repositories.forEach(function(repository) {
operations.push(function(callback) {
instance.list(repository.owner.login, repository.name, callback)
})
})
}
else {
repositories.forEach(function (repository) {
operations.push(function (callback) {
instance.list(repository.owner.login, repository.name, callback);
});
});
}
async.series(operations, opt_callback);
});
};
async.series(operations, opt_callback)
})
}
exports.Impl = Milestone;
exports.Impl = Milestone
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -11,3 +11,3 @@ * Code licensed under the BSD License:

'use strict';
'use strict'

@@ -19,3 +19,3 @@ // -- Requires -------------------------------------------------------------------------------------

logger = require('../logger'),
printed = {};
printed = {}

@@ -25,6 +25,6 @@ // -- Constructor ----------------------------------------------------------------------------------

function Notifications(options) {
this.options = options;
this.options = options
if (!options.repo) {
logger.error('You must specify a Git repository with a GitHub remote to run this command');
logger.error('You must specify a Git repository with a GitHub remote to run this command')
}

@@ -38,42 +38,43 @@ }

description: 'Provides a set of util commands to work with Notifications.',
commands: [
'latest',
'watch'
],
commands: ['latest', 'watch'],
options: {
'latest': Boolean,
'remote': String,
'repo': String,
'user': String,
'watch': Boolean
latest: Boolean,
remote: String,
repo: String,
user: String,
watch: Boolean,
},
shorthands: {
'l': ['--latest'],
'r': ['--repo'],
'u': ['--user'],
'w': ['--watch']
l: ['--latest'],
r: ['--repo'],
u: ['--user'],
w: ['--watch'],
},
payload: function (payload, options) {
options.latest = true;
}
};
payload: function(payload, options) {
options.latest = true
},
}
// -- Commands -------------------------------------------------------------------------------------
Notifications.prototype.run = function () {
Notifications.prototype.run = function() {
var instance = this,
options = instance.options;
options = instance.options
if (options.latest) {
logger.log('Listing activities on ' + logger.colors.green(options.user + '/' + options.repo));
instance.latest();
logger.log(
'Listing activities on ' + logger.colors.green(options.user + '/' + options.repo)
)
instance.latest()
}
if (options.watch) {
logger.log('Watching any activity on ' + logger.colors.green(options.user + '/' + options.repo));
instance.watch();
logger.log(
'Watching any activity on ' + logger.colors.green(options.user + '/' + options.repo)
)
instance.watch()
}
};
}
Notifications.prototype.latest = function (opt_watch) {
Notifications.prototype.latest = function(opt_watch) {
var instance = this,

@@ -84,42 +85,40 @@ options = instance.options,

listEvents,
filteredListEvents = [];
filteredListEvents = []
operations = [
function (callback) {
function(callback) {
payload = {
user: options.user,
repo: options.repo
};
repo: options.repo,
}
base.github.events.getFromRepo(payload, function (err, data) {
base.github.events.getFromRepo(payload, function(err, data) {
if (!err) {
listEvents = data;
listEvents = data
}
callback(err);
});
callback(err)
})
},
function (callback) {
listEvents.forEach(function (event) {
event.txt = instance.getMessage_(event);
function(callback) {
listEvents.forEach(function(event) {
event.txt = instance.getMessage_(event)
if (opt_watch) {
if (!printed[event.created_at]) {
filteredListEvents.push(event);
filteredListEvents.push(event)
}
} else {
filteredListEvents.push(event)
}
else {
filteredListEvents.push(event);
}
printed[event.created_at] = true;
});
callback();
}
];
printed[event.created_at] = true
})
callback()
},
]
async.series(operations, function (err) {
async.series(operations, function(err) {
if (err) {
logger.error('Can\'t get latest notifications.');
return;
logger.error("Can't get latest notifications.")
return
}

@@ -129,87 +128,106 @@

if (!options.watch) {
logger.log(logger.colors.yellow(options.user + '/' + options.repo));
logger.log(logger.colors.yellow(options.user + '/' + options.repo))
}
filteredListEvents.forEach(function (event) {
logger.log(logger.colors.magenta('@' + event.actor.login) + ' ' +
event.txt + ' ' + logger.colors.cyan(options.repo) + ' ' +
logger.getDuration(event.created_at));
});
filteredListEvents.forEach(function(event) {
logger.log(
logger.colors.magenta('@' + event.actor.login) +
' ' +
event.txt +
' ' +
logger.colors.cyan(options.repo) +
' ' +
logger.getDuration(event.created_at)
)
})
}
});
};
})
}
Notifications.prototype.watch = function () {
Notifications.prototype.watch = function() {
var instance = this,
intervalTime = 3000;
intervalTime = 3000
instance.latest();
instance.latest()
setInterval(function () {
instance.latest(true);
}, intervalTime);
};
setInterval(function() {
instance.latest(true)
}, intervalTime)
}
Notifications.prototype.getMessage_ = function (event) {
Notifications.prototype.getMessage_ = function(event) {
var txt = '',
type = event.type,
payload = event.payload;
payload = event.payload
switch (type) {
case 'CommitCommentEvent':
txt = 'commented on a commit at';
break;
txt = 'commented on a commit at'
break
case 'CreateEvent':
txt = 'created ' + payload.ref_type + ' ' + logger.colors.green(payload.ref) + ' at';
break;
txt = 'created ' + payload.ref_type + ' ' + logger.colors.green(payload.ref) + ' at'
break
case 'DeleteEvent':
txt = 'removed ' + payload.ref_type + ' ' + logger.colors.green(payload.ref) + ' at';
break;
txt = 'removed ' + payload.ref_type + ' ' + logger.colors.green(payload.ref) + ' at'
break
case 'ForkEvent':
txt = 'forked';
break;
txt = 'forked'
break
case 'GollumEvent':
txt = payload.pages[0].action + ' the ' + logger.colors.green(payload.pages[0].page_name) + ' wiki page at';
break;
txt =
payload.pages[0].action +
' the ' +
logger.colors.green(payload.pages[0].page_name) +
' wiki page at'
break
case 'IssueCommentEvent':
txt = 'commented on issue ' + logger.colors.green('#' + payload.issue.number) + ' at';
break;
txt = 'commented on issue ' + logger.colors.green('#' + payload.issue.number) + ' at'
break
case 'IssuesEvent':
txt = payload.action + ' issue ' + logger.colors.green('#' + payload.issue.number) + ' at';
break;
txt =
payload.action + ' issue ' + logger.colors.green('#' + payload.issue.number) + ' at'
break
case 'MemberEvent':
txt = 'added ' + logger.colors.green('@' + payload.member.login) + ' as a collaborator to';
break;
txt =
'added ' + logger.colors.green('@' + payload.member.login) + ' as a collaborator to'
break
case 'PageBuildEvent':
txt = 'builded a GitHub Page at';
break;
txt = 'builded a GitHub Page at'
break
case 'PublicEvent':
txt = 'open sourced';
break;
txt = 'open sourced'
break
case 'PullRequestEvent':
txt = payload.action + ' pull request ' + logger.colors.green('#' + payload.number) + ' at';
break;
txt =
payload.action +
' pull request ' +
logger.colors.green('#' + payload.number) +
' at'
break
case 'PullRequestReviewCommentEvent':
txt = 'commented on pull request ' + logger.colors.green('#' + payload.pull_request.number) + ' at';
break;
txt =
'commented on pull request ' +
logger.colors.green('#' + payload.pull_request.number) +
' at'
break
case 'PushEvent':
txt = 'pushed ' + logger.colors.green(payload.size) + ' commit(s) to';
break;
txt = 'pushed ' + logger.colors.green(payload.size) + ' commit(s) to'
break
case 'ReleaseEvent':
txt = 'released ' + logger.colors.green(payload.release.tag_name) + ' at';
break;
txt = 'released ' + logger.colors.green(payload.release.tag_name) + ' at'
break
case 'StatusEvent':
txt = 'changed the status of a commit at';
break;
txt = 'changed the status of a commit at'
break
case 'WatchEvent':
txt = 'starred';
break;
txt = 'starred'
break
default:
logger.error('event type not found: ' + logger.colors.red(type));
break;
logger.error('event type not found: ' + logger.colors.red(type))
break
}
return txt;
};
return txt
}
exports.Impl = Notifications;
exports.Impl = Notifications
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -11,3 +11,3 @@ * Code licensed under the BSD License:

'use strict';
'use strict'

@@ -23,3 +23,3 @@ // -- Requires -------------------------------------------------------------------------------------

Issues = require('./issue').Impl,
config = base.getConfig();
config = base.getConfig()

@@ -29,9 +29,9 @@ // -- Constructor ----------------------------------------------------------------------------------

function PullRequest(options) {
this.options = options;
this.options = options
if (!options.repo && !options.all) {
logger.error('You must specify a Git repository with a GitHub remote to run this command');
logger.error('You must specify a Git repository with a GitHub remote to run this command')
}
this.issue = new Issues(options);
this.issue = new Issues(options)
}

@@ -56,159 +56,159 @@

'rebase',
'submit'
'submit',
],
options: {
'all': Boolean,
'branch': String,
'browser': Boolean,
'close': Boolean,
'comment': String,
'description': String,
'detailed': Boolean,
'direction': String,
'fetch': Boolean,
'fwd': String,
'issue': Number,
'info': Boolean,
'list': Boolean,
'me': Boolean,
'merge': Boolean,
'number': [String, Array],
'open': Boolean,
'org': String,
'rebase': Boolean,
'remote': String,
'repo': String,
'sort': String,
'state': ['open', 'closed'],
'submit': String,
'title': String,
'user': String
all: Boolean,
branch: String,
browser: Boolean,
close: Boolean,
comment: String,
description: String,
detailed: Boolean,
direction: String,
fetch: Boolean,
fwd: String,
issue: Number,
info: Boolean,
link: Boolean,
list: Boolean,
me: Boolean,
merge: Boolean,
number: [String, Array],
open: Boolean,
org: String,
rebase: Boolean,
remote: String,
repo: String,
sort: String,
state: ['open', 'closed'],
submit: String,
title: String,
user: String,
},
shorthands: {
'a': ['--all'],
'b': ['--branch'],
'B': ['--browser'],
'C': ['--close'],
'c': ['--comment'],
'D': ['--description'],
'd': ['--detailed'],
'f': ['--fetch'],
'i': ['--issue'],
'I': ['--info'],
'l': ['--list'],
'M': ['--merge'],
'm': ['--me'],
'n': ['--number'],
'o': ['--open'],
'O': ['--org'],
'R': ['--rebase'],
'r': ['--repo'],
'S': ['--state'],
's': ['--submit'],
't': ['--title'],
'u': ['--user']
a: ['--all'],
b: ['--branch'],
B: ['--browser'],
C: ['--close'],
c: ['--comment'],
D: ['--description'],
d: ['--detailed'],
f: ['--fetch'],
i: ['--issue'],
I: ['--info'],
k: ['--link'],
l: ['--list'],
M: ['--merge'],
m: ['--me'],
n: ['--number'],
o: ['--open'],
O: ['--org'],
R: ['--rebase'],
r: ['--repo'],
S: ['--state'],
s: ['--submit'],
t: ['--title'],
u: ['--user'],
},
payload: function (payload, options) {
payload: function(payload, options) {
if (payload[0]) {
options.fetch = true;
options.fetch = true
} else {
options.list = true
}
else {
options.list = true;
}
}
};
},
}
PullRequest.DIRECTION_DESC = 'desc';
PullRequest.DIRECTION_ASC = 'asc';
PullRequest.FETCH_TYPE_CHECKOUT = 'checkout';
PullRequest.FETCH_TYPE_MERGE = 'merge';
PullRequest.FETCH_TYPE_REBASE = 'rebase';
PullRequest.FETCH_TYPE_SILENT = 'silent';
PullRequest.SORT_CREATED = 'created';
PullRequest.SORT_COMPLEXITY = 'complexity';
PullRequest.STATE_CLOSED = 'closed';
PullRequest.STATE_OPEN = 'open';
PullRequest.DIRECTION_DESC = 'desc'
PullRequest.DIRECTION_ASC = 'asc'
PullRequest.FETCH_TYPE_CHECKOUT = 'checkout'
PullRequest.FETCH_TYPE_MERGE = 'merge'
PullRequest.FETCH_TYPE_REBASE = 'rebase'
PullRequest.FETCH_TYPE_SILENT = 'silent'
PullRequest.SORT_CREATED = 'created'
PullRequest.SORT_COMPLEXITY = 'complexity'
PullRequest.STATE_CLOSED = 'closed'
PullRequest.STATE_OPEN = 'open'
// -- Commands -------------------------------------------------------------------------------------
PullRequest.prototype.options = null;
PullRequest.prototype.options = null
PullRequest.prototype.issues = null;
PullRequest.prototype.issues = null
PullRequest.prototype.run = function () {
PullRequest.prototype.run = function() {
var instance = this,
options = instance.options;
options = instance.options
instance.config = config;
instance.config = config
options.number = options.number || instance.getPullRequestNumberFromBranch_();
options.pullBranch = instance.getBranchNameFromPullNumber_(options.number);
options.state = options.state || PullRequest.STATE_OPEN;
options.number = options.number || instance.getPullRequestNumberFromBranch_()
options.pullBranch = instance.getBranchNameFromPullNumber_(options.number)
options.state = options.state || PullRequest.STATE_OPEN
if (!options.pullBranch && (options.close || options.fetch || options.merge)) {
logger.error('You\'ve invoked a method that requires an issue number.');
logger.error("You've invoked a method that requires an issue number.")
}
if (options.browser) {
instance.browser(options.user, options.repo, options.number);
instance.browser(options.user, options.repo, options.number)
}
if (!options.list) {
options.branch = options.branch || config.default_branch;
options.branch = options.branch || config.default_branch
}
if (options.close) {
instance._closeHandler();
instance._closeHandler()
}
if (options.comment) {
instance._commentHandler();
instance._commentHandler()
}
if (options.fetch) {
instance._fetchHandler();
instance._fetchHandler()
} else if (options.merge || options.rebase) {
instance._mergeHandler()
}
else if (options.merge || options.rebase) {
instance._mergeHandler();
}
if (options.fwd === '') {
options.fwd = config.default_pr_forwarder;
options.fwd = config.default_pr_forwarder
}
if (options.fwd) {
this._fwdHandler();
this._fwdHandler()
}
if (options.info) {
this._infoHandler();
this._infoHandler()
}
if (options.list) {
this._listHandler();
this._listHandler()
}
if (options.open) {
this._openHandler();
this._openHandler()
}
if (options.submit === '') {
options.submit = config.default_pr_reviewer;
options.submit = config.default_pr_reviewer
}
if (options.submit) {
this._submitHandler();
this._submitHandler()
}
};
}
PullRequest.prototype.addComplexityParamToPulls_ = function (pulls, opt_callback) {
PullRequest.prototype.addComplexityParamToPulls_ = function(pulls, opt_callback) {
var instance = this,
metrics,
operations,
options = instance.options;
options = instance.options
operations = pulls.map(function (pull) {
return function (callback) {
options.number = pull.number;
instance.getPullRequest_(function (err, pull2) {
operations = pulls.map(function(pull) {
return function(callback) {
options.number = pull.number
instance.getPullRequest_(function(err, pull2) {
if (!err) {

@@ -220,21 +220,25 @@ metrics = {

deletions: pull2.deletions,
reviewComments: pull2.review_comments
};
pull.complexity = instance.calculateComplexity_(metrics);
reviewComments: pull2.review_comments,
}
pull.complexity = instance.calculateComplexity_(metrics)
}
callback(err, pull);
});
};
});
callback(err, pull)
})
}
})
async.series(operations, function (err, results) {
opt_callback(err, results);
});
};
async.series(operations, function(err, results) {
opt_callback(err, results)
})
}
PullRequest.prototype.browser = function (user, repo, number) {
openUrl(config.github_host + user + '/' + repo + '/pull/' + number);
};
PullRequest.prototype.browser = function(user, repo, number) {
if (number) {
openUrl(config.github_host + user + '/' + repo + '/pull/' + number)
} else {
openUrl(config.github_host + user + '/' + repo + '/pulls')
}
}
PullRequest.prototype.calculateComplexity_ = function (metrics) {
PullRequest.prototype.calculateComplexity_ = function(metrics) {
var complexity,

@@ -245,56 +249,55 @@ weightAddition = 2,

weightDeletion = 2,
weightReviewComment = 1;
weightReviewComment = 1
complexity = (metrics.additions * weightAddition) +
(metrics.changedFiles * weightChangedFile) +
(metrics.comments * weightComment) +
(metrics.deletions * weightDeletion) +
(metrics.reviewComments * weightReviewComment);
complexity =
metrics.additions * weightAddition +
metrics.changedFiles * weightChangedFile +
metrics.comments * weightComment +
metrics.deletions * weightDeletion +
metrics.reviewComments * weightReviewComment
return complexity;
};
return complexity
}
PullRequest.prototype.close = function (opt_callback) {
PullRequest.prototype.close = function(opt_callback) {
var instance = this,
options = instance.options,
operations,
pull;
pull
operations = [
function (callback) {
instance.getPullRequest_(function (err, data) {
function(callback) {
instance.getPullRequest_(function(err, data) {
if (!err) {
pull = data;
pull = data
}
callback(err);
});
callback(err)
})
},
function (callback) {
instance.updatePullRequest_(
pull.title, pull.body, PullRequest.STATE_CLOSED, callback);
function(callback) {
instance.updatePullRequest_(pull.title, pull.body, PullRequest.STATE_CLOSED, callback)
},
function (callback) {
function(callback) {
if (options.pullBranch === options.currentBranch) {
git.checkout(pull.base.ref);
git.checkout(pull.base.ref)
}
if (options.pullBranch) {
git.deleteBranch(options.pullBranch);
git.deleteBranch(options.pullBranch)
}
callback();
}
];
callback()
},
]
async.series(operations, function (err) {
opt_callback && opt_callback(err, pull);
});
};
async.series(operations, function(err) {
opt_callback && opt_callback(err, pull)
})
}
PullRequest.prototype.checkPullRequestIntegrity_ = function (originalError, user, opt_callback) {
PullRequest.prototype.checkPullRequestIntegrity_ = function(originalError, user, opt_callback) {
var instance = this,
options = instance.options,
payload,
pull;
pull

@@ -304,64 +307,65 @@ payload = {

repo: options.repo,
state: PullRequest.STATE_OPEN
};
state: PullRequest.STATE_OPEN,
}
base.github.pullRequests.getAll(payload, function (err, pulls) {
base.github.pullRequests.getAll(payload, function(err, pulls) {
if (!err) {
pulls.forEach(function (data) {
if ((data.base.ref === options.branch) &&
(data.head.ref === options.currentBranch) &&
(data.base.sha === data.head.sha) &&
(data.base.user.login === user) &&
(data.head.user.login === options.user)) {
pull = data;
originalError = null;
return;
pulls.forEach(function(data) {
if (
data.base.ref === options.branch &&
data.head.ref === options.currentBranch &&
data.base.sha === data.head.sha &&
data.base.user.login === user &&
data.head.user.login === options.user
) {
pull = data
originalError = null
return
}
});
})
}
opt_callback && opt_callback(originalError, pull);
});
};
opt_callback && opt_callback(originalError, pull)
})
}
PullRequest.prototype.fetch = function (opt_type, opt_callback) {
PullRequest.prototype.fetch = function(opt_type, opt_callback) {
var instance = this,
options = instance.options,
headBranch,
repoUrl;
repoUrl
instance.getPullRequest_(function (err, pull) {
instance.getPullRequest_(function(err, pull) {
if (err) {
opt_callback && opt_callback(err);
return;
opt_callback && opt_callback(err)
return
}
headBranch = pull.head.ref;
repoUrl = pull.head.repo.ssh_url;
headBranch = pull.head.ref
repoUrl = pull.head.repo.ssh_url
git.fetch(repoUrl, headBranch, options.pullBranch);
git.fetch(repoUrl, headBranch, options.pullBranch)
if (opt_type !== PullRequest.FETCH_TYPE_SILENT) {
git[opt_type](options.pullBranch);
git[opt_type](options.pullBranch)
}
opt_callback(err, pull);
});
};
opt_callback(err, pull)
})
}
PullRequest.prototype.filterPullsSentByMe_ = function (pulls) {
PullRequest.prototype.filterPullsSentByMe_ = function(pulls) {
var instance = this,
options = instance.options;
options = instance.options
pulls = pulls.filter(function (pull) {
pulls = pulls.filter(function(pull) {
if (options.loggedUser === pull.user.login) {
return pull;
return pull
}
});
})
return pulls;
};
return pulls
}
PullRequest.prototype.forward = function (opt_callback) {
PullRequest.prototype.forward = function(opt_callback) {
var instance = this,

@@ -371,40 +375,39 @@ options = instance.options,

submittedPull,
pull;
pull
operations = [
function (callback) {
instance.fetch(PullRequest.FETCH_TYPE_SILENT, function (err, data) {
pull = data;
callback(err);
});
function(callback) {
instance.fetch(PullRequest.FETCH_TYPE_SILENT, function(err, data) {
pull = data
callback(err)
})
},
function (callback) {
options.title = pull.title;
options.description = pull.body;
options.submittedUser = pull.user.login;
function(callback) {
options.title = pull.title
options.description = pull.body
options.submittedUser = pull.user.login
instance.submit(options.fwd, function (err, data) {
instance.submit(options.fwd, function(err, data) {
if (err) {
callback(err);
return;
callback(err)
return
}
options.submittedPullNumber = data.number;
options.submittedPullNumber = data.number
submittedPull = data;
callback();
});
}
];
submittedPull = data
callback()
})
},
]
async.series(operations, function (err) {
opt_callback && opt_callback(err, submittedPull);
});
};
async.series(operations, function(err) {
opt_callback && opt_callback(err, submittedPull)
})
}
PullRequest.prototype.getPullRequest_ = function (opt_callback) {
PullRequest.prototype.getPullRequest_ = function(opt_callback) {
var instance = this,
options = instance.options,
payload;
payload

@@ -414,27 +417,27 @@ payload = {

repo: options.repo,
user: options.user
};
user: options.user,
}
base.github.pullRequests.get(payload, opt_callback);
};
base.github.pullRequests.get(payload, opt_callback)
}
PullRequest.prototype.getBranchNameFromPullNumber_ = function (number) {
PullRequest.prototype.getBranchNameFromPullNumber_ = function(number) {
if (number) {
return config.pull_branch_name_prefix + number;
return config.pull_branch_name_prefix + number
}
};
}
PullRequest.prototype.getPullRequestNumberFromBranch_ = function () {
PullRequest.prototype.getPullRequestNumberFromBranch_ = function() {
var instance = this,
options = instance.options,
prefix;
prefix
prefix = config.pull_branch_name_prefix;
prefix = config.pull_branch_name_prefix
if (options.currentBranch && options.currentBranch.indexOf(prefix) > -1) {
return options.currentBranch.replace(prefix, '');
return options.currentBranch.replace(prefix, '')
}
};
}
PullRequest.prototype.getPullsTemplateJson_ = function (pulls, opt_callback) {
PullRequest.prototype.getPullsTemplateJson_ = function(pulls, opt_callback) {
var instance = this,

@@ -444,55 +447,78 @@ options = instance.options,

branches,
json;
json
branches = {};
branches = {}
json = {
branches: []
};
branches: [],
}
pulls.forEach(function (pull) {
branch = pull.base.ref;
pulls.forEach(function(pull) {
branch = pull.base.ref
if (!options.branch || options.branch === branch) {
branches[branch] = branches[branch] || [];
branches[branch].push(pull);
branches[branch] = branches[branch] || []
branches[branch].push(pull)
}
});
})
Object.keys(branches).forEach(function (branch) {
Object.keys(branches).forEach(function(branch) {
json.branches.push({
name: branch,
pulls: branches[branch],
total: branches[branch].length
});
});
total: branches[branch].length,
})
})
opt_callback && opt_callback(null, json);
};
opt_callback && opt_callback(null, json)
}
PullRequest.prototype.printPullInfo_ = function (pull) {
var options = this.options;
PullRequest.prototype.printPullInfo_ = function(pull) {
var options = this.options
logger.log(logger.colors.green('#' + pull.number) + ' ' +
pull.title + ' ' + logger.colors.magenta('@' + pull.user.login) +
' (' + logger.getDuration(pull.created_at) + ')');
var status = ''
if (options.detailed) {
logger.log(logger.colors.blue(pull.html_url));
switch (pull.combinedStatus) {
case 'success':
status = logger.colors.green(' ✓')
break
case 'failure':
status = logger.colors.red(' ✗')
break
}
if (pull.mergeable_state === 'clean') {
logger.log(logger.colors.green('Mergeable (' + pull.mergeable_state + ')'));
var headline =
logger.colors.green('#' + pull.number) +
' ' +
pull.title +
' ' +
logger.colors.magenta('@' + pull.user.login) +
' (' +
logger.getDuration(pull.created_at) +
')' +
status
if (options.link) {
headline += ' ' + logger.colors.blue(pull.html_url)
}
else if (pull.mergeable_state !== undefined) {
logger.warn(logger.colors.red('Not mergeable (' + pull.mergeable_state + ')'));
logger.log(headline)
if (options.detailed && !options.link) {
logger.log(logger.colors.blue(pull.html_url))
}
if (pull.mergeable_state === 'clean') {
logger.log('Mergeable (' + pull.mergeable_state + ')')
} else if (pull.mergeable_state !== undefined) {
logger.warn('Not mergeable (' + pull.mergeable_state + ')')
}
if ((options.info || options.detailed) && pull.body) {
logger.log(pull.body + '\n');
logger.log(pull.body + '\n')
}
};
}
PullRequest.prototype.get = function (user, repo, number) {
PullRequest.prototype.get = function(user, repo, number) {
var pr = this,
payload;
payload

@@ -502,16 +528,16 @@ payload = {

user: user,
number: number
};
number: number,
}
base.github.pullRequests.get(payload, function (err, pull) {
base.github.pullRequests.get(payload, function(err, pull) {
if (err) {
logger.warn('Can\'t get pull request ' + user + '/' + repo + '/' + number);
return;
logger.warn("Can't get pull request " + user + '/' + repo + '/' + number)
return
}
pr.printPullInfo_(pull);
});
};
pr.printPullInfo_(pull)
})
}
PullRequest.prototype.list = function (user, repo, opt_callback) {
PullRequest.prototype.list = function(user, repo, opt_callback) {
var instance = this,

@@ -523,8 +549,8 @@ options = instance.options,

pulls,
sort;
sort
sort = options.sort;
sort = options.sort
if (options.sort === PullRequest.SORT_COMPLEXITY) {
sort = PullRequest.SORT_CREATED;
sort = PullRequest.SORT_CREATED
}

@@ -537,18 +563,16 @@

state: options.state,
user: user
};
user: user,
}
operations = [
function(callback) {
base.github.pullRequests.getAll(payload, function(err, data) {
pulls = []
function (callback) {
base.github.pullRequests.getAll(payload, function (err, data) {
pulls = [];
if (!err) {
if (options.me) {
pulls = instance.filterPullsSentByMe_(data);
pulls = instance.filterPullsSentByMe_(data)
} else {
pulls = data
}
else {
pulls = data;
}
}

@@ -559,56 +583,79 @@

// due to the repo being disabled (e.g., private repo with debt)
logger.warn('Can\'t list pull requests for ' + user + '/' + payload.repo);
callback();
logger.warn("Can't list pull requests for " + user + '/' + payload.repo)
callback()
} else {
callback(err)
}
else {
callback(err);
}
});
})
},
function (callback) {
function(callback) {
if (options.sort && options.sort === PullRequest.SORT_COMPLEXITY) {
instance.addComplexityParamToPulls_(pulls, function (err, data) {
instance.addComplexityParamToPulls_(pulls, function(err, data) {
if (!err) {
pulls = instance.sortPullsByComplexity_(data);
pulls = instance.sortPullsByComplexity_(data)
}
callback(err);
});
callback(err)
})
} else {
callback()
}
else {
callback();
}
},
function (callback) {
instance.getPullsTemplateJson_(pulls, function (err, data) {
function(callback) {
var statusOperations = []
var statusPayload
pulls.forEach(function(pull) {
statusOperations.push(function(callback) {
statusPayload = {
repo: repo,
user: user,
sha: pull.head.sha,
}
base.github.statuses.getCombined(statusPayload, function(err, data) {
pull.combinedStatus = data.state
callback(err)
})
})
})
async.series(statusOperations, function(err) {
callback(err)
})
},
function(callback) {
instance.getPullsTemplateJson_(pulls, function(err, data) {
if (!err) {
json = data;
json = data
}
callback(err);
});
}
];
callback(err)
})
},
]
async.series(operations, function (err) {
async.series(operations, function(err) {
if (!err && pulls.length) {
logger.log(logger.colors.yellow(user + '/' + repo));
logger.log(logger.colors.yellow(user + '/' + repo))
json.branches.forEach(function (branch) {
logger.log(branch.name + ' (' + branch.total + ')');
json.branches.forEach(function(branch) {
logger.log(branch.name + ' (' + branch.total + ')')
branch.pulls.forEach(instance.printPullInfo_, instance);
});
branch.pulls.forEach(instance.printPullInfo_, instance)
})
}
opt_callback && opt_callback(err);
});
};
opt_callback && opt_callback(err)
})
}
PullRequest.prototype.listFromAllRepositories = function (opt_callback) {
PullRequest.prototype.listFromAllRepositories = function(opt_callback) {
var instance = this,
options = instance.options,
payload,
apiMethod;
apiMethod

@@ -618,28 +665,27 @@ payload = {

user: options.user,
per_page: 1000
};
per_page: 1000,
}
if(options.org) {
apiMethod = 'getFromOrg';
payload.org = options.org;
if (options.org) {
apiMethod = 'getFromOrg'
payload.org = options.org
} else {
apiMethod = 'getAll';
apiMethod = 'getAll'
}
base.github.repos[apiMethod](payload, function (err, repositories) {
base.github.repos[apiMethod](payload, function(err, repositories) {
if (err) {
opt_callback && opt_callback(err);
opt_callback && opt_callback(err)
} else {
repositories.forEach(function(repository) {
instance.list(repository.owner.login, repository.name, opt_callback)
})
}
else {
repositories.forEach(function (repository) {
instance.list(repository.owner.login, repository.name, opt_callback);
});
}
});
};
})
}
PullRequest.prototype.listFromAllOrgRepositories = function (opt_callback) {
PullRequest.prototype.listFromAllOrgRepositories = function(opt_callback) {
var instance = this,
options = instance.options,
payload;
payload

@@ -650,108 +696,102 @@ payload = {

org: options.org,
per_page: 1000
};
per_page: 1000,
}
base.github.repos.getFromOrg(payload, function (err, repositories) {
base.github.repos.getFromOrg(payload, function(err, repositories) {
if (err) {
opt_callback && opt_callback(err);
opt_callback && opt_callback(err)
} else {
repositories.forEach(function(repository) {
instance.list(repository.owner.login, repository.name, opt_callback)
})
}
else {
repositories.forEach(function (repository) {
instance.list(repository.owner.login, repository.name, opt_callback);
});
}
});
};
})
}
PullRequest.prototype.merge = function (opt_callback) {
PullRequest.prototype.merge = function(opt_callback) {
var instance = this,
options = instance.options,
method = 'merge';
method = 'merge'
if (options.rebase) {
method = 'rebase';
method = 'rebase'
}
git.checkout(options.branch);
git[method](options.pullBranch);
git.push(config.default_remote, options.branch);
git.deleteBranch(options.pullBranch);
opt_callback && opt_callback();
};
git.checkout(options.branch)
git[method](options.pullBranch)
git.push(config.default_remote, options.branch)
git.deleteBranch(options.pullBranch)
opt_callback && opt_callback()
}
PullRequest.prototype.open = function (opt_callback) {
var instance = this;
PullRequest.prototype.open = function(opt_callback) {
var instance = this
instance.getPullRequest_(function (err, pull) {
instance.getPullRequest_(function(err, pull) {
if (err) {
opt_callback && opt_callback(err);
opt_callback && opt_callback(err)
} else {
instance.updatePullRequest_(pull.title, pull.body, PullRequest.STATE_OPEN, opt_callback)
}
else {
instance.updatePullRequest_(
pull.title, pull.body, PullRequest.STATE_OPEN, opt_callback);
}
});
};
})
}
PullRequest.prototype.setMergeCommentRequiredOptions_ = function (opt_callback) {
PullRequest.prototype.setMergeCommentRequiredOptions_ = function(opt_callback) {
var options = this.options,
lastCommitSHA = git.getLastCommitSHA(),
changes = git.countUserAdjacentCommits();
changes = git.countUserAdjacentCommits()
options.currentSHA = lastCommitSHA;
options.currentSHA = lastCommitSHA
if (changes > 0) {
options.changes = changes;
options.changes = changes
}
options.pullHeadSHA = lastCommitSHA + '~' + changes;
options.pullHeadSHA = lastCommitSHA + '~' + changes
opt_callback && opt_callback();
};
opt_callback && opt_callback()
}
PullRequest.prototype.sortPullsByComplexity_ = function (data) {
PullRequest.prototype.sortPullsByComplexity_ = function(data) {
var instance = this,
options = instance.options;
options = instance.options
data.sort(function (a, b) {
data.sort(function(a, b) {
if (a.complexity > b.complexity) {
return -1;
return -1
} else if (a.complexity < b.complexity) {
return +1
} else {
return 0
}
else if (a.complexity < b.complexity) {
return +1;
}
else {
return 0;
}
});
})
if (options.direction === PullRequest.DIRECTION_ASC) {
data.reverse();
data.reverse()
}
return data;
};
return data
}
PullRequest.prototype.submit = function (user, opt_callback) {
PullRequest.prototype.submit = function(user, opt_callback) {
var instance = this,
options = instance.options,
operations,
pullBranch;
pullBranch
pullBranch = options.pullBranch || options.currentBranch;
pullBranch = options.pullBranch || options.currentBranch
operations = [
function (callback) {
git.push(config.default_remote, pullBranch);
callback();
function(callback) {
git.push(config.default_remote, pullBranch)
callback()
},
function (callback) {
function(callback) {
if (!options.title) {
options.title = git.getLastCommitMessage(pullBranch);
options.title = git.getLastCommitMessage(pullBranch)
}
callback();
callback()
},
function (callback) {
function(callback) {
var payload = {

@@ -761,34 +801,32 @@ base: options.branch,

repo: options.repo,
user: user
};
user: user,
}
if (options.issue) {
payload.issue = options.issue;
base.github.pullRequests.createFromIssue(payload, callback);
payload.issue = options.issue
base.github.pullRequests.createFromIssue(payload, callback)
} else {
payload.body = options.description
payload.title = options.title
base.github.pullRequests.create(payload, callback)
}
else {
payload.body = options.description;
payload.title = options.title;
base.github.pullRequests.create(payload, callback);
}
}
];
},
]
async.series(operations, function (err, results) {
async.series(operations, function(err, results) {
if (err) {
instance.checkPullRequestIntegrity_(err, user, opt_callback);
instance.checkPullRequestIntegrity_(err, user, opt_callback)
} else {
opt_callback && opt_callback(err, results[2])
}
else {
opt_callback && opt_callback(err, results[2]);
}
});
};
})
}
PullRequest.prototype.updatePullRequest_ = function (title, opt_body, state, opt_callback) {
PullRequest.prototype.updatePullRequest_ = function(title, opt_body, state, opt_callback) {
var instance = this,
options = instance.options,
payload;
payload
if (opt_body) {
opt_body = logger.applyReplacements(opt_body, config.replace);
opt_body = logger.applyReplacements(opt_body, config.replace)
}

@@ -802,227 +840,252 @@

title: title,
user: options.user
};
user: options.user,
}
base.github.pullRequests.update(payload, opt_callback);
};
base.github.pullRequests.update(payload, opt_callback)
}
PullRequest.prototype._fetchHandler = function () {
PullRequest.prototype._fetchHandler = function() {
var instance = this,
options = this.options,
fetchType = PullRequest.FETCH_TYPE_CHECKOUT;
fetchType = PullRequest.FETCH_TYPE_CHECKOUT
if (options.merge) {
fetchType = PullRequest.FETCH_TYPE_MERGE;
fetchType = PullRequest.FETCH_TYPE_MERGE
} else if (options.rebase) {
fetchType = PullRequest.FETCH_TYPE_REBASE
}
else if (options.rebase) {
fetchType = PullRequest.FETCH_TYPE_REBASE;
}
hooks.invoke('pull-request.fetch', instance, function (afterHooksCallback) {
hooks.invoke('pull-request.fetch', instance, function(afterHooksCallback) {
var operation = '',
branch = options.pullBranch;
branch = options.pullBranch
if (options.merge) {
operation = ' and merging';
branch = options.currentBranch;
operation = ' and merging'
branch = options.currentBranch
}
if (options.rebase) {
operation = ' and rebasing';
branch = options.currentBranch;
operation = ' and rebasing'
branch = options.currentBranch
}
logger.log('Fetching pull request ' +
logger.colors.green('#' + options.number) + operation +
' into branch ' + logger.colors.green(branch));
logger.log(
'Fetching pull request ' +
logger.colors.green('#' + options.number) +
operation +
' into branch ' +
logger.colors.green(branch)
)
instance.fetch(fetchType, function (err) {
instance.fetch(fetchType, function(err) {
if (err) {
logger.error('Can\'t fetch pull request ' + options.number + '.');
return;
logger.error("Can't fetch pull request " + options.number + '.')
return
}
afterHooksCallback();
});
});
};
afterHooksCallback()
})
})
}
PullRequest.prototype._mergeHandler = function () {
PullRequest.prototype._mergeHandler = function() {
var instance = this,
options = this.options,
operation = 'Merging';
operation = 'Merging'
hooks.invoke('pull-request.merge', instance, function (afterHooksCallback) {
hooks.invoke('pull-request.merge', instance, function(afterHooksCallback) {
if (options.rebase) {
operation = 'Rebasing';
operation = 'Rebasing'
}
logger.log(operation + ' pull request ' + logger.colors.green('#' + options.number) +
' into branch ' + logger.colors.green(options.branch));
logger.log(
operation +
' pull request ' +
logger.colors.green('#' + options.number) +
' into branch ' +
logger.colors.green(options.branch)
)
instance.merge();
instance.setMergeCommentRequiredOptions_(afterHooksCallback);
});
};
instance.merge()
instance.setMergeCommentRequiredOptions_(afterHooksCallback)
})
}
PullRequest.prototype._fwdHandler = function () {
PullRequest.prototype._fwdHandler = function() {
var instance = this,
options = this.options;
options = this.options
hooks.invoke('pull-request.fwd', instance, function (afterHooksCallback) {
logger.log('Forwarding pull request ' +
logger.colors.green('#' + options.number) + ' to ' + logger.colors.magenta('@' + options.fwd));
hooks.invoke('pull-request.fwd', instance, function(afterHooksCallback) {
logger.log(
'Forwarding pull request ' +
logger.colors.green('#' + options.number) +
' to ' +
logger.colors.magenta('@' + options.fwd)
)
instance.forward(function (err, pull) {
instance.forward(function(err, pull) {
if (err) {
logger.error('Can\'t forward pull request ' + options.number + ' to ' + options.fwd + '.');
return;
logger.error(
"Can't forward pull request " + options.number + ' to ' + options.fwd + '.'
)
return
}
if (pull) {
options.forwardedPull = pull.number;
options.forwardedPull = pull.number
}
logger.log(pull.html_url);
instance.setMergeCommentRequiredOptions_(afterHooksCallback);
});
});
};
logger.log(pull.html_url)
instance.setMergeCommentRequiredOptions_(afterHooksCallback)
})
})
}
PullRequest.prototype._closeHandler = function () {
PullRequest.prototype._closeHandler = function() {
var instance = this,
options = this.options;
options = this.options
hooks.invoke('pull-request.close', instance, function (afterHooksCallback) {
logger.log('Closing pull request ' + logger.colors.green('#' + options.number));
hooks.invoke('pull-request.close', instance, function(afterHooksCallback) {
logger.log('Closing pull request ' + logger.colors.green('#' + options.number))
instance.close(function (err, pull) {
instance.close(function(err, pull) {
if (err) {
logger.warn('Can\'t close pull request ' + options.number + '.');
return;
logger.warn("Can't close pull request " + options.number + '.')
return
}
logger.log(pull.html_url);
logger.log(pull.html_url)
instance.setMergeCommentRequiredOptions_(afterHooksCallback);
});
});
};
instance.setMergeCommentRequiredOptions_(afterHooksCallback)
})
})
}
PullRequest.prototype._commentHandler = function () {
var options = this.options;
PullRequest.prototype._commentHandler = function() {
var options = this.options
logger.log('Adding comment on pull request ' + logger.colors.green('#' + options.number));
logger.log('Adding comment on pull request ' + logger.colors.green('#' + options.number))
this.issue.comment(function (err, pull) {
this.issue.comment(function(err, pull) {
if (err) {
logger.error('Can\'t comment on pull request ' + options.number + '.');
return;
logger.error("Can't comment on pull request " + options.number + '.')
return
}
logger.log(pull.html_url);
});
};
logger.log(pull.html_url)
})
}
PullRequest.prototype._infoHandler = function () {
PullRequest.prototype._infoHandler = function() {
var instance = this,
options = this.options;
options = this.options
instance.get(options.user, options.repo, options.number, function (err) {
instance.get(options.user, options.repo, options.number, function(err) {
if (err) {
logger.error('Can\'t get pull requests.');
return;
logger.error("Can't get pull requests.")
return
}
});
};
})
}
PullRequest.prototype._listHandler = function () {
PullRequest.prototype._listHandler = function() {
var instance = this,
options = this.options,
who;
who
options.sort = options.sort || PullRequest.SORT_CREATED;
options.direction = options.direction || PullRequest.DIRECTION_DESC;
options.sort = options.sort || PullRequest.SORT_CREATED
options.direction = options.direction || PullRequest.DIRECTION_DESC
if (options.all) {
who = options.user;
who = options.user
if (options.org) {
who = options.org;
who = options.org
}
logger.log('Listing all ' + options.state + ' pull requests for ' + logger.colors.green(who));
logger.log(
'Listing all ' + options.state + ' pull requests for ' + logger.colors.green(who)
)
instance.listFromAllRepositories(function (err) {
instance.listFromAllRepositories(function(err) {
if (err) {
logger.error('Can\'t list all pull requests from repos.');
return;
logger.error("Can't list all pull requests from repos.")
return
}
});
}
else {
})
} else {
if (options.me) {
logger.log('Listing ' + options.state + ' pull requests sent by ' +
logger.colors.green(options.loggedUser) + ' on ' +
logger.colors.green(options.user + '/' + options.repo));
logger.log(
'Listing ' +
options.state +
' pull requests sent by ' +
logger.colors.green(options.loggedUser) +
' on ' +
logger.colors.green(options.user + '/' + options.repo)
)
} else {
logger.log(
'Listing ' +
options.state +
' pull requests on ' +
logger.colors.green(options.user + '/' + options.repo)
)
}
else {
logger.log('Listing ' + options.state + ' pull requests on ' +
logger.colors.green(options.user + '/' + options.repo));
}
instance.list(options.user, options.repo, function (err) {
instance.list(options.user, options.repo, function(err) {
if (err) {
logger.error('Can\'t list pull requests.');
return;
logger.error("Can't list pull requests.")
return
}
});
})
}
};
}
PullRequest.prototype._openHandler = function () {
PullRequest.prototype._openHandler = function() {
var instance = this,
options = this.options;
options = this.options
hooks.invoke('pull-request.open', instance, function (afterHooksCallback) {
logger.log('Opening pull request ' + logger.colors.green('#' + options.number));
hooks.invoke('pull-request.open', instance, function(afterHooksCallback) {
logger.log('Opening pull request ' + logger.colors.green('#' + options.number))
instance.open(function (err, pull) {
instance.open(function(err, pull) {
if (err) {
logger.error('Can\'t open pull request ' + options.number + '.');
return;
logger.error("Can't open pull request " + options.number + '.')
return
}
logger.log(pull.html_url);
afterHooksCallback();
});
});
};
logger.log(pull.html_url)
afterHooksCallback()
})
})
}
PullRequest.prototype._submitHandler = function () {
PullRequest.prototype._submitHandler = function() {
var instance = this,
options = this.options;
options = this.options
hooks.invoke('pull-request.submit', instance, function (afterHooksCallback) {
logger.log('Submitting pull request to ' + logger.colors.magenta('@' + options.submit));
hooks.invoke('pull-request.submit', instance, function(afterHooksCallback) {
logger.log('Submitting pull request to ' + logger.colors.magenta('@' + options.submit))
instance.submit(options.submit, function (err, pull) {
instance.submit(options.submit, function(err, pull) {
if (err) {
try {
logger.error('Can\'t submit pull request. ' + JSON.parse(err.message).errors[0].message);
logger.error(
"Can't submit pull request. " + JSON.parse(err.message).errors[0].message
)
} catch (ignore) {
console.error(err);
console.error(err)
}
return;
return
}
if (pull) {
options.submittedPull = pull.number;
options.submittedPull = pull.number
}
logger.log(pull.html_url);
instance.setMergeCommentRequiredOptions_(afterHooksCallback);
});
});
};
logger.log(pull.html_url)
instance.setMergeCommentRequiredOptions_(afterHooksCallback)
})
})
}
exports.Impl = PullRequest;
exports.Impl = PullRequest
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -12,3 +12,3 @@ * Code licensed under the BSD License:

'use strict';
'use strict'

@@ -18,2 +18,3 @@ // -- Requires -------------------------------------------------------------------------------------

var base = require('../base'),
fs = require('fs'),
git = require('../git'),

@@ -25,3 +26,3 @@ hooks = require('../hooks'),

url = require('url'),
config = base.getConfig();
config = base.getConfig()

@@ -31,3 +32,3 @@ // -- Constructor ----------------------------------------------------------------------------------

function Repo(options) {
this.options = options;
this.options = options
}

@@ -40,74 +41,127 @@

description: 'Provides a set of util commands to work with Repositories.',
commands: [
'browser',
'clone',
'delete',
'fork',
'list',
'new'
],
commands: ['browser', 'clone', 'delete', 'fork', 'list', 'new', 'update'],
options: {
'browser': Boolean,
'clone': Boolean,
'delete': String,
'description': String,
'detailed': Boolean,
'gitignore': String,
'fork': String,
'homepage': String,
'init': Boolean,
'list': Boolean,
'new': String,
'organization': String,
'private': Boolean,
'repo': String,
'type': ['all', 'forks', 'member', 'owner', 'public', 'private', 'sources'],
'user': String
browser: Boolean,
clone: Boolean,
color: String,
delete: String,
description: String,
detailed: Boolean,
gitignore: String,
fork: String,
homepage: String,
init: Boolean,
label: Boolean,
list: Boolean,
new: String,
organization: String,
page: String,
per_page: String,
private: Boolean,
protocol: String,
repo: String,
type: ['all', 'forks', 'member', 'owner', 'public', 'private', 'sources'],
update: String,
user: String,
},
shorthands: {
'B': ['--browser'],
'c': ['--clone'],
'D': ['--delete'],
'd': ['--detailed'],
'f': ['--fork'],
'l': ['--list'],
'N': ['--new'],
'O': ['--organization'],
'p': ['--private'],
'r': ['--repo'],
't': ['--type'],
'u': ['--user']
B: ['--browser'],
c: ['--clone'],
C: ['--color'],
D: ['--delete'],
d: ['--detailed'],
f: ['--fork'],
L: ['--label'],
l: ['--list'],
N: ['--new'],
O: ['--organization'],
p: ['--private'],
P: ['--protocol'],
r: ['--repo'],
t: ['--type'],
U: ['--update'],
u: ['--user'],
},
payload: function (payload, options) {
payload: function(payload, options) {
if (options.browser !== false) {
options.browser = true;
options.browser = true
}
}
};
},
}
Repo.TYPE_ALL = 'all';
Repo.TYPE_FORKS = 'forks';
Repo.TYPE_MEMBER = 'member';
Repo.TYPE_OWNER = 'owner';
Repo.TYPE_PRIVATE = 'private';
Repo.TYPE_PUBLIC = 'public';
Repo.TYPE_SOURCES = 'sources';
Repo.TYPE_ALL = 'all'
Repo.TYPE_FORKS = 'forks'
Repo.TYPE_MEMBER = 'member'
Repo.TYPE_OWNER = 'owner'
Repo.TYPE_PRIVATE = 'private'
Repo.TYPE_PUBLIC = 'public'
Repo.TYPE_SOURCES = 'sources'
// -- Commands -------------------------------------------------------------------------------------
Repo.prototype.run = function () {
Repo.prototype.run = function() {
var instance = this,
options = instance.options,
user = options.loggedUser;
user = options.loggedUser
instance.config = config;
instance.config = config
if (options.browser) {
instance.browser(options.user, options.repo);
instance.browser(options.user, options.repo)
}
if (options.delete) {
hooks.invoke('repo.delete', instance, function (afterHooksCallback) {
logger.log('Deleting repo ' + logger.colors.green(options.user + '/' + options.delete));
if (options.clone) {
hooks.invoke('repo.get', instance, function(afterHooksCallback) {
if (options.organization) {
user = options.organization
} else if (options.user) {
user = options.user
}
if (fs.existsSync(process.cwd() + '/' + options.repo)) {
logger.error(
"Can't clone " +
logger.colors.green(user + '/' + options.repo) +
'. ' +
logger.colors.green(options.repo) +
' already exists in this directory.'
)
return
}
instance.get(user, options.repo, function(err1, repo) {
if (err1) {
logger.error(
"Can't clone " +
logger.colors.green(user + '/' + options.repo) +
'. ' +
JSON.parse(err1).message
)
return
}
logger.log(repo.html_url)
var repoUrl
if (options.protocol) {
if (options.protocol === 'https') {
repoUrl = 'https://github.com/' + user + '/' + options.repo + '.git'
}
} else {
repoUrl = 'git@github.com:' + user + '/' + options.repo + '.git'
}
if (repo) {
instance.clone_(user, options.repo, repoUrl)
}
afterHooksCallback()
})
})
}
if (options.delete && !options.label) {
hooks.invoke('repo.delete', instance, function(afterHooksCallback) {
logger.log('Deleting repo ' + logger.colors.green(options.user + '/' + options.delete))
inquirer.prompt(

@@ -118,125 +172,269 @@ [

message: 'Are you sure? This action CANNOT be undone. [y/N]',
name: 'confirmation'
}
], function (answers) {
name: 'confirmation',
},
],
function(answers) {
if (answers.confirmation.toLowerCase() === 'y') {
instance.delete(options.user, options.delete, function (err) {
instance.delete(options.user, options.delete, function(err) {
if (err) {
logger.error('Can\'t delete repo.');
return;
logger.error("Can't delete repo.")
return
}
afterHooksCallback();
});
afterHooksCallback()
})
} else {
logger.log('Not deleted.')
}
else {
logger.log('Not deleted.');
}
});
});
}
)
})
}
if (options.fork) {
hooks.invoke('repo.fork', instance, function (afterHooksCallback) {
hooks.invoke('repo.fork', instance, function(afterHooksCallback) {
if (options.organization) {
user = options.organization;
user = options.organization
}
options.repo = options.fork;
options.repo = options.fork
logger.log('Forking repo ' + logger.colors.green(options.user + '/' + options.repo) +
' on ' + logger.colors.green(user + '/' + options.repo));
logger.log(
'Forking repo ' +
logger.colors.green(options.user + '/' + options.repo) +
' on ' +
logger.colors.green(user + '/' + options.repo)
)
instance.fork(function (err1, repo) {
instance.fork(function(err1, repo) {
if (err1) {
logger.error('Can\'t fork. ' + JSON.parse(err1).message);
return;
logger.error("Can't fork. " + JSON.parse(err1).message)
return
}
logger.log(repo.html_url);
logger.log(repo.html_url)
if (repo && options.clone) {
instance.clone_(options.loggedUser, options.repo, repo.ssh_url);
instance.clone_(options.loggedUser, options.repo, repo.ssh_url)
}
afterHooksCallback();
});
});
afterHooksCallback()
})
})
}
if (options.list) {
if (options.label) {
if (options.organization) {
user = options.organization;
options.type = options.type || Repo.TYPE_ALL;
user = options.organization
} else if (options.user) {
user = options.user
}
if (options.delete) {
hooks.invoke('repo.deleteLabel', instance, function(afterHooksCallback) {
options.label = options.delete
logger.log(
'Deleting label ' +
logger.colors.green(options.label) +
' on ' +
logger.colors.green(user + '/' + options.repo)
)
instance.deleteLabel(user, function(err1) {
if (err1) {
logger.error("Can't delete label.")
return
}
afterHooksCallback()
})
})
} else if (options.list) {
hooks.invoke('repo.listLabels', instance, function(afterHooksCallback) {
if (options.page) {
logger.log(
'Listing labels from page ' +
logger.colors.green(options.page) +
' on ' +
logger.colors.green(user + '/' + options.repo)
)
} else {
logger.log(
'Listing labels' + ' on ' + logger.colors.green(user + '/' + options.repo)
)
}
instance.listLabels(user, function(err1) {
if (err1) {
logger.error("Can't list labels.")
return
}
afterHooksCallback()
})
})
} else if (options.new) {
hooks.invoke('repo.createLabel', instance, function(afterHooksCallback) {
options.label = options.new
logger.log(
'Creating label ' +
logger.colors.green(options.label) +
' on ' +
logger.colors.green(user + '/' + options.repo)
)
instance.createLabel(user, function(err1) {
if (err1) {
logger.error("Can't create label.")
return
}
afterHooksCallback()
})
})
} else if (options.update) {
hooks.invoke('repo.updateLabel', instance, function(afterHooksCallback) {
options.label = options.update
logger.log(
'Updating label ' +
logger.colors.green(options.label) +
' on ' +
logger.colors.green(user + '/' + options.repo)
)
instance.updateLabel(user, function(err1) {
if (err1) {
logger.error("Can't update label.")
return
}
afterHooksCallback()
})
})
}
}
if (options.list && !options.label) {
if (options.organization) {
user = options.organization
options.type = options.type || Repo.TYPE_ALL
} else {
user = options.user;
options.type = options.type || Repo.TYPE_OWNER;
user = options.user
options.type = options.type || Repo.TYPE_OWNER
}
if (options.isTTY.out) {
logger.log('Listing ' + logger.colors.green(options.type) + ' repos for ' +
logger.colors.green(user));
logger.log(
'Listing ' +
logger.colors.green(options.type) +
' repos for ' +
logger.colors.green(user)
)
}
instance.list(user, function (err) {
instance.list(user, function(err) {
if (err) {
logger.error('Can\'t list repos.');
logger.error("Can't list repos.")
}
});
})
}
if (options.new) {
hooks.invoke('repo.new', instance, function (afterHooksCallback) {
options.repo = options.new;
if (options.new && !options.label) {
hooks.invoke('repo.new', instance, function(afterHooksCallback) {
options.repo = options.new
if (options.organization) {
options.user = options.organization;
options.user = options.organization
}
logger.log('Creating a new repo on ' + logger.colors.green(options.user + '/' + options.new));
logger.log(
'Creating a new repo on ' + logger.colors.green(options.user + '/' + options.new)
)
instance.new(function (err1, repo) {
instance.new(function(err1, repo) {
if (err1) {
logger.error('Can\'t create new repo. ' + JSON.parse(err1.message).message);
return;
logger.error("Can't create new repo. " + JSON.parse(err1.message).message)
return
}
logger.log(repo.html_url);
logger.log(repo.html_url)
if (repo && options.clone) {
instance.clone_(options.user, options.repo, repo.ssh_url);
instance.clone_(options.user, options.repo, repo.ssh_url)
}
afterHooksCallback();
});
});
afterHooksCallback()
})
})
}
};
}
Repo.prototype.browser = function (user, repo) {
openUrl(config.github_host + user + '/' + repo);
};
Repo.prototype.browser = function(user, repo) {
openUrl(config.github_host + user + '/' + repo)
}
Repo.prototype.clone_ = function (user, repo, repo_url) {
logger.log('Cloning ' + logger.colors.green(user + '/' + repo));
git.clone(url.parse(repo_url).href, repo);
};
Repo.prototype.clone_ = function(user, repo, repo_url) {
logger.log('Cloning ' + logger.colors.green(user + '/' + repo))
git.clone(url.parse(repo_url).href, repo)
}
Repo.prototype.delete = function (user, repo, opt_callback) {
var payload;
Repo.prototype.createLabel = function(user, opt_callback) {
var instance = this,
options = instance.options,
payload
payload = {
color: options.color,
name: options.new,
repo: options.repo,
user: user,
repo: repo
};
}
base.github.repos.delete(payload, opt_callback);
};
base.github.issues.createLabel(payload, opt_callback)
}
Repo.prototype.list = function (user, opt_callback) {
Repo.prototype.delete = function(user, repo, opt_callback) {
var payload
payload = {
user: user,
repo: repo,
}
base.github.repos.delete(payload, opt_callback)
}
Repo.prototype.deleteLabel = function(user, opt_callback) {
var instance = this,
options = instance.options,
payload
payload = {
name: options.delete,
repo: options.repo,
user: user,
}
base.github.issues.deleteLabel(payload, opt_callback)
}
Repo.prototype.get = function(user, repo, opt_callback) {
var payload
payload = {
user: user,
repo: repo,
}
base.github.repos.get(payload, opt_callback)
}
Repo.prototype.list = function(user, opt_callback) {
var instance = this,
method = 'getFromUser',
options = instance.options,
payload;
payload

@@ -246,8 +444,8 @@ payload = {

user: user,
per_page: 1000
};
per_page: 1000,
}
if (options.organization) {
method = 'getFromOrg';
payload.org = options.organization;
method = 'getFromOrg'
payload.org = options.organization
}

@@ -257,23 +455,22 @@

if (user === options.user) {
method = 'getAll';
method = 'getAll'
} else {
logger.error('You can only list your own public and private repos.')
return
}
else {
logger.error('You can only list your own public and private repos.');
return;
}
}
base.github.repos[method](payload, function (err, repos) {
instance.listCallback_(err, repos, opt_callback);
});
};
base.github.repos[method](payload, function(err, repos) {
instance.listCallback_(err, repos, opt_callback)
})
}
Repo.prototype.listCallback_ = function (err, repos, opt_callback) {
Repo.prototype.listCallback_ = function(err, repos, opt_callback) {
var instance = this,
options = instance.options,
pos,
repo;
repo
if (err && !options.all) {
logger.error(logger.getErrorMessage(err));
logger.error(logger.getErrorMessage(err))
}

@@ -284,22 +481,30 @@

if (repos.hasOwnProperty(pos) && repos[pos].full_name) {
repo = repos[pos];
logger.log(repo.full_name);
repo = repos[pos]
logger.log(repo.full_name)
if (options.detailed) {
logger.log(logger.colors.blue(repo.html_url));
logger.log(logger.colors.blue(repo.html_url))
if (repo.description) {
logger.log(logger.colors.blue(repo.description));
logger.log(logger.colors.blue(repo.description))
}
if (repo.homepage) {
logger.log(logger.colors.blue(repo.homepage));
logger.log(logger.colors.blue(repo.homepage))
}
logger.log('last update ' + logger.getDuration(repo.updated_at));
logger.log('last update ' + logger.getDuration(repo.updated_at))
}
if (options.isTTY.out) {
logger.log(logger.colors.green('forks: ' + repo.forks +
', stars: ' + repo.watchers + ', issues: ' + repo.open_issues) + '\n');
logger.log(
logger.colors.green(
'forks: ' +
repo.forks +
', stars: ' +
repo.watchers +
', issues: ' +
repo.open_issues
) + '\n'
)
}

@@ -309,42 +514,76 @@ }

opt_callback && opt_callback(err);
opt_callback && opt_callback(err)
}
};
}
Repo.prototype.fork = function (opt_callback) {
Repo.prototype.listLabels = function(user, opt_callback) {
var instance = this,
options = instance.options,
payload;
payload
payload = {
page: options.page,
per_page: options.per_page,
repo: options.repo,
user: user,
}
base.github.issues.getLabels(payload, function(err, labels) {
instance.listLabelsCallback_(err, labels, opt_callback)
})
}
Repo.prototype.listLabelsCallback_ = function(err, labels, opt_callback) {
var instance = this,
options = instance.options
if (err && !options.all) {
logger.error(logger.getErrorMessage(err))
}
if (labels && labels.length > 0) {
labels.forEach(function(label) {
logger.log(logger.colors.yellow(label.name))
})
opt_callback && opt_callback(err)
}
}
Repo.prototype.fork = function(opt_callback) {
var instance = this,
options = instance.options,
payload
payload = {
user: options.user,
repo: options.repo
};
repo: options.repo,
}
if (options.organization) {
payload.organization = options.organization;
payload.organization = options.organization
}
base.github.repos.fork(payload, opt_callback);
};
base.github.repos.fork(payload, opt_callback)
}
Repo.prototype.new = function (opt_callback) {
Repo.prototype.new = function(opt_callback) {
var instance = this,
options = instance.options,
payload,
method = 'create';
method = 'create'
options.description = options.description || '';
options.gitignore = options.gitignore || '';
options.homepage = options.homepage || '';
options.init = options.init || false;
options.description = options.description || ''
options.gitignore = options.gitignore || ''
options.homepage = options.homepage || ''
options.init = options.init || false
if (options.type === Repo.TYPE_PRIVATE) {
options.private = true;
options.private = true
}
options.private = options.private || false;
options.private = options.private || false
if (options.gitignore) {
options.init = true;
options.init = true
}

@@ -358,13 +597,28 @@

name: options.new,
private: options.private
};
private: options.private,
}
if (options.organization) {
method = 'createFromOrg';
payload.org = options.organization;
method = 'createFromOrg'
payload.org = options.organization
}
base.github.repos[method](payload, opt_callback);
};
base.github.repos[method](payload, opt_callback)
}
exports.Impl = Repo;
Repo.prototype.updateLabel = function(user, opt_callback) {
var instance = this,
options = instance.options,
payload
payload = {
color: options.color,
name: options.update,
repo: options.repo,
user: user,
}
base.github.issues.updateLabel(payload, opt_callback)
}
exports.Impl = Repo
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -12,3 +12,3 @@ * Code licensed under the BSD License:

'use strict';
'use strict'

@@ -22,3 +22,3 @@ // -- Requires -------------------------------------------------------------------------------------

moment = require('moment'),
config = configs.getConfig();
config = configs.getConfig()

@@ -28,3 +28,3 @@ // -- Constructor ----------------------------------------------------------------------------------

function User(options) {
this.options = options;
this.options = options
}

@@ -37,33 +37,29 @@

description: 'Provides the ability to login and logout if needed.',
commands: [
'login',
'logout',
'whoami'
],
commands: ['login', 'logout', 'whoami'],
options: {
'login': Boolean,
'logout': Boolean,
'whoami': Boolean
login: Boolean,
logout: Boolean,
whoami: Boolean,
},
shorthands: {
'l': ['--login'],
'L': ['--logout'],
'w': ['--whoami']
l: ['--login'],
L: ['--logout'],
w: ['--whoami'],
},
payload: function (payload, options) {
options.login = true;
}
};
payload: function(payload, options) {
options.login = true
},
}
// -- Commands -------------------------------------------------------------------------------------
User.prototype.run = function () {
User.prototype.run = function() {
var instance = this,
options = instance.options;
options = instance.options
options.user = options.loggedUser;
options.user = options.loggedUser
if (options.login) {
if (User.hasCredentials()) {
logger.log('You\'re logged in as ' + logger.colors.green(options.user));
logger.log("You're logged in as " + logger.colors.green(options.user))
}

@@ -73,40 +69,40 @@ }

if (options.logout) {
logger.log('Logging out of user ' + logger.colors.green(options.user));
logger.log('Logging out of user ' + logger.colors.green(options.user))
User.logout();
User.logout()
}
if (options.whoami) {
logger.log(options.user);
logger.log(options.user)
}
};
}
// -- Static ---------------------------------------------------------------------------------------
User.authorize = function () {
config = configs.getConfig();
User.authorize = function() {
config = configs.getConfig()
base.github.authenticate({
type: 'oauth',
token: config.github_token
});
};
token: config.github_token,
})
}
User.authorizationCallback_ = function (user, err, res) {
User.authorizationCallback_ = function(user, err, res) {
if (err) {
logger.error(err);
return;
logger.error(err)
return
}
if (res.token) {
configs.writeGlobalConfigCredentials(user, res.token);
configs.writeGlobalConfigCredentials(user, res.token)
User.authorize();
User.authorize()
}
logger.log('Authentication succeed.');
};
logger.log('Authentication succeed.')
}
User.createAuthorization = function (opt_callback) {
logger.log('First we need authorization to use GitHub\'s API. Login with your GitHub account.');
User.createAuthorization = function(opt_callback) {
logger.log("First we need authorization to use GitHub's API. Login with your GitHub account.")

@@ -118,3 +114,3 @@ inquirer.prompt(

message: 'Enter your GitHub user',
name: 'user'
name: 'user',
},

@@ -124,10 +120,11 @@ {

message: 'Enter your GitHub password',
name: 'password'
}
], function (answers) {
name: 'password',
},
],
function(answers) {
var payload = {
note: 'Node GH (' + moment().format('MMMM Do YYYY, h:mm:ss a') + ')',
note_url: 'https://github.com/eduardolundgren/node-gh',
scopes: ['user', 'public_repo', 'repo', 'repo:status', 'delete_repo', 'gist']
};
scopes: ['user', 'public_repo', 'repo', 'repo:status', 'delete_repo', 'gist'],
}

@@ -137,43 +134,42 @@ base.github.authenticate({

username: answers.user,
password: answers.password
});
password: answers.password,
})
base.github.authorization.create(payload, function (err, res) {
var isTwoFactorAuthentication = err && err.message && err.message.indexOf('OTP') > 0;
base.github.authorization.create(payload, function(err, res) {
var isTwoFactorAuthentication = err && err.message && err.message.indexOf('OTP') > 0
if (isTwoFactorAuthentication) {
User.twoFactorAuthenticator_(payload, answers.user, opt_callback);
User.twoFactorAuthenticator_(payload, answers.user, opt_callback)
} else {
User.authorizationCallback_(answers.user, err, res)
opt_callback && opt_callback(err)
}
else {
User.authorizationCallback_(answers.user, err, res);
opt_callback && opt_callback(err);
}
});
});
};
})
}
)
}
User.hasCredentials = function () {
User.hasCredentials = function() {
if (config.github_token && config.github_user) {
return true;
return true
}
return false;
};
return false
}
User.login = function (opt_callback) {
User.login = function(opt_callback) {
if (User.hasCredentials()) {
User.authorize();
opt_callback && opt_callback();
User.authorize()
opt_callback && opt_callback()
} else {
User.createAuthorization(opt_callback)
}
else {
User.createAuthorization(opt_callback);
}
};
}
User.logout = function () {
configs.removeGlobalConfig('github_user');
configs.removeGlobalConfig('github_token');
};
User.logout = function() {
configs.removeGlobalConfig('github_user')
configs.removeGlobalConfig('github_token')
}
User.twoFactorAuthenticator_ = function (payload, user, opt_callback) {
User.twoFactorAuthenticator_ = function(payload, user, opt_callback) {
inquirer.prompt(

@@ -184,18 +180,20 @@ [

message: 'Enter your two-factor code',
name: 'otp'
}
], function (factor) {
name: 'otp',
},
],
function(factor) {
if (!payload.headers) {
payload.headers = [];
payload.headers = []
}
payload.headers['X-GitHub-OTP'] = factor.otp;
payload.headers['X-GitHub-OTP'] = factor.otp
base.github.authorization.create(payload, function (err, res) {
User.authorizationCallback_(user, err, res);
opt_callback && opt_callback(err);
});
});
};
base.github.authorization.create(payload, function(err, res) {
User.authorizationCallback_(user, err, res)
opt_callback && opt_callback(err)
})
}
)
}
exports.Impl = User;
exports.Impl = User
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -10,23 +10,22 @@ * Code licensed under the BSD License:

'use strict';
'use strict'
var base = require('../base'),
logger = require('../logger');
logger = require('../logger')
function Version() {
}
function Version() {}
Version.DETAILS = {
alias: 'v',
description: 'Print gh version.'
};
description: 'Print gh version.',
}
Version.prototype.run = function () {
base.asyncReadPackages(this.printVersion);
};
Version.prototype.run = function() {
base.asyncReadPackages(this.printVersion)
}
Version.prototype.printVersion = function (pkg) {
logger.log(pkg.name + ' ' + pkg.version);
};
Version.prototype.printVersion = function(pkg) {
logger.log(pkg.name + ' ' + pkg.version)
}
exports.Impl = Version;
exports.Impl = Version
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -10,3 +10,3 @@ * Code licensed under the BSD License:

'use strict';
'use strict'

@@ -21,28 +21,27 @@ var fs = require('fs'),

plugins,
PLUGINS_PATH_KEY = 'plugins_path';
PLUGINS_PATH_KEY = 'plugins_path'
// -- Config -------------------------------------------------------------------
exports.getNodeModulesGlobalPath = function () {
exports.getNodeModulesGlobalPath = function() {
var result,
path = exports.getConfig()[PLUGINS_PATH_KEY];
path = exports.getConfig()[PLUGINS_PATH_KEY]
if (path === undefined) {
result = exec.spawnSync('npm', ['root', '-g']);
result = exec.spawnSync('npm', ['root', '-g'])
if (result.stdout) {
path = result.stdout;
exports.writeGlobalConfig(PLUGINS_PATH_KEY, path);
path = result.stdout
exports.writeGlobalConfig(PLUGINS_PATH_KEY, path)
} else {
logger.warn("Can't resolve plugins directory path.")
}
else {
logger.warn('Can\'t resolve plugins directory path.');
}
}
return path;
};
return path
}
exports.getUserHomePath = function () {
return userhome('.gh.json');
};
exports.getUserHomePath = function() {
return userhome('.gh.json')
}

@@ -52,101 +51,100 @@ function getConfig(opt_plugin) {

projectConfig,
result = {};
result = {}
try {
projectConfig = JSON.parse(fs.readFileSync(exports.getProjectConfigPath()));
projectConfig = JSON.parse(fs.readFileSync(exports.getProjectConfigPath()))
Object.keys(globalConfig).forEach(function (key) {
result[key] = globalConfig[key];
});
Object.keys(globalConfig).forEach(function(key) {
result[key] = globalConfig[key]
})
Object.keys(projectConfig).forEach(function (key) {
result[key] = projectConfig[key];
});
Object.keys(projectConfig).forEach(function(key) {
result[key] = projectConfig[key]
})
return result;
}
catch (e) {
logger.debug(e.message);
return result
} catch (e) {
logger.debug(e.message)
if (e.code !== 'MODULE_NOT_FOUND' && e.code !== 'ENOENT') {
throw e;
throw e
}
return globalConfig;
return globalConfig
}
}
exports.getConfig = function (opt_plugin) {
var config = cache[opt_plugin];
exports.getConfig = function(opt_plugin) {
var config = cache[opt_plugin]
if (!config) {
config = getConfig(opt_plugin);
cache[opt_plugin] = config;
config = getConfig(opt_plugin)
cache[opt_plugin] = config
}
var protocol = config.api.protocol + '://',
is_enterprise = (config.api.host !== 'api.github.com');
is_enterprise = config.api.host !== 'api.github.com'
if (config.github_host === undefined) {
config.github_host = protocol + (is_enterprise ? config.api.host : 'github.com') + '/';
config.github_host = protocol + (is_enterprise ? config.api.host : 'github.com') + '/'
}
if (config.github_gist_host === undefined) {
config.github_gist_host = protocol + (is_enterprise ? config.api.host + '/gist' : 'gist.github.com') + '/';
config.github_gist_host =
protocol + (is_enterprise ? config.api.host + '/gist' : 'gist.github.com') + '/'
}
return config;
};
return config
}
exports.getGlobalConfig = function (opt_plugin) {
var config,
configPath,
userConfig;
exports.getGlobalConfig = function(opt_plugin) {
var config, configPath, userConfig
configPath = exports.getUserHomePath();
configPath = exports.getUserHomePath()
if (!fs.existsSync(configPath)) {
exports.createGlobalConfig();
exports.createGlobalConfig()
}
config = JSON.parse(fs.readFileSync(exports.getGlobalConfigPath()));
userConfig = JSON.parse(fs.readFileSync(configPath));
config = JSON.parse(fs.readFileSync(exports.getGlobalConfigPath()))
userConfig = JSON.parse(fs.readFileSync(configPath))
Object.keys(userConfig).forEach(function (key) {
config[key] = userConfig[key];
});
Object.keys(userConfig).forEach(function(key) {
config[key] = userConfig[key]
})
if (opt_plugin) {
exports.getPlugins().forEach(function (plugin) {
exports.addPluginConfig(config, plugin);
});
exports.getPlugins().forEach(function(plugin) {
exports.addPluginConfig(config, plugin)
})
}
return config;
};
return config
}
exports.getGlobalConfigPath = function () {
return path.join(__dirname, '../', 'default.gh.json');
};
exports.getGlobalConfigPath = function() {
return path.join(__dirname, 'default.gh.json')
}
exports.getProjectConfigPath = function () {
return path.join(process.cwd(), '.gh.json');
};
exports.getProjectConfigPath = function() {
return path.join(process.cwd(), '.gh.json')
}
exports.removeGlobalConfig = function (key) {
var config = exports.getGlobalConfig();
exports.removeGlobalConfig = function(key) {
var config = exports.getGlobalConfig()
delete config[key];
delete config[key]
exports.saveJsonConfig(exports.getUserHomePath(), config);
cache = {};
};
exports.saveJsonConfig(exports.getUserHomePath(), config)
cache = {}
}
exports.createGlobalConfig = function () {
exports.saveJsonConfig(exports.getUserHomePath(),
exports.createGlobalConfig = function() {
exports.saveJsonConfig(
exports.getUserHomePath(),
JSON.parse(fs.readFileSync(exports.getGlobalConfigPath()))
);
cache = {};
};
)
cache = {}
}
exports.writeGlobalConfig = function (jsonPath, value) {
exports.writeGlobalConfig = function(jsonPath, value) {
var config = exports.getGlobalConfig(),

@@ -156,37 +154,36 @@ i,

path,
pathLen;
pathLen
path = jsonPath.split('.');
output = config;
path = jsonPath.split('.')
output = config
for (i = 0, pathLen = path.length; i < pathLen; i++) {
output[path[i]] = config[path[i]] || (i + 1 === pathLen ? value : {});
output = output[path[i]];
output[path[i]] = config[path[i]] || (i + 1 === pathLen ? value : {})
output = output[path[i]]
}
exports.saveJsonConfig(exports.getUserHomePath(), config);
cache = {};
};
exports.saveJsonConfig(exports.getUserHomePath(), config)
cache = {}
}
exports.saveJsonConfig = function (path, object) {
exports.saveJsonConfig = function(path, object) {
var options = {
mode: parseInt('0600', 8)
};
mode: parseInt('0600', 8),
}
fs.writeFileSync(path, JSON.stringify(object, null, 4), options);
};
fs.writeFileSync(path, JSON.stringify(object, null, 4), options)
}
exports.writeGlobalConfigCredentials = function (user, token) {
var configPath = exports.getUserHomePath();
exports.writeGlobalConfigCredentials = function(user, token) {
var configPath = exports.getUserHomePath()
exports.writeGlobalConfig('github_user', user);
exports.writeGlobalConfig('github_token', token);
logger.log('Writing GH config data: ' + configPath);
};
exports.writeGlobalConfig('github_user', user)
exports.writeGlobalConfig('github_token', token)
logger.log('Writing GH config data: ' + configPath)
}
// -- Plugins ------------------------------------------------------------------
exports.addPluginConfig = function (config, plugin) {
var pluginConfig,
userConfig;
exports.addPluginConfig = function(config, plugin) {
var pluginConfig, userConfig

@@ -196,74 +193,74 @@ try {

// prefix from passed plugin.
plugin = exports.getPluginBasename(plugin || process.env.NODEGH_PLUGIN);
plugin = exports.getPluginBasename(plugin || process.env.NODEGH_PLUGIN)
pluginConfig = require(path.join(
exports.getNodeModulesGlobalPath(), 'gh-' + plugin, 'gh-plugin.json'));
exports.getNodeModulesGlobalPath(),
'gh-' + plugin,
'gh-plugin.json'
))
// Merge default plugin configuration with the user's.
userConfig = config.plugins[plugin] || {};
userConfig = config.plugins[plugin] || {}
Object.keys(userConfig).forEach(function (key) {
pluginConfig[key] = userConfig[key];
});
Object.keys(userConfig).forEach(function(key) {
pluginConfig[key] = userConfig[key]
})
config.plugins[plugin] = pluginConfig;
}
catch (e) {
config.plugins[plugin] = pluginConfig
} catch (e) {
if (e.code !== 'MODULE_NOT_FOUND') {
throw e;
throw e
}
}
};
}
function getPlugins() {
var pluginsPath = exports.getNodeModulesGlobalPath();
var pluginsPath = exports.getNodeModulesGlobalPath()
if (pluginsPath === '') {
return [];
return []
}
try {
plugins = fs.readdirSync(pluginsPath).filter(function (plugin) {
return plugin.substring(0, 3) === 'gh-';
});
plugins = fs.readdirSync(pluginsPath).filter(function(plugin) {
return plugin.substring(0, 3) === 'gh-'
})
} catch (e) {
plugins = []
logger.warn("Can't read plugins directory.")
} finally {
return plugins
}
catch(e) {
plugins = [];
logger.warn('Can\'t read plugins directory.');
}
finally {
return plugins;
}
}
exports.getPlugins = function () {
exports.getPlugins = function() {
if (!plugins) {
plugins = getPlugins();
plugins = getPlugins()
}
return plugins;
};
return plugins
}
exports.getPlugin = function (plugin) {
plugin = exports.getPluginBasename(plugin);
exports.getPlugin = function(plugin) {
plugin = exports.getPluginBasename(plugin)
return require(exports.getPluginPath('gh-' + plugin));
};
return require(exports.getPluginPath('gh-' + plugin))
}
exports.getPluginPath = function (plugin) {
return fs.realpathSync(which.sync(plugin));
};
exports.getPluginPath = function(plugin) {
return fs.realpathSync(which.sync(plugin))
}
exports.getPluginBasename = function (plugin) {
return plugin && plugin.replace('gh-', '');
};
exports.getPluginBasename = function(plugin) {
return plugin && plugin.replace('gh-', '')
}
exports.isPluginIgnored = function (plugin) {
exports.isPluginIgnored = function(plugin) {
if (exports.getConfig().ignored_plugins.indexOf(exports.getPluginBasename(plugin)) > -1) {
return true;
return true
}
return false;
};
return false
}
exports.PLUGINS_PATH_KEY = PLUGINS_PATH_KEY;
exports.PLUGINS_PATH_KEY = PLUGINS_PATH_KEY
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -11,17 +11,17 @@ * Code licensed under the BSD License:

'use strict';
'use strict'
var child_process = require('child_process'),
logger = require('./logger');
logger = require('./logger')
exports.spawnSync = function (cmd, args, options) {
var exec;
exports.spawnSync = function(cmd, args, options) {
var exec
logger.debug('spawnSync: ' + cmd + ' ' + args.join(' '));
logger.debug('spawnSync: ' + cmd + ' ' + args.join(' '))
exec = child_process.spawnSync(cmd, args, options);
exec = child_process.spawnSync(cmd, args, options)
if (exec.error && exec.error.code === 'ENOENT' && process.platform === 'win32') {
logger.debug('Invoking patched sapwnSync due to Windows\' libuv bug');
exec = child_process.spawnSync(cmd + '.cmd', args, options);
logger.debug("Invoking patched sapwnSync due to Windows' libuv bug")
exec = child_process.spawnSync(cmd + '.cmd', args, options)
}

@@ -32,53 +32,52 @@

stderr: exec.stderr.toString().trim(),
status: exec.status
};
};
status: exec.status,
}
}
exports.spawnSyncStream = function (cmd, args, options) {
var proc,
err;
exports.spawnSyncStream = function(cmd, args, options) {
var proc, err
if (!options) {
options = {};
options = {}
}
options.stdio = ['pipe', process.stdout, process.stderr];
options.stdio = ['pipe', process.stdout, process.stderr]
logger.debug('spawnSyncStream: ' + cmd + ' ' + args.join(' '));
logger.debug('spawnSyncStream: ' + cmd + ' ' + args.join(' '))
proc = child_process.spawnSync(cmd, args, options);
proc = child_process.spawnSync(cmd, args, options)
if (proc.status !== 0) {
err = new Error();
err.code = proc.status;
err.message = 'Child process terminated with error code ' + err.code;
err = new Error()
err.code = proc.status
err.message = 'Child process terminated with error code ' + err.code
throw err;
throw err
}
return proc;
};
return proc
}
exports.execSync = function (cmd, options) {
exports.execSync = function(cmd, options) {
if (!options) {
options = {};
options = {}
}
logger.debug('execSync: ' + cmd);
logger.debug('execSync: ' + cmd)
options.stdio = ['pipe', process.stdout, process.stderr];
options.stdio = ['pipe', process.stdout, process.stderr]
return child_process.execSync(cmd, options);
};
return child_process.execSync(cmd, options)
}
exports.execSyncInteractiveStream = function (cmd, options) {
exports.execSyncInteractiveStream = function(cmd, options) {
if (!options) {
options = {};
options = {}
}
logger.debug('execSyncInteractiveStream: ' + cmd);
logger.debug('execSyncInteractiveStream: ' + cmd)
options.stdio = 'inherit';
options.stdio = 'inherit'
return child_process.execSync(cmd, options);
};
return child_process.execSync(cmd, options)
}
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -10,66 +10,64 @@ * Code licensed under the BSD License:

'use strict';
'use strict'
var logger = require('./logger'),
exec = require('./exec'),
git_command = process.env.GH_GIT_COMMAND || 'git';
git_command = process.env.GH_GIT_COMMAND || 'git'
exports.checkout = function (branch, newBranch) {
var args = ['checkout', branch];
exports.checkout = function(branch, newBranch) {
var args = ['checkout', branch]
if (newBranch) {
args.push('-B', newBranch);
args.push('-B', newBranch)
}
return exec.spawnSyncStream(git_command, args);
};
return exec.spawnSyncStream(git_command, args)
}
exports.clone = function (url, folder) {
var args = ['clone', url];
exports.clone = function(url, folder) {
var args = ['clone', url]
if (folder) {
args.push(folder);
args.push(folder)
}
return exec.spawnSyncStream(git_command, args);
};
return exec.spawnSyncStream(git_command, args)
}
exports._merge = function (branch, type) {
var res;
exports._merge = function(branch, type) {
try {
res = exec.spawnSyncStream(git_command, [type, branch]);
} catch(err) {
exec.spawnSyncStream(git_command, [type, branch])
} catch (err) {
if (err.code && err.code !== 0) {
exec.spawnSyncStream(git_command, [type, '--abort']);
throw err;
exec.spawnSyncStream(git_command, [type, '--abort'])
throw err
}
}
};
}
exports.merge = function (branch) {
return this._merge(branch, 'merge');
};
exports.merge = function(branch) {
return this._merge(branch, 'merge')
}
exports.rebase = function (branch) {
return this._merge(branch, 'rebase');
};
exports.rebase = function(branch) {
return this._merge(branch, 'rebase')
}
exports.push = function (remote, branch) {
var args = ['push', remote];
exports.push = function(remote, branch) {
var args = ['push', remote]
if (branch) {
args.push(branch);
args.push(branch)
}
return exec.spawnSyncStream(git_command, args);
};
return exec.spawnSyncStream(git_command, args)
}
exports.fetch = function (repoUrl, headBranch, pullBranch) {
var args = ['fetch', repoUrl, headBranch + ':' + pullBranch, '--no-tags'];
exports.fetch = function(repoUrl, headBranch, pullBranch) {
var args = ['fetch', repoUrl, headBranch + ':' + pullBranch, '--no-tags']
return exec.spawnSyncStream(git_command, args);
};
return exec.spawnSyncStream(git_command, args)
}
exports.countUserAdjacentCommits = function () {
exports.countUserAdjacentCommits = function() {
var git,

@@ -79,135 +77,134 @@ params,

user = exports.getConfig('user.name'),
author;
author
do {
params = ['log', '-1', '--skip=' + commits, '--pretty=%an'];
git = exec.spawnSync(git_command, params);
params = ['log', '-1', '--skip=' + commits, '--pretty=%an']
git = exec.spawnSync(git_command, params)
if (git.status !== 0) {
logger.error(git.stderr);
logger.error(git.stderr)
}
author = git.stdout;
author = git.stdout
commits += 1;
} while (author === user);
commits += 1
} while (author === user)
commits -= 1;
commits -= 1
return commits;
};
return commits
}
exports.deleteBranch = function (branch) {
var git = exec.spawnSync(git_command, ['branch', '-d', branch]);
exports.deleteBranch = function(branch) {
var git = exec.spawnSync(git_command, ['branch', '-d', branch])
if (git.status !== 0) {
logger.debug(git.stderr);
logger.debug(git.stderr)
}
return git.stdout;
};
return git.stdout
}
exports.findRoot = function () {
return exec.spawnSync(git_command, ['rev-parse', '--show-toplevel']).stdout;
};
exports.findRoot = function() {
return exec.spawnSync(git_command, ['rev-parse', '--show-toplevel']).stdout
}
exports.getCommitMessage = function (branch, number) {
exports.getCommitMessage = function(branch, number) {
var git,
params = ['log'];
params = ['log']
if (!number) {
number = 1;
number = 1
}
params.push('-' + number, '--first-parent', '--no-merges', '--pretty=%s');
params.push('-' + number, '--first-parent', '--no-merges', '--pretty=%s')
if (branch) {
params.push(branch);
params.push(branch)
}
params.push('--');
params.push('--')
git = exec.spawnSync(git_command, params);
git = exec.spawnSync(git_command, params)
if (git.status !== 0) {
logger.debug('Can\'t get commit message.');
return;
logger.debug("Can't get commit message.")
return
}
return git.stdout;
};
return git.stdout
}
exports.getConfig = function (key) {
var git = exec.spawnSync(git_command, ['config', '--get', key]);
exports.getConfig = function(key) {
var git = exec.spawnSync(git_command, ['config', '--get', key])
if (git.status !== 0) {
throw new Error('No git config found for ' + key + '\n');
throw new Error('No git config found for ' + key + '\n')
}
return git.stdout;
};
return git.stdout
}
exports.getCurrentBranch = function () {
var git = exec.spawnSync(git_command, ['symbolic-ref', '--short', 'HEAD']);
exports.getCurrentBranch = function() {
var git = exec.spawnSync(git_command, ['symbolic-ref', '--short', 'HEAD'])
if (git.status !== 0) {
logger.debug('Can\'t get current branch.');
return;
logger.debug("Can't get current branch.")
return
}
return git.stdout;
};
return git.stdout
}
exports.getLastCommitMessage = function (branch) {
return exports.getCommitMessage(branch, 1);
};
exports.getLastCommitMessage = function(branch) {
return exports.getCommitMessage(branch, 1)
}
exports.getLastCommitSHA = function () {
var git = exec.spawnSync(git_command, ['rev-parse', '--short', 'HEAD']);
exports.getLastCommitSHA = function() {
var git = exec.spawnSync(git_command, ['rev-parse', '--short', 'HEAD'])
if (git.status !== 0) {
throw new Error('Can\'t retrieve last commit.');
throw new Error("Can't retrieve last commit.")
}
return git.stdout;
};
return git.stdout
}
exports.getRemoteUrl = function (remote) {
exports.getRemoteUrl = function(remote) {
try {
return exports.getConfig('remote.' + remote + '.url');
return exports.getConfig('remote.' + remote + '.url')
} catch (e) {
logger.debug("Can't get remote URL.")
return
}
catch(e) {
logger.debug('Can\'t get remote URL.');
return;
}
};
}
exports.getRepoFromRemoteURL = function (url) {
var parsed = exports.parseRemoteUrl(url);
exports.getRepoFromRemoteURL = function(url) {
var parsed = exports.parseRemoteUrl(url)
return parsed && parsed[1];
};
return parsed && parsed[1]
}
exports.getUserFromRemoteUrl = function (url) {
var parsed = exports.parseRemoteUrl(url);
exports.getUserFromRemoteUrl = function(url) {
var parsed = exports.parseRemoteUrl(url)
return parsed && parsed[0];
};
return parsed && parsed[0]
}
exports.getRepo = function (remote) {
return exports.getRepoFromRemoteURL(exports.getRemoteUrl(remote));
};
exports.getRepo = function(remote) {
return exports.getRepoFromRemoteURL(exports.getRemoteUrl(remote))
}
exports.getUser = function (remote) {
return exports.getUserFromRemoteUrl(exports.getRemoteUrl(remote));
};
exports.getUser = function(remote) {
return exports.getUserFromRemoteUrl(exports.getRemoteUrl(remote))
}
exports.parseRemoteUrl = function (url) {
var parsed = /[\/:]([\w-]+)\/(.*?)(?:\.git)?$/.exec(url);
exports.parseRemoteUrl = function(url) {
var parsed = /[\/:]([\w-]+)\/(.*?)(?:\.git)?$/.exec(url)
if (parsed) {
parsed.shift();
parsed.shift()
}
return parsed;
};
return parsed
}
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -10,3 +10,3 @@ * Code licensed under the BSD License:

'use strict';
'use strict'

@@ -18,57 +18,56 @@ var async = require('async'),

logger = require('./logger'),
config = configs.getConfig(true);
config = configs.getConfig(true)
exports.createContext = function (scope) {
exports.createContext = function(scope) {
return {
options: scope.options,
signature: config.signature
};
};
signature: config.signature,
}
}
exports.getHooksArrayFromPath_ = function (path, opt_config) {
exports.getHooksArrayFromPath_ = function(path, opt_config) {
var keys = path.split('.'),
key = keys.shift(),
hooks;
hooks
opt_config = opt_config || config;
opt_config = opt_config || config
hooks = opt_config.hooks || {};
hooks = opt_config.hooks || {}
while (hooks[key]) {
hooks = hooks[key];
key = keys.shift();
hooks = hooks[key]
key = keys.shift()
}
return Array.isArray(hooks) ? hooks : [];
};
return Array.isArray(hooks) ? hooks : []
}
exports.getHooksFromPath = function (path) {
exports.getHooksFromPath = function(path) {
var hooks,
plugins = configs.getPlugins(),
pluginHooks = [];
pluginHooks = []
// First, load all core hooks for the specified path.
hooks = exports.getHooksArrayFromPath_(path);
hooks = exports.getHooksArrayFromPath_(path)
// Second, search all installed plugins and load the hooks for each into
// core hooks array.
plugins.forEach(function (plugin) {
var pluginConfig;
plugins.forEach(function(plugin) {
var pluginConfig
plugin = configs.getPluginBasename(plugin);
plugin = configs.getPluginBasename(plugin)
if (config.plugins && !configs.isPluginIgnored(plugin)) {
pluginConfig = config.plugins[plugin];
pluginConfig = config.plugins[plugin]
if (pluginConfig) {
pluginHooks = pluginHooks.concat(
exports.getHooksArrayFromPath_(path, pluginConfig));
pluginHooks = pluginHooks.concat(exports.getHooksArrayFromPath_(path, pluginConfig))
}
}
});
})
return hooks.concat(pluginHooks);
};
return hooks.concat(pluginHooks)
}
exports.invoke = function (path, scope, opt_callback) {
exports.invoke = function(path, scope, opt_callback) {
var after = exports.getHooksFromPath(path + '.after'),

@@ -79,92 +78,90 @@ before = exports.getHooksFromPath(path + '.before'),

options = scope.options,
context;
context
if (options.hooks === false || process.env.NODEGH_HOOK_IS_LOCKED) {
opt_callback && opt_callback();
return;
opt_callback && opt_callback()
return
}
context = exports.createContext(scope);
context = exports.createContext(scope)
beforeOperations = [
function(callback) {
exports.setupPlugins_(context, 'setupBeforeHooks', callback)
},
]
function (callback) {
exports.setupPlugins_(context, 'setupBeforeHooks', callback);
}
];
before.forEach(function(cmd) {
beforeOperations.push(exports.wrapCommand_(cmd, context, 'before'))
})
before.forEach(function (cmd) {
beforeOperations.push(exports.wrapCommand_(cmd, context, 'before'));
});
afterOperations = [
function(callback) {
exports.setupPlugins_(context, 'setupAfterHooks', callback)
},
]
function (callback) {
exports.setupPlugins_(context, 'setupAfterHooks', callback);
}
];
after.forEach(function(cmd) {
afterOperations.push(exports.wrapCommand_(cmd, context, 'after'))
})
after.forEach(function (cmd) {
afterOperations.push(exports.wrapCommand_(cmd, context, 'after'));
});
afterOperations.push(function(callback) {
process.env.NODEGH_HOOK_IS_LOCKED = false
callback()
})
afterOperations.push(function (callback) {
process.env.NODEGH_HOOK_IS_LOCKED = false;
callback();
});
process.env.NODEGH_HOOK_IS_LOCKED = true
process.env.NODEGH_HOOK_IS_LOCKED = true;
async.series(beforeOperations, function() {
opt_callback &&
opt_callback(function() {
async.series(afterOperations)
})
})
}
async.series(beforeOperations, function () {
opt_callback && opt_callback(function () {
async.series(afterOperations);
});
});
};
exports.setupPlugins_ = function (context, setupFn, opt_callback) {
exports.setupPlugins_ = function(context, setupFn, opt_callback) {
var plugins = configs.getPlugins(),
operations = [];
operations = []
plugins.forEach(function (plugin) {
plugins.forEach(function(plugin) {
try {
plugin = configs.getPlugin(plugin);
plugin = configs.getPlugin(plugin)
} catch (e) {
logger.warn("Can't get " + plugin + ' plugin.')
}
catch(e) {
logger.warn('Can\'t get ' + plugin + ' plugin.');
}
if (plugin && plugin[setupFn]) {
operations.push(function (callback) {
plugin[setupFn](context, callback);
});
operations.push(function(callback) {
plugin[setupFn](context, callback)
})
}
});
})
async.series(operations, function () {
opt_callback && opt_callback();
});
};
async.series(operations, function() {
opt_callback && opt_callback()
})
}
exports.wrapCommand_ = function (cmd, context, when) {
return function (callback) {
var raw = logger.compileTemplate(cmd, context);
exports.wrapCommand_ = function(cmd, context, when) {
return function(callback) {
var raw = logger.compileTemplate(cmd, context)
if (!raw) {
callback && callback();
return;
callback && callback()
return
}
logger.log(logger.colors.cyan('[hook]'), truncate(raw.trim(), 120));
logger.log(logger.colors.cyan('[hook]'), truncate(raw.trim(), 120))
try {
exec.execSyncInteractiveStream(raw, {cwd: process.cwd()});
} catch(e) {
logger.debug('[' + when + ' hook failure]');
exec.execSyncInteractiveStream(raw, { cwd: process.cwd() })
} catch (e) {
logger.debug('[' + when + ' hook failure]')
} finally {
logger.debug(logger.colors.cyan('[end of ' + when + ' hook]'));
logger.debug(logger.colors.cyan('[end of ' + when + ' hook]'))
}
callback && callback();
};
};
callback && callback()
}
}
/*
* Copyright 2013-2015, All Rights Reserved.
* Copyright 2013-2018, All Rights Reserved.
*

@@ -11,3 +11,3 @@ * Code licensed under the BSD License:

'use strict';
'use strict'

@@ -20,80 +20,79 @@ var logger = {},

wrap = require('wordwrap').hard(0, 80),
colors = require('colors/safe');
colors = require('colors/safe')
function stripHandlebarsNewLine(str) {
return str.replace(/[\s\t\r\n](\{\{[#\/])/g, '$1');
return str.replace(/[\s\t\r\n](\{\{[#\/])/g, '$1')
}
logger.debug = function () {
logger.debug = function() {
if (!process.env.GH_VERBOSE) {
return;
return
}
if (typeof arguments[0] === 'string') {
arguments[0] = 'DEBUG: ' + arguments[0];
console.log.apply(this, arguments);
return;
arguments[0] = 'DEBUG: ' + arguments[0]
console.log.apply(this, arguments)
return
}
console.log('DEBUG:');
console.log.apply(this, arguments);
};
console.log('DEBUG:')
console.log.apply(this, arguments)
}
logger.insane = function () {
logger.insane = function() {
if (!process.env.GH_VERBOSE_INSANE) {
return;
return
}
console.log.apply(this, arguments);
};
console.log.apply(this, arguments)
}
logger.error = function () {
logger.error = function() {
if (typeof arguments[0] === 'string') {
arguments[0] = 'fatal: ' + arguments[0];
arguments[0] = 'fatal: ' + arguments[0]
}
console.error.apply(this, arguments);
process.exit(1);
};
console.error.apply(this, arguments)
process.exit(1)
}
logger.warn = function () {
arguments[0] = 'warning: ' + arguments[0];
console.error.apply(this, arguments);
};
logger.warn = function() {
arguments[0] = 'warning: ' + arguments[0]
console.error.apply(this, arguments)
}
logger.log = function () {
console.log.apply(this, arguments);
};
logger.log = function() {
console.log.apply(this, arguments)
}
logger.getDuration = function (start, opt_end) {
logger.getDuration = function(start, opt_end) {
if (opt_end === undefined) {
opt_end = Date.now();
opt_end = Date.now()
}
return moment.duration(moment(start).diff(opt_end)).humanize(true);
};
return moment.duration(moment(start).diff(opt_end)).humanize(true)
}
logger.applyReplacements = function (output, replaceMap) {
var regexPattern;
logger.applyReplacements = function(output, replaceMap) {
var regexPattern
for (regexPattern in replaceMap) {
if (replaceMap.hasOwnProperty(regexPattern)) {
output = output.replace(
new RegExp(regexPattern, 'g'), replaceMap[regexPattern]);
output = output.replace(new RegExp(regexPattern, 'g'), replaceMap[regexPattern])
}
}
return output;
};
return output
}
logger.getErrorMessage = function (err) {
var msg;
logger.getErrorMessage = function(err) {
var msg
// General normalizer
if (!err) {
return 'No error message.';
return 'No error message.'
}
if (err.errors) {
return err.errors;
return err.errors
}

@@ -103,114 +102,145 @@

if (!err.message) {
return err;
return err
}
try {
msg = JSON.parse(err.message);
} catch(e) {
return err.message;
msg = JSON.parse(err.message)
} catch (e) {
return err.message
}
if (typeof msg === 'string') {
return msg;
return msg
}
if (msg.errors && msg.errors[0] && msg.errors[0].message) {
return msg.errors[0].message;
return msg.errors[0].message
}
if (msg.message) {
return msg.message;
return msg.message
}
// Normalize git error
return err.message.replace('Command failed: fatal: ', '').trim();
};
return err.message.replace('Command failed: fatal: ', '').trim()
}
logger.compileTemplate = function (source, map) {
var template = handlebars.compile(source);
logger.compileTemplate = function(source, map) {
var template = handlebars.compile(source)
return logger.applyReplacements(template(map));
};
return logger.applyReplacements(template(map))
}
logger.logTemplate = function (source, map) {
console.log(logger.compileTemplate(source, map || {}));
};
logger.logTemplate = function(source, map) {
console.log(logger.compileTemplate(source, map || {}))
}
logger.logTemplateFile = function (file, map) {
var templatePath,
source;
logger.logTemplateFile = function(file, map) {
var templatePath, source
templatePath = path.join(file);
templatePath = path.join(file)
if (!fs.existsSync(templatePath)) {
templatePath = path.join(__dirname, 'cmds/templates', file);
templatePath = path.join(__dirname, 'cmds/templates', file)
}
source = fs.readFileSync(templatePath).toString();
source = fs.readFileSync(templatePath).toString()
logger.logTemplate(stripHandlebarsNewLine(source), map);
};
logger.logTemplate(stripHandlebarsNewLine(source), map)
}
logger.registerHelper = function (name, callback) {
handlebars.registerHelper(name, callback);
};
logger.registerHelper = function(name, callback) {
handlebars.registerHelper(name, callback)
}
logger.registerHelpers_ = function () {
handlebars.registerHelper('date', function (date) {
return logger.getDuration(date);
});
logger.registerHelpers_ = function() {
handlebars.registerHelper('date', function(date) {
return logger.getDuration(date)
})
handlebars.registerHelper('compareLink', function () {
return this.options.github_host + this.options.user + '/' + this.options.repo +
'/compare/' + this.options.pullHeadSHA + '...' + this.options.currentSHA;
});
handlebars.registerHelper('compareLink', function() {
return (
this.options.github_host +
this.options.user +
'/' +
this.options.repo +
'/compare/' +
this.options.pullHeadSHA +
'...' +
this.options.currentSHA
)
})
handlebars.registerHelper('forwardedLink', function () {
return this.options.github_host + this.options.fwd + '/' + this.options.repo + '/pull/' +
this.options.forwardedPull;
});
handlebars.registerHelper('forwardedLink', function() {
return (
this.options.github_host +
this.options.fwd +
'/' +
this.options.repo +
'/pull/' +
this.options.forwardedPull
)
})
handlebars.registerHelper('link', function () {
return this.options.github_host + this.options.user + '/' + this.options.repo + '/pull/' +
this.options.number;
});
handlebars.registerHelper('link', function() {
return (
this.options.github_host +
this.options.user +
'/' +
this.options.repo +
'/pull/' +
this.options.number
)
})
handlebars.registerHelper('submittedLink', function () {
return this.options.github_host + this.options.submit + '/' + this.options.repo + '/pull/' +
this.options.submittedPull;
});
handlebars.registerHelper('submittedLink', function() {
return (
this.options.github_host +
this.options.submit +
'/' +
this.options.repo +
'/pull/' +
this.options.submittedPull
)
})
handlebars.registerHelper('issueLink', function () {
return this.options.github_host + this.options.user + '/' + this.options.repo + '/issues/' +
this.options.number;
});
handlebars.registerHelper('issueLink', function() {
return (
this.options.github_host +
this.options.user +
'/' +
this.options.repo +
'/issues/' +
this.options.number
)
})
handlebars.registerHelper('gistLink', function () {
return this.options.github_gist_host + this.options.loggedUser + '/' + this.options.id;
});
handlebars.registerHelper('gistLink', function() {
return this.options.github_gist_host + this.options.loggedUser + '/' + this.options.id
})
handlebars.registerHelper('repoLink', function () {
return this.options.github_host + this.options.user + '/' + this.options.repo;
});
handlebars.registerHelper('repoLink', function() {
return this.options.github_host + this.options.user + '/' + this.options.repo
})
handlebars.registerHelper('wordwrap', function (text, padding, stripNewLines) {
var gutter = '';
handlebars.registerHelper('wordwrap', function(text, padding, stripNewLines) {
var gutter = ''
if (stripNewLines !== false) {
text = text.replace(/[\r\n\s\t]+/g, ' ');
text = text.replace(/[\r\n\s\t]+/g, ' ')
}
text = wrap(text).split('\n');
text = wrap(text).split('\n')
if (padding > 0) {
gutter = (new Array(padding)).join(' ');
gutter = new Array(padding).join(' ')
}
return text.join('\n' + gutter);
});
};
return text.join('\n' + gutter)
})
}
logger.registerHelpers_();
logger.registerHelpers_()
logger.colors = colors;
module.exports = logger;
logger.colors = colors
module.exports = logger

@@ -0,4 +1,17 @@

/*
* Copyright 2013-2018, All Rights Reserved.
*
* Code licensed under the BSD License:
* https://github.com/node-gh/gh/blob/master/LICENSE.md
*
* @author Eduardo Lundgren <edu@rdo.io>
*/
'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError('Cannot call a class as a function');
}
}

@@ -46,4 +59,4 @@ var _request = require('request');

p.auth = {
'user': options.user,
'pass': options.password
user: options.user,
pass: options.password
};

@@ -50,0 +63,0 @@ }

Software License Agreement (BSD License)
Copyright (c) 2013-2015, Eduardo Antonio Lundgren Melo and Zeno Rocha Bueno Netto.
Copyright (c) 2013-2018, Eduardo Antonio Lundgren Melo and Zeno Rocha Bueno Netto.
All rights reserved.

@@ -5,0 +5,0 @@

{
"name": "gh",
"description": "GitHub command line tools.",
"version": "1.12.8",
"homepage": "http://nodegh.io",
"author": {
"name": "Eduardo Lundgren",
"email": "eduardolundgren@gmail.com",
"web": "http://eduardo.io",
"twitter": "eduardolundgren"
},
"contributors": [
{
"name": "Zeno Rocha",
"email": "zno.rocha@gmail.com",
"web": "http://zenorocha.com",
"twitter": "zenorocha"
}
],
"license": "BSD-3-Clause",
"repository": {
"type": "git",
"url": "git@github.com:node-gh/gh.git"
},
"bugs": {
"url": "https://github.com/node-gh/gh/issues"
},
"trackingCode": "UA-58265773-2",
"keywords": [
"git",
"github",
"external",
"commands",
"helpers"
],
"bin": {
"gh": "bin/gh.js"
},
"scripts": {
"prepublish": "sh prepublish.sh",
"postpublish": "sh postpublish.sh",
"test": "gulp test",
"ci": "gulp ci"
},
"dependencies": {
"async": "^1.5.0",
"babel-polyfill": "^6.0.16",
"lodash": "^3.10.1",
"request": "^2.65.0",
"colors": "^1.1.2",
"github": "^0.2.4",
"handlebars": "^4.0.4",
"inquirer": "^0.11.0",
"insight": "^0.7.0",
"moment": "^2.13.0",
"nopt": "^3.0.4",
"open": "^0.0.5",
"truncate": "^2.0.0",
"update-notifier": "^0.5.0",
"userhome": "^1.0.0",
"which": "^1.2.0",
"wordwrap": "^1.0.0"
},
"devDependencies": {
"babel": "^5.8",
"gulp": "^3.9.0",
"gulp-mocha": "^2.1.3",
"gulp-istanbul": "^0.10.2",
"gulp-complexity": "^0.3.2",
"gulp-jshint": "^1.12.0",
"gulp-jscs": "^3.0.2",
"plato": "^1.5.0",
"jshint-stylish": "^2.0.1",
"rewire": "^2.3.4",
"run-sequence": "^1.1.4"
},
"engines": {
"node": ">=0.12"
},
"preferGlobal": "true"
"name": "gh",
"description": "GitHub command line tools.",
"version": "1.12.9",
"homepage": "http://nodegh.io",
"author": {
"name": "Eduardo Lundgren",
"email": "eduardolundgren@gmail.com",
"web": "http://eduardo.io",
"twitter": "eduardolundgren"
},
"contributors": [
{
"name": "Zeno Rocha",
"email": "zno.rocha@gmail.com",
"web": "http://zenorocha.com",
"twitter": "zenorocha"
}
],
"license": "BSD-3-Clause",
"repository": {
"type": "git",
"url": "git@github.com:node-gh/gh.git"
},
"bugs": {
"url": "https://github.com/node-gh/gh/issues"
},
"keywords": ["git", "github", "external", "commands", "helpers"],
"bin": {
"gh": "bin/gh.js"
},
"scripts": {
"ci": "gulp ci",
"eslint-check": "eslint --print-config .eslintrc.js | eslint-config-prettier-check",
"fix": "eslint --fix \"lib/**/*.js\" \"lib/*.js\" \"test/*.js\"",
"format": "prettier --write \"lib/**/*.js\" \"lib/*.js\" \"test/*.js\" && npm run fix",
"lint-staged": "lint-staged",
"postpublish": "sh scripts/postpublish.sh",
"precommit": "lint-staged && npm test",
"prepublish": "sh scripts/prepublish.sh",
"test": "gulp test"
},
"lint-staged": {
"*.{js,json}": ["prettier --write && eslint --fix", "git add"]
},
"dependencies": {
"async": "^1.5.0",
"babel-polyfill": "^6.0.16",
"colors": "^1.1.2",
"github": "^0.2.4",
"handlebars": "^4.0.4",
"inquirer": "^0.11.0",
"lodash": "^3.10.1",
"moment": "^2.20.1",
"nopt": "^3.0.4",
"open": "^0.0.5",
"request": "^2.83.0",
"truncate": "^2.0.0",
"update-notifier": "^0.5.0",
"userhome": "^1.0.0",
"which": "^1.2.0",
"wordwrap": "^1.0.0"
},
"devDependencies": {
"babel": "^5.8",
"babel-eslint": "^8.1.2",
"eslint": "^4.14.0",
"eslint-config-prettier": "^2.9.0",
"eslint-config-recommended": "^2.0.0",
"eslint-plugin-prettier": "^2.4.0",
"gulp": "^3.9.0",
"gulp-complexity": "^0.3.2",
"gulp-istanbul": "^0.10.2",
"gulp-mocha": "^2.1.3",
"husky": "^0.14.3",
"lint-staged": "^6.0.0",
"plato": "^1.5.0",
"prettier": "^1.9.2",
"rewire": "^2.3.4",
"run-sequence": "^1.1.4"
},
"engines": {
"node": ">=0.12"
},
"preferGlobal": true
}

@@ -57,11 +57,11 @@ # Node GH

```
```
gh help --all
```
```
* List specific command options.
```
```
gh help <command>
```
```

@@ -116,59 +116,59 @@ ### Global flags

```
```
gh pr
```
```
* Get information about a pull request.
```
```
gh pr --info number
```
```
* List open pull requests for all branches from all your repositories.
```
```
gh pr --list --all
```
```
* List open pull requests for all branches in all repositories belonging to the "github" organization.
```
```
gh pr --list --all --org github
```
```
* List open pull requests sent by logged user on current repository.
```
```
gh pr --list --me
```
```
* List open pull requests with link and content.
```
```
gh pr --list --detailed
```
```
* List open pull requests for a branch.
```
```
gh pr --list --branch master
```
```
* List open pull requests and sort them by popularity *(comment count)*.
```
```
gh pr --list --sort popularity
```
```
* List open pull requests and sort them by asc long-running *(old but still active)*.
```
```
gh pr --list --sort long-running --direction asc
```
```
* List open pull requests and sort them by complexity *(complexity is calculated based on number of additions, deletions, changed files, comments and review comments)*.
```
```
gh pr --list --sort complexity
```
```

@@ -191,14 +191,14 @@ ### 3. Fetch

```
```
gh pr 1
```
```
* Fech pull request rebasing or merging into the current branch.
```
```
gh pr 1 --fetch --rebase
```
```
```
```
gh pr 1 --fetch --merge
```
```

@@ -223,19 +223,19 @@ ### 4. Merge or rebase

```
```
gh pr 1 --fetch --merge
```
```
```
```
gh pr 1 --fetch --rebase
```
```
* Merge or rebase pull request into branch `dev`.
```
```
gh pr 1 --fetch --rebase --branch dev
```
```
```
```
gh pr 1 --fetch --merge --branch dev
```
```

@@ -256,5 +256,5 @@ ### 5. Comment

```
```
gh pr 1 --comment "Merged, thank you!"
```
```

@@ -275,5 +275,5 @@ ### 6. Forward

```
```
gh pr 1 --fwd username
```
```

@@ -295,28 +295,28 @@ ### 7. Open or close

```
```
gh pr 1 --open
```
```
* Close a pull request.
```
```
gh pr 1 --close
```
```
* Close multiple pull requests.
```
```
gh pr --close --number 1 --number 2
```
```
* Open multiple pull requests.
```
```
gh pr --open --number 1 --number 2
```
```
* Open or close a pull request that you've sent to someone.
```
```
gh pr 1 --close --user eduardolundgren
```
```

@@ -342,17 +342,17 @@ ### 8. Submit

```
```
gh pr --submit eduardolundgren --title 'Fix #32' --description 'Awesome fix'
```
```
* Submit a pull request using the current branch to dev branch.
```
```
gh pr --submit eduardolundgren --branch dev
```
```
* Submit a pull request from a issue.
```
```
gh pr --submit eduardolundgren --issue 150
```
```

@@ -372,5 +372,5 @@ ### 9. Open in Browser

```
```
gh pr 100 --browser
```
```

@@ -399,11 +399,11 @@ ## Notifications

```
```
gh nt
```
```
* Display the latest activities on a certain repository.
```
```
gh nt --latest --user eduardolundgren --repo node-gh
```
```

@@ -423,11 +423,11 @@ ### 2. Watch

```
```
gh nt --watch
```
```
* Watch for any activity on a certain repository.
```
```
gh nt --watch --user eduardolundgren --repo node-gh
```
```

@@ -459,23 +459,23 @@ ## Issues

```
```
gh is 'Node GH rocks!' 'Body with **Markdown** support'
```
```
* Create a new issue on a certain repository.
```
```
gh is --new --title 'Node GH rocks!' --message 'Body with **Markdown** support' --user eduardolundgren --repo node-gh
```
```
* Create a new issue with labels.
```
```
gh is --new --title 'Node GH rocks!' --label bug,question,test
```
```
* Create a new issue and assign it to someone.
```
```
gh is --new --title 'Node GH rocks!' --assignee zenorocha
```
```

@@ -496,11 +496,11 @@ ### 2. Comment

```
```
gh is 1 --comment 'Node GH rocks!'
```
```
* Comment on an issue of a certain repository.
```
```
gh is 1 --comment 'Node GH rocks!' --user eduardolundgren --repo node-gh
```
```

@@ -522,28 +522,28 @@ ### 3. Open or close

```
```
gh is 1 --open
```
```
* Close an issue.
```
```
gh is 1 --close
```
```
* Close multiple issues.
```
```
gh is --close --number 1 --number 2
```
```
* Open multiple issues.
```
```
gh is --open --number 1 --number 2
```
```
* Open or close an issue that you've sent to someone.
```
```
gh is 1 --close --user eduardolundgren
```
```

@@ -569,47 +569,47 @@ ### 4. List

```
```
gh is
```
```
* List all issues from all repositories.
```
```
gh is --list --all
```
```
* List issues assigned to someone.
```
```
gh is --list --assignee zenorocha
```
```
* List issues with link and content.
```
```
gh is --list --detailed
```
```
* List only closed issues on the current repository.
```
```
gh is --list --state closed
```
```
* List issues filtered by milestone.
```
```
gh is --list --milestone 1
```
```
* List issues that contains labels `todo` and `bug`.
```
```
gh is --list --label todo,bug
```
```
* List all issues on a certain repository.
```
```
gh is --list --user eduardolundgren --repo node-gh
```
```

@@ -628,11 +628,11 @@ ### 5. Open in Browser

* **Shortcut** for opening GitHub issue page in the browser.
```
```
gh is 100
```
```
* Open GitHub issue page in the browser.
```
```
gh is 100 --browser
```
```

@@ -653,30 +653,54 @@ ### 6. Search

```
```
gh is --search 'term'
```
```
* Search issues in all repositories for a user
```
```
gh is --all --user node-gh --search 'term'
```
```
* Search issues in a repository for a user
```
```
gh is --user node-gh --repo gh --search 'term'
```
```
* Search issues in a repository for a user with link and content
```
```
gh is --user node-gh --repo gh --search 'term'
```
```
* Search issues with github filters
```
```
gh is --user node-gh --repo gh --search 'updated:<=2013-05-24'
```
```
### 7. Assign
Option | Usage | Type
--- | --- | ---
`--assign` | **Required** | `Boolean`
`-A`, `--assignee`| **Required** | `String`
`-n`, `--number` | **Required** | `Number`
`-r`, `--repo` | *Optional* | `String`
`-u`, `--user` | *Optional* | `String`
#### Examples
* Assign an issue on the current repository to a user.
```
gh is --assign --assignee zenorocha --number 1
```
* Assign an issue on a specific repository to a user.
```
gh is --assign --assignee zenorocha --number 1 --user eduardolundgren --repo gh
```
## Repo

@@ -701,11 +725,11 @@ ```

```
```
gh re
```
```
* Open GitHub repository page in the browser.
```
```
gh re --browser --user eduardolundgren --repo node-gh
```
```

@@ -725,17 +749,17 @@ ### 2. List

```
```
gh re --list
```
```
* List all private repositories.
```
```
gh re --list --type private
```
```
* List all repositories from someone.
```
```
gh re --list --user zenorocha
```
```

@@ -747,3 +771,3 @@ ### 3. Create

`-N`, `--new` | **Required** | `String`
`--organization` | *Optional* | `String`
`-O`, `--organization`| *Optional* | `String`
`-c`, `--clone` | *Optional* | `Boolean`

@@ -760,23 +784,23 @@ `-t`, `--type` | *Optional* | [`private`]

```
```
gh re --new foo --clone
```
```
* Create a new GitHub repository for an organization.
```
```
gh re --new foo --organization node-gh
```
```
* Create a new GitHub repository using .gitignore template for Ruby.
```
```
gh re --new gemified --gitignore Ruby
```
```
* Create a new private repository on GitHub, initializing it with a initial commit of the README.
```
```
gh re --new foo --init --type private
```
```

@@ -789,3 +813,3 @@ ### 4. Fork

`-u`, `--user` | **Required** | `String`
`-O`, `--organization`| **Optional** | `Boolean`
`-O`, `--organization`| *Optional* | `String`

@@ -796,13 +820,12 @@ #### Examples

```
```
gh re --fork repo --user user
```
```
* Fork a GitHub repository into the node-gh organization.
```
```
gh re --fork repo --user user --organization node-gh
```
```
### 5. Delete

@@ -819,6 +842,128 @@

```
```
gh re --delete foo
```
```
### 6. Clone
Option | Usage | Type
--- | --- | ---
`-c`, `--clone` | **Required** | `String`
`-r`, `--repo` | **Required** | `String`
`-O`, `--organization`| *Optional* | `String`
`-P`, `--protocol` | *Optional* | `String`
`-u`, `--user` | *Optional* | `String`
#### Examples
* Clone a repository.
```
gh re --clone --repo gh
```
* Clone a repository from a specific user using HTTPS protocol.
```
gh re --clone --user eduardolundgren --repo gh --protocol https
```
### 7. Create Label
Option | Usage | Type
--- | --- | ---
`-C`, `--color` | **Required** | `String`
`-L`, `--label` | **Required** | `Boolean`
`-N`, `--new` | **Required** | `String`
`-r`, `--repo` | **Required** | `String`
`-O`, `--organization`| *Optional* | `String`
`-u`, `--user` | *Optional* | `String`
#### Examples
* Create a label for a repository.
```
gh re --label --new bug --color color --repo gh
```
* Create a label for a user's repository.
```
gh re --label --new bug --color color --user eduardolundgren --repo gh
```
### 8. Delete Label
Option | Usage | Type
--- | --- | ---
`-L`, `--label` | **Required** | `Boolean`
`-D`, `--delete` | **Required** | `String`
`-r`, `--repo` | **Required** | `String`
`-O`, `--organization`| *Optional* | `String`
`-u`, `--user` | *Optional* | `String`
#### Examples
* Delete a label from a repository.
```
gh re --label --delete bug --repo gh
```
* Delete a label from a user's repository.
```
gh re --label --delete bug --user eduardolundgren --repo gh
```
### 9. List Labels
Option | Usage | Type
--- | --- | ---
`-L`, `--label` | **Required** | `Boolean`
`-l`, `--list` | **Required** | `Boolean`
`-r`, `--repo` | **Required** | `String`
`-O`, `--organization`| *Optional* | `String`
`-u`, `--user` | *Optional* | `String`
#### Examples
* List labels for a repository.
```
gh re --label --list --repo gh
```
* List labels for a user's repository.
```
gh re --label --list --user eduardolundgren --repo gh
```
### 10. Update Label
Option | Usage | Type
--- | --- | ---
`-C`, `--color` | **Required** | `String`
`-L`, `--label` | **Required** | `Boolean`
`-r`, `--repo` | **Required** | `String`
`-U`, `--update` | **Required** | `String`
`-O`, `--organization`| *Optional* | `String`
`-u`, `--user` | *Optional* | `String`
#### Examples
* Update a label for a repository.
```
gh re --label --update bug --color color --repo gh
```
* Update a label for a user's repository.
```
gh re --label --update bug --color color --user eduardolundgren --repo gh
```
## Gists

@@ -844,11 +989,11 @@

```
```
gh gi
```
```
* Open a Gist in the browser.
```
```
gh gi --browser --id 5991877
```
```

@@ -866,11 +1011,11 @@ ### 2. List

```
```
gh gi --list
```
```
* List all gists from someone.
```
```
gh gi --list --user brunocoelho
```
```

@@ -890,11 +1035,11 @@ ### 3. Create

```
```
gh gi --new hello --content "Hello World!"
```
```
* Create a private Gist `hello` containing "Hello World".
```
```
gh gi --new hello --content "Hello World!" --private
```
```

@@ -912,5 +1057,5 @@

```
```
gh gi --fork 5444883
```
```

@@ -928,11 +1073,11 @@

```
```
gh gi --delete 4252323
```
```
* Delete multiple Gists.
```
```
gh gi --delete 4252321 --delete 4252322
```
```

@@ -958,11 +1103,11 @@ ## User

```
```
gh user --login
```
```
* Logout current GitHub account.
```
```
gh user --logout
```
```

@@ -979,5 +1124,5 @@ ### 2. Whoami

```
```
gh user --whoami
```
```

@@ -1002,11 +1147,11 @@ ## Alias

```
```
gh alias
```
```
* List aliases.
```
```
gh alias --list
```
```

@@ -1024,5 +1169,5 @@ ### 2. Add

```
```
gh alias --add zeno --user zenorocha
```
```

@@ -1039,9 +1184,9 @@ ### 3. Remove

```
```
gh alias --remove zeno
```
```
## Config
There are some pretty useful configurations that you can set on [.gh.json](https://github.com/node-gh/gh/blob/master/.gh.json).
There are some pretty useful configurations that you can set on [.gh.json](lib/default.gh.json).
This file can be found under home directory *(on MacOSx: `/Users/yourName/.gh.json` on Windows: `C:\\Users\yourName\.gh.json`)*.

@@ -1053,3 +1198,3 @@

```javascript
```javascript
"api": {

@@ -1061,28 +1206,28 @@ "host": "api.github.com",

}
```
```
* Set default branch and remote.
```javascript
```javascript
"default_branch": "master",
"default_remote": "origin"
```
```
* Set default users when [submitting](#7-submit) or [forwarding](#5-forward) pull requests.
```javascript
```javascript
"default_pr_forwarder": "",
"default_pr_reviewer": ""
```
```
* GitHub data filled once you log in.
```javascript
```javascript
"github_token": "",
"github_user": ""
```
```
* Run automated tasks before or after a certain command.
```javascript
```javascript
"hooks": {

@@ -1098,7 +1243,7 @@ "pull-request": {

}
```
```
* Run automated tasks passing arguments to the commands. Required for prompt commands.
```javascript
```javascript
"hooks": {

@@ -1111,15 +1256,15 @@ "pull-request": {

}
```
```
* Set default branch name prefix for PR fetching.
```javascript
```javascript
"pull_branch_name_prefix": "pr-"
```
```
* Insert signature below issue comment.
```javascript
```javascript
"signature": "<br><br>:octocat: *Sent from [GH](http://nodegh.io).*"
```
```

@@ -1137,3 +1282,2 @@ If you need to use a custom git command, set the environment variable `GH_GIT_COMMAND`.

## Developer Tasks
* `lint` Detect errors on the code or its style using [JSHint](http://jshint.com/) and [JSCH](http://jscs.info/)
* `complexity` Show code complexity analysis summary

@@ -1145,3 +1289,2 @@ * `plato` Create advanced code complexity static analysis in HTML

* `plato-report` Open code complexity and static analysis report
* `watch` Watch for any changes and run linting and tests

@@ -1152,5 +1295,6 @@ ## Team

[![Eduardo Lundgren](http://gravatar.com/avatar/42327de520e674a6d1686845b30778d0?s=70)](https://github.com/eduardolundgren/) | [![Zeno Rocha](http://gravatar.com/avatar/e190023b66e2b8aa73a842b106920c93?s=70)](https://github.com/zenorocha/) | [![Henrique Vicente](http://gravatar.com/avatar/5733fd332f2a0da11931e0e73ddfb20d?s=70)](https://github.com/henvic/) | [![Bruno Coelho](http://gravatar.com/avatar/1f90c690b534779560d3bfdb23772915?s=70)](https://github.com/brunocoelho/)
--- | --- | --- | ---
[Eduardo Lundgren](https://github.com/eduardolundgren/) | [Zeno Rocha](https://github.com/zenorocha/) | [Henrique Vicente](https://github.com/henvic/) | [Bruno Coelho](https://github.com/brunocoelho/)
| Contributors | | |
|---|---|---|
|[![Eduardo Lundgren](http://gravatar.com/avatar/42327de520e674a6d1686845b30778d0?s=70)](https://github.com/eduardolundgren/) [Eduardo Lundgren](https://github.com/eduardolundgren/) | [![Zeno Rocha](http://gravatar.com/avatar/e190023b66e2b8aa73a842b106920c93?s=70)](https://github.com/zenorocha/) [Zeno Rocha](https://github.com/zenorocha/) | [![Henrique Vicente](http://gravatar.com/avatar/5733fd332f2a0da11931e0e73ddfb20d?s=70)](https://github.com/henvic/) [Henrique Vicente](https://github.com/henvic/)
[![Bruno Coelho](http://gravatar.com/avatar/1f90c690b534779560d3bfdb23772915?s=70)](https://github.com/brunocoelho/) [Bruno Coelho](https://github.com/brunocoelho/) | [![Dustin Ryerson](https://avatars2.githubusercontent.com/u/2080476?v=3&s=70)](https://github.com/dustinryerson/) [Dustin Ryerson](https://github.com/dustinryerson/)

@@ -1161,2 +1305,18 @@ ## Contributing

### Optional Plugins to install for your code editor:
#### Prettier (formatter primarily for JS files)
> Prettier is an opinionated code formatter. https://prettier.io/playground/
* User Guide: https://github.com/prettier/prettier
* VS Code Editor Plugin: https://github.com/prettier/prettier-vscode
* Vim Plugin: https://github.com/prettier/vim-prettier
* Sublime: https://packagecontrol.io/packages/JsPrettier
#### ESlint (linter)
> ESlint is a pluggable linting utility for JavaScript
* User Guide: https://eslint.org/docs/user-guide/getting-started#configuration
* VS Code Editor Plugin: https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint
* Vim Plugin: https://github.com/vim-syntastic/syntastic/tree/master/syntax_checkers/javascript
* Sublime: https://github.com/roadhump/SublimeLinter-eslint
## History

@@ -1163,0 +1323,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc