UNPKG

@buildo/hophop

Version:

A minimal tool to accelerate the GitHub workflow from the command line.

201 lines (171 loc) 5.7 kB
import { ArgumentParser } from 'argparse'; import { assign, uniqueId } from 'lodash'; import R from 'ramda'; import github from 'octonode'; import child_process from 'child_process'; import fs from 'fs'; import promisify from 'es6-promisify'; import semver from 'semver'; import inquirer from 'inquirer'; import clc from 'cli-color'; const cmdoutc = clc.blackBright; const issuec = clc.bold; const warning = clc.xterm(184); function log(l) { console.log(l); // eslint-disable-line no-console } function error(e) { console.error(e); // eslint-disable-line no-console } function rlinterface() { return { question: (question, defaultInput) => new Promise((resolve) => { const qName = question.name || uniqueId('question_'); const enhancedQ = assign({}, { type: 'input', name: qName, default: defaultInput || null }, question); inquirer.prompt([enhancedQ], a => resolve(a[qName])); }), yesOrNoQuestion: (message, defaultInput) => new Promise((resolve) => { const enhancedQ = { message: `${message} (y/n)`, name: uniqueId('yes_or_no_question_'), type: 'input', default: defaultInput || 'n' }; inquirer.prompt([enhancedQ], a => resolve(a[enhancedQ.name])); }) }; } const rl = rlinterface(); const exec = (cmd) => new Promise((resolve) => child_process.exec(cmd, (err, o, i) => { if (!!err) throw err; resolve({ stdout: o, stderr: i }); })); const execF = (cmd) => new Promise((resolve) => child_process.exec(cmd, (err, o, i) => { resolve({ err, stdout: o, stderr: i }); })); const enterpriseRepos = { 'buildo/labonline': { apiEndpoint: 'github.omnilab.our.buildo.io/api/v3', githubURL: 'github.omnilab.our.buildo.io', accountName: 'omnilab' } }; async function origin() { const _origin = (await exec('git remote -v | grep origin | grep fetch')).stdout.replace('\t', ' ').replace('\n', '').split(' '); return _origin[1].replace('.git', '').split(':')[1]; } async function currBranch() { const o = (await exec('git rev-parse --abbrev-ref HEAD')).stdout; return o.split('\n')[0]; } const issuesLabelMapper = (issues) => { return issues .map(i => ({ name: `${issuec(i.number)}\t${i.title}`, value: i.number })); }; function slugify(s) { const fullSlug = s.toLowerCase().replace(/[^\w ]+/g, '').replace(/ +/g, '_'); const shortSlugify = R.compose(R.join('_'), R.take(4), R.split('_')); return shortSlugify(fullSlug); } function gh_token_file_name(gheAccountName) { const prefix = '.hophop_gh_token'; return gheAccountName ? `${prefix}_${gheAccountName}` : prefix; } function gh_token(gheAccountName) { const fileName = gh_token_file_name(gheAccountName); return fs.readFileSync(`${process.env.HOME}/${fileName}`, 'utf8'); } async function gh_helper() { const repo_name = await origin(); const config = {}; const { [repo_name]: { apiEndpoint, accountName } = {} } = enterpriseRepos; if (apiEndpoint) { config.hostname = apiEndpoint; } const client = github.client(gh_token(accountName), config); // FIXME(gabro): this is here because omnilab's github SSL cert is currently self-signed if (apiEndpoint) { client.requestDefaults.rejectUnhauthorized = false; client.requestDefaults.strictSSL = false; } const repo = client.repo(repo_name); return { repo_name, client, repo }; } async function gh_me(client) { const clientMe = client.me(); try { const me = await promisify(clientMe.info.bind(clientMe))(); return me; } catch (e) { error(e); } } async function checkForUpdates() { const latestVersion = (await exec('npm view @buildo/hophop version')).stdout.replace(/\n/g, ''); const installedVersion = (await exec('npm list -g --depth=0 @buildo/hophop | grep hophop | cut -d@ -f3')).stdout.replace(/\n/g, ''); if (semver.gt(latestVersion, installedVersion)) { log(` ------------------------------------------------------- | A new version of hophop is available! Update with | | | | npm install -g @buildo/hophop | | | ------------------------------------------------------- `); } } function parseArgs() { const parser = new ArgumentParser({ version: '0.0.1', addHelp: true, description: 'Argparse example' }); const subparsers = parser.addSubparsers({ title: 'subcommand', dest: 'cmd' }); const gh = subparsers.addParser('gh', { addHelp: true }); const toggl = subparsers.addParser('toggl', { addHelp: true }); const gh_sp = gh.addSubparsers({ title: 'gh', dest: 'cmd_gh' }); const toggl_sp = toggl.addSubparsers({ title: 'toggl', dest: 'cmd_toggl' }); gh_sp.addParser('pr', { addHelp: true }); const gh_feature_sp = gh_sp.addParser('feature', { addHelp: true }); gh_feature_sp.addArgument(['issueNumber'], { nargs: '?' }); gh_sp.addParser('setup', { addHelp: true }); const gh_setup_sp = gh_sp.addParser('setup', { addHelp: true }); gh_setup_sp.addArgument(['gheAccountName'], { nargs: '?' }); gh_sp.addParser('commit', { addHelp: true }); toggl_sp.addParser('setup', { addHelp: true }); toggl_sp.addParser('start', { addHelp: true }); toggl_sp.addParser('stop', { addHelp: true }); toggl_sp.addParser('install-hooks', { addHelp: true }); return parser.parseArgs(); } export default { rl, exec, execF, currBranch, issuesLabelMapper, slugify, gh_helper, gh_me, checkForUpdates, parseArgs, cmdoutc, issuec, warning, log, error, origin, enterpriseRepos, gh_token_file_name };