import type { Argv, ArgumentsCamelCase } from "yargs" import { CLICommand } from "../cli/CLICommand" import { parseTodoFile, writeTodoFile } from "../file" import { getCurrentBranch, commitFileWithBody } from "../git" import { validateStatusTransition } from "../issue" export class DoneCommand extends CLICommand { readonly name = "done " readonly help = "Mark an issue as done" readonly description = "Set issue to done (must be on issue branch)" addArguments(yargs: Argv): Argv { return yargs .positional("id", { type: "number", demandOption: true }) .option("summary", { type: "string", demandOption: true, description: "High-level summary of what was delivered", }) } async execute(args: ArgumentsCamelCase): Promise { const todo = await parseTodoFile() const issue = todo.issues.find(i => i.id === args.id) if (!issue) { console.error(`Issue #${args.id} not found`) return 1 } // Must be on the correct issue branch const expectedBranch = `${issue.type}/${issue.id}` const branch = getCurrentBranch() if (branch !== expectedBranch) { console.error(`Must be on ${expectedBranch} to mark issue as done (currently on ${branch})`) return 1 } const err = validateStatusTransition(issue.status, "done") if (err) { console.error(err) return 1 } issue.status = "done" writeTodoFile(todo) commitFileWithBody( "TODO", `todo(${issue.id}): done`, args.summary as string ) console.log(`Issue #${issue.id} is now done`) return 0 } }