Skip to content

Commit

Permalink
improve comment
Browse files Browse the repository at this point in the history
  • Loading branch information
baseballyama committed Nov 3, 2023
1 parent 92d3c96 commit f11bf30
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 17 deletions.
86 changes: 72 additions & 14 deletions packages/ai-craftsman/src/ci.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,74 @@
import { getDiff, postComment } from "./git.js";
import { chunk } from "./diff.js";
import { getTokenCount, chat } from "./openai.js";
import { splitForEachDIff } from "./diff.js";
import { chat } from "./openai.js";
import { promiseAllWithConcurrencyLimit } from "./concurrent.js";

const prompt = `\
あなたは世界最高峰のプログラマーです。あなたの仕事はGitHubのdiffを見てコードレビューをすることです。
以下のdiffをレビューして改善点を挙げてください。改善点が特にない場合は 'NO' と回答してください。
diffの各行の先頭には行番号がついていることに注意してください。
回答形式は以下です。
---
## 改善点
lines: {{指摘開始行}},{{指摘終了行}}
{{ここに改善点を書いてください}}
## 改善点
lines: {{指摘開始行}},{{指摘終了行}}
{{ここに改善点を書いてください}}
`;

const excludePatterns = [
/.*node_modules/,
/.*pnpm-lock.yaml$/,
/.*yarn.lock$/,
/.*package-lock.json$/,
];

const splitComments = (
response: string
): { start: number; end: number; comment: string }[] => {
const build = (str: string) => {
let start = 0;
let end = 0;
let encountLine = false;
let comment = "";
for (const l of str.split("\n")) {
if (l.startsWith("lines:")) {
const [s, e] = l.split(/:\s*/)[1]?.split(/[,\-]/) ?? [];
start = Number(s) || 0;
end = Number(e) || 0;
encountLine = true;
} else if (encountLine) {
if (comment) comment += "\n";
comment += l;
}
}
if (start === 0 || end === 0 || comment === "") return undefined;
return { start, end, comment };
};

const comments: { start: number; end: number; comment: string }[] = [];
let buf = "";
const lines =
response.match(/.*?(##\s*改善点[\s\S]*)/m)?.[0].split("\n") ?? [];
for (const line of lines) {
if (line?.match(/^##\s*改善点/)) {
const comment = build(buf);
if (comment != null) {
comments.push(comment);
}
buf = "";
} else {
if (buf !== "") buf += "\n";
buf += line;
}
}

return comments;
};

const main = async () => {
const baseref = process.env["BASE_REF"];
if (baseref == null || baseref === "") {
Expand All @@ -24,27 +83,26 @@ const main = async () => {
} else {
console.log(`RUN REVIEW: ${path}`);
}
const chunked = chunk({
source: diff,
counter: getTokenCount,
maxCount: 500,
duplicateLines: 2,
});
for (const { source } of chunked) {
console.log(diff);
const chunked = splitForEachDIff(diff);
for (const source of chunked) {
promises.push(async () => {
const response = await chat([
{
content:
"あなたは世界最高峰のプログラマーです。あなたの仕事はGitHubのdiffを見てコードレビューをすることです。それでは、以下のdiffをレビューして改善点を挙げてください。改善点が特にない場合は 'NO' と回答してください。diffは途中で切れている場合があることに注意してください。",
content: prompt,
role: "system",
},
{
content: source,
content: source.diff,
role: "user",
},
]);
postComment(path, 1, response);
console.log({ source, response });

console.log({ response });
for (const comment of splitComments(response)) {
console.log({ comment });
postComment(path, comment.start, comment.end, comment.comment);
}
});
}
}
Expand Down
50 changes: 50 additions & 0 deletions packages/ai-craftsman/src/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ export interface SourceRow {
level: number;
}

export interface Diff {
startRow: number;
endRow: number;
diff: string;
}

export const parse = (source: string): SourceRow[] => {
const rows: SourceRow[] = [];
const lines = source.split("\n");
Expand All @@ -19,6 +25,50 @@ export const parse = (source: string): SourceRow[] => {
return rows;
};

export const splitForEachDIff = (source: string): Diff[] => {
const lines = source.split("\n");
const diff = lines[0];
const index = lines[1];
const minus = lines[2];
const plus = lines[3];

const diffs: Diff[] = [];
let buf = "";
const currentDiffLines = { start: 0, end: 0 };

const flush = () => {
diffs.push({
startRow: currentDiffLines.start,
endRow: currentDiffLines.end,
diff: `${diff}\n${index}\n${minus}\n${plus}\n${buf}`,
});
};

let currentRawNumber = 4;

for (const line of lines.slice(5)) {
if (line.startsWith("@@")) {
if (buf.length > 0) {
flush();
}
buf = line;
const [start, end] = line.match(/\+(\d+),(\d+)/)?.slice(1) ?? [];
currentDiffLines.start = Number(start) || 0;
currentDiffLines.end = Number(end) || currentDiffLines.start;
currentRawNumber = currentDiffLines.start;
} else {
buf += "\n" + `${currentRawNumber} ${line}`;
currentRawNumber++;
}
}

if (buf.length > 0) {
flush();
}

return diffs;
};

export const chunk = ({
source,
counter,
Expand Down
10 changes: 7 additions & 3 deletions packages/ai-craftsman/src/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ const getPullNumberAndCommitId = () => {

export const postComment = async (
path: string,
position: number,
startLine: number,
endLine: number,
body: string
) => {
try {
Expand All @@ -41,7 +42,9 @@ export const postComment = async (
pull_number: pullNumber,
commit_id: commitId,
path,
position,
start_line: startLine,
line: endLine,
side: "RIGHT",
body,
});
} catch (error) {
Expand Down Expand Up @@ -69,9 +72,10 @@ export const getDiff = (targetBranch: string) => {

return diffFiles.map((diffFile) => {
const file = readFileSync(diffFile, "utf-8");
const diff = execSync(`git --no-pager diff --minimal ${branch} ${diffFile}`)
const diff = execSync(`git --no-pager diff ${branch} ${diffFile}`)
.toString()
.trim();

return { file, diff, path: diffFile };
});
};

0 comments on commit f11bf30

Please sign in to comment.