-
Notifications
You must be signed in to change notification settings - Fork 100
fix: resolve ripgrep from @vscode/ripgrep-universal and the system PATH #248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
42e35a6
7e65af3
91f0548
a21e29b
062b528
417bc71
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,16 @@ | ||
| // npx vitest run src/services/ripgrep/__tests__/index.spec.ts | ||
|
|
||
| import { truncateLine } from "../index" | ||
| import path from "path" | ||
| import { vi, describe, it, expect, beforeEach } from "vitest" | ||
|
|
||
| import { truncateLine, getBinPath } from "../index" | ||
| import { fileExistsAtPath } from "../../../utils/fs" | ||
|
|
||
| vi.mock("../../../utils/fs", () => ({ | ||
| fileExistsAtPath: vi.fn(), | ||
| })) | ||
|
|
||
| const mockFileExists = vi.mocked(fileExistsAtPath) | ||
|
|
||
| describe("Ripgrep line truncation", () => { | ||
| // The default MAX_LINE_LENGTH is 500 in the implementation | ||
|
|
@@ -48,3 +58,41 @@ describe("Ripgrep line truncation", () => { | |
| expect(truncated).toContain("[truncated...]") | ||
| }) | ||
| }) | ||
|
|
||
| describe("getBinPath", () => { | ||
| const appRoot = "/fake/vscode/appRoot" | ||
| const binName = process.platform.startsWith("win") ? "rg.exe" : "rg" | ||
| const platformDir = `${process.platform}-${process.arch}` | ||
|
|
||
| beforeEach(() => { | ||
| mockFileExists.mockReset() | ||
| mockFileExists.mockResolvedValue(false) | ||
| }) | ||
|
|
||
| it("resolves ripgrep from the classic @vscode/ripgrep layout", async () => { | ||
| const rg = path.join(appRoot, "node_modules/@vscode/ripgrep/bin", binName) | ||
| mockFileExists.mockImplementation(async (p: string) => p === rg) | ||
|
|
||
| expect(await getBinPath(appRoot)).toBe(rg) | ||
| }) | ||
|
|
||
| it("resolves ripgrep from the @vscode/ripgrep-universal layout (VS Code Insiders)", async () => { | ||
| const rg = path.join(appRoot, "node_modules/@vscode/ripgrep-universal/bin", platformDir, binName) | ||
| mockFileExists.mockImplementation(async (p: string) => p === rg) | ||
|
|
||
| expect(await getBinPath(appRoot)).toBe(rg) | ||
| }) | ||
|
|
||
| it("resolves ripgrep from the unpacked `@vscode/ripgrep-universal` layout", async () => { | ||
| const rg = path.join(appRoot, "node_modules.asar.unpacked/@vscode/ripgrep-universal/bin", platformDir, binName) | ||
| mockFileExists.mockImplementation(async (p: string) => p === rg) | ||
|
|
||
| expect(await getBinPath(appRoot)).toBe(rg) | ||
| }) | ||
|
|
||
| it("returns undefined when ripgrep cannot be found", async () => { | ||
| mockFileExists.mockResolvedValue(false) | ||
|
|
||
| expect(await getBinPath(appRoot)).toBeUndefined() | ||
| }) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The tests cover the classic layout, universal, and unpacked-universal probes — but |
||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,7 +11,7 @@ This file provides functionality to perform regex searches on files using ripgre | |
| Inspired by: https://github.com/DiscreteTom/vscode-ripgrep-utils | ||
|
|
||
| Key components: | ||
| 1. getBinPath: Locates the ripgrep binary within the VSCode installation. | ||
| 1. getBinPath: Locates the ripgrep binary inside the VS Code installation. | ||
| 2. execRipgrep: Executes the ripgrep command and returns the output. | ||
| 3. regexSearchFiles: The main function that performs regex searches on files. | ||
| - Parameters: | ||
|
|
@@ -51,6 +51,11 @@ rel/path/to/helper.ts | |
| const isWindows = process.platform.startsWith("win") | ||
| const binName = isWindows ? "rg.exe" : "rg" | ||
|
|
||
| // VS Code's @vscode/ripgrep-universal package (used by recent VS Code builds, | ||
| // including the Insiders staged-install layout) nests the binary under | ||
| // bin/<platform>-<arch>/ rather than directly in bin/. | ||
| const ripgrepUniversalBinDir = `bin/${process.platform}-${process.arch}` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The name |
||
|
|
||
| interface SearchFileResult { | ||
| file: string | ||
| searchResults: SearchResult[] | ||
|
|
@@ -80,7 +85,13 @@ export function truncateLine(line: string, maxLength: number = MAX_LINE_LENGTH): | |
| return line.length > maxLength ? line.substring(0, maxLength) + " [truncated...]" : line | ||
| } | ||
| /** | ||
| * Get the path to the ripgrep binary within the VSCode installation | ||
| * Get the path to the ripgrep binary shipped inside the VS Code installation. | ||
| * | ||
| * Both the long-standing `@vscode/ripgrep` layout and the newer | ||
| * `@vscode/ripgrep-universal` layout are checked — the latter is what VS Code | ||
| * Insiders' staged-install builds use (see microsoft/vscode#252063). | ||
| * | ||
| * Returns `undefined` when ripgrep cannot be located. | ||
| */ | ||
| export async function getBinPath(vscodeAppRoot: string): Promise<string | undefined> { | ||
| const checkPath = async (pkgFolder: string) => { | ||
|
|
@@ -92,7 +103,9 @@ export async function getBinPath(vscodeAppRoot: string): Promise<string | undefi | |
| (await checkPath("node_modules/@vscode/ripgrep/bin/")) || | ||
| (await checkPath("node_modules/vscode-ripgrep/bin")) || | ||
| (await checkPath("node_modules.asar.unpacked/vscode-ripgrep/bin/")) || | ||
| (await checkPath("node_modules.asar.unpacked/@vscode/ripgrep/bin/")) | ||
| (await checkPath("node_modules.asar.unpacked/@vscode/ripgrep/bin/")) || | ||
| (await checkPath(`node_modules/@vscode/ripgrep-universal/${ripgrepUniversalBinDir}`)) || | ||
| (await checkPath(`node_modules.asar.unpacked/@vscode/ripgrep-universal/${ripgrepUniversalBinDir}`)) | ||
| ) | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a test that verifies probe priority — e.g. that when both classic and universal paths exist, the classic one wins? The waterfall ordering in
getBinPathis load-bearing, but nothing currently asserts which path is returned when more than onefileExistsAtPathcall would returntrue.