github.com/wangyougui/gf/v2@v2.6.5/os/gcfg/gcfg_adapter_file_path.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/wangyougui/gf. 6 7 package gcfg 8 9 import ( 10 "bytes" 11 "context" 12 "fmt" 13 "os" 14 15 "github.com/wangyougui/gf/v2/errors/gcode" 16 "github.com/wangyougui/gf/v2/errors/gerror" 17 "github.com/wangyougui/gf/v2/internal/intlog" 18 "github.com/wangyougui/gf/v2/os/gfile" 19 "github.com/wangyougui/gf/v2/os/gres" 20 "github.com/wangyougui/gf/v2/os/gspath" 21 "github.com/wangyougui/gf/v2/text/gstr" 22 ) 23 24 // SetPath sets the configuration `directory` path for file search. 25 // The parameter `path` can be absolute or relative `directory` path, 26 // but absolute `directory` path is strongly recommended. 27 // 28 // Note that this parameter is a path to a directory not a file. 29 func (a *AdapterFile) SetPath(directoryPath string) (err error) { 30 var ( 31 isDir = false 32 realPath = "" 33 ) 34 if file := gres.Get(directoryPath); file != nil { 35 realPath = directoryPath 36 isDir = file.FileInfo().IsDir() 37 } else { 38 // Absolute path. 39 realPath = gfile.RealPath(directoryPath) 40 if realPath == "" { 41 // Relative path. 42 a.searchPaths.RLockFunc(func(array []string) { 43 for _, v := range array { 44 if searchedPath, _ := gspath.Search(v, directoryPath); searchedPath != "" { 45 realPath = searchedPath 46 break 47 } 48 } 49 }) 50 } 51 if realPath != "" { 52 isDir = gfile.IsDir(realPath) 53 } 54 } 55 // Path not exist. 56 if realPath == "" { 57 buffer := bytes.NewBuffer(nil) 58 if a.searchPaths.Len() > 0 { 59 buffer.WriteString(fmt.Sprintf( 60 `SetPath failed: cannot find directory "%s" in following paths:`, 61 directoryPath, 62 )) 63 a.searchPaths.RLockFunc(func(array []string) { 64 for k, v := range array { 65 buffer.WriteString(fmt.Sprintf("\n%d. %s", k+1, v)) 66 } 67 }) 68 } else { 69 buffer.WriteString(fmt.Sprintf( 70 `SetPath failed: path "%s" does not exist`, 71 directoryPath, 72 )) 73 } 74 return gerror.New(buffer.String()) 75 } 76 // Should be a directory. 77 if !isDir { 78 return gerror.NewCodef( 79 gcode.CodeInvalidParameter, 80 `SetPath failed: path "%s" should be directory type`, 81 directoryPath, 82 ) 83 } 84 // Repeated path check. 85 if a.searchPaths.Search(realPath) != -1 { 86 return nil 87 } 88 a.jsonMap.Clear() 89 a.searchPaths.Clear() 90 a.searchPaths.Append(realPath) 91 intlog.Print(context.TODO(), "SetPath:", realPath) 92 return nil 93 } 94 95 // AddPath adds an absolute or relative `directory` path to the search paths. 96 // 97 // Note that this parameter is paths to a directories not files. 98 func (a *AdapterFile) AddPath(directoryPaths ...string) (err error) { 99 for _, directoryPath := range directoryPaths { 100 if err = a.doAddPath(directoryPath); err != nil { 101 return err 102 } 103 } 104 return nil 105 } 106 107 // doAddPath adds an absolute or relative `directory` path to the search paths. 108 func (a *AdapterFile) doAddPath(directoryPath string) (err error) { 109 var ( 110 isDir = false 111 realPath = "" 112 ) 113 // It firstly checks the resource manager, 114 // and then checks the filesystem for the path. 115 if file := gres.Get(directoryPath); file != nil { 116 realPath = directoryPath 117 isDir = file.FileInfo().IsDir() 118 } else { 119 // Absolute path. 120 realPath = gfile.RealPath(directoryPath) 121 if realPath == "" { 122 // Relative path. 123 a.searchPaths.RLockFunc(func(array []string) { 124 for _, v := range array { 125 if searchedPath, _ := gspath.Search(v, directoryPath); searchedPath != "" { 126 realPath = searchedPath 127 break 128 } 129 } 130 }) 131 } 132 if realPath != "" { 133 isDir = gfile.IsDir(realPath) 134 } 135 } 136 if realPath == "" { 137 buffer := bytes.NewBuffer(nil) 138 if a.searchPaths.Len() > 0 { 139 buffer.WriteString(fmt.Sprintf( 140 `AddPath failed: cannot find directory "%s" in following paths:`, 141 directoryPath, 142 )) 143 a.searchPaths.RLockFunc(func(array []string) { 144 for k, v := range array { 145 buffer.WriteString(fmt.Sprintf("\n%d. %s", k+1, v)) 146 } 147 }) 148 } else { 149 buffer.WriteString(fmt.Sprintf( 150 `AddPath failed: path "%s" does not exist`, 151 directoryPath, 152 )) 153 } 154 return gerror.New(buffer.String()) 155 } 156 if !isDir { 157 return gerror.NewCodef( 158 gcode.CodeInvalidParameter, 159 `AddPath failed: path "%s" should be directory type`, 160 directoryPath, 161 ) 162 } 163 // Repeated path check. 164 if a.searchPaths.Search(realPath) != -1 { 165 return nil 166 } 167 a.searchPaths.Append(realPath) 168 intlog.Print(context.TODO(), "AddPath:", realPath) 169 return nil 170 } 171 172 // GetPaths returns the searching directory path array of current configuration manager. 173 func (a *AdapterFile) GetPaths() []string { 174 return a.searchPaths.Slice() 175 } 176 177 // doGetFilePath returns the absolute configuration file path for the given filename by `file`. 178 // If `file` is not passed, it returns the configuration file path of the default name. 179 // It returns an empty `path` string and an error if the given `file` does not exist. 180 func (a *AdapterFile) doGetFilePath(fileName string) (filePath string) { 181 var ( 182 tempPath string 183 resFile *gres.File 184 fileInfo os.FileInfo 185 ) 186 // Searching resource manager. 187 if !gres.IsEmpty() { 188 for _, tryFolder := range resourceTryFolders { 189 tempPath = tryFolder + fileName 190 if resFile = gres.Get(tempPath); resFile != nil { 191 fileInfo, _ = resFile.Stat() 192 if fileInfo != nil && !fileInfo.IsDir() { 193 filePath = resFile.Name() 194 return 195 } 196 } 197 } 198 a.searchPaths.RLockFunc(func(array []string) { 199 for _, searchPath := range array { 200 for _, tryFolder := range resourceTryFolders { 201 tempPath = searchPath + tryFolder + fileName 202 if resFile = gres.Get(tempPath); resFile != nil { 203 fileInfo, _ = resFile.Stat() 204 if fileInfo != nil && !fileInfo.IsDir() { 205 filePath = resFile.Name() 206 return 207 } 208 } 209 } 210 } 211 }) 212 } 213 214 a.autoCheckAndAddMainPkgPathToSearchPaths() 215 216 // Searching local file system. 217 if filePath == "" { 218 // Absolute path. 219 if filePath = gfile.RealPath(fileName); filePath != "" && !gfile.IsDir(filePath) { 220 return 221 } 222 a.searchPaths.RLockFunc(func(array []string) { 223 for _, searchPath := range array { 224 searchPath = gstr.TrimRight(searchPath, `\/`) 225 for _, tryFolder := range localSystemTryFolders { 226 relativePath := gstr.TrimRight( 227 gfile.Join(tryFolder, fileName), 228 `\/`, 229 ) 230 if filePath, _ = gspath.Search(searchPath, relativePath); filePath != "" && 231 !gfile.IsDir(filePath) { 232 return 233 } 234 } 235 } 236 }) 237 } 238 return 239 } 240 241 // GetFilePath returns the absolute configuration file path for the given filename by `file`. 242 // If `file` is not passed, it returns the configuration file path of the default name. 243 // It returns an empty `path` string and an error if the given `file` does not exist. 244 func (a *AdapterFile) GetFilePath(fileName ...string) (filePath string, err error) { 245 var ( 246 fileExtName string 247 tempFileName string 248 usedFileName = a.defaultName 249 ) 250 if len(fileName) > 0 { 251 usedFileName = fileName[0] 252 } 253 fileExtName = gfile.ExtName(usedFileName) 254 if filePath = a.doGetFilePath(usedFileName); (filePath == "" || gfile.IsDir(filePath)) && !gstr.InArray(supportedFileTypes, fileExtName) { 255 // If it's not using default configuration or its configuration file is not available, 256 // it searches the possible configuration file according to the name and all supported 257 // file types. 258 for _, fileType := range supportedFileTypes { 259 tempFileName = fmt.Sprintf(`%s.%s`, usedFileName, fileType) 260 if filePath = a.doGetFilePath(tempFileName); filePath != "" { 261 break 262 } 263 } 264 } 265 // If it cannot find the filePath of `file`, it formats and returns a detailed error. 266 if filePath == "" { 267 var buffer = bytes.NewBuffer(nil) 268 if a.searchPaths.Len() > 0 { 269 if !gstr.InArray(supportedFileTypes, fileExtName) { 270 buffer.WriteString(fmt.Sprintf( 271 `possible config files "%s" or "%s" not found in resource manager or following system searching paths:`, 272 usedFileName, fmt.Sprintf(`%s.%s`, usedFileName, gstr.Join(supportedFileTypes, "/")), 273 )) 274 } else { 275 buffer.WriteString(fmt.Sprintf( 276 `specified config file "%s" not found in resource manager or following system searching paths:`, 277 usedFileName, 278 )) 279 } 280 a.searchPaths.RLockFunc(func(array []string) { 281 index := 1 282 for _, searchPath := range array { 283 searchPath = gstr.TrimRight(searchPath, `\/`) 284 for _, tryFolder := range localSystemTryFolders { 285 buffer.WriteString(fmt.Sprintf( 286 "\n%d. %s", 287 index, gfile.Join(searchPath, tryFolder), 288 )) 289 index++ 290 } 291 } 292 }) 293 } else { 294 buffer.WriteString(fmt.Sprintf(`cannot find config file "%s" with no filePath configured`, usedFileName)) 295 } 296 err = gerror.NewCode(gcode.CodeNotFound, buffer.String()) 297 } 298 return 299 }