From 12fdfbf8b2b1e66fdcd9d1f6490b457adce39bfe Mon Sep 17 00:00:00 2001 From: John Guo Date: Tue, 1 Mar 2022 21:14:45 +0800 Subject: [PATCH] improve package gcfg --- os/gcfg/gcfg.go | 29 ++++--------- os/gcfg/gcfg_adapter_file.go | 3 +- os/gcfg/gcfg_adapter_file_content.go | 6 +-- os/gcfg/gcfg_adapter_file_path.go | 61 ++++++++++++++++++++-------- os/gcfg/gcfg_z_unit_basic_test.go | 16 +++++--- os/gcfg/gcfg_z_unit_instance_test.go | 10 +++-- os/gfile/gfile.go | 7 +++- 7 files changed, 79 insertions(+), 53 deletions(-) diff --git a/os/gcfg/gcfg.go b/os/gcfg/gcfg.go index 74cad55d0..c32f00d97 100644 --- a/os/gcfg/gcfg.go +++ b/os/gcfg/gcfg.go @@ -9,7 +9,6 @@ package gcfg import ( "context" - "fmt" "github.com/gogf/gf/v2/container/gvar" "github.com/gogf/gf/v2/errors/gcode" @@ -26,7 +25,8 @@ type Config struct { } const ( - DefaultName = "config" // DefaultName is the default group name for instance usage. + DefaultInstanceName = "config" // DefaultName is the default instance name for instance usage. + DefaultConfigFileName = "config" // DefaultConfigFile is the default configuration file name. ) // New creates and returns a Config object with default adapter of AdapterFile. @@ -52,31 +52,20 @@ func NewWithAdapter(adapter Adapter) *Config { // exists in the configuration directory, it then sets it as the default configuration file. The // toml file type is the default configuration file type. func Instance(name ...string) *Config { - var ( - ctx = context.TODO() - key = DefaultName - ) + var instanceName = DefaultInstanceName if len(name) > 0 && name[0] != "" { - key = name[0] + instanceName = name[0] } - return localInstances.GetOrSetFuncLock(key, func() interface{} { - adapter, err := NewAdapterFile() + return localInstances.GetOrSetFuncLock(instanceName, func() interface{} { + adapterFile, err := NewAdapterFile() if err != nil { intlog.Errorf(context.Background(), `%+v`, err) return nil } - // If it's not using default configuration or its configuration file is not available, - // it searches the possible configuration file according to the name and all supported - // file types. - if key != DefaultName || !adapter.Available(ctx) { - for _, fileType := range supportedFileTypes { - if file := fmt.Sprintf(`%s.%s`, key, fileType); adapter.Available(ctx, file) { - adapter.SetFileName(file) - break - } - } + if instanceName != DefaultInstanceName { + adapterFile.SetFileName(instanceName) } - return NewWithAdapter(adapter) + return NewWithAdapter(adapterFile) }).(*Config) } diff --git a/os/gcfg/gcfg_adapter_file.go b/os/gcfg/gcfg_adapter_file.go index 80ea4c4c7..795228432 100644 --- a/os/gcfg/gcfg_adapter_file.go +++ b/os/gcfg/gcfg_adapter_file.go @@ -30,7 +30,6 @@ type AdapterFile struct { } const ( - DefaultConfigFile = "config.toml" // DefaultConfigFile is the default configuration file name. commandEnvKeyForFile = "gf.gcfg.file" // commandEnvKeyForFile is the configuration key for command argument or environment configuring file name. commandEnvKeyForPath = "gf.gcfg.path" // commandEnvKeyForPath is the configuration key for command argument or environment configuring directory path. ) @@ -55,7 +54,7 @@ var ( func NewAdapterFile(file ...string) (*AdapterFile, error) { var ( err error - name = DefaultConfigFile + name = DefaultConfigFileName ) if len(file) > 0 { name = file[0] diff --git a/os/gcfg/gcfg_adapter_file_content.go b/os/gcfg/gcfg_adapter_file_content.go index f72f7ff09..b709fe393 100644 --- a/os/gcfg/gcfg_adapter_file_content.go +++ b/os/gcfg/gcfg_adapter_file_content.go @@ -15,7 +15,7 @@ import ( // SetContent sets customized configuration content for specified `file`. // The `file` is unnecessary param, default is DefaultConfigFile. func (c *AdapterFile) SetContent(content string, file ...string) { - name := DefaultConfigFile + name := DefaultConfigFileName if len(file) > 0 { name = file[0] } @@ -37,7 +37,7 @@ func (c *AdapterFile) SetContent(content string, file ...string) { // GetContent returns customized configuration content for specified `file`. // The `file` is unnecessary param, default is DefaultConfigFile. func (c *AdapterFile) GetContent(file ...string) string { - name := DefaultConfigFile + name := DefaultConfigFileName if len(file) > 0 { name = file[0] } @@ -47,7 +47,7 @@ func (c *AdapterFile) GetContent(file ...string) string { // RemoveContent removes the global configuration with specified `file`. // If `name` is not passed, it removes configuration of the default group name. func (c *AdapterFile) RemoveContent(file ...string) { - name := DefaultConfigFile + name := DefaultConfigFileName if len(file) > 0 { name = file[0] } diff --git a/os/gcfg/gcfg_adapter_file_path.go b/os/gcfg/gcfg_adapter_file_path.go index b23c682fc..c4149a983 100644 --- a/os/gcfg/gcfg_adapter_file_path.go +++ b/os/gcfg/gcfg_adapter_file_path.go @@ -138,21 +138,15 @@ func (c *AdapterFile) AddPath(path string) (err error) { return nil } -// GetFilePath returns the absolute configuration file path for the given filename by `file`. +// doGetFilePath returns the absolute configuration file path for the given filename by `file`. // If `file` is not passed, it returns the configuration file path of the default name. // It returns an empty `path` string and an error if the given `file` does not exist. -func (c *AdapterFile) GetFilePath(fileName ...string) (path string, err error) { - var ( - tempPath string - usedFileName = c.defaultName - ) - if len(fileName) > 0 { - usedFileName = fileName[0] - } +func (c *AdapterFile) doGetFilePath(fileName string) (path string) { + var tempPath string // Searching resource manager. if !gres.IsEmpty() { for _, tryFolder := range resourceTryFolders { - tempPath = tryFolder + usedFileName + tempPath = tryFolder + fileName if file := gres.Get(tempPath); file != nil { path = file.Name() return @@ -161,7 +155,7 @@ func (c *AdapterFile) GetFilePath(fileName ...string) (path string, err error) { c.searchPaths.RLockFunc(func(array []string) { for _, searchPath := range array { for _, tryFolder := range resourceTryFolders { - tempPath = searchPath + tryFolder + usedFileName + tempPath = searchPath + tryFolder + fileName if file := gres.Get(tempPath); file != nil { path = file.Name() return @@ -176,7 +170,7 @@ func (c *AdapterFile) GetFilePath(fileName ...string) (path string, err error) { // Searching local file system. if path == "" { // Absolute path. - if path = gfile.RealPath(usedFileName); path != "" { + if path = gfile.RealPath(fileName); path != "" { return } c.searchPaths.RLockFunc(func(array []string) { @@ -184,7 +178,7 @@ func (c *AdapterFile) GetFilePath(fileName ...string) (path string, err error) { searchPath = gstr.TrimRight(searchPath, `\/`) for _, tryFolder := range localSystemTryFolders { relativePath := gstr.TrimRight( - gfile.Join(tryFolder, usedFileName), + gfile.Join(tryFolder, fileName), `\/`, ) if path, _ = gspath.Search(searchPath, relativePath); path != "" { @@ -194,15 +188,48 @@ func (c *AdapterFile) GetFilePath(fileName ...string) (path string, err error) { } }) } + return +} +// GetFilePath returns the absolute configuration file path for the given filename by `file`. +// If `file` is not passed, it returns the configuration file path of the default name. +// It returns an empty `path` string and an error if the given `file` does not exist. +func (c *AdapterFile) GetFilePath(fileName ...string) (path string, err error) { + var ( + fileExtName string + tempFileName string + usedFileName = c.defaultName + ) + if len(fileName) > 0 { + usedFileName = fileName[0] + } + fileExtName = gfile.ExtName(usedFileName) + if path = c.doGetFilePath(usedFileName); path == "" && !gstr.InArray(supportedFileTypes, fileExtName) { + // If it's not using default configuration or its configuration file is not available, + // it searches the possible configuration file according to the name and all supported + // file types. + for _, fileType := range supportedFileTypes { + tempFileName = fmt.Sprintf(`%s.%s`, usedFileName, fileType) + if path = c.doGetFilePath(tempFileName); path != "" { + break + } + } + } // If it cannot find the path of `file`, it formats and returns a detailed error. if path == "" { var buffer = bytes.NewBuffer(nil) if c.searchPaths.Len() > 0 { - buffer.WriteString(fmt.Sprintf( - `config file "%s" not found in resource manager or the following system searching paths:`, - usedFileName, - )) + if !gstr.InArray(supportedFileTypes, fileExtName) { + buffer.WriteString(fmt.Sprintf( + `possible config files "%s" or "%s" not found in resource manager or following system searching paths:`, + usedFileName, fmt.Sprintf(`%s.%s`, usedFileName, gstr.Join(supportedFileTypes, "/")), + )) + } else { + buffer.WriteString(fmt.Sprintf( + `specified config file "%s" not found in resource manager or following system searching paths:`, + usedFileName, + )) + } c.searchPaths.RLockFunc(func(array []string) { index := 1 for _, searchPath := range array { diff --git a/os/gcfg/gcfg_z_unit_basic_test.go b/os/gcfg/gcfg_z_unit_basic_test.go index c9c11d24f..67ecbe29e 100644 --- a/os/gcfg/gcfg_z_unit_basic_test.go +++ b/os/gcfg/gcfg_z_unit_basic_test.go @@ -31,9 +31,11 @@ array = [1,2,3] cache = "127.0.0.1:6379,1" ` gtest.C(t, func(t *gtest.T) { - path := gcfg.DefaultConfigFile - err := gfile.PutContents(path, config) - t.Assert(err, nil) + var ( + path = gcfg.DefaultConfigFileName + err = gfile.PutContents(path, config) + ) + t.AssertNil(err) defer gfile.Remove(path) c, err := gcfg.New() @@ -47,9 +49,11 @@ array = [1,2,3] func Test_Basic2(t *testing.T) { config := `log-path = "logs"` gtest.C(t, func(t *gtest.T) { - path := gcfg.DefaultConfigFile - err := gfile.PutContents(path, config) - t.Assert(err, nil) + var ( + path = gcfg.DefaultConfigFileName + err = gfile.PutContents(path, config) + ) + t.AssertNil(err) defer func() { _ = gfile.Remove(path) }() diff --git a/os/gcfg/gcfg_z_unit_instance_test.go b/os/gcfg/gcfg_z_unit_instance_test.go index 2e7f0dc42..3cc5997b4 100644 --- a/os/gcfg/gcfg_z_unit_instance_test.go +++ b/os/gcfg/gcfg_z_unit_instance_test.go @@ -37,11 +37,13 @@ v4 = "1.234" ` gtest.C(t, func(t *gtest.T) { - path := DefaultConfigFile - err := gfile.PutContents(path, config) - t.Assert(err, nil) + var ( + path = DefaultConfigFileName + err = gfile.PutContents(path, config) + ) + t.AssertNil(err) defer func() { - t.Assert(gfile.Remove(path), nil) + t.AssertNil(gfile.Remove(path)) }() c := Instance() diff --git a/os/gfile/gfile.go b/os/gfile/gfile.go index 590112bf7..7d29a4279 100644 --- a/os/gfile/gfile.go +++ b/os/gfile/gfile.go @@ -417,8 +417,10 @@ func IsEmpty(path string) bool { // The extension is the suffix beginning at the final dot // in the final element of path; it is empty if there is // no dot. -// // Note: the result contains symbol '.'. +// Eg: +// main.go => .go +// api.json => .json func Ext(path string) string { ext := filepath.Ext(path) if p := strings.IndexByte(ext, '?'); p != -1 { @@ -429,6 +431,9 @@ func Ext(path string) string { // ExtName is like function Ext, which returns the file name extension used by path, // but the result does not contain symbol '.'. +// Eg: +// main.go => go +// api.json => json func ExtName(path string) string { return strings.TrimLeft(Ext(path), ".") }