Skip to content

fix: handle Windows separators in recursive find paths#1255

Open
airforce000 wants to merge 1 commit into
shelljs:mainfrom
airforce000:fix-find-windows-path-join
Open

fix: handle Windows separators in recursive find paths#1255
airforce000 wants to merge 1 commit into
shelljs:mainfrom
airforce000:fix-find-windows-path-join

Conversation

@airforce000

Copy link
Copy Markdown

Summary

Fixes #1227.

This fixes recursive find()/ls -R behavior on Windows when the input path uses native backslash separators, such as a path created by path.join().

The underlying issue is in ls's recursive glob path construction. find() calls recursive ls() for directory contents, and on Windows a native path like project\source was being passed to fast-glob as a mixed-separator pattern:

project\source/**

fast-glob expects / separators in glob patterns, so the directory itself could be returned without the recursive contents. This patch normalizes the glob pattern to forward slashes on Windows before appending/using the recursive glob.

Why this approach

  • The fix is at the shared recursive ls() glob boundary, where the mixed-separator pattern is created.
  • It is Windows-only, so POSIX paths containing literal backslashes are not changed.
  • ShellJS already normalizes returned Windows path separators in ls()/find(), so this keeps the existing output behavior.
  • The change is limited to the recursive directory branch.

Test coverage

I added a regression test for shell.find(path.join('test', 'resources', 'find')). This is the case that creates native Windows backslashes and reproduces the issue.

There was an earlier closed PR (#1228) that added an absolute-path test, but it built the path with / separators and did not include an implementation fix. This test covers the failing Windows-native input shape.

Local verification

On Windows, before the fix, this minimal repro returned only the directory for path.join() input:

{"input":"project\\source","result":["project/source"],"length":1,"code":0}

After the fix, the same repro returns the nested file as expected:

{"input":"project\\source","result":["project/source","project/source/index.js"],"length":2,"code":0}

I also verified absolute Windows paths with backslashes recurse correctly.

Commands run locally:

npm test -- --match="simple path from path.join"
npx ava test/find.js --match="!*folder is symlinked*"
npx ava test/ls.js --match="!*link*" --match="!*symlink*"
npm run lint -- src/ls.js test/find.js
git diff --check

Note: the full test/find.js run on my Windows checkout hits the existing symlink fixture issue where test/resources/find/dir2_link is checked out as a plain file rather than a symlink, so I excluded only that unrelated symlink-specific assertion for the local Windows run.

@airforce000 airforce000 force-pushed the fix-find-windows-path-join branch from e6eafde to aa6bc28 Compare May 23, 2026 18:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

shelljs.find doesn't return contents of a dir on windows

1 participant