From a410ea2ea0cd348d887c175aab0ec23882f82d7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Nov 2022 15:24:27 +0000 Subject: [PATCH] Bump github.com/bmatcuk/doublestar/v4 from 4.2.0 to 4.3.0 (#107) Bumps [github.com/bmatcuk/doublestar/v4](https://github.com/bmatcuk/doublestar) from 4.2.0 to 4.3.0. - [Release notes](https://github.com/bmatcuk/doublestar/releases) - [Commits](https://github.com/bmatcuk/doublestar/compare/v4.2.0...v4.3.0) --- updated-dependencies: - dependency-name: github.com/bmatcuk/doublestar/v4 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 +- .../bmatcuk/doublestar/v4/README.md | 70 +++++++++-- .../github.com/bmatcuk/doublestar/v4/glob.go | 117 +++++++++++------- .../bmatcuk/doublestar/v4/globoptions.go | 46 +++++++ .../bmatcuk/doublestar/v4/globwalk.go | 89 ++++++++----- .../github.com/bmatcuk/doublestar/v4/match.go | 3 + .../github.com/bmatcuk/doublestar/v4/utils.go | 23 ++-- vendor/modules.txt | 2 +- 9 files changed, 260 insertions(+), 96 deletions(-) create mode 100644 vendor/github.com/bmatcuk/doublestar/v4/globoptions.go diff --git a/go.mod b/go.mod index 5ab2bea..22eecc0 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.17 require ( github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d - github.com/bmatcuk/doublestar/v4 v4.2.0 + github.com/bmatcuk/doublestar/v4 v4.3.0 github.com/cenkalti/backoff v2.2.1+incompatible github.com/go-git/go-git/v5 v5.4.2 github.com/heroku/heroku-go/v5 v5.5.0 diff --git a/go.sum b/go.sum index 32d9f7e..6021360 100644 --- a/go.sum +++ b/go.sum @@ -12,8 +12,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= -github.com/bmatcuk/doublestar/v4 v4.2.0 h1:Qu+u9wR3Vd89LnlLMHvnZ5coJMWKQamqdz9/p5GNthA= -github.com/bmatcuk/doublestar/v4 v4.2.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bmatcuk/doublestar/v4 v4.3.0 h1:Ct0GphHCZaXvUh2Gqtk37Mzj1qWvXcW9XnXQs1GL9S0= +github.com/bmatcuk/doublestar/v4 v4.3.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= diff --git a/vendor/github.com/bmatcuk/doublestar/v4/README.md b/vendor/github.com/bmatcuk/doublestar/v4/README.md index 0f930b0..eee2eb3 100644 --- a/vendor/github.com/bmatcuk/doublestar/v4/README.md +++ b/vendor/github.com/bmatcuk/doublestar/v4/README.md @@ -56,6 +56,16 @@ import "github.com/bmatcuk/doublestar/v4" ## Usage +### ErrBadPattern + +```go +doublestar.ErrBadPattern +``` + +Returned by various functions to report that the pattern is malformed. At the +moment, this value is equal to `path.ErrBadPattern`, but, for portability, this +equivalence should probably not be relied upon. + ### Match ```go @@ -67,7 +77,7 @@ Match returns true if `name` matches the file name `pattern` ([see and may be relative or absolute. Match requires pattern to match all of name, not just a substring. The only -possible returned error is ErrBadPattern, when pattern is malformed. +possible returned error is `ErrBadPattern`, when pattern is malformed. Note: this is meant as a drop-in replacement for `path.Match()` which always uses `'/'` as the path separator. If you want to support systems which use a @@ -75,6 +85,9 @@ different path separator (such as Windows), what you want is `PathMatch()`. Alternatively, you can run `filepath.ToSlash()` on both pattern and name and then use this function. +Note: users should _not_ count on the returned error, +`doublestar.ErrBadPattern`, being equal to `path.ErrBadPattern`. + ### PathMatch @@ -92,19 +105,35 @@ that both `pattern` and `name` are using the system's path separator. If you can't be sure of that, use `filepath.ToSlash()` on both `pattern` and `name`, and then use the `Match()` function instead. +### GlobOption + +Options that may be passed to `Glob`, `GlobWalk`, or `FilepathGlob`. Any number +of options may be passed to these functions, and in any order, as the last +argument(s). + +```go +WithFailOnIOErrors() +``` + +If passed, it enables aborting and returning the error when an IO error is +encountered. + ### Glob ```go -func Glob(fsys fs.FS, pattern string) ([]string, error) +func Glob(fsys fs.FS, pattern string, opts ...GlobOption) ([]string, error) ``` Glob returns the names of all files matching pattern or nil if there is no matching file. The syntax of patterns is the same as in `Match()`. The pattern may describe hierarchical names such as `usr/*/bin/ed`. -Glob ignores file system errors such as I/O errors reading directories. The -only possible returned error is ErrBadPattern, reporting that the pattern is -malformed. +Glob ignores file system errors such as I/O errors reading directories by +default. The only possible returned error is `ErrBadPattern`, reporting that +the pattern is malformed. + +To enable aborting on I/O errors, the `WithFailOnIOErrors` option can be +passed. Note: this is meant as a drop-in replacement for `io/fs.Glob()`. Like `io/fs.Glob()`, this function assumes that your pattern uses `/` as the path @@ -118,12 +147,15 @@ decision](https://github.com/golang/go/issues/44092#issuecomment-774132549), even if counter-intuitive. You can use [SplitPattern] to divide a pattern into a base path (to initialize an `FS` object) and pattern. +Note: users should _not_ count on the returned error, +`doublestar.ErrBadPattern`, being equal to `path.ErrBadPattern`. + ### GlobWalk ```go type GlobWalkFunc func(path string, d fs.DirEntry) error -func GlobWalk(fsys fs.FS, pattern string, fn GlobWalkFunc) error +func GlobWalk(fsys fs.FS, pattern string, fn GlobWalkFunc, opts ...GlobOption) error ``` GlobWalk calls the callback function `fn` for every file matching pattern. The @@ -141,8 +173,13 @@ will skip the current directory. This means that if the current path _is_ a directory, GlobWalk will not recurse into it. If the current path is not a directory, the rest of the parent directory will be skipped. -GlobWalk ignores file system errors such as I/O errors reading directories. -GlobWalk may return ErrBadPattern, reporting that the pattern is malformed. +GlobWalk ignores file system errors such as I/O errors reading directories by +default. GlobWalk may return `ErrBadPattern`, reporting that the pattern is +malformed. + +To enable aborting on I/O errors, the `WithFailOnIOErrors` option can be +passed. + Additionally, if the callback function `fn` returns an error, GlobWalk will exit immediately and return that error. @@ -151,19 +188,25 @@ separator even if that's not correct for your OS (like Windows). If you aren't sure if that's the case, you can use filepath.ToSlash() on your pattern before calling GlobWalk(). +Note: users should _not_ count on the returned error, +`doublestar.ErrBadPattern`, being equal to `path.ErrBadPattern`. + ### FilepathGlob ```go -func FilepathGlob(pattern string) (matches []string, err error) +func FilepathGlob(pattern string, opts ...GlobOption) (matches []string, err error) ``` FilepathGlob returns the names of all files matching pattern or nil if there is no matching file. The syntax of pattern is the same as in Match(). The pattern may describe hierarchical names such as usr/*/bin/ed. -FilepathGlob ignores file system errors such as I/O errors reading directories. -The only possible returned error is ErrBadPattern, reporting that the pattern -is malformed. +FilepathGlob ignores file system errors such as I/O errors reading directories +by default. The only possible returned error is `ErrBadPattern`, reporting that +the pattern is malformed. + +To enable aborting on I/O errors, the `WithFailOnIOErrors` option can be +passed. Note: FilepathGlob is a convenience function that is meant as a drop-in replacement for `path/filepath.Glob()` for users who don't need the @@ -177,6 +220,9 @@ complication of io/fs. Basically, it: Returned paths will use the system's path separator, just like `filepath.Glob()`. +Note: the returned error `doublestar.ErrBadPattern` is not equal to +`filepath.ErrBadPattern`. + ### SplitPattern ```go diff --git a/vendor/github.com/bmatcuk/doublestar/v4/glob.go b/vendor/github.com/bmatcuk/doublestar/v4/glob.go index 6ae7ceb..754d8cd 100644 --- a/vendor/github.com/bmatcuk/doublestar/v4/glob.go +++ b/vendor/github.com/bmatcuk/doublestar/v4/glob.go @@ -9,9 +9,12 @@ import ( // matching file. The syntax of pattern is the same as in Match(). The pattern // may describe hierarchical names such as usr/*/bin/ed. // -// Glob ignores file system errors such as I/O errors reading directories. -// The only possible returned error is ErrBadPattern, reporting that the -// pattern is malformed. +// Glob ignores file system errors such as I/O errors reading directories by +// default. The only possible returned error is ErrBadPattern, reporting that +// the pattern is malformed. +// +// To enable aborting on I/O errors, the WithFailOnIOErrors option can be +// passed. // // Note: this is meant as a drop-in replacement for io/fs.Glob(). Like // io/fs.Glob(), this function assumes that your pattern uses `/` as the path @@ -23,27 +26,33 @@ import ( // will return no results and no errors. You can use SplitPattern to divide a // pattern into a base path (to initialize an `FS` object) and pattern. // -func Glob(fsys fs.FS, pattern string) ([]string, error) { +// Note: users should _not_ count on the returned error, +// doublestar.ErrBadPattern, being equal to path.ErrBadPattern. +// +func Glob(fsys fs.FS, pattern string, opts ...GlobOption) ([]string, error) { if !ValidatePattern(pattern) { return nil, ErrBadPattern } + + g := newGlob(opts...) + if hasMidDoubleStar(pattern) { // If the pattern has a `**` anywhere but the very end, GlobWalk is more // performant because it can get away with less allocations. If the pattern // ends in a `**`, both methods are pretty much the same, but Glob has a // _very_ slight advantage because of lower function call overhead. var matches []string - err := doGlobWalk(fsys, pattern, true, func(p string, d fs.DirEntry) error { + err := g.doGlobWalk(fsys, pattern, true, func(p string, d fs.DirEntry) error { matches = append(matches, p) return nil }) return matches, err } - return doGlob(fsys, pattern, nil, true) + return g.doGlob(fsys, pattern, nil, true) } // Does the actual globbin' -func doGlob(fsys fs.FS, pattern string, m []string, firstSegment bool) (matches []string, err error) { +func (g *glob) doGlob(fsys fs.FS, pattern string, m []string, firstSegment bool) (matches []string, err error) { matches = m patternStart := indexMeta(pattern) if patternStart == -1 { @@ -51,12 +60,16 @@ func doGlob(fsys fs.FS, pattern string, m []string, firstSegment bool) (matches // pattern exist? // The pattern may contain escaped wildcard characters for an exact path match. path := unescapeMeta(pattern) - if exists(fsys, path) { + pathExists, pathErr := g.exists(fsys, path) + if pathErr != nil { + return nil, pathErr + } + + if pathExists { matches = append(matches, path) - return - } else { - return } + + return } dir := "." @@ -70,7 +83,7 @@ func doGlob(fsys fs.FS, pattern string, m []string, firstSegment bool) (matches splitIdx = lastIndexSlash(pattern[:splitIdx]) } else { // otherwise, we have to handle the alts: - return globAlts(fsys, pattern, openingIdx, splitIdx, matches, firstSegment) + return g.globAlts(fsys, pattern, openingIdx, splitIdx, matches, firstSegment) } } @@ -82,16 +95,16 @@ func doGlob(fsys fs.FS, pattern string, m []string, firstSegment bool) (matches // characters. They would be equal if they are both -1, which means `dir` // will be ".", and we know that doesn't have meta characters either. if splitIdx <= patternStart { - return globDir(fsys, dir, pattern, matches, firstSegment) + return g.globDir(fsys, dir, pattern, matches, firstSegment) } var dirs []string - dirs, err = doGlob(fsys, dir, matches, false) + dirs, err = g.doGlob(fsys, dir, matches, false) if err != nil { return } for _, d := range dirs { - matches, err = globDir(fsys, d, pattern, matches, firstSegment) + matches, err = g.globDir(fsys, d, pattern, matches, firstSegment) if err != nil { return } @@ -102,7 +115,7 @@ func doGlob(fsys fs.FS, pattern string, m []string, firstSegment bool) (matches // handle alts in the glob pattern - `openingIdx` and `closingIdx` are the // indexes of `{` and `}`, respectively -func globAlts(fsys fs.FS, pattern string, openingIdx, closingIdx int, m []string, firstSegment bool) (matches []string, err error) { +func (g *glob) globAlts(fsys fs.FS, pattern string, openingIdx, closingIdx int, m []string, firstSegment bool) (matches []string, err error) { matches = m var dirs []string @@ -114,7 +127,7 @@ func globAlts(fsys fs.FS, pattern string, openingIdx, closingIdx int, m []string dirs = []string{""} } else { // our alts have a common prefix that we can process first - dirs, err = doGlob(fsys, pattern[:splitIdx], matches, false) + dirs, err = g.doGlob(fsys, pattern[:splitIdx], matches, false) if err != nil { return } @@ -135,7 +148,7 @@ func globAlts(fsys fs.FS, pattern string, openingIdx, closingIdx int, m []string } alt := buildAlt(d, pattern, startIdx, openingIdx, patIdx, nextIdx, afterIdx) - matches, err = doGlob(fsys, alt, matches, firstSegment) + matches, err = g.doGlob(fsys, alt, matches, firstSegment) if err != nil { return } @@ -165,34 +178,46 @@ func globAlts(fsys fs.FS, pattern string, openingIdx, closingIdx int, m []string } // find files/subdirectories in the given `dir` that match `pattern` -func globDir(fsys fs.FS, dir, pattern string, matches []string, canMatchFiles bool) (m []string, e error) { +func (g *glob) globDir(fsys fs.FS, dir, pattern string, matches []string, canMatchFiles bool) (m []string, e error) { m = matches if pattern == "" { // pattern can be an empty string if the original pattern ended in a slash, // in which case, we should just return dir, but only if it actually exists // and it's a directory (or a symlink to a directory) - if isPathDir(fsys, dir) { + isDir, err := g.isPathDir(fsys, dir) + if err != nil { + return nil, err + } + if isDir { m = append(m, dir) } return } if pattern == "**" { - m = globDoubleStar(fsys, dir, m, canMatchFiles) - return + return g.globDoubleStar(fsys, dir, m, canMatchFiles) } dirs, err := fs.ReadDir(fsys, dir) if err != nil { - // ignore IO errors + if g.failOnIOErrors { + return nil, err + } return } var matched bool for _, info := range dirs { name := info.Name() - if canMatchFiles || isDir(fsys, dir, name, info) { + matched = canMatchFiles + if !matched { + matched, e = g.isDir(fsys, dir, name, info) + if e != nil { + return + } + } + if matched { matched, e = matchWithSeparator(pattern, name, '/', false) if e != nil { return @@ -206,25 +231,34 @@ func globDir(fsys fs.FS, dir, pattern string, matches []string, canMatchFiles bo return } -func globDoubleStar(fsys fs.FS, dir string, matches []string, canMatchFiles bool) []string { +func (g *glob) globDoubleStar(fsys fs.FS, dir string, matches []string, canMatchFiles bool) ([]string, error) { dirs, err := fs.ReadDir(fsys, dir) if err != nil { - // ignore IO errors - return matches + if g.failOnIOErrors { + return nil, err + } + return matches, nil } // `**` can match *this* dir, so add it matches = append(matches, dir) for _, info := range dirs { name := info.Name() - if isDir(fsys, dir, name, info) { - matches = globDoubleStar(fsys, path.Join(dir, name), matches, canMatchFiles) + isDir, err := g.isDir(fsys, dir, name, info) + if err != nil { + return nil, err + } + if isDir { + matches, err = g.globDoubleStar(fsys, path.Join(dir, name), matches, canMatchFiles) + if err != nil { + return nil, err + } } else if canMatchFiles { matches = append(matches, path.Join(dir, name)) } } - return matches + return matches, nil } // Returns true if the pattern has a doublestar in the middle of the pattern. @@ -302,26 +336,25 @@ func indexMatchedOpeningAlt(s string) int { } // Returns true if the path exists -func exists(fsys fs.FS, name string) bool { - if _, err := fs.Stat(fsys, name); err != nil { - return false - } - return true +func (g *glob) exists(fsys fs.FS, name string) (bool, error) { + _, err := fs.Stat(fsys, name) + return err == nil, g.forwardErrIfFailOnIOErrors(err) } // Returns true if the path is a directory, or a symlink to a directory -func isPathDir(fsys fs.FS, name string) bool { +func (g *glob) isPathDir(fsys fs.FS, name string) (bool, error) { info, err := fs.Stat(fsys, name) if err != nil { - return false + return false, g.forwardErrIfFailOnIOErrors(err) } - return info.IsDir() + + return info.IsDir(), nil } // Returns whether or not the given DirEntry is a directory. If the DirEntry // represents a symbolic link, the link is followed by running fs.Stat() on // `path.Join(dir, name)` (if dir is "", name will be used without joining) -func isDir(fsys fs.FS, dir, name string, info fs.DirEntry) bool { +func (g *glob) isDir(fsys fs.FS, dir, name string, info fs.DirEntry) (bool, error) { if (info.Type() & fs.ModeSymlink) > 0 { p := name if dir != "" { @@ -329,11 +362,11 @@ func isDir(fsys fs.FS, dir, name string, info fs.DirEntry) bool { } finfo, err := fs.Stat(fsys, p) if err != nil { - return false + return false, g.forwardErrIfFailOnIOErrors(err) } - return finfo.IsDir() + return finfo.IsDir(), nil } - return info.IsDir() + return info.IsDir(), nil } // Builds a string from an alt diff --git a/vendor/github.com/bmatcuk/doublestar/v4/globoptions.go b/vendor/github.com/bmatcuk/doublestar/v4/globoptions.go new file mode 100644 index 0000000..4837cdf --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/v4/globoptions.go @@ -0,0 +1,46 @@ +package doublestar + +// glob is an internal type to store options during globbing. +type glob struct { + failOnIOErrors bool +} + +// GlobOption represents a setting that can be passed to Glob, GlobWalk, and +// FilepathGlob. +type GlobOption func(*glob) + +// Construct a new glob object with the given options +func newGlob(opts ...GlobOption) *glob { + g := &glob{} + for _, opt := range opts { + opt(g) + } + return g +} + +// WithFailOnIOErrors is an option that can be passed to Glob, GlobWalk, or +// FilepathGlob. If passed, it enables aborting and returning the error when an +// IO error is encountered. +// +func WithFailOnIOErrors() GlobOption { + return func(g *glob) { + g.failOnIOErrors = true + } +} + +// forwardErrIfFailOnIOErrors is used to wrap the return values of I/O +// functions. When failOnIOErrors is enabled, it will return err; otherwise, it +// always returns nil. +func (g *glob) forwardErrIfFailOnIOErrors(err error) error { + if g.failOnIOErrors { + return err + } + return nil +} + +func (g *glob) GoString() string { + if g.failOnIOErrors { + return "opts: WithFailOnIOErrors" + } + return "opts: nil" +} diff --git a/vendor/github.com/bmatcuk/doublestar/v4/globwalk.go b/vendor/github.com/bmatcuk/doublestar/v4/globwalk.go index ff4cdf1..6a94c6b 100644 --- a/vendor/github.com/bmatcuk/doublestar/v4/globwalk.go +++ b/vendor/github.com/bmatcuk/doublestar/v4/globwalk.go @@ -32,8 +32,13 @@ type GlobWalkFunc func(path string, d fs.DirEntry) error // path _is_ a directory, GlobWalk will not recurse into it. If the current // path is not a directory, the rest of the parent directory will be skipped. // -// GlobWalk ignores file system errors such as I/O errors reading directories. -// GlobWalk may return ErrBadPattern, reporting that the pattern is malformed. +// GlobWalk ignores file system errors such as I/O errors reading directories +// by default. GlobWalk may return ErrBadPattern, reporting that the pattern is +// malformed. +// +// To enable aborting on I/O errors, the WithFailOnIOErrors option can be +// passed. +// // Additionally, if the callback function `fn` returns an error, GlobWalk will // exit immediately and return that error. // @@ -42,15 +47,20 @@ type GlobWalkFunc func(path string, d fs.DirEntry) error // aren't sure if that's the case, you can use filepath.ToSlash() on your // pattern before calling GlobWalk(). // -func GlobWalk(fsys fs.FS, pattern string, fn GlobWalkFunc) error { +// Note: users should _not_ count on the returned error, +// doublestar.ErrBadPattern, being equal to path.ErrBadPattern. +// +func GlobWalk(fsys fs.FS, pattern string, fn GlobWalkFunc, opts ...GlobOption) error { if !ValidatePattern(pattern) { return ErrBadPattern } - return doGlobWalk(fsys, pattern, true, fn) + + g := newGlob(opts...) + return g.doGlobWalk(fsys, pattern, true, fn) } // Actually execute GlobWalk -func doGlobWalk(fsys fs.FS, pattern string, firstSegment bool, fn GlobWalkFunc) error { +func (g *glob) doGlobWalk(fsys fs.FS, pattern string, firstSegment bool, fn GlobWalkFunc) error { patternStart := indexMeta(pattern) if patternStart == -1 { // pattern doesn't contain any meta characters - does a file matching the @@ -65,8 +75,7 @@ func doGlobWalk(fsys fs.FS, pattern string, firstSegment bool, fn GlobWalkFunc) } return err } else { - // ignore IO errors - return nil + return g.forwardErrIfFailOnIOErrors(err) } } @@ -81,7 +90,7 @@ func doGlobWalk(fsys fs.FS, pattern string, firstSegment bool, fn GlobWalkFunc) splitIdx = lastIndexSlash(pattern[:splitIdx]) } else { // otherwise, we have to handle the alts: - return globAltsWalk(fsys, pattern, openingIdx, splitIdx, firstSegment, fn) + return g.globAltsWalk(fsys, pattern, openingIdx, splitIdx, firstSegment, fn) } } @@ -93,11 +102,11 @@ func doGlobWalk(fsys fs.FS, pattern string, firstSegment bool, fn GlobWalkFunc) // characters. They would be equal if they are both -1, which means `dir` // will be ".", and we know that doesn't have meta characters either. if splitIdx <= patternStart { - return globDirWalk(fsys, dir, pattern, firstSegment, fn) + return g.globDirWalk(fsys, dir, pattern, firstSegment, fn) } - return doGlobWalk(fsys, dir, false, func(p string, d fs.DirEntry) error { - if err := globDirWalk(fsys, p, pattern, firstSegment, fn); err != nil { + return g.doGlobWalk(fsys, dir, false, func(p string, d fs.DirEntry) error { + if err := g.globDirWalk(fsys, p, pattern, firstSegment, fn); err != nil { return err } return nil @@ -106,22 +115,22 @@ func doGlobWalk(fsys fs.FS, pattern string, firstSegment bool, fn GlobWalkFunc) // handle alts in the glob pattern - `openingIdx` and `closingIdx` are the // indexes of `{` and `}`, respectively -func globAltsWalk(fsys fs.FS, pattern string, openingIdx, closingIdx int, firstSegment bool, fn GlobWalkFunc) (err error) { +func (g *glob) globAltsWalk(fsys fs.FS, pattern string, openingIdx, closingIdx int, firstSegment bool, fn GlobWalkFunc) (err error) { var matches []DirEntryWithFullPath startIdx := 0 afterIdx := closingIdx + 1 splitIdx := lastIndexSlashOrAlt(pattern[:openingIdx]) if splitIdx == -1 || pattern[splitIdx] == '}' { // no common prefix - matches, err = doGlobAltsWalk(fsys, "", pattern, startIdx, openingIdx, closingIdx, afterIdx, firstSegment, matches) + matches, err = g.doGlobAltsWalk(fsys, "", pattern, startIdx, openingIdx, closingIdx, afterIdx, firstSegment, matches) if err != nil { return } } else { // our alts have a common prefix that we can process first startIdx = splitIdx + 1 - err = doGlobWalk(fsys, pattern[:splitIdx], false, func(p string, d fs.DirEntry) (e error) { - matches, e = doGlobAltsWalk(fsys, p, pattern, startIdx, openingIdx, closingIdx, afterIdx, firstSegment, matches) + err = g.doGlobWalk(fsys, pattern[:splitIdx], false, func(p string, d fs.DirEntry) (e error) { + matches, e = g.doGlobAltsWalk(fsys, p, pattern, startIdx, openingIdx, closingIdx, afterIdx, firstSegment, matches) return e }) if err != nil { @@ -151,7 +160,11 @@ func globAltsWalk(fsys fs.FS, pattern string, openingIdx, closingIdx int, firstS } if err = fn(m.Path, m.Entry); err != nil { if err == SkipDir { - if isDir(fsys, "", m.Path, m.Entry) { + isDir, err := g.isDir(fsys, "", m.Path, m.Entry) + if err != nil { + return err + } + if isDir { // append a slash to guarantee `skip` will be treated as a parent dir skip = m.Path + "/" } else { @@ -170,7 +183,7 @@ func globAltsWalk(fsys fs.FS, pattern string, openingIdx, closingIdx int, firstS } // runs actual matching for alts -func doGlobAltsWalk(fsys fs.FS, d, pattern string, startIdx, openingIdx, closingIdx, afterIdx int, firstSegment bool, m []DirEntryWithFullPath) (matches []DirEntryWithFullPath, err error) { +func (g *glob) doGlobAltsWalk(fsys fs.FS, d, pattern string, startIdx, openingIdx, closingIdx, afterIdx int, firstSegment bool, m []DirEntryWithFullPath) (matches []DirEntryWithFullPath, err error) { matches = m matchesLen := len(m) patIdx := openingIdx + 1 @@ -183,7 +196,7 @@ func doGlobAltsWalk(fsys fs.FS, d, pattern string, startIdx, openingIdx, closing } alt := buildAlt(d, pattern, startIdx, openingIdx, patIdx, nextIdx, afterIdx) - err = doGlobWalk(fsys, alt, firstSegment, func(p string, d fs.DirEntry) error { + err = g.doGlobWalk(fsys, alt, firstSegment, func(p string, d fs.DirEntry) error { // insertion sort, ignoring dups insertIdx := matchesLen for insertIdx > 0 && matches[insertIdx-1].Path > p { @@ -215,13 +228,16 @@ func doGlobAltsWalk(fsys fs.FS, d, pattern string, startIdx, openingIdx, closing return } -func globDirWalk(fsys fs.FS, dir, pattern string, canMatchFiles bool, fn GlobWalkFunc) (e error) { +func (g *glob) globDirWalk(fsys fs.FS, dir, pattern string, canMatchFiles bool, fn GlobWalkFunc) (e error) { if pattern == "" { // pattern can be an empty string if the original pattern ended in a slash, // in which case, we should just return dir, but only if it actually exists // and it's a directory (or a symlink to a directory) info, err := fs.Stat(fsys, dir) - if err != nil || !info.IsDir() { + if err != nil { + return g.forwardErrIfFailOnIOErrors(err) + } + if !info.IsDir() { return nil } @@ -235,7 +251,10 @@ func globDirWalk(fsys fs.FS, dir, pattern string, canMatchFiles bool, fn GlobWal if pattern == "**" { // `**` can match *this* dir info, err := fs.Stat(fsys, dir) - if err != nil || !info.IsDir() { + if err != nil { + return g.forwardErrIfFailOnIOErrors(err) + } + if !info.IsDir() { return nil } if e = fn(dir, dirEntryFromFileInfo(info)); e != nil { @@ -244,19 +263,25 @@ func globDirWalk(fsys fs.FS, dir, pattern string, canMatchFiles bool, fn GlobWal } return } - return globDoubleStarWalk(fsys, dir, canMatchFiles, fn) + return g.globDoubleStarWalk(fsys, dir, canMatchFiles, fn) } dirs, err := fs.ReadDir(fsys, dir) if err != nil { - // ignore IO errors - return nil + return g.forwardErrIfFailOnIOErrors(err) } var matched bool for _, info := range dirs { name := info.Name() - if canMatchFiles || isDir(fsys, dir, name, info) { + matched = canMatchFiles + if !matched { + matched, e = g.isDir(fsys, dir, name, info) + if e != nil { + return e + } + } + if matched { matched, e = matchWithSeparator(pattern, name, '/', false) if e != nil { return @@ -276,17 +301,21 @@ func globDirWalk(fsys fs.FS, dir, pattern string, canMatchFiles bool, fn GlobWal } // recursively walk files/directories in a directory -func globDoubleStarWalk(fsys fs.FS, dir string, canMatchFiles bool, fn GlobWalkFunc) (e error) { +func (g *glob) globDoubleStarWalk(fsys fs.FS, dir string, canMatchFiles bool, fn GlobWalkFunc) (e error) { dirs, err := fs.ReadDir(fsys, dir) if err != nil { - // ignore IO errors - return + return g.forwardErrIfFailOnIOErrors(err) } // `**` can match *this* dir, so add it for _, info := range dirs { name := info.Name() - if isDir(fsys, dir, name, info) { + isDir, err := g.isDir(fsys, dir, name, info) + if err != nil { + return err + } + + if isDir { p := path.Join(dir, name) if e = fn(p, info); e != nil { if e == SkipDir { @@ -295,7 +324,7 @@ func globDoubleStarWalk(fsys fs.FS, dir string, canMatchFiles bool, fn GlobWalkF } return } - if e = globDoubleStarWalk(fsys, p, canMatchFiles, fn); e != nil { + if e = g.globDoubleStarWalk(fsys, p, canMatchFiles, fn); e != nil { return } } else if canMatchFiles { diff --git a/vendor/github.com/bmatcuk/doublestar/v4/match.go b/vendor/github.com/bmatcuk/doublestar/v4/match.go index 00363e0..6581d99 100644 --- a/vendor/github.com/bmatcuk/doublestar/v4/match.go +++ b/vendor/github.com/bmatcuk/doublestar/v4/match.go @@ -46,6 +46,9 @@ import ( // is PathMatch(). Alternatively, you can run filepath.ToSlash() on both // pattern and name and then use this function. // +// Note: users should _not_ count on the returned error, +// doublestar.ErrBadPattern, being equal to path.ErrBadPattern. +// func Match(pattern, name string) (bool, error) { return matchWithSeparator(pattern, name, '/', true) } diff --git a/vendor/github.com/bmatcuk/doublestar/v4/utils.go b/vendor/github.com/bmatcuk/doublestar/v4/utils.go index d4d2cc1..f1404d4 100644 --- a/vendor/github.com/bmatcuk/doublestar/v4/utils.go +++ b/vendor/github.com/bmatcuk/doublestar/v4/utils.go @@ -62,25 +62,32 @@ func SplitPattern(p string) (base, pattern string) { // pattern may describe hierarchical names such as usr/*/bin/ed. // // FilepathGlob ignores file system errors such as I/O errors reading -// directories. The only possible returned error is ErrBadPattern, reporting -// that the pattern is malformed. +// directories by default. The only possible returned error is ErrBadPattern, +// reporting that the pattern is malformed. +// +// To enable aborting on I/O errors, the WithFailOnIOErrors option can be +// passed. // // Note: FilepathGlob is a convenience function that is meant as a drop-in // replacement for `path/filepath.Glob()` for users who don't need the // complication of io/fs. Basically, it: -// * Runs `filepath.Clean()` and `ToSlash()` on the pattern -// * Runs `SplitPattern()` to get a base path and a pattern to Glob -// * Creates an FS object from the base path and `Glob()s` on the pattern -// * Joins the base path with all of the matches from `Glob()` +// - Runs `filepath.Clean()` and `ToSlash()` on the pattern +// - Runs `SplitPattern()` to get a base path and a pattern to Glob +// - Creates an FS object from the base path and `Glob()s` on the pattern +// - Joins the base path with all of the matches from `Glob()` // // Returned paths will use the system's path separator, just like // `filepath.Glob()`. -func FilepathGlob(pattern string) (matches []string, err error) { +// +// Note: the returned error doublestar.ErrBadPattern is not equal to +// filepath.ErrBadPattern. +// +func FilepathGlob(pattern string, opts ...GlobOption) (matches []string, err error) { pattern = filepath.Clean(pattern) pattern = filepath.ToSlash(pattern) base, f := SplitPattern(pattern) fs := os.DirFS(base) - if matches, err = Glob(fs, f); err != nil { + if matches, err = Glob(fs, f, opts...); err != nil { return nil, err } for i := range matches { diff --git a/vendor/modules.txt b/vendor/modules.txt index e900f52..e92407b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -26,7 +26,7 @@ github.com/acomagu/bufpipe # github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d ## explicit github.com/bgentry/go-netrc/netrc -# github.com/bmatcuk/doublestar/v4 v4.2.0 +# github.com/bmatcuk/doublestar/v4 v4.3.0 ## explicit; go 1.16 github.com/bmatcuk/doublestar/v4 # github.com/cenkalti/backoff v2.2.1+incompatible