Skip to content

Commit

Permalink
feat: Initial file walking glob implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
erikgeiser committed Nov 6, 2020
1 parent 89a42fa commit 6f18a39
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 8 deletions.
81 changes: 73 additions & 8 deletions glob.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package zglob

import (
"fmt"
"os"
"strings"
"path"

"github.com/gobwas/glob"
"github.com/spf13/afero"
Expand All @@ -14,14 +15,78 @@ func Glob(pattern string) ([]string, error) {

func GlobWithFs(fs afero.Fs, pattern string) ([]string, error) {
var matches []string
g, err := glob.Compile(strings.TrimPrefix(pattern, "./"), '/')

matcher, err := glob.Compile(pattern)
if err != nil {
return matches, err
}
return matches, afero.Walk(fs, ".", func(path string, info os.FileInfo, err error) error {
if g.Match(path) {
matches = append(matches, path)
}
return nil
})

prefix, err := staticPrefix(pattern)
if err != nil {
return nil, fmt.Errorf("determine static prefix: %w", err)
}

prefixInfo, err := os.Stat(prefix)
if os.IsNotExist(err) {
// if the prefix does not exist, the whole
// glob pattern won't match anything
return []string{}, nil
} else if err != nil {
return nil, fmt.Errorf("stat prefix: %w", err)
}

if !prefixInfo.IsDir() {
// if the prefix is a file, it either has to be
// the only match, or nothing matches at all
if matcher.Match(prefix) {
return []string{prefix}, nil
}

return []string{}, nil
}

return matches, afero.Walk(fs, prefix, func(currentPath string, info os.FileInfo,
err error) error {
if err != nil {
return err
}

if !matcher.Match(info.Name()) {
return nil
}

if info.IsDir() {
// a direct match on a directory implies that all files inside match
filesInDir, err := filesInDirectory(fs, path.Join(currentPath, info.Name()))
if err != nil {
return err
}

matches = append(matches, filesInDir...)
} else {
matches = append(matches, path.Join(currentPath, info.Name()))
}

return nil
})
}

func filesInDirectory(fs afero.Fs, dir string) ([]string, error) {
files := []string{}

err := afero.Walk(fs, dir, func(currentPath string, info os.FileInfo, err error) error {
if err != nil {
return err
}

if info.IsDir() {
return nil
}

files = append(files, path.Join(currentPath, info.Name()))

return nil
})

return files, err
}
2 changes: 2 additions & 0 deletions prefix.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"github.com/gobwas/glob/syntax/lexer"
)

// staticPrefix returns the filepath up to the
// first path element that contains a wildcard.
func staticPrefix(pattern string) (string, error) {
parts := strings.Split(pattern, string(filepath.Separator))

Expand Down

0 comments on commit 6f18a39

Please sign in to comment.