From a3cdc62c81570fa2d0ac8ffa01b08bbe13fb9163 Mon Sep 17 00:00:00 2001 From: CJ Salem Date: Wed, 1 Jan 2025 20:12:41 -0600 Subject: [PATCH 1/2] compare local & remote comment body before updating --- karen.ts | 51 ++++++++++++++++++++++-------------------------- src/Issue.ts | 31 +++++++++++++++++++++++++++-- src/Reporting.ts | 2 +- 3 files changed, 53 insertions(+), 31 deletions(-) diff --git a/karen.ts b/karen.ts index ae52b3b..00b2cb6 100755 --- a/karen.ts +++ b/karen.ts @@ -845,6 +845,7 @@ export async function main() { } = {}, ) { const issueStore = IssueStore(storage); + const reportStore = ReportStore(storage); const reporting = ReportingService(storage, settings); if (options.all) return await reportAll(options); @@ -853,19 +854,20 @@ export async function main() { const issue = await issueStore .get(key) .catch(console.expect("Issue not found")); - const report = await reporting.collect(issue, options); - if (["markdown", "jira"].includes(options.format ?? "markdown")) { - const markdown = await reporting.format(report, { - format: options.format ?? "markdown", - }); - console.log(markdown); - } else { - console.print(report, options.format); - } - if (options.publish) { - await reporting.publish(report); - console.info(Fmt.green("Report published")); + return await reportIssue(issue, options); + + async function reportAll( + options: { + publish?: boolean; + force?: boolean; + format?: string; + model?: string; + } = {}, + ) { + const issues = issueStore.list(); + for await (const issue of issues) await reportIssue(issue, options); + return console.info("done"); } async function reportIssue( @@ -875,32 +877,25 @@ export async function main() { format?: string; force?: boolean; model?: string; + details?: boolean; } = {}, ) { console.log("Collecting report for", issue.key); const report = await reporting.collect(issue, options); if (options.publish) { - await reporting.publish(report); - return console.info(Fmt.green(`Published report for ${issue.key}`)); + const published = await reporting.publish(report); + if (published) { + console.info(Fmt.green(`Published ${issue.key}`)); + } else { + console.info(Fmt.yellow(`Already published ${issue.key}`)); + } } if (options.format === "markdown") { const markdown = await reporting.format(report, { format: "markdown" }); return console.log(markdown); } - return console.print(report, options.format); - } - - async function reportAll( - options: { - publish?: boolean; - force?: boolean; - format?: string; - model?: string; - } = {}, - ) { - const issues = issueStore.list(); - for await (const issue of issues) await reportIssue(issue, options); - return console.info("done"); + if (options.details) return console.print(report, options.format); + return console.print(reportStore.summarize(report), options.format); } } diff --git a/src/Issue.ts b/src/Issue.ts index 334fd4a..e5ee4ec 100644 --- a/src/Issue.ts +++ b/src/Issue.ts @@ -267,7 +267,25 @@ export function IssueService(storage: Deno.Kv) { await response.text(); } + async function getComment(issue: Issue, id: string): Promise { + const baseUrl = await getBaseUrl(); + const headers = await getHeaders(); + const url = new URL( + `/rest/api/2/issue/${issue.key}/comment/${id}`, + baseUrl, + ); + const request = new Request(url, { + method: "GET", + headers, + }); + const response = await fetch(request); + if (!response.ok) throw response; + const comment = await response.json().then(fmtComment); + return comment; + } + async function postComment(issue: Issue, body: string): Promise { + throw new Error("Not implemented"); const baseUrl = await getBaseUrl(); const headers = await getHeaders(); const url = new URL(`/rest/api/2/issue/${issue.key}/comment`, baseUrl); @@ -289,6 +307,7 @@ export function IssueService(storage: Deno.Kv) { comment: Comment, body: string, ): Promise { + throw new Error("Not implemented"); const baseUrl = await getBaseUrl(); const headers = await getHeaders(); const url = new URL( @@ -309,7 +328,15 @@ export function IssueService(storage: Deno.Kv) { const cached = await myCommentsStore .get(issue.key) .catch(() => null); - if (cached) return await updateComment(issue, cached, body); - return await postComment(issue, body); + if (cached) { + const remote = await getComment(issue, cached.id); + if (body && remote.body && remote.body !== body) { + await updateComment(issue, cached, body); + return true; + } + return false; + } + await postComment(issue, body); + return true; } } diff --git a/src/Reporting.ts b/src/Reporting.ts index e0220ac..4174669 100644 --- a/src/Reporting.ts +++ b/src/Reporting.ts @@ -71,7 +71,7 @@ export function ReportingService(storage: Deno.Kv, settings: SettingsV1) { async function publish(report: Report) { const text = await format(report, { format: "jira" }); - await issueService.upsertComment(report.issue, text); + return await issueService.upsertComment(report.issue, text); } async function format(report: Report, options: { format: string }) { From 2a42e0b97356d8c3d5f29aa452473f8f838fb04a Mon Sep 17 00:00:00 2001 From: CJ Salem Date: Wed, 1 Jan 2025 20:15:04 -0600 Subject: [PATCH 2/2] remove safety goggles --- src/Issue.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Issue.ts b/src/Issue.ts index e5ee4ec..4a9f940 100644 --- a/src/Issue.ts +++ b/src/Issue.ts @@ -285,7 +285,6 @@ export function IssueService(storage: Deno.Kv) { } async function postComment(issue: Issue, body: string): Promise { - throw new Error("Not implemented"); const baseUrl = await getBaseUrl(); const headers = await getHeaders(); const url = new URL(`/rest/api/2/issue/${issue.key}/comment`, baseUrl); @@ -307,7 +306,6 @@ export function IssueService(storage: Deno.Kv) { comment: Comment, body: string, ): Promise { - throw new Error("Not implemented"); const baseUrl = await getBaseUrl(); const headers = await getHeaders(); const url = new URL(