Skip to content

DrJosh9000/zzglob

Repository files navigation

zzglob

Go Reference Build status

A better glob library for Go

Goals

  • ✅ Glob in a deterministic order, like fs.WalkDir.
  • ✅ Support the classics like ? and *, and also modern conveniences like **, {x,y,z}, [abc], and [^abc].
  • ✅ Expand ~ to the current user's homedir.
  • ✅ Optionally traverse directory symlinks.
  • ✅ Avoid walking directories unnecessarily - globbing foo*/bar should only walk inside directories starting with foo, not other directories.
  • ✅ Pass walk errors (e.g. permissions errors) to the callback.
  • ✅ Supports globbing over any io.FS, not just the host filesystem.
  • ✅ Supports globbing on Windows with Windows-style paths, by default.

Also the implementation shouldn't be totally inscrutable. It is based on a state machine, and I have attempted to cleanly separate each parsing phase. You can convert a pattern to GraphViz format, that you can then convert into a diagram, by calling Pattern.WriteDot. zzglob includes a tool called zzdot which can do this for you, e.g.:

go run ./cmd/zzdot '[abcd]{*g,h*,i/j}/**/k' | dot -Tsvg > example.svg

Example.svg

In progress

Pattern syntax

  • \ - used to escape the next character in the pattern. \x matches x, \* matches *.
  • / - the path separator. Separates segments of each path. Matches itself only.
  • ? - matches exactly one character, except for /.
  • * - matches zero or more characters, except for /.
  • ** - matches zero or more characters, including /. Since it can be used to mean zero or more path components, /**/ also matches /.
  • {a,b,c} - matches a or b or c. A component can be empty, e.g. {,a,b} matches either nothing or a or b. Multiple path segments, *, **, etc are all allowed within {}. To specify a path containing , within {}, escape it (\,).
  • [abc] - matches a single character (a or b or c). [] is a shorter way to write a match for a single character than {}.
  • ~ - is expanded to be current user's home directory.

Each syntax element can be enabled or disabled individually when calling Parse, and the meaning of forward slash and backslash can be swapped (enabled by default on Windows):

pattern, err := zzglob.Parse(`C:\Windows\Media\*.mid`,
    zzglob.ExpandTilde(false),
    zzglob.SwapSlashes(true),
    zzglob.AllowEscaping(false),
)

Similarly, symlink traversal, slash conversion, and custom fs.FS can be supplied to Glob:

err := pattern.Glob(myWalkDirFunc,
    zzglob.TraverseSymlinks(false),
    zzglob.TranslateSlashes(true),
    zzglob.WithFilesystem(os.DirFS("/secrets/")),
)

About

A better glob for Go

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages