From bc99a1e2cb1fe9f3eaf69bdb36b31056f750f931 Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Tue, 10 Mar 2026 16:42:11 -0700 Subject: [PATCH] Filter gitignored files from discovery --- src/cli/index.ts | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/cli/index.ts b/src/cli/index.ts index 0bbc63b..336fba4 100755 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -12,8 +12,26 @@ import type { TestResult } from "../format.ts" import { parseDuration } from "../duration.ts" import { rewriteFile } from "../update.ts" +async function filterGitignored(files: string[]): Promise { + if (files.length === 0) return files + try { + const proc = Bun.spawn(["git", "check-ignore", "--stdin"], { + stdin: new Blob([files.join("\n")]), + stdout: "pipe", + stderr: "ignore", + }) + const output = await new Response(proc.stdout).text() + await proc.exited + const ignored = new Set(output.trim().split("\n").filter(Boolean)) + return files.filter(f => !ignored.has(f)) + } catch { + return files + } +} + async function findShoutFiles(paths: string[]): Promise { - const files: string[] = [] + const explicit: string[] = [] + const discovered: string[] = [] for (const p of paths) { const abs = resolve(p) @@ -22,7 +40,7 @@ async function findShoutFiles(paths: string[]): Promise { : null if (stat && abs.endsWith(".shout")) { - files.push(abs) + explicit.push(abs) continue } @@ -31,16 +49,17 @@ async function findShoutFiles(paths: string[]): Promise { const entries = await readdir(abs, { recursive: true }) for (const entry of entries) { if (entry.endsWith(".shout")) { - files.push(resolve(abs, entry)) + discovered.push(resolve(abs, entry)) } } } catch { // If not a directory, try as file anyway - if (abs.endsWith(".shout")) files.push(abs) + if (abs.endsWith(".shout")) explicit.push(abs) } } - return files.sort() + const filtered = await filterGitignored(discovered) + return [...explicit, ...filtered].sort() } import pkg from "../../package.json"