|
| 1 | +import { Command } from "@cliffy/command" |
| 2 | +import { isClientError, logClientError } from "../../utils/graphql.ts" |
| 3 | +import { getIssueId, getIssueIdentifier } from "../../utils/linear.ts" |
| 4 | +import { getNoIssueFoundMessage, getVcs } from "../../utils/vcs.ts" |
| 5 | + |
| 6 | +export const commitsCommand = new Command() |
| 7 | + .name("commits") |
| 8 | + .description("Show all commits for a Linear issue (jj only)") |
| 9 | + .arguments("[issueId:string]") |
| 10 | + .action(async (_options, issueId) => { |
| 11 | + const vcs = getVcs() |
| 12 | + |
| 13 | + if (vcs !== "jj") { |
| 14 | + console.error("✗ commits is only supported with jj-vcs") |
| 15 | + Deno.exit(1) |
| 16 | + } |
| 17 | + |
| 18 | + const resolvedId = await getIssueIdentifier(issueId) |
| 19 | + if (!resolvedId) { |
| 20 | + console.error(getNoIssueFoundMessage()) |
| 21 | + Deno.exit(1) |
| 22 | + } |
| 23 | + |
| 24 | + // Verify the issue exists in Linear |
| 25 | + let linearIssueId: string | undefined |
| 26 | + try { |
| 27 | + linearIssueId = await getIssueId(resolvedId) |
| 28 | + } catch (error) { |
| 29 | + if (isClientError(error)) { |
| 30 | + logClientError(error) |
| 31 | + Deno.exit(1) |
| 32 | + } |
| 33 | + throw error |
| 34 | + } |
| 35 | + if (!linearIssueId) { |
| 36 | + console.error(`✗ issue not found: ${resolvedId}`) |
| 37 | + Deno.exit(1) |
| 38 | + } |
| 39 | + |
| 40 | + // Build the revset to find all commits with this Linear issue |
| 41 | + const revset = `description(regex:"(?m)^Linear-issue:.*${resolvedId}")` |
| 42 | + |
| 43 | + // First check if any commits exist |
| 44 | + const checkProcess = new Deno.Command("jj", { |
| 45 | + args: ["log", "-r", revset, "-T", "commit_id", "--no-graph"], |
| 46 | + stdout: "piped", |
| 47 | + stderr: "piped", |
| 48 | + }) |
| 49 | + const checkResult = await checkProcess.output() |
| 50 | + const commitIds = new TextDecoder().decode(checkResult.stdout).trim() |
| 51 | + |
| 52 | + if (!commitIds) { |
| 53 | + console.error(`✗ no commits found for ${resolvedId}`) |
| 54 | + Deno.exit(1) |
| 55 | + } |
| 56 | + |
| 57 | + // Show the commits with full details |
| 58 | + const process = new Deno.Command("jj", { |
| 59 | + args: [ |
| 60 | + "log", |
| 61 | + "-r", |
| 62 | + revset, |
| 63 | + "-p", |
| 64 | + "--git", |
| 65 | + "--no-graph", |
| 66 | + "-T", |
| 67 | + "builtin_log_compact_full_description", |
| 68 | + ], |
| 69 | + stdout: "inherit", |
| 70 | + stderr: "inherit", |
| 71 | + }) |
| 72 | + |
| 73 | + const { code } = await process.output() |
| 74 | + Deno.exit(code) |
| 75 | + }) |
0 commit comments