Skip to content

Commit

Permalink
optimize glopping
Browse files Browse the repository at this point in the history
  • Loading branch information
Equanox committed Jan 2, 2023
1 parent 7957a21 commit 407b583
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 6 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ require (
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 // indirect
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bmatcuk/doublestar v1.3.4 // indirect
github.com/buger/goterm v1.0.4 // indirect
github.com/bugsnag/bugsnag-go v2.1.2+incompatible // indirect
github.com/bugsnag/panicwrap v1.3.4 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/bmatcuk/doublestar v1.1.5/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/bombsimon/wsl/v2 v2.0.0/go.mod h1:mf25kr/SqFEPhhcxW1+7pxzGlW+hIl/hYTKY95VwV8U=
github.com/bombsimon/wsl/v2 v2.2.0/go.mod h1:Azh8c3XGEJl9LyX0/sFC+CKMc7Ssgua0g+6abzXN4Pg=
Expand Down
8 changes: 2 additions & 6 deletions pkg/filepathutil/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"os"
"path/filepath"

"github.com/yargevad/filepathx"
"github.com/benchkram/bob/pkg/filepathxx"
)

// DefaultIgnores
Expand Down Expand Up @@ -50,7 +50,7 @@ func ListRecursive(inp string) (all []string, err error) {
if s, err := os.Stat(inp); err != nil || !s.IsDir() {
// File
// Use glob for unknowns (wildcard-paths) and existing files (non-dirs)
matches, err := filepathx.Glob(inp)
matches, err := filepathxx.Glob(inp)
if err != nil {
return nil, fmt.Errorf("failed to glob %q: %w", inp, err)
}
Expand Down Expand Up @@ -85,11 +85,7 @@ func ListRecursive(inp string) (all []string, err error) {
return all, nil
}

var WalkedDirs = map[string]int{}

func listDir(path string) ([]string, error) {
times := WalkedDirs[path]
WalkedDirs[path] = times + 1

var all []string
if err := filepath.WalkDir(path, func(p string, fi fs.DirEntry, err error) error {
Expand Down
123 changes: 123 additions & 0 deletions pkg/filepathxx/filepathxx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// From https://github.com/klauspost/filepathx/blob/master/filepathx.go
//
// Package filepathx adds double-star globbing support to the Glob function from the core path/filepath package.
// You might recognize "**" recursive globs from things like your .gitignore file, and zsh.
// The "**" glob represents a recursive wildcard matching zero-or-more directory levels deep.
package filepathxx

import (
"io/fs"
"path/filepath"
"runtime"
"strings"
)

// Globs represents one filepath glob, with its elements joined by "**".
type Globs []string

// Glob adds double-star support to the core path/filepath Glob function.
// It's useful when your globs might have double-stars, but you're not sure.
func Glob(pattern string) ([]string, error) {
if !strings.Contains(pattern, "**") {
// passthru to core package if no double-star
return filepath.Glob(pattern)
}
return Globs(strings.Split(pattern, "**")).Expand()
}

const replaceIfAny = "[]*"

var replacements [][2]string

func init() {
// Escape `filepath.Match` syntax.
// On Unix escaping works with `\\`,
// on Windows it is disabled, therefore
// replace it by '?' := any character.
if runtime.GOOS == "windows" {
replacements = [][2]string{
// Windows cannot have * in file names.
{"[", "?"},
{"]", "?"},
}
} else {
replacements = [][2]string{
{"*", "\\*"},
{"[", "\\["},
{"]", "\\]"},
}
}
}

// Expand finds matches for the provided Globs.
func (globs Globs) Expand() ([]string, error) {
var matches = []string{""} // accumulate here
for _, glob := range globs {
if glob == "" {
// If the glob is empty string that means it was **
// By setting this to . patterns like **/*.txt are supported
glob = "."
}
var hits []string
//var hitMap = map[string]bool{}
for _, match := range matches {
if strings.ContainsAny(match, replaceIfAny) {
for _, sr := range replacements {
match = strings.ReplaceAll(match, sr[0], sr[1])
}
}

paths, err := filepath.Glob(filepath.Join(match, glob))
if err != nil {
return nil, err
}

for _, path := range paths {
err = filepath.WalkDir(path, func(path string, _ fs.DirEntry, err error) error {
if err != nil {
return err
}
// save deduped match from current iteration
// if _, ok := hitMap[path]; !ok {
// hits = append(hits, path)
// hitMap[path] = true
// }
hits = appendUnique(hits, path)
// if !contains(path, hits) {
// hits = append(hits, path)
// }
return nil
})
if err != nil {
return nil, err
}
}
}
matches = hits
}

// fix up return value for nil input
if globs == nil && len(matches) > 0 && matches[0] == "" {
matches = matches[1:]
}

return matches, nil
}

func contains(entry string, arr []string) bool {
for _, e := range arr {
if entry == e {
return true
}
}
return false
}

func appendUnique(a []string, x string) []string {
for _, y := range a {
if x == y {
return a
}
}
return append(a, x)
}

0 comments on commit 407b583

Please sign in to comment.