Skip to content

Commit 83f09ea

Browse files
committed
add comment
1 parent 36c02a5 commit 83f09ea

File tree

1 file changed

+82
-14
lines changed
  • apps/array/src/main/services

1 file changed

+82
-14
lines changed

apps/array/src/main/services/git.ts

Lines changed: 82 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,25 @@ export const parseGitHubUrl = (url: string): GitHubRepo | null => {
9090
};
9191
};
9292

93+
const getRepositoryFromRemoteUrl = async (
94+
directoryPath: string,
95+
): Promise<string> => {
96+
const remoteUrl = await getRemoteUrl(directoryPath);
97+
if (!remoteUrl) {
98+
throw new Error("No remote URL found");
99+
}
100+
101+
// Parse repo from URL (handles both HTTPS and SSH formats)
102+
const repoMatch = remoteUrl.match(
103+
/github\.com[:/]([^/]+\/[^/]+?)(?:\.git)?$/,
104+
);
105+
if (!repoMatch) {
106+
throw new Error(`Cannot parse repository from URL: ${remoteUrl}`);
107+
}
108+
109+
return repoMatch[1];
110+
};
111+
93112
export const isGitRepository = async (
94113
directoryPath: string,
95114
): Promise<boolean> => {
@@ -555,20 +574,7 @@ const getPullRequestReviewComments = async (
555574
}
556575

557576
try {
558-
// Extract repo from remote URL (format: owner/repo)
559-
const remoteUrl = await getRemoteUrl(directoryPath);
560-
if (!remoteUrl) {
561-
throw new Error("No remote URL found");
562-
}
563-
564-
// Parse repo from URL (handles both HTTPS and SSH formats)
565-
const repoMatch = remoteUrl.match(
566-
/github\.com[:/]([^/]+\/[^/]+?)(?:\.git)?$/,
567-
);
568-
if (!repoMatch) {
569-
throw new Error(`Cannot parse repository from URL: ${remoteUrl}`);
570-
}
571-
const repo = repoMatch[1];
577+
const repo = await getRepositoryFromRemoteUrl(directoryPath);
572578

573579
// TODO: Paginate if many comments
574580
const { stdout } = await execAsync(
@@ -581,6 +587,56 @@ const getPullRequestReviewComments = async (
581587
}
582588
};
583589

590+
interface AddPullRequestCommentOptions {
591+
body: string;
592+
commitId: string;
593+
path: string;
594+
line: number;
595+
side?: "LEFT" | "RIGHT";
596+
}
597+
598+
const addPullRequestComment = async (
599+
directoryPath: string,
600+
prNumber: number,
601+
options: AddPullRequestCommentOptions,
602+
): Promise<any> => {
603+
// Validate prNumber: must be a positive integer
604+
if (
605+
typeof prNumber !== "number" ||
606+
!Number.isInteger(prNumber) ||
607+
prNumber < 1
608+
) {
609+
throw new Error(`Invalid pull request number: ${prNumber}`);
610+
}
611+
612+
// Validate required options
613+
if (!options.body || !options.commitId || !options.path) {
614+
throw new Error("body, commitId, and path are required");
615+
}
616+
617+
if (typeof options.line !== "number" || options.line < 1) {
618+
throw new Error("line must be a positive number");
619+
}
620+
621+
try {
622+
const repo = await getRepositoryFromRemoteUrl(directoryPath);
623+
const side = options.side || "RIGHT";
624+
625+
const { stdout } = await execAsync(
626+
`gh api repos/${repo}/pulls/${prNumber}/comments ` +
627+
`-f body="${options.body.replace(/"/g, '\\"')}" ` +
628+
`-f commit_id="${options.commitId}" ` +
629+
`-f path="${options.path}" ` +
630+
`-f line=${options.line} ` +
631+
`-f side="${side}"`,
632+
{ cwd: directoryPath },
633+
);
634+
return JSON.parse(stdout);
635+
} catch (error) {
636+
throw new Error(`Failed to add PR comment: ${error}`);
637+
}
638+
};
639+
584640
export function registerGitIpc(
585641
getMainWindow: () => BrowserWindow | null,
586642
): void {
@@ -882,4 +938,16 @@ export function registerGitIpc(
882938
return getPullRequestReviewComments(directoryPath, prNumber);
883939
},
884940
);
941+
942+
ipcMain.handle(
943+
"add-pr-comment",
944+
async (
945+
_event: IpcMainInvokeEvent,
946+
directoryPath: string,
947+
prNumber: number,
948+
options: AddPullRequestCommentOptions,
949+
): Promise<any> => {
950+
return addPullRequestComment(directoryPath, prNumber, options);
951+
},
952+
);
885953
}

0 commit comments

Comments
 (0)