Skip to content

Commit

Permalink
Merge pull request #3 from jarxorg/improve-glob
Browse files Browse the repository at this point in the history
Improve glob
  • Loading branch information
mojatter authored Sep 18, 2023
2 parents d100766 + 156e91a commit 744d232
Show file tree
Hide file tree
Showing 7 changed files with 1,435 additions and 48 deletions.
26 changes: 17 additions & 9 deletions fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,27 +192,36 @@ func (fsys *GCSFS) Sub(dir string) (fs.FS, error) {
// Glob returns the names of all files matching pattern, providing an implementation
// of the top-level Glob function.
func (fsys *GCSFS) Glob(pattern string) ([]string, error) {
if _, err := path.Match(pattern, ""); err != nil {
return nil, err
}
c, err := fsys.client()
if err != nil {
return nil, err
}

query := newQuery("/", normalizePrefix(fsys.dir), "")
query := newQuery("", normalizePrefixPattern(fsys.dir, pattern), "")
it := c.bucket(fsys.bucket).objects(fsys.Context(), query)

var names []string
matchAppend := func(name string) error {
contains := func(name string) bool {
for _, n := range names {
if n == name {
return true
}
}
return false
}
appendIfMatch := func(name string) error {
ok, err := path.Match(pattern, name)
if err != nil {
return toPathError(err, "Glob", pattern)
}
if ok {
if ok && !contains(name) {
names = append(names, name)
}
return nil
}

lastDir := ""
for {
attrs, err := it.nextAttrs()
if err == iterator.Done {
Expand All @@ -226,13 +235,12 @@ func (fsys *GCSFS) Glob(pattern string) ([]string, error) {
name = strings.TrimSuffix(attrs.Prefix, "/")
}
name = fsys.rel(name)
if dir := path.Dir(name); dir != lastDir {
if err := matchAppend(dir); err != nil {
if dir := path.Dir(name); dir != "." {
if err := appendIfMatch(dir); err != nil {
return nil, err
}
lastDir = dir
}
if err := matchAppend(name); err != nil {
if err := appendIfMatch(name); err != nil {
return nil, err
}
}
Expand Down
4 changes: 3 additions & 1 deletion fs_integ_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build integtest
// +build integtest

package gcsfs
Expand All @@ -6,6 +7,7 @@ import (
"context"
"log"
"os"
"strings"
"testing"
"testing/fstest"

Expand All @@ -26,7 +28,7 @@ func TestFSIntegration(t *testing.T) {
log.Fatal(err)
}
fsys := New(bucket).WithClient(client).WithContext(ctx)
if err := fstest.TestFS(fsys, expected); err != nil {
if err := fstest.TestFS(fsys, strings.Split(expected, ",")...); err != nil {
t.Errorf("Error testing/fstest: %+v", err)
}
}
56 changes: 50 additions & 6 deletions fs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ package gcsfs

import (
"context"
"errors"
"io"
"io/fs"
"os"
"path"
"path/filepath"
"strings"
"syscall"
"testing"
"testing/fstest"

Expand Down Expand Up @@ -115,13 +120,43 @@ func (o *fsObjects) initAttrs() error {
return o.walkDir()
}

func (o *fsObjects) namePrefixes() (string, string, error) {
namePrefix := ""
prefix := o.query.Prefix
dirWithPrefix := path.Join(o.dir, prefix)
info, err := fs.Stat(o.fsys, dirWithPrefix)
if err != nil {
if !errors.Is(err, os.ErrNotExist) {
return "", "", err
}
if dirSlash := strings.LastIndex(prefix, "/"); dirSlash != -1 {
namePrefix = prefix[dirSlash+1:]
prefix = prefix[:dirSlash]
} else {
namePrefix = prefix
prefix = ""
}
} else if !info.IsDir() {
return "", "", &fs.PathError{Op: "readDir", Path: dirWithPrefix, Err: syscall.ENOTDIR}
}
return prefix, namePrefix, nil
}

func (o *fsObjects) readDir() error {
ds, err := fs.ReadDir(o.fsys, path.Join(o.dir, o.query.Prefix))
prefix, namePrefix, err := o.namePrefixes()
if err != nil {
return err
}

ds, err := fs.ReadDir(o.fsys, path.Join(o.dir, prefix))
if err != nil {
return toObjectNotExistIfNoExist(err)
}
for _, d := range ds {
name := path.Join(o.query.Prefix, d.Name())
name := path.Join(prefix, d.Name())
if !strings.HasPrefix(name, namePrefix) {
continue
}
if d.IsDir() {
name = name + "/"
}
Expand Down Expand Up @@ -151,16 +186,25 @@ func (o *fsObjects) readDir() error {
}

func (o *fsObjects) walkDir() error {
root := path.Join(o.dir, o.query.Prefix)
prefix, namePrefix, err := o.namePrefixes()
if err != nil {
return err
}

return fs.WalkDir(o.fsys, root, func(dir string, d fs.DirEntry, err error) error {
root := path.Join(o.dir, prefix)
namePrefix = path.Join(root, namePrefix)

return fs.WalkDir(o.fsys, root, func(name string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
name := path.Join(o.query.Prefix, d.Name())
if name == root {
if name == root || !strings.HasPrefix(name, namePrefix) {
return nil
}
name, err = filepath.Rel(o.dir, name)
if err != nil {
return err
}
if d.IsDir() {
name = name + "/"
}
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module github.com/jarxorg/gcsfs
go 1.16

require (
cloud.google.com/go/storage v1.18.2
github.com/jarxorg/io2 v0.4.0
github.com/jarxorg/wfs v0.3.0
google.golang.org/api v0.58.0
cloud.google.com/go/storage v1.33.0
github.com/jarxorg/io2 v0.7.1
github.com/jarxorg/wfs v0.3.2
google.golang.org/api v0.141.0
)
Loading

0 comments on commit 744d232

Please sign in to comment.