Knip fixes

This commit is contained in:
Matt Rubens 2025-04-27 00:11:00 -04:00
parent 0e7a14e68a
commit 29d73dce4c
3 changed files with 2 additions and 433 deletions

View file

@ -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": {

View file

@ -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

View file

@ -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