Skip to content

Commit

Permalink
refactor: separator et al
Browse files Browse the repository at this point in the history
Signed-off-by: Carlos Alexandro Becker <[email protected]>
  • Loading branch information
caarlos0 committed Nov 7, 2020
1 parent a65d8f9 commit 74616f9
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 36 deletions.
2 changes: 2 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package fileglob provides a filesystem glob API.
package fileglob
42 changes: 12 additions & 30 deletions glob.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/spf13/afero"
)

// FileSystem is meant to be used with WithFs.
type FileSystem afero.Fs

// globOptions allowed to be passed to Glob.
Expand All @@ -20,34 +21,23 @@ type globOptions struct {
// be treated just like a matching file. If set to false, a matching directory
// will auto-match all files inside instead of the directory itself.
matchDirectoriesDirectly bool

separator rune
}

type OptFunc func(opts *globOptions) error
type OptFunc func(opts *globOptions)

// WithFs allows to provide another afero.Fs implementation to Glob.
func WithFs(fs FileSystem) OptFunc {
return func(opts *globOptions) error {
return func(opts *globOptions) {
opts.fs = fs
return nil
}
}

// MatchDirectories determines weather a matching directory should
// result in only the folder name itself being returned (true) or
// in all files inside that folder being returned (false).
func MatchDirectories(v bool) OptFunc {
return func(opts *globOptions) error {
return func(opts *globOptions) {
opts.matchDirectoriesDirectly = v
return nil
}
}

func WithSeparator(sep rune) OptFunc {
return func(opts *globOptions) error {
opts.separator = sep
return nil
}
}

Expand All @@ -59,22 +49,18 @@ func QuoteMeta(pattern string) string {

// Glob returns all files that match the given pattern in the current directory.
func Glob(pattern string, opts ...OptFunc) ([]string, error) { // nolint:funlen
options, err := compileOptions(opts)
if err != nil {
return nil, fmt.Errorf("compile options: %w", err)
}

var options = compileOptions(opts)
pattern = strings.TrimPrefix(pattern, "./")

var fs = options.fs
var matches []string

matcher, err := glob.Compile(pattern, options.separator)
matcher, err := glob.Compile(pattern, filepath.Separator)
if err != nil {
return matches, fmt.Errorf("compile glob pattern: %w", err)
}

prefix, err := staticPrefix(pattern, options.separator)
prefix, err := staticPrefix(pattern)
if err != nil {
return nil, fmt.Errorf("cannot determine static prefix: %w", err)
}
Expand Down Expand Up @@ -131,20 +117,16 @@ func Glob(pattern string, opts ...OptFunc) ([]string, error) { // nolint:funlen
})
}

func compileOptions(optFuncs []OptFunc) (*globOptions, error) {
func compileOptions(optFuncs []OptFunc) *globOptions {
var opts = &globOptions{
fs: afero.NewOsFs(),
separator: filepath.Separator,
fs: afero.NewOsFs(),
}

for _, optFunc := range optFuncs {
err := optFunc(opts)
if err != nil {
return nil, fmt.Errorf("applying options: %w", err)
}
for _, apply := range optFuncs {
apply(opts)
}

return opts, nil
return opts
}

func filesInDirectory(fs afero.Fs, dir string) ([]string, error) {
Expand Down
19 changes: 19 additions & 0 deletions glob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,25 @@ func TestGlob(t *testing.T) { // nolint:funlen
"/a/c",
}, matches)
})

t.Run("pattern ending with star and subdir", func(t *testing.T) {
matches, err := Glob("a/*", WithFs(testFs(t, []string{
"./a/1.txt",
"./a/2.txt",
"./a/3.txt",
"./a/b/4.txt",
}, []string{
"a",
"a/b",
})))
require.NoError(t, err)
require.Equal(t, []string{
"a/1.txt",
"a/2.txt",
"a/3.txt",
"a/b/4.txt",
}, matches)
})
}

func TestQuoteMeta(t *testing.T) {
Expand Down
8 changes: 4 additions & 4 deletions prefix.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import (

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

prefix := ""
if len(pattern) > 0 && rune(pattern[0]) == separator {
prefix = string(separator)
if len(pattern) > 0 && rune(pattern[0]) == filepath.Separator {
prefix = string(filepath.Separator)
}

for _, part := range parts {
Expand Down
3 changes: 1 addition & 2 deletions prefix_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package fileglob

import (
"path/filepath"
"testing"
)

Expand All @@ -20,7 +19,7 @@ func TestStaticPrefix(t *testing.T) {
}

for _, testCase := range testCases {
prefix, err := staticPrefix(testCase.pattern, filepath.Separator)
prefix, err := staticPrefix(testCase.pattern)
if err != nil {
t.Errorf("staticPrefix: %v", err)
}
Expand Down

0 comments on commit 74616f9

Please sign in to comment.