fix: improve glob tool Windows compatibility and rg resolution (#309)
This commit is contained in:
+57
-9
@@ -1,6 +1,7 @@
|
||||
import { spawn } from "bun"
|
||||
import {
|
||||
resolveGrepCli,
|
||||
type GrepBackend,
|
||||
DEFAULT_TIMEOUT_MS,
|
||||
DEFAULT_LIMIT,
|
||||
DEFAULT_MAX_DEPTH,
|
||||
@@ -10,6 +11,11 @@ import {
|
||||
import type { GlobOptions, GlobResult, FileMatch } from "./types"
|
||||
import { stat } from "node:fs/promises"
|
||||
|
||||
export interface ResolvedCli {
|
||||
path: string
|
||||
backend: GrepBackend
|
||||
}
|
||||
|
||||
function buildRgArgs(options: GlobOptions): string[] {
|
||||
const args: string[] = [
|
||||
...RG_FILES_FLAGS,
|
||||
@@ -40,6 +46,25 @@ function buildFindArgs(options: GlobOptions): string[] {
|
||||
return args
|
||||
}
|
||||
|
||||
function buildPowerShellCommand(options: GlobOptions): string[] {
|
||||
const maxDepth = Math.min(options.maxDepth ?? DEFAULT_MAX_DEPTH, DEFAULT_MAX_DEPTH)
|
||||
const paths = options.paths?.length ? options.paths : ["."]
|
||||
const searchPath = paths[0] || "."
|
||||
|
||||
const escapedPath = searchPath.replace(/'/g, "''")
|
||||
const escapedPattern = options.pattern.replace(/'/g, "''")
|
||||
|
||||
let psCommand = `Get-ChildItem -Path '${escapedPath}' -File -Recurse -Depth ${maxDepth - 1} -Filter '${escapedPattern}'`
|
||||
|
||||
if (options.hidden) {
|
||||
psCommand += " -Force"
|
||||
}
|
||||
|
||||
psCommand += " -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName"
|
||||
|
||||
return ["powershell", "-NoProfile", "-Command", psCommand]
|
||||
}
|
||||
|
||||
async function getFileMtime(filePath: string): Promise<number> {
|
||||
try {
|
||||
const stats = await stat(filePath)
|
||||
@@ -49,25 +74,40 @@ async function getFileMtime(filePath: string): Promise<number> {
|
||||
}
|
||||
}
|
||||
|
||||
export async function runRgFiles(options: GlobOptions): Promise<GlobResult> {
|
||||
const cli = resolveGrepCli()
|
||||
export async function runRgFiles(
|
||||
options: GlobOptions,
|
||||
resolvedCli?: ResolvedCli
|
||||
): Promise<GlobResult> {
|
||||
const cli = resolvedCli ?? resolveGrepCli()
|
||||
const timeout = Math.min(options.timeout ?? DEFAULT_TIMEOUT_MS, DEFAULT_TIMEOUT_MS)
|
||||
const limit = Math.min(options.limit ?? DEFAULT_LIMIT, DEFAULT_LIMIT)
|
||||
|
||||
const isRg = cli.backend === "rg"
|
||||
const args = isRg ? buildRgArgs(options) : buildFindArgs(options)
|
||||
const isWindows = process.platform === "win32"
|
||||
|
||||
let command: string[]
|
||||
let cwd: string | undefined
|
||||
|
||||
const paths = options.paths?.length ? options.paths : ["."]
|
||||
if (isRg) {
|
||||
const args = buildRgArgs(options)
|
||||
const paths = options.paths?.length ? options.paths : ["."]
|
||||
args.push(...paths)
|
||||
command = [cli.path, ...args]
|
||||
cwd = undefined
|
||||
} else if (isWindows) {
|
||||
command = buildPowerShellCommand(options)
|
||||
cwd = undefined
|
||||
} else {
|
||||
const args = buildFindArgs(options)
|
||||
const paths = options.paths?.length ? options.paths : ["."]
|
||||
cwd = paths[0] || "."
|
||||
command = [cli.path, ...args]
|
||||
}
|
||||
|
||||
const cwd = paths[0] || "."
|
||||
|
||||
const proc = spawn([cli.path, ...args], {
|
||||
const proc = spawn(command, {
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
cwd: isRg ? undefined : cwd,
|
||||
cwd,
|
||||
})
|
||||
|
||||
const timeoutPromise = new Promise<never>((_, reject) => {
|
||||
@@ -106,7 +146,15 @@ export async function runRgFiles(options: GlobOptions): Promise<GlobResult> {
|
||||
break
|
||||
}
|
||||
|
||||
const filePath = isRg ? line : `${cwd}/${line}`
|
||||
let filePath: string
|
||||
if (isRg) {
|
||||
filePath = line
|
||||
} else if (isWindows) {
|
||||
filePath = line.trim()
|
||||
} else {
|
||||
filePath = `${cwd}/${line}`
|
||||
}
|
||||
|
||||
const mtime = await getFileMtime(filePath)
|
||||
files.push({ path: filePath, mtime })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user