Skip to content

Commit 3bcb869

Browse files
committed
fix(ast-grep): add isValidBinary check to all path resolutions
- Check file size >10KB to filter out placeholder files - Check cached binary first - Then npm package paths with validation - Homebrew paths as last resort - Fixes SIGTRAP/ENOEXEC from invalid binaries
1 parent 54e13e4 commit 3bcb869

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

src/tools/ast-grep/constants.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
import { createRequire } from "module"
2+
import { dirname, join } from "path"
13
import { existsSync, statSync } from "fs"
24
import { getCachedBinaryPath } from "./downloader"
35

6+
type Platform = "darwin" | "linux" | "win32" | "unsupported"
7+
48
function isValidBinary(filePath: string): boolean {
59
try {
610
return statSync(filePath).size > 10000
@@ -9,12 +13,70 @@ function isValidBinary(filePath: string): boolean {
913
}
1014
}
1115

16+
function getPlatformPackageName(): string | null {
17+
const platform = process.platform as Platform
18+
const arch = process.arch
19+
20+
const platformMap: Record<string, string> = {
21+
"darwin-arm64": "@ast-grep/cli-darwin-arm64",
22+
"darwin-x64": "@ast-grep/cli-darwin-x64",
23+
"linux-arm64": "@ast-grep/cli-linux-arm64-gnu",
24+
"linux-x64": "@ast-grep/cli-linux-x64-gnu",
25+
"win32-x64": "@ast-grep/cli-win32-x64-msvc",
26+
"win32-arm64": "@ast-grep/cli-win32-arm64-msvc",
27+
"win32-ia32": "@ast-grep/cli-win32-ia32-msvc",
28+
}
29+
30+
return platformMap[`${platform}-${arch}`] ?? null
31+
}
32+
1233
export function findSgCliPathSync(): string | null {
34+
const binaryName = process.platform === "win32" ? "sg.exe" : "sg"
35+
1336
const cachedPath = getCachedBinaryPath()
1437
if (cachedPath && isValidBinary(cachedPath)) {
1538
return cachedPath
1639
}
1740

41+
try {
42+
const require = createRequire(import.meta.url)
43+
const cliPkgPath = require.resolve("@ast-grep/cli/package.json")
44+
const cliDir = dirname(cliPkgPath)
45+
const sgPath = join(cliDir, binaryName)
46+
47+
if (existsSync(sgPath) && isValidBinary(sgPath)) {
48+
return sgPath
49+
}
50+
} catch {
51+
// @ast-grep/cli not installed
52+
}
53+
54+
const platformPkg = getPlatformPackageName()
55+
if (platformPkg) {
56+
try {
57+
const require = createRequire(import.meta.url)
58+
const pkgPath = require.resolve(`${platformPkg}/package.json`)
59+
const pkgDir = dirname(pkgPath)
60+
const astGrepName = process.platform === "win32" ? "ast-grep.exe" : "ast-grep"
61+
const binaryPath = join(pkgDir, astGrepName)
62+
63+
if (existsSync(binaryPath) && isValidBinary(binaryPath)) {
64+
return binaryPath
65+
}
66+
} catch {
67+
// Platform-specific package not installed
68+
}
69+
}
70+
71+
if (process.platform === "darwin") {
72+
const homebrewPaths = ["/opt/homebrew/bin/sg", "/usr/local/bin/sg"]
73+
for (const path of homebrewPaths) {
74+
if (existsSync(path) && isValidBinary(path)) {
75+
return path
76+
}
77+
}
78+
}
79+
1880
return null
1981
}
2082

0 commit comments

Comments
 (0)