github.com/SuCicada/su-hugo@v1.0.0/hugofs/glob.go (about) 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.NormalizePathNoLower(pattern) 30 if pattern == "" { 31 return nil 32 } 33 root := glob.ResolveRootDir(pattern) 34 pattern = strings.ToLower(pattern) 35 36 g, err := glob.GetGlob(pattern) 37 if err != nil { 38 return err 39 } 40 41 hasSuperAsterisk := strings.Contains(pattern, "**") 42 levels := strings.Count(pattern, "/") 43 44 // Signals that we're done. 45 done := errors.New("done") 46 47 wfn := func(p string, info FileMetaInfo, err error) error { 48 p = glob.NormalizePath(p) 49 if info.IsDir() { 50 if !hasSuperAsterisk { 51 // Avoid walking to the bottom if we can avoid it. 52 if p != "" && strings.Count(p, "/") >= levels { 53 return filepath.SkipDir 54 } 55 } 56 return nil 57 } 58 59 if g.Match(p) { 60 d, err := handle(info) 61 if err != nil { 62 return err 63 } 64 if d { 65 return done 66 } 67 } 68 69 return nil 70 } 71 72 w := NewWalkway(WalkwayConfig{ 73 Root: root, 74 Fs: fs, 75 WalkFn: wfn, 76 }) 77 78 err = w.Walk() 79 80 if err != done { 81 return err 82 } 83 84 return nil 85 }