mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Knip fixes
This commit is contained in:
parent
0e7a14e68a
commit
29d73dce4c
3 changed files with 2 additions and 433 deletions
11
knip.json
11
knip.json
|
|
@ -1,12 +1,6 @@
|
|||
{
|
||||
"$schema": "https://unpkg.com/knip@latest/schema.json",
|
||||
"entry": [
|
||||
"src/extension.ts",
|
||||
"src/activate/index.ts",
|
||||
"src/core/mentions/index.ts",
|
||||
"webview-ui/src/index.tsx",
|
||||
"src/core/webview/webviewMessageHandler.ts"
|
||||
],
|
||||
"entry": ["src/extension.ts", "src/activate/index.ts", "webview-ui/src/index.tsx"],
|
||||
"project": ["src/**/*.ts", "webview-ui/src/**/*.{ts,tsx}"],
|
||||
"ignore": [
|
||||
"**/__mocks__/**",
|
||||
|
|
@ -25,9 +19,8 @@
|
|||
"src/exports/**",
|
||||
"src/schemas/ipc.ts",
|
||||
"src/extension.ts",
|
||||
"scripts/**",
|
||||
"marketplace-template/**",
|
||||
"src/utils/git.ts"
|
||||
"scripts/**"
|
||||
],
|
||||
"workspaces": {
|
||||
"webview-ui": {
|
||||
|
|
|
|||
|
|
@ -1,295 +0,0 @@
|
|||
import { jest } from "@jest/globals";
|
||||
import { searchCommits, getCommitInfo, getWorkingState } from "../git";
|
||||
// Mock child_process.exec
|
||||
jest.mock("child_process", () => ({
|
||||
exec: jest.fn(),
|
||||
}));
|
||||
// Mock util.promisify to return our own mock function
|
||||
jest.mock("util", () => ({
|
||||
promisify: jest.fn((fn) => {
|
||||
return async (command, options) => {
|
||||
// Call the original mock to maintain the mock implementation
|
||||
return new Promise((resolve, reject) => {
|
||||
fn(command, options || {}, (error, result) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
}),
|
||||
}));
|
||||
// Mock extract-text
|
||||
jest.mock("../../integrations/misc/extract-text", () => ({
|
||||
truncateOutput: jest.fn((text) => text),
|
||||
}));
|
||||
describe("git utils", () => {
|
||||
// Get the mock with proper typing
|
||||
const { exec } = jest.requireMock("child_process");
|
||||
const cwd = "/test/path";
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
describe("searchCommits", () => {
|
||||
const mockCommitData = [
|
||||
"abc123def456",
|
||||
"abc123",
|
||||
"fix: test commit",
|
||||
"John Doe",
|
||||
"2024-01-06",
|
||||
"def456abc789",
|
||||
"def456",
|
||||
"feat: new feature",
|
||||
"Jane Smith",
|
||||
"2024-01-05",
|
||||
].join("\n");
|
||||
it("should return commits when git is installed and repo exists", async () => {
|
||||
// Set up mock responses
|
||||
const responses = new Map([
|
||||
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
||||
["git rev-parse --git-dir", { stdout: ".git", stderr: "" }],
|
||||
[
|
||||
'git log -n 10 --format="%H%n%h%n%s%n%an%n%ad" --date=short --grep="test" --regexp-ignore-case',
|
||||
{ stdout: mockCommitData, stderr: "" },
|
||||
],
|
||||
]);
|
||||
exec.mockImplementation((command, options, callback) => {
|
||||
// Find matching response
|
||||
for (const [cmd, response] of responses) {
|
||||
if (command === cmd) {
|
||||
callback(null, response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
callback(new Error(`Unexpected command: ${command}`));
|
||||
});
|
||||
const result = await searchCommits("test", cwd);
|
||||
// First verify the result is correct
|
||||
expect(result).toHaveLength(2);
|
||||
expect(result[0]).toEqual({
|
||||
hash: "abc123def456",
|
||||
shortHash: "abc123",
|
||||
subject: "fix: test commit",
|
||||
author: "John Doe",
|
||||
date: "2024-01-06",
|
||||
});
|
||||
// Then verify all commands were called correctly
|
||||
expect(exec).toHaveBeenCalledWith("git --version", {}, expect.any(Function));
|
||||
expect(exec).toHaveBeenCalledWith("git rev-parse --git-dir", { cwd }, expect.any(Function));
|
||||
expect(exec).toHaveBeenCalledWith('git log -n 10 --format="%H%n%h%n%s%n%an%n%ad" --date=short --grep="test" --regexp-ignore-case', { cwd }, expect.any(Function));
|
||||
});
|
||||
it("should return empty array when git is not installed", async () => {
|
||||
exec.mockImplementation((command, options, callback) => {
|
||||
if (command === "git --version") {
|
||||
callback(new Error("git not found"));
|
||||
return;
|
||||
}
|
||||
callback(new Error("Unexpected command"));
|
||||
});
|
||||
const result = await searchCommits("test", cwd);
|
||||
expect(result).toEqual([]);
|
||||
expect(exec).toHaveBeenCalledWith("git --version", {}, expect.any(Function));
|
||||
});
|
||||
it("should return empty array when not in a git repository", async () => {
|
||||
const responses = new Map([
|
||||
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
||||
["git rev-parse --git-dir", null], // null indicates error should be called
|
||||
]);
|
||||
exec.mockImplementation((command, options, callback) => {
|
||||
const response = responses.get(command);
|
||||
if (response === null) {
|
||||
callback(new Error("not a git repository"));
|
||||
}
|
||||
else if (response) {
|
||||
callback(null, response);
|
||||
}
|
||||
else {
|
||||
callback(new Error("Unexpected command"));
|
||||
}
|
||||
});
|
||||
const result = await searchCommits("test", cwd);
|
||||
expect(result).toEqual([]);
|
||||
expect(exec).toHaveBeenCalledWith("git --version", {}, expect.any(Function));
|
||||
expect(exec).toHaveBeenCalledWith("git rev-parse --git-dir", { cwd }, expect.any(Function));
|
||||
});
|
||||
it("should handle hash search when grep search returns no results", async () => {
|
||||
const responses = new Map([
|
||||
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
||||
["git rev-parse --git-dir", { stdout: ".git", stderr: "" }],
|
||||
[
|
||||
'git log -n 10 --format="%H%n%h%n%s%n%an%n%ad" --date=short --grep="abc123" --regexp-ignore-case',
|
||||
{ stdout: "", stderr: "" },
|
||||
],
|
||||
[
|
||||
'git log -n 10 --format="%H%n%h%n%s%n%an%n%ad" --date=short --author-date-order abc123',
|
||||
{ stdout: mockCommitData, stderr: "" },
|
||||
],
|
||||
]);
|
||||
exec.mockImplementation((command, options, callback) => {
|
||||
for (const [cmd, response] of responses) {
|
||||
if (command === cmd) {
|
||||
callback(null, response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
callback(new Error("Unexpected command"));
|
||||
});
|
||||
const result = await searchCommits("abc123", cwd);
|
||||
expect(result).toHaveLength(2);
|
||||
expect(result[0]).toEqual({
|
||||
hash: "abc123def456",
|
||||
shortHash: "abc123",
|
||||
subject: "fix: test commit",
|
||||
author: "John Doe",
|
||||
date: "2024-01-06",
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("getCommitInfo", () => {
|
||||
const mockCommitInfo = [
|
||||
"abc123def456",
|
||||
"abc123",
|
||||
"fix: test commit",
|
||||
"John Doe",
|
||||
"2024-01-06",
|
||||
"Detailed description",
|
||||
].join("\n");
|
||||
const mockStats = "1 file changed, 2 insertions(+), 1 deletion(-)";
|
||||
const mockDiff = "@@ -1,1 +1,2 @@\n-old line\n+new line";
|
||||
it("should return formatted commit info", async () => {
|
||||
const responses = new Map([
|
||||
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
||||
["git rev-parse --git-dir", { stdout: ".git", stderr: "" }],
|
||||
[
|
||||
'git show --format="%H%n%h%n%s%n%an%n%ad%n%b" --no-patch abc123',
|
||||
{ stdout: mockCommitInfo, stderr: "" },
|
||||
],
|
||||
['git show --stat --format="" abc123', { stdout: mockStats, stderr: "" }],
|
||||
['git show --format="" abc123', { stdout: mockDiff, stderr: "" }],
|
||||
]);
|
||||
exec.mockImplementation((command, options, callback) => {
|
||||
for (const [cmd, response] of responses) {
|
||||
if (command.startsWith(cmd)) {
|
||||
callback(null, response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
callback(new Error("Unexpected command"));
|
||||
});
|
||||
const result = await getCommitInfo("abc123", cwd);
|
||||
expect(result).toContain("Commit: abc123");
|
||||
expect(result).toContain("Author: John Doe");
|
||||
expect(result).toContain("Files Changed:");
|
||||
expect(result).toContain("Full Changes:");
|
||||
});
|
||||
it("should return error message when git is not installed", async () => {
|
||||
exec.mockImplementation((command, options, callback) => {
|
||||
if (command === "git --version") {
|
||||
callback(new Error("git not found"));
|
||||
return;
|
||||
}
|
||||
callback(new Error("Unexpected command"));
|
||||
});
|
||||
const result = await getCommitInfo("abc123", cwd);
|
||||
expect(result).toBe("Git is not installed");
|
||||
});
|
||||
it("should return error message when not in a git repository", async () => {
|
||||
const responses = new Map([
|
||||
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
||||
["git rev-parse --git-dir", null], // null indicates error should be called
|
||||
]);
|
||||
exec.mockImplementation((command, options, callback) => {
|
||||
const response = responses.get(command);
|
||||
if (response === null) {
|
||||
callback(new Error("not a git repository"));
|
||||
}
|
||||
else if (response) {
|
||||
callback(null, response);
|
||||
}
|
||||
else {
|
||||
callback(new Error("Unexpected command"));
|
||||
}
|
||||
});
|
||||
const result = await getCommitInfo("abc123", cwd);
|
||||
expect(result).toBe("Not a git repository");
|
||||
});
|
||||
});
|
||||
describe("getWorkingState", () => {
|
||||
const mockStatus = " M src/file1.ts\n?? src/file2.ts";
|
||||
const mockDiff = "@@ -1,1 +1,2 @@\n-old line\n+new line";
|
||||
it("should return working directory changes", async () => {
|
||||
const responses = new Map([
|
||||
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
||||
["git rev-parse --git-dir", { stdout: ".git", stderr: "" }],
|
||||
["git status --short", { stdout: mockStatus, stderr: "" }],
|
||||
["git diff HEAD", { stdout: mockDiff, stderr: "" }],
|
||||
]);
|
||||
exec.mockImplementation((command, options, callback) => {
|
||||
for (const [cmd, response] of responses) {
|
||||
if (command === cmd) {
|
||||
callback(null, response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
callback(new Error("Unexpected command"));
|
||||
});
|
||||
const result = await getWorkingState(cwd);
|
||||
expect(result).toContain("Working directory changes:");
|
||||
expect(result).toContain("src/file1.ts");
|
||||
expect(result).toContain("src/file2.ts");
|
||||
});
|
||||
it("should return message when working directory is clean", async () => {
|
||||
const responses = new Map([
|
||||
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
||||
["git rev-parse --git-dir", { stdout: ".git", stderr: "" }],
|
||||
["git status --short", { stdout: "", stderr: "" }],
|
||||
]);
|
||||
exec.mockImplementation((command, options, callback) => {
|
||||
for (const [cmd, response] of responses) {
|
||||
if (command === cmd) {
|
||||
callback(null, response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
callback(new Error("Unexpected command"));
|
||||
});
|
||||
const result = await getWorkingState(cwd);
|
||||
expect(result).toBe("No changes in working directory");
|
||||
});
|
||||
it("should return error message when git is not installed", async () => {
|
||||
exec.mockImplementation((command, options, callback) => {
|
||||
if (command === "git --version") {
|
||||
callback(new Error("git not found"));
|
||||
return;
|
||||
}
|
||||
callback(new Error("Unexpected command"));
|
||||
});
|
||||
const result = await getWorkingState(cwd);
|
||||
expect(result).toBe("Git is not installed");
|
||||
});
|
||||
it("should return error message when not in a git repository", async () => {
|
||||
const responses = new Map([
|
||||
["git --version", { stdout: "git version 2.39.2", stderr: "" }],
|
||||
["git rev-parse --git-dir", null], // null indicates error should be called
|
||||
]);
|
||||
exec.mockImplementation((command, options, callback) => {
|
||||
const response = responses.get(command);
|
||||
if (response === null) {
|
||||
callback(new Error("not a git repository"));
|
||||
}
|
||||
else if (response) {
|
||||
callback(null, response);
|
||||
}
|
||||
else {
|
||||
callback(new Error("Unexpected command"));
|
||||
}
|
||||
});
|
||||
const result = await getWorkingState(cwd);
|
||||
expect(result).toBe("Not a git repository");
|
||||
});
|
||||
});
|
||||
});
|
||||
//# sourceMappingURL=git.test.js.map
|
||||
129
src/utils/git.js
129
src/utils/git.js
|
|
@ -1,129 +0,0 @@
|
|||
import { exec } from "child_process";
|
||||
import { promisify } from "util";
|
||||
import { truncateOutput } from "../integrations/misc/extract-text";
|
||||
const execAsync = promisify(exec);
|
||||
const GIT_OUTPUT_LINE_LIMIT = 500;
|
||||
async function checkGitRepo(cwd) {
|
||||
try {
|
||||
await execAsync("git rev-parse --git-dir", { cwd });
|
||||
return true;
|
||||
}
|
||||
catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async function checkGitInstalled() {
|
||||
try {
|
||||
await execAsync("git --version");
|
||||
return true;
|
||||
}
|
||||
catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export async function searchCommits(query, cwd) {
|
||||
try {
|
||||
const isInstalled = await checkGitInstalled();
|
||||
if (!isInstalled) {
|
||||
console.error("Git is not installed");
|
||||
return [];
|
||||
}
|
||||
const isRepo = await checkGitRepo(cwd);
|
||||
if (!isRepo) {
|
||||
console.error("Not a git repository");
|
||||
return [];
|
||||
}
|
||||
// Search commits by hash or message, limiting to 10 results
|
||||
const { stdout } = await execAsync(`git log -n 10 --format="%H%n%h%n%s%n%an%n%ad" --date=short ` + `--grep="${query}" --regexp-ignore-case`, { cwd });
|
||||
let output = stdout;
|
||||
if (!output.trim() && /^[a-f0-9]+$/i.test(query)) {
|
||||
// If no results from grep search and query looks like a hash, try searching by hash
|
||||
const { stdout: hashStdout } = await execAsync(`git log -n 10 --format="%H%n%h%n%s%n%an%n%ad" --date=short ` + `--author-date-order ${query}`, { cwd }).catch(() => ({ stdout: "" }));
|
||||
if (!hashStdout.trim()) {
|
||||
return [];
|
||||
}
|
||||
output = hashStdout;
|
||||
}
|
||||
const commits = [];
|
||||
const lines = output
|
||||
.trim()
|
||||
.split("\n")
|
||||
.filter((line) => line !== "--");
|
||||
for (let i = 0; i < lines.length; i += 5) {
|
||||
commits.push({
|
||||
hash: lines[i],
|
||||
shortHash: lines[i + 1],
|
||||
subject: lines[i + 2],
|
||||
author: lines[i + 3],
|
||||
date: lines[i + 4],
|
||||
});
|
||||
}
|
||||
return commits;
|
||||
}
|
||||
catch (error) {
|
||||
console.error("Error searching commits:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
export async function getCommitInfo(hash, cwd) {
|
||||
try {
|
||||
const isInstalled = await checkGitInstalled();
|
||||
if (!isInstalled) {
|
||||
return "Git is not installed";
|
||||
}
|
||||
const isRepo = await checkGitRepo(cwd);
|
||||
if (!isRepo) {
|
||||
return "Not a git repository";
|
||||
}
|
||||
// Get commit info, stats, and diff separately
|
||||
const { stdout: info } = await execAsync(`git show --format="%H%n%h%n%s%n%an%n%ad%n%b" --no-patch ${hash}`, {
|
||||
cwd,
|
||||
});
|
||||
const [fullHash, shortHash, subject, author, date, body] = info.trim().split("\n");
|
||||
const { stdout: stats } = await execAsync(`git show --stat --format="" ${hash}`, { cwd });
|
||||
const { stdout: diff } = await execAsync(`git show --format="" ${hash}`, { cwd });
|
||||
const summary = [
|
||||
`Commit: ${shortHash} (${fullHash})`,
|
||||
`Author: ${author}`,
|
||||
`Date: ${date}`,
|
||||
`\nMessage: ${subject}`,
|
||||
body ? `\nDescription:\n${body}` : "",
|
||||
"\nFiles Changed:",
|
||||
stats.trim(),
|
||||
"\nFull Changes:",
|
||||
].join("\n");
|
||||
const output = summary + "\n\n" + diff.trim();
|
||||
return truncateOutput(output, GIT_OUTPUT_LINE_LIMIT);
|
||||
}
|
||||
catch (error) {
|
||||
console.error("Error getting commit info:", error);
|
||||
return `Failed to get commit info: ${error instanceof Error ? error.message : String(error)}`;
|
||||
}
|
||||
}
|
||||
export async function getWorkingState(cwd) {
|
||||
try {
|
||||
const isInstalled = await checkGitInstalled();
|
||||
if (!isInstalled) {
|
||||
return "Git is not installed";
|
||||
}
|
||||
const isRepo = await checkGitRepo(cwd);
|
||||
if (!isRepo) {
|
||||
return "Not a git repository";
|
||||
}
|
||||
// Get status of working directory
|
||||
const { stdout: status } = await execAsync("git status --short", { cwd });
|
||||
if (!status.trim()) {
|
||||
return "No changes in working directory";
|
||||
}
|
||||
// Get all changes (both staged and unstaged) compared to HEAD
|
||||
const { stdout: diff } = await execAsync("git diff HEAD", { cwd });
|
||||
const lineLimit = GIT_OUTPUT_LINE_LIMIT;
|
||||
const output = `Working directory changes:\n\n${status}\n\n${diff}`.trim();
|
||||
return truncateOutput(output, lineLimit);
|
||||
}
|
||||
catch (error) {
|
||||
console.error("Error getting working state:", error);
|
||||
return `Failed to get working state: ${error instanceof Error ? error.message : String(error)}`;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=git.js.map
|
||||
Loading…
Add table
Reference in a new issue