Skip to content

Commit 838fb91

Browse files
committed
fix: scope the bundled ripgrep path to platform and arch
The published VSIX is universal but copyRipgrep bundled only the build host's rg. Because rg (no extension) is the binary name on both Linux and macOS, a macOS user could resolve a Linux-built dist/bin/rg and execute an incompatible binary. Bundle and resolve the binary under dist/bin/<platform>-<arch>/ so the fallback is used only on a host matching the bundled binary.
1 parent 4b29feb commit 838fb91

4 files changed

Lines changed: 28 additions & 11 deletions

File tree

.github/workflows/marketplace-publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ jobs:
6363
grep -q "extension/webview-ui/build/assets/index.js" /tmp/zoo-code-vsix-contents.txt
6464
grep -q "extension/assets/codicons/codicon.ttf" /tmp/zoo-code-vsix-contents.txt
6565
grep -q "extension/assets/vscode-material-icons/icons/3d.svg" /tmp/zoo-code-vsix-contents.txt
66-
grep -q "extension/dist/bin/rg" /tmp/zoo-code-vsix-contents.txt
66+
grep -qE "extension/dist/bin/[^/]+/rg" /tmp/zoo-code-vsix-contents.txt
6767
6868
- name: Validate packaged manifest identity
6969
run: |

src/esbuild.mjs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,19 @@ async function main() {
8989
name: "copyRipgrep",
9090
setup(build) {
9191
build.onEnd(async () => {
92-
// Copy the ripgrep binary into dist/bin/ so it ships inside the
93-
// VSIX. getBinPath() in src/services/ripgrep/index.ts falls back
94-
// to this bundled copy when ripgrep cannot be located in the VS
95-
// Code installation (e.g. VS Code Insiders' staged-install layout).
92+
// Copy the ripgrep binary into dist/bin/<platform>-<arch>/ so it
93+
// ships inside the universal VSIX. getBinPath() in
94+
// src/services/ripgrep/index.ts falls back to this bundled copy
95+
// when ripgrep cannot be located in the VS Code installation
96+
// (e.g. VS Code Insiders' staged-install layout). The
97+
// <platform>-<arch> subfolder keeps the runtime fallback from
98+
// picking a binary built for a different OS (the name `rg` is
99+
// shared by Linux and macOS).
96100
const { rgPath } = await import("@vscode/ripgrep")
97101
if (!rgPath) {
98102
throw new Error("[copyRipgrep] @vscode/ripgrep did not provide rgPath")
99103
}
100-
const rgDestDir = path.join(distDir, "bin")
104+
const rgDestDir = path.join(distDir, "bin", `${process.platform}-${process.arch}`)
101105
fs.mkdirSync(rgDestDir, { recursive: true })
102106
const rgDest = path.join(rgDestDir, path.basename(rgPath))
103107
fs.copyFileSync(rgPath, rgDest)

src/services/ripgrep/__tests__/index.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,11 @@ describe("getBinPath bundled-ripgrep fallback", () => {
9292

9393
expect(result).toBeUndefined()
9494
})
95+
96+
it("scopes the bundled ripgrep path to the current platform and arch", () => {
97+
// Guards the universal VSIX from handing a wrong-OS binary to the
98+
// fallback: the path must carry a <platform>-<arch> segment so a
99+
// macOS host never resolves a Linux-built `dist/bin/rg`.
100+
expect(bundledRgPath).toContain(path.join("bin", `${process.platform}-${process.arch}`))
101+
})
95102
})

src/services/ripgrep/index.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,18 @@ export function truncateLine(line: string, maxLength: number = MAX_LINE_LENGTH):
8282
/**
8383
* Path to the ripgrep binary bundled inside the extension itself.
8484
*
85-
* esbuild copies the platform `rg`/`rg.exe` into `dist/bin/` at build time
86-
* (see the `copyRipgrep` plugin in esbuild.mjs). At runtime this module is
87-
* bundled into `dist/extension.js`, so `__dirname` is the extension's `dist/`
88-
* directory.
85+
* esbuild copies the platform `rg`/`rg.exe` into `dist/bin/<platform>-<arch>/`
86+
* at build time (see the `copyRipgrep` plugin in esbuild.mjs). At runtime this
87+
* module is bundled into `dist/extension.js`, so `__dirname` is the extension's
88+
* `dist/` directory.
89+
*
90+
* The `<platform>-<arch>` segment is required: the published VSIX is universal
91+
* but carries only the build host's binary. Without it, a macOS user would
92+
* resolve a Linux-built `dist/bin/rg` (the binary name `rg` is shared by Linux
93+
* and macOS) and execute an incompatible binary. With it, the fallback resolves
94+
* only on a host matching the bundled binary.
8995
*/
90-
export const bundledRgPath = path.join(__dirname, "bin", binName)
96+
export const bundledRgPath = path.join(__dirname, "bin", `${process.platform}-${process.arch}`, binName)
9197

9298
/**
9399
* Get the path to the ripgrep binary.

0 commit comments

Comments
 (0)