Skip to content
This repository has been archived by the owner on Mar 12, 2024. It is now read-only.

Fix/prevent double console log commenting #377

Merged
merged 10 commits into from
Nov 15, 2023
172 changes: 70 additions & 102 deletions utils/actions/detectConsoleLogs.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
const { Configuration, OpenAIApi } = require("openai");
import { App } from "@octokit/app";
import { successPosthogTracking } from "../../utils/api/posthogTracking";
import {
failedToFetchResponse,
missingParamsResponse,
} from "../../utils/api/responses";
import validateParams from "../../utils/api/validateParams";
import { Octokit } from "octokit";

const configuration = new Configuration({
apiKey: process.env.OPEN_AI_KEY,
Expand All @@ -17,71 +10,55 @@ const app = new App({
appId: process.env.GITHUB_APP_ID!,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file contains at least one console log. Please remove any present.

privateKey: process.env.GITHUB_PRIVATE_KEY!,
});

function getAdditions(filePatch: string) {
const commentBody = `This PR contains console logs. Please review or remove them.`;
const consoleLogDetectionPrompt = `This is a list of code additions. Identify
if there's a console log or its equivalent in another programming language
such as Java, Golang, Python, C, Rust, C++, Ruby, etc.
(console.log(), println(), println!(), System.out.println(), print(), fmt.Println(), puts, and cout << "Print a String" << endl; are some examples).
If the console log or its equivalent in another language is in a code comment, don't
count it as a detected console log. For example JavaScript comments start with // or /*,
Python comments start with #.
Other console functions such as console.info() shouldn't be counted as console logs.
Ignore code comments from this analysis.
Something like 'input[type="email"]' is fine and should not be counted as a console log.
If there is a console log, return "true", else return "false".
If you return true, return a string that that has 2 values: result (true) and the line of code.
The line value, is the actual line in the file that contains the console log.
For example: true,console.log("hello world");`;

function getLineDiffs(filePatch: string) {
const additions: string[] = [];
const removals: string[] = [];

// Split the patch into lines
const lines = filePatch.split("\n");

// Track if we are in a deletion block
let inDeletionBlock = false;

// Loop through lines
for (let i = 0; i < lines.length; i++) {
const line = lines[i];

// Check if entering a deletion block
if (line.startsWith("-")) {
inDeletionBlock = true;
continue;
removals.push(line.replace("-", "").trim());
}

// Check if exiting a deletion block
if (line.startsWith("+") && inDeletionBlock) {
inDeletionBlock = false;
continue;
}

// If not in a deletion block, add lines starting with +
if (!inDeletionBlock && line.startsWith("+")) {
additions.push(line);
}

// Delete the pluses
lines[i] = line.replace("+", "");

// Trim the line to delete leading spaces
lines[i] = lines[i].trim();

// If the line is a comment, remove it
if (
lines[i].startsWith("#") ||
lines[i].startsWith("//") ||
lines[i].startsWith("/*")
) {
lines.splice(i, 1);
i--;
if (line.startsWith("+")) {
additions.push(line.replace("+", "").trim());
}
}

return lines.join("\n");
return { additions: additions.join("\n"), removals: removals.join("\n") };
}

function getConsoleLogPosition(filePatchAndIndividualLine: any) {
let positionInDiff = 1;
const { filePatch, individualLine } = filePatchAndIndividualLine;

// get the position of the indiviudalLine in th filePatch
function getConsoleLogPosition({ filePatch, individualLine }) {
// Split the filePatch into lines and find the index of the line that includes individualLine
const lines = filePatch.split("\n");
for (let i = 1; i < lines.length; i++) {
if (lines[i].includes(individualLine)) {
positionInDiff = i;
break;
}
}
const zeroBasedIndex = lines.findIndex((line) =>
line.includes(individualLine)
);

return positionInDiff;
// Convert to one-based index, or return -1 if not found
return zeroBasedIndex === -1 ? 0 : zeroBasedIndex + 1;
}

export default async function detectConsoleLogs({
Expand Down Expand Up @@ -113,23 +90,24 @@ export default async function detectConsoleLogs({
}
);

function getLatestCommitHash() {
return octokit
.request("GET /repos/{owner}/{repo}/pulls/{pull_number}", {
owner,
repo,
pull_number: issue_number,
})
.then((result) => {
return result.data.head.sha;
})
.catch((err) => {
console.log(err);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file contains at least one console log. Please remove any present.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file contains at least one console log. Please remove any present.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file contains at least one console log. Please remove any present.

});
}
const latestCommitHash = await getLatestCommitHash();

const commentPromises = diffFiles.map(async (file) => {
const additions = getAdditions(file.patch ?? "");

const consoleLogDetectionPrompt = `This is a list of code additions. Identify
if there's a console log or its equivalent in another programming language
such as Java, Golang, Python, C, Rust, C++, Ruby, etc.
(console.log(), println(), println!(), System.out.println(), print(), fmt.Println(), puts, and cout << "Print a String" << endl; are some examples).
If the console log or its equivalent in another language is in a code comment, don't
count it as a detected console log. For example JavaScript comments start with // or /*,
Python comments start with #.
Other console functions such as console.info() shouldn't be counted as console logs.
Ignore code comments from this analysis.
Something like 'input[type="email"]' is fine and should not be counted as a console log.
If there is a console log, return "true", else return "false".
If you return true, return a string that that has 2 values: result (true) and the line of code.
The line value, is the actual line in the file that contains the console log.
For example: true,console.log("hello world");`;
const { additions } = getLineDiffs(file.patch ?? "");

// detect if the additions contain console logs or not
try {
Expand All @@ -152,43 +130,33 @@ export default async function detectConsoleLogs({

if (addtionsHaveConsoleLog === "true") {
const commentFileDiff = () => {
const consoleLogPosition = getConsoleLogPosition({
filePatch: file.patch ?? "",
individualLine,
});

return octokit
.request("GET /repos/{owner}/{repo}/pulls/{pull_number}", {
owner,
repo,
pull_number: issue_number,
})
.then((result) => {
const latestCommitHash = result.data.head.sha;

const consoleLogPosition = getConsoleLogPosition({
filePatch: file.patch ?? "",
individualLine,
});

return octokit
.request(
"POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews",
.request(
"POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews",
{
owner,
repo,
pull_number: issue_number,
commit_id:
typeof latestCommitHash === "string"
? latestCommitHash
: undefined,
event: "COMMENT",
path: file.filename,
comments: [
{
owner,
repo,
pull_number: issue_number,
commit_id: latestCommitHash,
event: "COMMENT",
path: file.filename,
comments: [
{
path: file.filename,
position: consoleLogPosition || 1, // comment at the beggining of the file by default
body: "This file contains at least one console log. Please remove any present.",
},
],
}
)
.catch((err) => {
console.log(err);
});
})
position: consoleLogPosition || 1, // comment at the beggining of the file by default
body: commentBody,
},
],
}
)
.catch((err) => {
console.log(err);
});
Expand Down