glob.go (1868B)
1 // Copyright 2019 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 package hugofs
15
16 import (
17 "errors"
18 "path/filepath"
19 "strings"
20
21 "github.com/gohugoio/hugo/hugofs/glob"
22
23 "github.com/spf13/afero"
24 )
25
26 // Glob walks the fs and passes all matches to the handle func.
27 // The handle func can return true to signal a stop.
28 func Glob(fs afero.Fs, pattern string, handle func(fi FileMetaInfo) (bool, error)) error {
29 pattern = glob.NormalizePath(pattern)
30 if pattern == "" {
31 return nil
32 }
33
34 g, err := glob.GetGlob(pattern)
35 if err != nil {
36 return nil
37 }
38
39 hasSuperAsterisk := strings.Contains(pattern, "**")
40 levels := strings.Count(pattern, "/")
41 root := glob.ResolveRootDir(pattern)
42
43 // Signals that we're done.
44 done := errors.New("done")
45
46 wfn := func(p string, info FileMetaInfo, err error) error {
47 p = glob.NormalizePath(p)
48 if info.IsDir() {
49 if !hasSuperAsterisk {
50 // Avoid walking to the bottom if we can avoid it.
51 if p != "" && strings.Count(p, "/") >= levels {
52 return filepath.SkipDir
53 }
54 }
55 return nil
56 }
57
58 if g.Match(p) {
59 d, err := handle(info)
60 if err != nil {
61 return err
62 }
63 if d {
64 return done
65 }
66 }
67
68 return nil
69 }
70
71 w := NewWalkway(WalkwayConfig{
72 Root: root,
73 Fs: fs,
74 WalkFn: wfn,
75 })
76
77 err = w.Walk()
78
79 if err != done {
80 return err
81 }
82
83 return nil
84 }