1+ import { createRequire } from "module"
2+ import { dirname , join } from "path"
13import { existsSync , statSync } from "fs"
24import { getCachedBinaryPath } from "./downloader"
35
6+ type Platform = "darwin" | "linux" | "win32" | "unsupported"
7+
48function 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+
1233export 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