mirror of
https://github.com/di-sukharev/opencommit.git
synced 2026-04-20 03:02:51 -04:00
build
This commit is contained in:
@@ -27045,22 +27045,6 @@ function tokenCount(content) {
|
||||
return tokens.length;
|
||||
}
|
||||
|
||||
// src/utils/mergeDiffs.ts
|
||||
function mergeDiffs(arr, maxStringLength) {
|
||||
const mergedArr = [];
|
||||
let currentItem = arr[0];
|
||||
for (const item of arr.slice(1)) {
|
||||
if (tokenCount(currentItem + item) <= maxStringLength) {
|
||||
currentItem += item;
|
||||
} else {
|
||||
mergedArr.push(currentItem);
|
||||
currentItem = item;
|
||||
}
|
||||
}
|
||||
mergedArr.push(currentItem);
|
||||
return mergedArr;
|
||||
}
|
||||
|
||||
// src/generateCommitMessageFromGitDiff.ts
|
||||
var config3 = getConfig();
|
||||
var translation = i18n[config3?.OCO_LANGUAGE || "en"];
|
||||
@@ -27106,91 +27090,12 @@ ${config3?.OCO_EMOJI ? "\u2728 " : ""}${translation.commitFeat}
|
||||
${config3?.OCO_DESCRIPTION ? translation.commitDescription : ""}`
|
||||
}
|
||||
];
|
||||
var generateCommitMessageChatCompletionPrompt = (diff) => {
|
||||
const chatContextAsCompletionRequest = [...INIT_MESSAGES_PROMPT];
|
||||
chatContextAsCompletionRequest.push({
|
||||
role: import_openai2.ChatCompletionRequestMessageRoleEnum.User,
|
||||
content: diff
|
||||
});
|
||||
return chatContextAsCompletionRequest;
|
||||
};
|
||||
var INIT_MESSAGES_PROMPT_LENGTH = INIT_MESSAGES_PROMPT.map(
|
||||
(msg) => tokenCount(msg.content) + 4
|
||||
).reduce((a2, b) => a2 + b, 0);
|
||||
var MAX_REQ_TOKENS = 3e3 - INIT_MESSAGES_PROMPT_LENGTH;
|
||||
var generateCommitMessageByDiff = async (diff) => {
|
||||
try {
|
||||
if (tokenCount(diff) >= MAX_REQ_TOKENS) {
|
||||
const commitMessagePromises = getCommitMsgsPromisesFromFileDiffs(
|
||||
diff,
|
||||
MAX_REQ_TOKENS
|
||||
);
|
||||
const commitMessages = await Promise.all(commitMessagePromises);
|
||||
return commitMessages.join("\n\n");
|
||||
} else {
|
||||
const messages = generateCommitMessageChatCompletionPrompt(diff);
|
||||
const commitMessage = await api.generateCommitMessage(messages);
|
||||
if (!commitMessage)
|
||||
throw new Error("EMPTY_MESSAGE" /* emptyMessage */);
|
||||
return commitMessage;
|
||||
}
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
function getMessagesPromisesByChangesInFile(fileDiff, separator, maxChangeLength) {
|
||||
const hunkHeaderSeparator = "@@ ";
|
||||
const [fileHeader, ...fileDiffByLines] = fileDiff.split(hunkHeaderSeparator);
|
||||
const mergedChanges = mergeDiffs(
|
||||
fileDiffByLines.map((line) => hunkHeaderSeparator + line),
|
||||
maxChangeLength
|
||||
);
|
||||
const lineDiffsWithHeader = mergedChanges.map(
|
||||
(change) => fileHeader + change
|
||||
);
|
||||
const commitMsgsFromFileLineDiffs = lineDiffsWithHeader.map((lineDiff) => {
|
||||
const messages = generateCommitMessageChatCompletionPrompt(
|
||||
separator + lineDiff
|
||||
);
|
||||
return api.generateCommitMessage(messages);
|
||||
});
|
||||
return commitMsgsFromFileLineDiffs;
|
||||
}
|
||||
function getCommitMsgsPromisesFromFileDiffs(diff, maxDiffLength) {
|
||||
const separator = "diff --git ";
|
||||
const diffByFiles = diff.split(separator).slice(1);
|
||||
const mergedFilesDiffs = mergeDiffs(diffByFiles, maxDiffLength);
|
||||
const commitMessagePromises = [];
|
||||
for (const fileDiff of mergedFilesDiffs) {
|
||||
if (tokenCount(fileDiff) >= maxDiffLength) {
|
||||
const messagesPromises = getMessagesPromisesByChangesInFile(
|
||||
fileDiff,
|
||||
separator,
|
||||
maxDiffLength
|
||||
);
|
||||
commitMessagePromises.push(...messagesPromises);
|
||||
} else {
|
||||
const messages = generateCommitMessageChatCompletionPrompt(
|
||||
separator + fileDiff
|
||||
);
|
||||
commitMessagePromises.push(api.generateCommitMessage(messages));
|
||||
}
|
||||
}
|
||||
return commitMessagePromises;
|
||||
}
|
||||
|
||||
// src/utils/sleep.ts
|
||||
function sleep(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
// src/utils/randomIntFromInterval.ts
|
||||
function randomIntFromInterval(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1) + min);
|
||||
}
|
||||
|
||||
// src/github-action.ts
|
||||
var import_fs2 = require("fs");
|
||||
var import_util3 = require("util");
|
||||
var import_child_process = require("child_process");
|
||||
var execPromise = (0, import_util3.promisify)(import_child_process.exec);
|
||||
@@ -27200,109 +27105,6 @@ var octokit = import_github.default.getOctokit(GITHUB_TOKEN);
|
||||
var context = import_github.default.context;
|
||||
var owner = context.repo.owner;
|
||||
var repo = context.repo.repo;
|
||||
async function getCommitDiff(commitSha) {
|
||||
const diffResponse = await octokit.request(
|
||||
"GET /repos/{owner}/{repo}/commits/{ref}",
|
||||
{
|
||||
owner,
|
||||
repo,
|
||||
ref: commitSha,
|
||||
headers: {
|
||||
Accept: "application/vnd.github.v3.diff"
|
||||
}
|
||||
}
|
||||
);
|
||||
return { sha: commitSha, diff: diffResponse.data };
|
||||
}
|
||||
async function improveMessagesInChunks(diffsAndSHAs) {
|
||||
const chunkSize = diffsAndSHAs.length % 2 === 0 ? 4 : 3;
|
||||
ce(`Improving commit messages in chunks of ${chunkSize}.`);
|
||||
const improvePromises = diffsAndSHAs.map(
|
||||
(commit) => generateCommitMessageByDiff(commit.diff)
|
||||
);
|
||||
let improvedMessagesAndSHAs = [];
|
||||
for (let step = 0; step < improvePromises.length; step += chunkSize) {
|
||||
const chunkOfPromises = improvePromises.slice(step, step + chunkSize);
|
||||
try {
|
||||
const chunkOfImprovedMessages = await Promise.all(chunkOfPromises);
|
||||
const chunkOfImprovedMessagesBySha = chunkOfImprovedMessages.map(
|
||||
(improvedMsg, i2) => {
|
||||
const index = improvedMessagesAndSHAs.length;
|
||||
const sha = diffsAndSHAs[index + i2].sha;
|
||||
return { sha, msg: improvedMsg };
|
||||
}
|
||||
);
|
||||
improvedMessagesAndSHAs.push(...chunkOfImprovedMessagesBySha);
|
||||
const sleepFor = 1e3 * randomIntFromInterval(1, 5) + 100 * (step / chunkSize) + 100 * randomIntFromInterval(1, 5);
|
||||
ce(
|
||||
`Improved ${chunkOfPromises.length} messages. Sleeping for ${sleepFor}`
|
||||
);
|
||||
await sleep(sleepFor);
|
||||
} catch (error) {
|
||||
ce(error);
|
||||
const sleepFor = 2e4 + 1e3 * randomIntFromInterval(1, 5);
|
||||
ce(`Retrying after sleeping for ${sleepFor}`);
|
||||
await sleep(sleepFor);
|
||||
step -= chunkSize;
|
||||
}
|
||||
}
|
||||
return improvedMessagesAndSHAs;
|
||||
}
|
||||
var getDiffsBySHAs = async (SHAs) => {
|
||||
const diffPromises = SHAs.map((sha) => getCommitDiff(sha));
|
||||
const diffs = await Promise.all(diffPromises).catch((error) => {
|
||||
ce(`error in Promise.all(getCommitDiffs(SHAs)): ${error}`);
|
||||
throw error;
|
||||
});
|
||||
return diffs;
|
||||
};
|
||||
async function improveCommitMessages(commits) {
|
||||
let commitsToImprove = pattern ? commits.filter(({ commit }) => new RegExp(pattern).test(commit.message)) : commits;
|
||||
if (commitsToImprove.length) {
|
||||
ce(`Found ${commitsToImprove.length} commits to improve.`);
|
||||
} else {
|
||||
ce("No new commits found.");
|
||||
return;
|
||||
}
|
||||
ce("Fetching commit diffs by SHAs.");
|
||||
const commitSHAsToImprove = commitsToImprove.map((commit) => commit.sha);
|
||||
const diffsWithSHAs = await getDiffsBySHAs(commitSHAsToImprove);
|
||||
ce("Done.");
|
||||
const improvedMessagesWithSHAs = await improveMessagesInChunks(diffsWithSHAs);
|
||||
console.log(
|
||||
`Improved ${improvedMessagesWithSHAs.length} commits: `,
|
||||
improvedMessagesWithSHAs
|
||||
);
|
||||
const createCommitMessageFile = (message, index) => (0, import_fs2.writeFileSync)(`./commit-${index}.txt`, message);
|
||||
improvedMessagesWithSHAs.forEach(
|
||||
({ msg }, i2) => createCommitMessageFile(msg, i2)
|
||||
);
|
||||
(0, import_fs2.writeFileSync)(`./count.txt`, "0");
|
||||
(0, import_fs2.writeFileSync)(
|
||||
"./rebase-exec.sh",
|
||||
"#!/bin/bash; count=$(cat count.txt); git commit --amend -F commit-$count.txt; echo $(( count + 1 )) > count.txt"
|
||||
);
|
||||
await import_exec.default.exec(`chmod +x ./rebase-exec.sh`);
|
||||
await import_exec.default.exec(
|
||||
"git",
|
||||
["rebase", `${commitsToImprove[0].sha}^`, "--exec", "./rebase-exec.sh"],
|
||||
{
|
||||
env: {
|
||||
GIT_SEQUENCE_EDITOR: 'sed -i -e "s/^pick/reword/g"',
|
||||
GIT_COMMITTER_NAME: process.env.GITHUB_ACTOR,
|
||||
GIT_COMMITTER_EMAIL: `${process.env.GITHUB_ACTOR}@users.noreply.github.com`
|
||||
}
|
||||
}
|
||||
);
|
||||
const deleteCommitMessageFile = (index) => (0, import_fs2.unlinkSync)(`./commit-${index}.txt`);
|
||||
commitsToImprove.forEach((_commit, i2) => deleteCommitMessageFile(i2));
|
||||
(0, import_fs2.unlinkSync)("./count.txt");
|
||||
(0, import_fs2.unlinkSync)("./rebase-exec.sh");
|
||||
ce("Force pushing non-interactively rebased commits into remote origin.");
|
||||
await import_exec.default.exec("git", ["status"]);
|
||||
await import_exec.default.exec("git", ["push", "origin", `--force`]);
|
||||
ce("Done \u{1F9D9}");
|
||||
}
|
||||
async function run(retries = 3) {
|
||||
ae("OpenCommit \u2014 improving commit messages with GPT");
|
||||
await import_exec.default.exec("git", [
|
||||
@@ -27311,35 +27113,29 @@ async function run(retries = 3) {
|
||||
`${process.env.GITHUB_ACTOR}@users.noreply.github.com`
|
||||
]);
|
||||
await import_exec.default.exec("git", ["config", "user.name", process.env.GITHUB_ACTOR]);
|
||||
await import_exec.default.exec("git", ["status"]);
|
||||
await import_exec.default.exec("git", ["log", "--oneline"]);
|
||||
try {
|
||||
if (import_github.default.context.eventName === "pull_request") {
|
||||
const baseBranch = import_github.default.context.payload.pull_request?.base.ref;
|
||||
const sourceBranch = import_github.default.context.payload.pull_request?.head.ref;
|
||||
ce(
|
||||
`Processing commits in a Pull Request from source: (${sourceBranch}) to base: (${baseBranch})`
|
||||
);
|
||||
if (import_github.default.context.payload.action === "opened")
|
||||
ce("Pull Request action: opened");
|
||||
else if (import_github.default.context.payload.action === "synchronize")
|
||||
ce("Pull Request action: synchronize");
|
||||
else
|
||||
if (import_github.default.context.eventName === "push") {
|
||||
ce(`Processing commits in a Push event`);
|
||||
const payload = import_github.default.context.payload;
|
||||
const commits = payload.commits;
|
||||
console.log(123123, { commits });
|
||||
await import_exec.default.exec("git", ["status"]);
|
||||
await import_exec.default.exec("git", ["log", "--oneline"]);
|
||||
} else if (import_github.default.context.eventName === "pull_request") {
|
||||
if (import_github.default.context.payload.action === "opened") {
|
||||
ce("Pull Request action: opened. Not yet implemented.");
|
||||
} else if (import_github.default.context.payload.action === "synchronize") {
|
||||
ce("Pull Request action: synchronize. Not yet implemented.");
|
||||
} else
|
||||
return ce(
|
||||
"Pull Request unhandled action: " + import_github.default.context.payload.action
|
||||
);
|
||||
const payload = import_github.default.context.payload;
|
||||
const commitsResponse = await octokit.rest.pulls.listCommits({
|
||||
owner,
|
||||
repo,
|
||||
pull_number: payload.pull_request.number
|
||||
});
|
||||
const commits = commitsResponse.data;
|
||||
await import_exec.default.exec("git", ["status"]);
|
||||
await import_exec.default.exec("git", ["log", "--oneline"]);
|
||||
await improveCommitMessages(commits);
|
||||
} else {
|
||||
ce("Wrong action.");
|
||||
import_core3.default.error(
|
||||
`OpenCommit was called on ${import_github.default.context.payload.action}. OpenCommit is not supposed to be used on actions other from "pull_request.opened" and "pull_request.synchronize".`
|
||||
`OpenCommit was called on ${import_github.default.context.payload.action}. OpenCommit is supposed to be used on "push" action.`
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user