github.com/jxskiss/gopkg/v2@v2.14.9-0.20240514120614-899f3e7952b4/easy/filepath.go (about) 1 package easy 2 3 import ( 4 "os" 5 "path/filepath" 6 "strings" 7 ) 8 9 // Glob adds double-star support to the std library's [path/filepath.Glob]. 10 // It's useful when your pattern might have double-stars. 11 func Glob(pattern string) (matches []string, err error) { 12 if !strings.Contains(pattern, "**") { 13 // Pass-through to std lib if no double-star. 14 return filepath.Glob(pattern) 15 } 16 parts := strings.Split(pattern, "**") 17 return globParts(parts).Expand() 18 } 19 20 type globParts []string 21 22 func (globs globParts) Expand() (matches []string, err error) { 23 matches = []string{""} 24 for i, glob := range globs { 25 isLast := i == len(globs)-1 26 var hits []string 27 var seen = make(map[string]bool) 28 for _, match := range matches { 29 paths, err := filepath.Glob(match + glob) 30 if err != nil { 31 return nil, err 32 } 33 for _, path := range paths { 34 err = filepath.Walk(path, func(path string, info os.FileInfo, err error) error { 35 if err != nil { 36 return err 37 } 38 if isLast || info.IsDir() { 39 if _, ok := seen[path]; !ok { 40 hits = append(hits, path) 41 seen[path] = true 42 } 43 } 44 return nil 45 }) 46 if err != nil { 47 return nil, err 48 } 49 } 50 } 51 matches = hits 52 } 53 54 if len(globs) == 0 && len(matches) > 0 && matches[0] == "" { 55 matches = matches[1:] 56 } 57 58 return matches, nil 59 } 60 61 // CreateNonExistingFolder checks whether a directory exists, 62 // the directory will be created by calling `os.MkdirAll(path, perm)` 63 // if it does not exist. 64 func CreateNonExistingFolder(path string, perm os.FileMode) error { 65 if perm == 0 { 66 perm = 0o700 67 } 68 if _, err := os.Stat(path); os.IsNotExist(err) { 69 return os.MkdirAll(path, perm) 70 } else if err != nil { 71 return err 72 } 73 return nil 74 } 75 76 // WriteFile writes data to the named file, creating it if necessary. 77 // If the file does not exist, WriteFile creates it with permissions perm (before umask); 78 // otherwise WriteFile truncates it before writing, without changing permissions. 79 // 80 // If creates the directory if it does not exist instead of reporting an error. 81 func WriteFile(name string, data []byte, perm os.FileMode) error { 82 dirPerm := getDirectoryPermFromFilePerm(perm) 83 err := CreateNonExistingFolder(filepath.Dir(name), dirPerm) 84 if err != nil { 85 return err 86 } 87 return os.WriteFile(name, data, perm) 88 } 89 90 func getDirectoryPermFromFilePerm(filePerm os.FileMode) os.FileMode { 91 var dirPerm os.FileMode = 0o700 92 if filePerm&0o060 > 0 { 93 dirPerm |= (filePerm & 0o070) | 0o010 94 } 95 if filePerm&0o006 > 0 { 96 dirPerm |= (filePerm & 0o007) | 0x001 97 } 98 return dirPerm 99 }