fix(ast-grep): validate binary before using, prioritize homebrew path
- Add isValidBinary() check: file must be >10KB (placeholder files are ~100 bytes) - Check homebrew paths first on macOS (most reliable) - Check cached binary second - npm package paths last (prone to placeholder issues) Fixes ENOEXEC error when @ast-grep/cli has placeholder instead of real binary
This commit is contained in:
@@ -22,16 +22,39 @@ function getPlatformPackageName(): string | null {
|
|||||||
return platformMap[`${platform}-${arch}`] ?? null
|
return platformMap[`${platform}-${arch}`] ?? null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isValidBinary(filePath: string): boolean {
|
||||||
|
try {
|
||||||
|
const stats = require("fs").statSync(filePath)
|
||||||
|
return stats.size > 10000
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function findSgCliPathSync(): string | null {
|
export function findSgCliPathSync(): string | null {
|
||||||
const binaryName = process.platform === "win32" ? "sg.exe" : "sg"
|
const binaryName = process.platform === "win32" ? "sg.exe" : "sg"
|
||||||
|
|
||||||
|
if (process.platform === "darwin") {
|
||||||
|
const homebrewPaths = ["/opt/homebrew/bin/sg", "/usr/local/bin/sg"]
|
||||||
|
for (const path of homebrewPaths) {
|
||||||
|
if (existsSync(path) && isValidBinary(path)) {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cachedPath = getCachedBinaryPath()
|
||||||
|
if (cachedPath && isValidBinary(cachedPath)) {
|
||||||
|
return cachedPath
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const require = createRequire(import.meta.url)
|
const require = createRequire(import.meta.url)
|
||||||
const cliPkgPath = require.resolve("@ast-grep/cli/package.json")
|
const cliPkgPath = require.resolve("@ast-grep/cli/package.json")
|
||||||
const cliDir = dirname(cliPkgPath)
|
const cliDir = dirname(cliPkgPath)
|
||||||
const sgPath = join(cliDir, binaryName)
|
const sgPath = join(cliDir, binaryName)
|
||||||
|
|
||||||
if (existsSync(sgPath)) {
|
if (existsSync(sgPath) && isValidBinary(sgPath)) {
|
||||||
return sgPath
|
return sgPath
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
@@ -47,7 +70,7 @@ export function findSgCliPathSync(): string | null {
|
|||||||
const astGrepName = process.platform === "win32" ? "ast-grep.exe" : "ast-grep"
|
const astGrepName = process.platform === "win32" ? "ast-grep.exe" : "ast-grep"
|
||||||
const binaryPath = join(pkgDir, astGrepName)
|
const binaryPath = join(pkgDir, astGrepName)
|
||||||
|
|
||||||
if (existsSync(binaryPath)) {
|
if (existsSync(binaryPath) && isValidBinary(binaryPath)) {
|
||||||
return binaryPath
|
return binaryPath
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
@@ -55,20 +78,6 @@ export function findSgCliPathSync(): string | null {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.platform === "darwin") {
|
|
||||||
const homebrewPaths = ["/opt/homebrew/bin/sg", "/usr/local/bin/sg"]
|
|
||||||
for (const path of homebrewPaths) {
|
|
||||||
if (existsSync(path)) {
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const cachedPath = getCachedBinaryPath()
|
|
||||||
if (cachedPath) {
|
|
||||||
return cachedPath
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user