@@ -248,6 +248,7 @@ async function downloadAndExtract(): Promise<void> {
248248 rmSync ( tmpDir , { recursive : true , force : true } )
249249 }
250250 } else {
251+ let fflateError : unknown
251252 try {
252253 const { unzipSync } = await import ( 'fflate' )
253254 const unzipped = unzipSync ( new Uint8Array ( buffer ) )
@@ -256,20 +257,50 @@ async function downloadAndExtract(): Promise<void> {
256257 throw new Error ( `Binary ${ extractedBinary } not found in zip` )
257258 }
258259 writeFileSync ( binaryPath , Buffer . from ( unzipped [ key ] ) )
259- } catch {
260- // No fflate or bad archive — try `unzip` CLI (common on Unix / Git for Windows)
260+ fflateError = undefined
261+ } catch ( e ) {
262+ fflateError = e
263+ }
264+
265+ if ( fflateError ) {
266+ // fflate failed — try PowerShell Expand-Archive on Windows, then unzip CLI
261267 const tmpDir = path . join ( binaryDir , '.tmp-download' )
262268 rmSync ( tmpDir , { recursive : true , force : true } )
263269 mkdirSync ( tmpDir , { recursive : true } )
264270 try {
265271 const archivePath = path . join ( tmpDir , assetName )
266272 writeFileSync ( archivePath , buffer )
267- const result = spawnSync ( 'unzip' , [ '-o' , archivePath , '-d' , tmpDir ] , {
268- stdio : 'pipe' ,
269- } )
270- if ( result . status !== 0 ) {
271- throw new Error ( `unzip failed: ${ result . stderr ?. toString ( ) } ` )
273+
274+ let extracted = false
275+
276+ // On Windows, prefer PowerShell Expand-Archive
277+ if ( process . platform === 'win32' ) {
278+ const psCmd = `Expand-Archive -Path '${ archivePath . replace ( / ' / g, "''" ) } ' -DestinationPath '${ tmpDir . replace ( / ' / g, "''" ) } ' -Force`
279+ const psResult = spawnSync (
280+ 'powershell.exe' ,
281+ [ '-NoProfile' , '-NonInteractive' , '-ExecutionPolicy' , 'Bypass' , '-Command' , psCmd ] ,
282+ { stdio : 'pipe' , windowsHide : true } ,
283+ )
284+ if ( psResult . status === 0 ) {
285+ extracted = true
286+ } else {
287+ const psErr = psResult . stderr ?. toString ( ) . trim ( ) || 'unknown error'
288+ console . log ( `[ripgrep] PowerShell Expand-Archive failed: ${ psErr } ` )
289+ }
272290 }
291+
292+ // Fallback: unzip CLI (Git for Windows, MSYS2, or Unix)
293+ if ( ! extracted ) {
294+ const result = spawnSync ( 'unzip' , [ '-o' , archivePath , '-d' , tmpDir ] , {
295+ stdio : 'pipe' ,
296+ } )
297+ if ( result . status !== 0 ) {
298+ const unzipErr = result . stderr ?. toString ( ) . trim ( ) || 'command not found'
299+ const fflateMsg = fflateError instanceof Error ? fflateError . message : String ( fflateError )
300+ throw new Error ( `zip extraction failed (fflate: ${ fflateMsg } ; unzip: ${ unzipErr } )` )
301+ }
302+ }
303+
273304 const srcBinary = path . join ( tmpDir , extractedBinary )
274305 if ( ! existsSync ( srcBinary ) ) {
275306 throw new Error ( `Binary not found at expected path: ${ srcBinary } ` )
0 commit comments