Comparing version 1.12.8 to 1.12.9
#!/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 |
206
lib/cmd.js
/* | ||
* 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) | ||
} |
219
lib/git.js
/* | ||
* 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 | ||
} |
171
lib/hooks.js
/* | ||
* 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 @@ |
163
package.json
{ | ||
"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 | ||
} |
562
README.md
@@ -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 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
16
1287
173237
16
25
4313
- Removedinsight@^0.7.0
- Removedinquirer@0.10.1(transitive)
- Removedinsight@0.7.0(transitive)
- Removedlodash._getnative@3.9.1(transitive)
- Removedlodash.debounce@3.1.1(transitive)
- Removedos-name@1.0.3(transitive)
- Removedosx-release@1.1.0(transitive)
- Removedwin-release@1.1.1(transitive)
Updatedmoment@^2.20.1
Updatedrequest@^2.83.0