Skip to content

Implement fs.glob, fs.globSync, and fs/promises.glob#6378

Merged
jasnell merged 7 commits intocloudflare:mainfrom
fraidev:feat/implement-fs-glob
Mar 27, 2026
Merged

Implement fs.glob, fs.globSync, and fs/promises.glob#6378
jasnell merged 7 commits intocloudflare:mainfrom
fraidev:feat/implement-fs-glob

Conversation

@fraidev
Copy link
Copy Markdown
Contributor

@fraidev fraidev commented Mar 22, 2026

Implements the Node.js fs.glob APIs that were previously stubbed with ERR_UNSUPPORTED_OPERATION. Uses a custom glob-to-regex pattern matcher.

Closes #5416

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 22, 2026

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@fraidev
Copy link
Copy Markdown
Contributor Author

fraidev commented Mar 22, 2026

I have read the CLA Document and I hereby sign the CLA

github-actions bot added a commit that referenced this pull request Mar 22, 2026
@jasnell
Copy link
Copy Markdown
Collaborator

jasnell commented Mar 23, 2026

Hey @fraidev! thank you for this! I've done a first pass look over and have asked the AI agent to review also.. it should post it's findings in a moment. How closely does this follow the node.js implementation? (I haven't looked at it in a while) Is it a straight up port of the original or did you reimplement? The main reason I ask is that if it is a straight port over, we might need to carry over the Node.js copyright/license detail in the header of the new file(s).

Copy link
Copy Markdown
Collaborator

@jasnell jasnell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Note: This review was generated by an AI assistant (Claude) and may contain inaccuracies. Please evaluate each suggestion on its merits.

Findings (6):

  • [HIGH] exclude type handling — unsafe cast in compileExclude when exclude is a user function
  • [MEDIUM] ** in middle of exclude pattern doesn't match zero segments (a/**/b won't match a/b)
  • [MEDIUM] walkGlob has unbounded recursion depth — no depth guard
  • [MEDIUM] Non-null assertions (!) used extensively — violates ts-style convention
  • [MEDIUM] Missing callback guard in fs.glob — throws when callback omitted
  • [LOW] Copyright year says 2017-2022 in new file

@fraidev
Copy link
Copy Markdown
Contributor Author

fraidev commented Mar 24, 2026

Hey @fraidev! thank you for this! I've done a first pass look over and have asked the AI agent to review also.. it should post it's findings in a moment. How closely does this follow the node.js implementation? (I haven't looked at it in a while) Is it a straight up port of the original or did you reimplement? The main reason I ask is that if it is a straight port over, we might need to carry over the Node.js copyright/license detail in the header of the new file(s).

Hey @jasnell! This is a reimplementation, not a port. Node.js uses minimatch internally, which isn't available in the Workers runtime, so I built glob-to-regex to convert and pattern-driven directory walker from scratch.
The test patterns and fixture structure are derived from Node.js's test-fs-glob.mjs to verify compatibility, but the implementation shares no code with Node.js.

@fraidev
Copy link
Copy Markdown
Contributor Author

fraidev commented Mar 24, 2026

@jasnell is there a way to run CI for a non-Cloudflare member?

@fraidev fraidev requested a review from jasnell March 24, 2026 00:08
@fraidev fraidev changed the title Feat/implement fs glob Implement fs.glob, fs.globSync, and fs/promises.glob Mar 24, 2026
@jasnell
Copy link
Copy Markdown
Collaborator

jasnell commented Mar 24, 2026

Just did. Internal_build will fail but I'll run that one manually

@fraidev
Copy link
Copy Markdown
Contributor Author

fraidev commented Mar 24, 2026

Just did. Internal_build will fail but I'll run that one manually

Great! I fixed ESLint errors. I think that we need one more run.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Mar 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.79%. Comparing base (a9fc5bb) to head (f726828).
⚠️ Report is 9 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff            @@
##             main    #6378    +/-   ##
========================================
  Coverage   70.79%   70.79%            
========================================
  Files         427      427            
  Lines      117724   117869   +145     
  Branches    18909    18935    +26     
========================================
+ Hits        83338    83446   +108     
- Misses      23132    23154    +22     
- Partials    11254    11269    +15     

☔ 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.

@fraidev fraidev marked this pull request as ready for review March 24, 2026 18:49
@fraidev fraidev requested review from a team as code owners March 24, 2026 18:49
@fraidev
Copy link
Copy Markdown
Contributor Author

fraidev commented Mar 26, 2026

Hi @jasnell, this PR is ready for another review. It was passing all tests (except Internal_build).
I just added a new commit to fix merge conflicts.

@jasnell
Copy link
Copy Markdown
Collaborator

jasnell commented Mar 26, 2026

@fraidev ... yeah, I'm just a bit backlogged on a number of PR review items. I've got this on my agenda to fully review either later today or tomorrow

@jasnell
Copy link
Copy Markdown
Collaborator

jasnell commented Mar 26, 2026

@fraidev ... can I ask you to remove the merge commit and instead rebase on main? Additional review comments coming shortly.

Copy link
Copy Markdown
Collaborator

@jasnell jasnell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correctness & Performance Analysis

Note: This review was generated by an AI assistant (Claude) and may contain inaccuracies. Please evaluate each suggestion on its merits.

Findings (5):

  • [MEDIUM] splitTopLevel lost backslash escape handling when converting to for...of
  • [MEDIUM] segmentToRegexStr doesn't escape { and } — patterns like a{3} silently produce wrong matches
  • [HIGH] .. traversal guard uses length comparison instead of prefix check
  • [MEDIUM] Consecutive ** segments not collapsed — potential exponential blowup
  • [MEDIUM] segmentToRegex recompiled on every recursive walkGlob call


// Handle '..' — go up one directory (but don't escape cwd)
if (seg === '..') {
if (currentAbsPath === cwd || currentAbsPath.length <= cwd.length) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[HIGH] The length comparison currentAbsPath.length <= cwd.length is not a safe containment check. While it works today because currentAbsPath is always built by appending to cwd, it's brittle — it would silently do the wrong thing if the code were refactored to allow other path construction.

Consider using a prefix check instead:

Suggested change
if (currentAbsPath === cwd || currentAbsPath.length <= cwd.length) {
if (currentAbsPath === cwd || !currentAbsPath.startsWith(cwd + '/')) {

Copy link
Copy Markdown
Contributor Author

@fraidev fraidev Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced currentAbsPath.length <= cwd.length with !currentAbsPath.startsWith(cwd + '/')

fraidev added 6 commits March 26, 2026 17:49
Implements the Node.js fs.glob APIs that were previously stubbed with
ERR_UNSUPPORTED_OPERATION. Uses a custom glob-to-regex pattern matcher
instead of the minimatch library which is unavailable in the Workers
runtime.

Closes cloudflare#5416
@fraidev fraidev force-pushed the feat/implement-fs-glob branch from 756e1b9 to 97e8aa8 Compare March 26, 2026 21:27
@fraidev
Copy link
Copy Markdown
Contributor Author

fraidev commented Mar 26, 2026

@fraidev ... can I ask you to remove the merge commit and instead rebase on main? Additional review comments coming shortly.

Sure, done

@jasnell
Copy link
Copy Markdown
Collaborator

jasnell commented Mar 27, 2026

Not quite sure what's happening with the CI right now. I'll try to run it again tomorrow and hopefully the issues are transient.

@fraidev
Copy link
Copy Markdown
Contributor Author

fraidev commented Mar 27, 2026

Not quite sure what's happening with the CI right now. I'll try to run it again tomorrow and hopefully the issues are transient.

oh, I think it's just lint. I think I fixed it

@codspeed-hq

This comment was marked as outdated.

@jasnell
Copy link
Copy Markdown
Collaborator

jasnell commented Mar 27, 2026

Manual testing on the internal-build is green. Merging! Thank you @fraidev !

@jasnell jasnell merged commit 47f5816 into cloudflare:main Mar 27, 2026
17 of 18 checks passed
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.

nodejs compat: implement fs.glob

3 participants