You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Failing to find files on MemoryFileSystem (Windows) when running on Linux machine #1998
I was running unit tests which are including Glob(...).matches(...), and it fails to match files when the mock filesystem is Windows-style, and the actual machine OS is POSIX-style. Even passing fileSystem.path as the context to Glob(...) does not help. When I had a closer look I found that in case of **\*a*, the class constructor appends {,/**} to the pattern. And although this should not produce any harm, I believe, it is not working as expected. I suspect, the machine's directory separator is used instead of the one for the file system. The similar issue happens to Glob(...).listFileStsemSync(...).
Hit the mirror image of this in dart-lang/native#3555: a POSIX MemoryFileSystem on a Windows host. listFileSystem throws "Can't list glob ...; it matches posix paths, but this platform uses windows paths", because it compares the glob's style against the host platform rather than the file system it's passed. Passing fileSystem.path as the context doesn't help, same as reported here.
Net effect is that globbing a MemoryFileSystem isn't possible whenever the fake's style differs from the host, which blocks writing OS agnostic unit tests over an injected file system.
@natebosch this is package:glob, and I'd like to fix it. Here's what I found and what I'd propose, happy to be steered.
What's happening
The listing path never receives the glob's own context. ListTree is constructed in Glob._listTreeForFileSystem, so context is in scope, but list_tree.dart uses the platform globals throughout: it splits with p.context, calls p.isAbsolute, and then uses p.join and p.relative in every node listing branch, plus toPosixPath(p.context, ...) in the validator. The _ListTreeNodelist and listSync methods take dir and fileSystem but no context.
Matching is already correct. matchAsPrefix goes through context.isAbsolute, context.absolute, context.relative and toPosixPath(context, ...), so only listing is affected.
Separately, listFileSystem and listFileSystemSync guard by comparing the glob's style against the platform's, rather than against the file system they were handed.
What I'd change
Thread the glob's context into ListTree and its node listing methods, and use it in place of p.context, p.isAbsolute, p.join, p.relative and the toPosixPath argument. It's around 16 call sites, all mechanical.
Change the two guards to compare against fileSystem.path.style, which is the file system actually being listed.
Minor: in the ListTree factory there is a text.replaceAll('/', '\\') whose result is discarded, so it currently does nothing.
Compatibility
Globs built without an explicit context keep the platform context, so their listing behavior is unchanged.
list() and listSync() delegate to listFileSystem with const LocalFileSystem(), and LocalFileSystem.path is a plain p.Context, so the guard is the same check as today for local listing.
The cases this enables currently throw StateError, so nothing that works today starts behaving differently.
One change worth flagging honestly: a glob with the platform context listed over a file system of a different style passes the guard today and then silently produces wrong paths, for example joining with \ while walking a POSIX file system. With the guard comparing against the file system, that would throw a clear StateError instead. I think that is better than silent misbehavior, but it is a behavior change.
Tests
The suite has no MemoryFileSystem listing tests today, so I would add them as regression coverage.
The POSIX fake on a Windows host direction is the one I hit. For the direction reported here, a Windows style fake on a POSIX host, I will check how far it gets, since glob patterns use forward slashes and a Windows style MemoryFileSystem does not resolve a C:/ prefixed root, which looks like Differences in behaviour between real windows FS and Window-style in-memory FS #632 rather than a glob issue.
I can see that Glob has Glob.context and FileSystem has FileSystem.path that both gives a package:pathContext.
Their styles must agree for listFileSystem to work.
I agree that the listFileSystem compares the glob's context to the platform context, not the filesystem's context,
and the ListTree constructor used by listFileSystem also uses p.context directly from package:path. That's wrong. They should all use FileSystem.path.
Activity
bartekpacia commentedon May 23, 2023
I'm also encountering this issue.
Varadraj75 commentedon Aug 25, 2026
Hit the mirror image of this in dart-lang/native#3555: a POSIX MemoryFileSystem on a Windows host. listFileSystem throws "Can't list glob ...; it matches posix paths, but this platform uses windows paths", because it compares the glob's style against the host platform rather than the file system it's passed. Passing fileSystem.path as the context doesn't help, same as reported here.
Net effect is that globbing a MemoryFileSystem isn't possible whenever the fake's style differs from the host, which blocks writing OS agnostic unit tests over an injected file system.
Varadraj75 commentedon Aug 25, 2026
@natebosch this is
package:glob, and I'd like to fix it. Here's what I found and what I'd propose, happy to be steered.What's happening
ListTreeis constructed inGlob._listTreeForFileSystem, socontextis in scope, butlist_tree.dartuses the platform globals throughout: it splits withp.context, callsp.isAbsolute, and then usesp.joinandp.relativein every node listing branch, plustoPosixPath(p.context, ...)in the validator. The_ListTreeNodelistandlistSyncmethods takedirandfileSystembut no context.matchAsPrefixgoes throughcontext.isAbsolute,context.absolute,context.relativeandtoPosixPath(context, ...), so only listing is affected.listFileSystemandlistFileSystemSyncguard by comparing the glob's style against the platform's, rather than against the file system they were handed.What I'd change
ListTreeand its node listing methods, and use it in place ofp.context,p.isAbsolute,p.join,p.relativeand thetoPosixPathargument. It's around 16 call sites, all mechanical.fileSystem.path.style, which is the file system actually being listed.ListTreefactory there is atext.replaceAll('/', '\\')whose result is discarded, so it currently does nothing.Compatibility
list()andlistSync()delegate tolistFileSystemwithconst LocalFileSystem(), andLocalFileSystem.pathis a plainp.Context, so the guard is the same check as today for local listing.StateError, so nothing that works today starts behaving differently.\while walking a POSIX file system. With the guard comparing against the file system, that would throw a clearStateErrorinstead. I think that is better than silent misbehavior, but it is a behavior change.Tests
MemoryFileSystemlisting tests today, so I would add them as regression coverage.MemoryFileSystemdoes not resolve aC:/prefixed root, which looks like Differences in behaviour between real windows FS and Window-style in-memory FS #632 rather than a glob issue.Context for how I ran into this: dart-lang/native#3555 and dart-lang/native#3583, where
native_toolchain_cwants to run its tool resolvers over a mocked file system.Happy to open a PR if this direction sounds right.
lrhn commentedon Aug 26, 2026
I can see that
GlobhasGlob.contextandFileSystemhasFileSystem.paththat both gives apackage:pathContext.Their styles must agree for
listFileSystemto work.I agree that the
listFileSystemcompares the glob's context to the platform context, not the filesystem's context,and the
ListTreeconstructor used bylistFileSystemalso usesp.contextdirectly frompackage:path. That's wrong. They should all useFileSystem.path.