github.com/lusis/distribution@v2.0.1+incompatible/registry/storage/walk.go (about) 1 package storage 2 3 import ( 4 "errors" 5 "fmt" 6 7 storageDriver "github.com/docker/distribution/registry/storage/driver" 8 ) 9 10 // SkipDir is used as a return value from onFileFunc to indicate that 11 // the directory named in the call is to be skipped. It is not returned 12 // as an error by any function. 13 var ErrSkipDir = errors.New("skip this directory") 14 15 // WalkFn is called once per file by Walk 16 // If the returned error is ErrSkipDir and fileInfo refers 17 // to a directory, the directory will not be entered and Walk 18 // will continue the traversal. Otherwise Walk will return 19 type WalkFn func(fileInfo storageDriver.FileInfo) error 20 21 // Walk traverses a filesystem defined within driver, starting 22 // from the given path, calling f on each file 23 func Walk(driver storageDriver.StorageDriver, from string, f WalkFn) error { 24 children, err := driver.List(from) 25 if err != nil { 26 return err 27 } 28 for _, child := range children { 29 fileInfo, err := driver.Stat(child) 30 if err != nil { 31 return err 32 } 33 err = f(fileInfo) 34 skipDir := (err == ErrSkipDir) 35 if err != nil && !skipDir { 36 return err 37 } 38 39 if fileInfo.IsDir() && !skipDir { 40 Walk(driver, child, f) 41 } 42 } 43 return nil 44 } 45 46 // pushError formats an error type given a path and an error 47 // and pushes it to a slice of errors 48 func pushError(errors []error, path string, err error) []error { 49 return append(errors, fmt.Errorf("%s: %s", path, err)) 50 }