Skip to content

Commit

Permalink
feat: move git commands in common folder out of review
Browse files Browse the repository at this point in the history
  • Loading branch information
gowoons committed Jul 31, 2023
1 parent 1925493 commit b4bd034
Show file tree
Hide file tree
Showing 14 changed files with 130 additions and 189 deletions.
38 changes: 38 additions & 0 deletions src/common/git/getChangedFileLines.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { exec } from "child_process";

import { getGitHubEnvVariables } from "../../config";

export const getChangesFileLinesCommand = (
isCi: boolean,
fileName: string
): string => {
if (isCi) {
const { githubSha, baseSha } = getGitHubEnvVariables();
return `git diff -U0 --diff-filter=AMT ${baseSha} ${githubSha} ${fileName}`;
}
return `git diff -U0 --diff-filter=AMT --cached ${fileName}`;
};

export const getChangedFileLines = async (
isCi: boolean,
fileName: string
): Promise<string> => {
const commandString = getChangesFileLinesCommand(isCi, fileName);

return new Promise((resolve, reject) => {
exec(commandString, (error, stdout, stderr) => {
if (error) {
reject(new Error(`Failed to execute command. Error: ${error.message}`));
} else if (stderr) {
reject(new Error(`Command execution error: ${stderr}`));
} else {
const changedLines = stdout
.split("\n")
.filter((line) => line.startsWith("+") || line.startsWith("-"))
.filter((line) => !line.startsWith("---") && !line.startsWith("+++"))
.join("\n");
resolve(changedLines);
}
});
});
};
34 changes: 34 additions & 0 deletions src/common/git/getChangedFilesNames.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { exec } from "child_process";
import { join } from "path";

import { getGitHubEnvVariables } from "../../config";

export const getChangedFilesNamesCommand = (isCi: boolean): string => {
if (isCi) {
const { githubSha, baseSha } = getGitHubEnvVariables();
return `git diff --name-only --diff-filter=AMT ${baseSha} ${githubSha}`;
}
return "git diff --name-only --diff-filter=AMT --cached";
};

export const getChangedFilesNames = async (
isCi: boolean
): Promise<string[]> => {
const commandString = getChangedFilesNamesCommand(isCi);

return new Promise((resolve, reject) => {
exec(commandString, (error, stdout, stderr) => {
if (error) {
reject(new Error(`Failed to execute command. Error: ${error.message}`));
} else if (stderr) {
reject(new Error(`Command execution error: ${stderr}`));
} else {
const files = stdout
.split("\n")
.filter((fileName) => fileName.trim() !== "")
.map((fileName) => join(process.cwd(), fileName.trim()));
resolve(files);
}
});
});
};
23 changes: 23 additions & 0 deletions src/common/git/getFilesWithChanges.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { readFile } from "fs/promises";
import { getChangedFileLines } from "./getChangedFileLines";
import { getChangedFilesNames } from "./getChangedFilesNames";
import { File } from "../types/File";

export const getFilesWithChanges = async (isCi: boolean): Promise<File[]> => {
try {
const fileNames = await getChangedFilesNames(isCi);

const files = await Promise.all(
fileNames.map(async (fileName) => {
const fileContent = await readFile(fileName, "utf8");
const changedLines = await getChangedFileLines(isCi, fileName);

return { fileName, fileContent, changedLines };
})
);

return files;
} catch (error) {
throw new Error(`Failed to get files with changes: ${error}`);
}
};
5 changes: 5 additions & 0 deletions src/common/types/File.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface File {
fileName: string;
fileContent: string;
changedLines: string;
}
1 change: 1 addition & 0 deletions src/common/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { File } from "./File";
6 changes: 5 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ const main = async () => {
break;
case "review":
const { review } = await import("./review");
await review(argv);
const { getFilesWithChanges } = await import(
"./common/git/getFilesWithChanges"
);
const files = await getFilesWithChanges(argv.ci);
await review(argv, files);
break;
case "test":
const { test } = await import("./test");
Expand Down
7 changes: 3 additions & 4 deletions src/review/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { commentPerFile } from "../common/ci/commentPerFile";
import { signOff } from "./constants";
import { askAI } from "./llm/askAI";
import { constructPromptsArray } from "./prompt/constructPrompt/constructPrompt";
import { getFileNames } from "./prompt/filesNames/getFileNames";
import { File } from "../common/types";

interface ReviewArgs {
[x: string]: unknown;
Expand All @@ -14,16 +14,15 @@ interface ReviewArgs {
$0: string;
}

export const review = async (yargs: ReviewArgs) => {
export const review = async (yargs: ReviewArgs, files: File[]) => {
const isCi = yargs.ci;
const shouldCommentPerFile = yargs.commentPerFile;

const modelName = yargs.model as string;

const maxPromptLength = getMaxPromptLength(modelName);

const fileNames = await getFileNames(isCi);
const prompts = await constructPromptsArray(fileNames, maxPromptLength, isCi);
const prompts = await constructPromptsArray(files, maxPromptLength);

const { markdownReport: response, feedbacks } = await askAI(
prompts,
Expand Down
36 changes: 8 additions & 28 deletions src/review/prompt/constructPrompt/constructPrompt.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { readFile } from "fs/promises";
import { makeSlimmedFile } from "../makeSlimmedFile";
import { instructionPrompt } from "../prompts";
import { File } from "../../../common/types";
import { ReviewFile } from "../types";

const getSizeOfReviewFile = (file: ReviewFile): number =>
file.fileName.length + file.fileContent.length;

const splitFilesIntoBatches = async (
files: ReviewFile[],
maxBatchSize: number,
isCi: boolean
files: File[],
maxBatchSize: number
): Promise<ReviewFile[][]> => {
const batches: ReviewFile[][] = [];
let currentBatch: ReviewFile[] = [];
Expand All @@ -20,7 +19,7 @@ const splitFilesIntoBatches = async (
console.warn(
`File ${file.fileName} is larger than the max prompt length, consider using a model with a larger context window. Attempting to slim the file...`
);
const slimmedFile = await makeSlimmedFile(file, maxBatchSize, isCi);
const slimmedFile = await makeSlimmedFile(file, maxBatchSize);
currentBatch.push(slimmedFile);
} else if (currentBatchSize + currentFileSize > maxBatchSize) {
batches.push(currentBatch);
Expand All @@ -40,33 +39,14 @@ const splitFilesIntoBatches = async (
return batches;
};

const readFiles = async (fileNames: string[]): Promise<ReviewFile[]> => {
const files: ReviewFile[] = [];

for (const fileName of fileNames) {
try {
const fileContent = await readFile(fileName, "utf8");
files.push({ fileName, fileContent });
} catch (error) {
console.error(`Failed to process file ${fileName}: ${error}`);
}
}

return files;
};

export const constructPromptsArray = async (
fileNames: string[],
maxPromptLength: number,
isCi: boolean
files: File[],
maxPromptLength: number
): Promise<string[]> => {
const filesToReview = await readFiles(fileNames);

const maxPromptPayloadLength = maxPromptLength - instructionPrompt.length;
const promptPayloads = await splitFilesIntoBatches(
filesToReview,
maxPromptPayloadLength,
isCi
files,
maxPromptPayloadLength
);

const prompts = promptPayloads.map((payload) => {
Expand Down
27 changes: 0 additions & 27 deletions src/review/prompt/fileLines/getChangedLines.ts

This file was deleted.

31 changes: 0 additions & 31 deletions src/review/prompt/filesNames/getFileNames.test.ts

This file was deleted.

33 changes: 0 additions & 33 deletions src/review/prompt/filesNames/getFileNames.ts

This file was deleted.

23 changes: 0 additions & 23 deletions src/review/prompt/filesNames/getFileNamesFromGit.ts

This file was deleted.

24 changes: 0 additions & 24 deletions src/review/prompt/gitCommands.ts

This file was deleted.

Loading

0 comments on commit b4bd034

Please sign in to comment.