Skip to content

fix(fs): walk does not apply exts filter to directories#7167

Open
LeSingh1 wants to merge 1 commit into
denoland:mainfrom
LeSingh1:fs-walk-exts-skip-dirs
Open

fix(fs): walk does not apply exts filter to directories#7167
LeSingh1 wants to merge 1 commit into
denoland:mainfrom
LeSingh1:fs-walk-exts-skip-dirs

Conversation

@LeSingh1
Copy link
Copy Markdown

Fixes #6736.

walk and walkSync ran the exts filter against the directory name in include() when deciding whether to yield a directory entry. Directories generally don't have file extensions, so any exts option effectively dropped every directory from the output, even with includeDirs:true (the default).

Repro before the patch:

import { walkSync } from "jsr:@std/fs/walk";
for (const e of walkSync("./project", { includeDirs: true, exts: ["ts"] })) {
  console.log(e.path, e.isDirectory ? "(dir)" : "(file)");
}
// only "*.ts" files - every directory is missing

After:

./project (dir)
./project/sub (dir)
./project/sub/b.ts (file)
./project/a.ts (file)

The fix passes undefined for exts in the includeDirs branch of both walk and walkSync. The match and skip regex filters still apply to directories. The !followSymlinks symlink emission branch is unchanged because a symlink's name still has an extension just like the target.

Tests:

  • Existing walk() / walkSync() accepts ext option as strings tests updated to include the root directory in the expected entries (the default includeDirs:true now actually yields it).
  • Two new tests pin the includeDirs:false case so the intent stays explicit.

All ext-related tests pass. The four pre-existing * regExps failures in fs/walk_test.ts reproduce on origin/main (verified by stashing the patch and re-running) so they're unrelated.

walk and walkSync's include() check ran the exts filter against the
directory name when deciding whether to yield a directory entry.
Directories generally don't have file extensions, so any `exts`
option effectively dropped every directory from the output, even when
includeDirs:true was set (the default).

Pass undefined for exts in the includeDirs branch so the filter only
applies to file entries. The match and skip regex filters still apply
to directories. Symlink emission (the !followSymlinks branch) is
unchanged because a symlink's name still has an extension just like
the file or directory it points to.

Existing 'walk() accepts ext option as strings' tests are updated to
include the root directory in the expected entries (default
includeDirs:true). Two new tests pin the includeDirs:false case so the
intent is explicit.

Fixes denoland#6736
@github-actions github-actions Bot added the fs label May 30, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.57%. Comparing base (cdf74a8) to head (9fc18f1).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7167   +/-   ##
=======================================
  Coverage   94.57%   94.57%           
=======================================
  Files         636      636           
  Lines       52142    52142           
  Branches     9401     9401           
=======================================
  Hits        49315    49315           
  Misses       2249     2249           
  Partials      578      578           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fs/walk do not include folders if exts option is given

1 participant