From a0213d141584f2f89bff5469dd895137f8e49f52 Mon Sep 17 00:00:00 2001 From: lvlcn-t <75443136+lvlcn-t@users.noreply.github.com> Date: Mon, 15 Jul 2024 18:37:19 +0200 Subject: [PATCH] chore: rename config.Settings interface to config.Loadable --- config/loader.go | 37 +++++++++++++++++++++++-------------- config/loader_test.go | 6 +++--- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/config/loader.go b/config/loader.go index e0e3a5d..9757921 100644 --- a/config/loader.go +++ b/config/loader.go @@ -18,12 +18,12 @@ import ( var ( // fsys is the filesystem used to load the configuration fsys afero.Fs = afero.NewOsFs() - // bin is the name of the binary - bin string = filepath.Base(os.Args[0]) + // appName is the name of the application (default: binary name) + appName string = filepath.Base(os.Args[0]) ) -// Settings is an interface that must be implemented by a configuration struct -type Settings interface { +// Loadable is an interface that must be implemented by a configuration struct to be loaded. +type Loadable interface { // IsEmpty returns true if the configuration is empty IsEmpty() bool } @@ -36,20 +36,29 @@ type Fallback func() (string, error) // // You can provide a slice of fallback functions that will be used to get the configuration path if an empty path is provided. // The first fallback function that returns a path is used. -// If no fallback functions are provided, the default fallback is used (~/.config//config.yaml). +// If no fallback functions are provided, the default fallback is used (~/.config//config.yaml). // -// All environment variables with the scheme "_(_)" will be considered. +// All environment variables with the scheme "_(_)" will be considered. // // The configuration is unmarshalled into the provided struct. // Its IsEmpty method is called to check if the loaded configuration is empty. -// Most of the time, you want to implement it like this: +// +// Example: +// +// type Config struct { +// Host string +// Port int +// } // // func (c Config) IsEmpty() bool { // return c == (Config{}) // } // -// Note: If the configuration is a pointer to a struct, the experimental feature behind viper.ExperimentalBindStruct() will not be used. -func Load[T Settings](path string, fallbacks ...Fallback) (cfg T, err error) { +// cfg, err := config.Load[Config]("config.yaml") +// if err != nil { +// // Handle error +// } +func Load[T Loadable](path string, fallbacks ...Fallback) (cfg T, err error) { cfg, err = ensureStruct(cfg) if err != nil { return cfg, fmt.Errorf("given type is not a struct: %w", err) @@ -73,7 +82,7 @@ func Load[T Settings](path string, fallbacks ...Fallback) (cfg T, err error) { } v.SetConfigFile(path) - v.SetEnvPrefix(strings.ToUpper(strings.ReplaceAll(bin, "-", "_"))) + v.SetEnvPrefix(strings.ToUpper(strings.ReplaceAll(appName, "-", "_"))) v.SetEnvKeyReplacer(strings.NewReplacer(".", "_", "-", "_")) v.AutomaticEnv() @@ -94,10 +103,10 @@ func Load[T Settings](path string, fallbacks ...Fallback) (cfg T, err error) { return cfg, nil } -// SetBinaryName replaces the default binary name with the provided one. +// SetName replaces the default application name with the provided one. // This function is not safe for concurrent use. -func SetBinaryName(name string) { - bin = name +func SetName(name string) { + appName = name } // SetFs replaces the default filesystem with the provided one. @@ -113,7 +122,7 @@ func defaultFallback() (string, error) { if err != nil { return "", fmt.Errorf("failed to get user home directory: %w", err) } - return filepath.Join(home, bin, "config.yaml"), nil + return filepath.Join(home, appName, "config.yaml"), nil } // ensureStruct ensures that the provided value is a struct or a pointer to a struct. diff --git a/config/loader_test.go b/config/loader_test.go index c712927..642c1d7 100644 --- a/config/loader_test.go +++ b/config/loader_test.go @@ -24,7 +24,7 @@ func TestLoad(t *testing.T) { name string path string fallbacks []Fallback - want Settings + want Loadable wantErr bool errType reflect.Type }{ @@ -112,7 +112,7 @@ func TestLoad_Pointer(t *testing.T) { tests := []struct { name string path string - want Settings + want Loadable wantErr bool }{ { @@ -152,7 +152,7 @@ func TestLoad_Pointer(t *testing.T) { } } -func setup(t *testing.T, path string, cfg Settings, fallbacks ...Fallback) { +func setup(t *testing.T, path string, cfg Loadable, fallbacks ...Fallback) { t.Helper() if path == "" { var err error