@buildo/hophop
Version:
A minimal tool to accelerate the GitHub workflow from the command line.
133 lines (117 loc) • 4.5 kB
JavaScript
import R from 'ramda';
import fs from 'fs';
import promisify from 'es6-promisify';
import TogglClient from 'toggl-api';
import {
rl,
currBranch,
issuesLabelMapper,
gh_helper,
warning,
log, error
} from '../utils';
function toggl_token() {
return fs.readFileSync(`${process.env.HOME}/.hophop_toggl_token`, 'utf8');
}
async function toggl_helper() {
const togglClient = new TogglClient({ apiToken: toggl_token() });
return { togglClient };
}
async function toggl_getProjects(togglClient) {
const togglUser = await promisify(togglClient.getUserData.bind(togglClient))({});
const wid = togglUser.default_wid;
const togglProjects = await promisify(togglClient.getWorkspaceProjects.bind(togglClient))(wid, {});
return { togglProjects };
}
async function toggl_setup() {
const token = await rl.question({ message: 'Personal access token: (from https://toggl.com/app/profile):' });
if (!token) {
error('No token inserted.');
process.exit(0);
}
fs.writeFileSync(`${process.env.HOME}/.hophop_toggl_token`, token);
}
async function toggl_start({ genericTask } = {}) {
try {
const { togglClient } = await toggl_helper();
const { repo_name, client, repo } = await gh_helper(); // TODO; gh_helper gets also me -> this slows down the process
const branch = await currBranch();
if (branch === 'master') {
log('You\'re not working on any PR, switch to a branch tracking a PR and retry.');
process.exit(0);
}
let issueno;
let issue;
if (!genericTask) {
issueno = R.take(2, branch.split('-').map((i) => parseInt(i, 10))).filter((x) => !!x)[0];
log(`Inferred issue number ${issueno} from branch name '${branch}'`);
if (!issueno) {
log('Cannot infer the issue number from the branch name');
const issues = await promisify(repo.issues.bind(repo))();
const issuesChoices = issuesLabelMapper(issues.filter((i) => !i.pull_request));
issueno = await rl.question({ type: 'list', message: 'Which issue?', choices: issuesChoices });
}
const issueRef = client.issue(repo_name, issueno);
issue = await promisify(issueRef.info.bind(issueRef))();
if (!issue) {
log('Invalid issue');
}
}
const { togglProjects } = await toggl_getProjects(togglClient);
const projectName = R.compose(R.drop(1), R.split('/'))(repo_name)[0];
const startTimeEntry = promisify(togglClient.startTimeEntry.bind(togglClient));
const getProject = (_projectName) => R.find(R.propEq('name', _projectName))(togglProjects);
const togglProject = getProject(projectName);
if (!togglProject) {
log(warning(`\n🚨 '${projectName}' does not exist on Toggl\n`));
}
await startTimeEntry({
description: genericTask ? 'miscellaneous' : `#${issueno}: ${issue.title}`,
billable: togglProject ? togglProject.billable : undefined,
pid: togglProject ? togglProject.id : undefined
});
const projectLog = togglProject ? ` on project '${togglProject.name}'` : '';
const issueLog = !genericTask ? `issue ${issueno}` : '';
log(`⏰ Started tracking time for ${issueLog}${projectLog}`);
} catch (err) {
log(err);
}
}
async function toggl_stop() {
try {
const { togglClient } = await toggl_helper();
const currentTimeEntry = await promisify(togglClient.getCurrentTimeEntry.bind(togglClient))();
if (currentTimeEntry) {
await promisify(togglClient.stopTimeEntry.bind(togglClient))(currentTimeEntry.id);
log(`⏰ Stopped tracking time for '${currentTimeEntry.description}'`);
const startGenericTask = await rl.question({ message: 'Start generic task? (y/n)', default: 'n' });
if (startGenericTask === 'y') {
await toggl_start({ genericTask: true });
}
} else {
log('Mmh, it seems like your Toggl isn\'t running');
}
} catch (err) {
log(err);
}
}
async function toggl_install_hooks() {
const exec = promisify(require('child_process').exec);
try {
const prefix = (await exec('npm prefix -g')).replace(/\r?\n|\r/g, '');
const repoDir = (await exec('git rev-parse --show-toplevel')).replace(/\r?\n|\r/g, '');
fs.symlinkSync(
`${prefix}/lib/node_modules/@buildo/hophop/hooks/post-checkout`,
`${repoDir}/.git/hooks/post-checkout`
);
log('🔧 Toggl git hooks correctly installed!');
} catch (err) {
log(err);
}
}
export default {
toggl_setup,
toggl_start,
toggl_stop,
toggl_install_hooks
};