UNPKG

@buildo/hophop

Version:

![](https://img.shields.io/npm/v/@buildo/hophop.svg)

128 lines (108 loc) 4.62 kB
import R from 'ramda'; import fs from 'fs'; import promisify from 'es6-promisify'; import TogglClient from 'toggl-api'; import { rl, currBranch, issuesLabelMapper, ghHelper, warning, log, getHophopDir, HophopError } from '../utils'; const togglTokenPath = `${getHophopDir()}/.toggl_token`; function togglToken() { return fs.readFileSync(togglTokenPath, 'utf8'); } function togglHelper() { const togglClient = new TogglClient({ apiToken: togglToken() }); return { togglClient }; } async function togglGetProjects(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 }; } export async function togglSetup() { if (fs.existsSync(togglTokenPath)) { warning('\n⚠️ You already have a token for Toggl: if you proceed the current token will be overwritten.\n'); } const token = await rl.question({ message: 'Personal access token: (from https://toggl.com/app/profile):' }); if (!token) { throw new HophopError('No token inserted.'); } else if (token.length !== 32) { // Toggl token length throw new HophopError('Invalid token: it should be 32 characters long.'); } fs.writeFileSync(togglTokenPath, token); } export async function togglStart({ customTask } = {}) { const { togglClient } = togglHelper(); const { repoName, client, repo } = await ghHelper(); // TODO; ghHelper gets also me -> this slows down the process const branch = await currBranch(); if (branch === 'master' && !customTask) { throw new HophopError('You\'re not working on any PR, switch to a branch tracking a PR and retry.'); } let issueno; let issue; if (!customTask) { 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(repoName, issueno); issue = await promisify(issueRef.info.bind(issueRef))(); if (!issue) { log('Invalid issue'); } } const { togglProjects } = await togglGetProjects(togglClient); const projectName = R.compose(R.drop(1), R.split('/'))(repoName)[0]; const startTimeEntry = promisify(togglClient.startTimeEntry.bind(togglClient)); const getProject = (_projectName) => R.find(R.propEq('name', _projectName))(togglProjects); const togglProject = getProject(projectName); if (!togglProject) { warning(`\n🚨 '${projectName}' does not exist on Toggl\n`); } await startTimeEntry({ description: customTask || `#${issueno}: ${issue.title}`, billable: togglProject ? togglProject.billable : undefined, pid: togglProject ? togglProject.id : undefined }); const projectLog = togglProject ? ` on project '${togglProject.name}'` : ''; const issueLog = !customTask ? `issue ${issueno}` : `'${customTask}'`; log(`⏰ Started tracking time for ${issueLog}${projectLog}`); } export async function togglMisc() { await togglStart({ customTask: 'miscellaneous' }); } export async function togglStop() { const { togglClient } = togglHelper(); 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 togglMisc(); } } else { log('Mmh, it seems like your Toggl isn\'t running'); } } export async function togglInstallHooks() { const exec = promisify(require('child_process').exec); 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!'); } export const togglTest = () => togglStart({ customTask: 'test' });