| 206 | } |
| 207 | |
| 208 | export async function* files(input: { cwd: string; glob?: string[] }) { |
| 209 | const args = [await filepath(), "--files", "--follow", "--hidden", "--glob=!.git/*"] |
| 210 | if (input.glob) { |
| 211 | for (const g of input.glob) { |
| 212 | args.push(`--glob=${g}`) |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | // Bun.spawn should throw this, but it incorrectly reports that the executable does not exist. |
| 217 | // See https://github.com/oven-sh/bun/issues/24012 |
| 218 | if (!(await fs.stat(input.cwd).catch(() => undefined))?.isDirectory()) { |
| 219 | throw Object.assign(new Error(`No such file or directory: '${input.cwd}'`), { |
| 220 | code: "ENOENT", |
| 221 | errno: -2, |
| 222 | path: input.cwd, |
| 223 | }) |
| 224 | } |
| 225 | |
| 226 | const proc = Bun.spawn(args, { |
| 227 | cwd: input.cwd, |
| 228 | stdout: "pipe", |
| 229 | stderr: "ignore", |
| 230 | maxBuffer: 1024 * 1024 * 20, |
| 231 | }) |
| 232 | |
| 233 | const reader = proc.stdout.getReader() |
| 234 | const decoder = new TextDecoder() |
| 235 | let buffer = "" |
| 236 | |
| 237 | try { |
| 238 | while (true) { |
| 239 | const { done, value } = await reader.read() |
| 240 | if (done) break |
| 241 | |
| 242 | buffer += decoder.decode(value, { stream: true }) |
| 243 | const lines = buffer.split("\n") |
| 244 | buffer = lines.pop() || "" |
| 245 | |
| 246 | for (const line of lines) { |
| 247 | if (line) yield line |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | if (buffer) yield buffer |
| 252 | } finally { |
| 253 | reader.releaseLock() |
| 254 | await proc.exited |
| 255 | } |
| 256 | } |
| 257 | |
| 258 | export async function tree(input: { cwd: string; limit?: number }) { |
| 259 | log.info("tree", input) |