import type { Argv, ArgumentsCamelCase } from "yargs" import { CLICommand } from "../cli/CLICommand" import { parseTodoFile, writeTodoFile } from "../file" import { getCurrentBranch, commitFile } from "../git" import type { IssueType, IssuePriority } from "../issue" export class CreateCommand extends CLICommand { readonly name = "create" readonly help = "Create a new issue" readonly description = "Add an issue to the TODO file (must be on develop)" addArguments(yargs: Argv): Argv { return yargs .option("type", { alias: "t", type: "string", choices: ["feature", "bugfix", "hotfix"] as const, demandOption: true, }) .option("title", { type: "string", demandOption: true, }) .option("priority", { alias: "p", type: "string", choices: ["low", "medium", "high"] as const, default: "medium", }) .option("plan", { type: "string", demandOption: true, description: "Description of what needs to be done", }) .option("module", { alias: "m", type: "string", }) } async execute(args: ArgumentsCamelCase): Promise { const branch = getCurrentBranch() if (branch !== "develop") { console.error(`Must be on develop to create issues (currently on ${branch})`) return 1 } const todo = await parseTodoFile() const mod = args.module as string | undefined if (mod && todo.modules) { const valid = todo.modules.map(m => m.name) if (!valid.includes(mod)) { console.error(`Module "${mod}" not defined. Valid: ${valid.join(", ")}`) return 1 } } const nextId = todo.issues.length > 0 ? Math.max(...todo.issues.map(i => i.id)) + 1 : 1 const today = new Date().toISOString().slice(0, 10) todo.issues.push({ id: nextId, type: args.type as IssueType, title: args.title as string, status: "open", priority: args.priority as IssuePriority, created: today, module: mod, relationships: {}, description: args.plan as string, body: "", }) writeTodoFile(todo) commitFile("TODO", `todo(${nextId}): open`) console.log(`Created issue #${nextId}: ${args.title}`) return 0 } }