github.com/netdata/go.d.plugin@v0.58.1/pkg/multipath/multipath.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package multipath 4 5 import ( 6 "fmt" 7 "os" 8 "path/filepath" 9 "strings" 10 11 "github.com/mitchellh/go-homedir" 12 ) 13 14 type ErrNotFound struct{ msg string } 15 16 func (e ErrNotFound) Error() string { return e.msg } 17 18 // IsNotFound returns a boolean indicating whether the error is ErrNotFound or not. 19 func IsNotFound(err error) bool { 20 switch err.(type) { 21 case ErrNotFound: 22 return true 23 } 24 return false 25 } 26 27 // MultiPath multi-paths 28 type MultiPath []string 29 30 // New multi-paths 31 func New(paths ...string) MultiPath { 32 set := map[string]bool{} 33 mPath := make(MultiPath, 0) 34 35 for _, dir := range paths { 36 if dir == "" { 37 continue 38 } 39 if d, err := homedir.Expand(dir); err != nil { 40 dir = d 41 } 42 if !set[dir] { 43 mPath = append(mPath, dir) 44 set[dir] = true 45 } 46 } 47 48 return mPath 49 } 50 51 // Find finds a file in given paths 52 func (p MultiPath) Find(filename string) (string, error) { 53 for _, dir := range p { 54 file := filepath.Join(dir, filename) 55 if _, err := os.Stat(file); !os.IsNotExist(err) { 56 return file, nil 57 } 58 } 59 return "", ErrNotFound{msg: fmt.Sprintf("can't find '%s' in %v", filename, p)} 60 } 61 62 func (p MultiPath) FindFiles(suffix string) ([]string, error) { 63 set := make(map[string]bool) 64 var files []string 65 66 for _, dir := range p { 67 entries, err := os.ReadDir(dir) 68 if err != nil { 69 continue 70 } 71 72 for _, e := range entries { 73 if !e.Type().IsRegular() || !strings.HasSuffix(e.Name(), suffix) || set[e.Name()] { 74 continue 75 } 76 set[e.Name()] = true 77 78 name := filepath.Join(dir, e.Name()) 79 files = append(files, name) 80 } 81 } 82 83 return files, nil 84 }