Исправлены замечания линтера, обновлена зависимость yaml.v2 => yaml.v3
This commit is contained in:
parent
a50330fa13
commit
1979c8dce6
79
.gitignore
vendored
79
.gitignore
vendored
@ -1,49 +1,40 @@
|
||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.swp
|
||||
main
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
# ---> Go
|
||||
# If you prefer the allow list template instead of the deny list, see community template:
|
||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||
#
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
*.prof
|
||||
|
||||
# OS generated files #
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Eclipse generated files #
|
||||
.project
|
||||
.classpath
|
||||
.settings
|
||||
**/target/
|
||||
*/bin/
|
||||
.metadata/
|
||||
clientdb.xml
|
||||
# jazz files #
|
||||
.jazzignore
|
||||
.factorypath
|
||||
.gitignore
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
vendor/
|
||||
|
||||
# Go workspace file
|
||||
go.work
|
||||
|
||||
# ---> VisualStudioCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
# Build outputs
|
||||
tmp/
|
||||
out/
|
||||
|
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"eschao",
|
||||
"stretchr"
|
||||
]
|
||||
}
|
18
README.md
18
README.md
@ -4,7 +4,7 @@
|
||||
## Installation
|
||||
1. Install [Yaml](https://github.com/go-yaml/yaml) library first:
|
||||
```
|
||||
go get gopkg.in/yaml.v2
|
||||
go get gopkg.in/yaml.v3
|
||||
```
|
||||
|
||||
2. Install **config** library:
|
||||
@ -16,14 +16,14 @@ go get github.com/eschao/config
|
||||
### I. Define configuration name in structure tags
|
||||
Like JSON, Yaml, **config** uses tags to define configurations:
|
||||
|
||||
| Tag | Example | Function |
|
||||
|-----|---------|------|
|
||||
| json | Host string `json:"host"` | Maps `Host` to a JSON field: **host** |
|
||||
| yaml | Host string `yaml:"host"` | Maps `Host` to a Yaml field: **host** |
|
||||
| env | Host string `env:"HOST"` | Maps `Host` to a Environment variable: **HOST** |
|
||||
| cli | Host string `cli:"host database host"` | Maps `Host` to a command line argument: **-host** or **--host** |
|
||||
| default | Port int `default:"8080"` | Defines the port with default value: **8080** |
|
||||
| separator | Path string `json:"path" separator:";"` | Separator is used to split string to a slice |
|
||||
| Tag | Example | Function |
|
||||
| --------- | --------------------------------------- | --------------------------------------------------------------- |
|
||||
| json | Host string `json:"host"` | Maps `Host` to a JSON field: **host** |
|
||||
| yaml | Host string `yaml:"host"` | Maps `Host` to a Yaml field: **host** |
|
||||
| env | Host string `env:"HOST"` | Maps `Host` to a Environment variable: **HOST** |
|
||||
| cli | Host string `cli:"host database host"` | Maps `Host` to a command line argument: **-host** or **--host** |
|
||||
| default | Port int `default:"8080"` | Defines the port with default value: **8080** |
|
||||
| separator | Path string `json:"path" separator:";"` | Separator is used to split string to a slice |
|
||||
|
||||
|
||||
#### 1. Data types
|
||||
|
104
cli/cli.go
104
cli/cli.go
@ -37,60 +37,60 @@ func newAnyValue(v reflect.Value) *anyValue {
|
||||
return &anyValue{any: v}
|
||||
}
|
||||
|
||||
func (this *anyValue) String() string {
|
||||
kind := this.any.Kind()
|
||||
func (v *anyValue) String() string {
|
||||
kind := v.any.Kind()
|
||||
switch kind {
|
||||
case reflect.Bool:
|
||||
return strconv.FormatBool(this.any.Bool())
|
||||
return strconv.FormatBool(v.any.Bool())
|
||||
case reflect.String:
|
||||
return this.any.String()
|
||||
return v.any.String()
|
||||
case reflect.Int8,
|
||||
reflect.Int16,
|
||||
reflect.Int,
|
||||
reflect.Int32,
|
||||
reflect.Int64:
|
||||
return strconv.FormatInt(this.any.Int(), 10)
|
||||
return strconv.FormatInt(v.any.Int(), 10)
|
||||
case reflect.Uint8,
|
||||
reflect.Uint16,
|
||||
reflect.Uint,
|
||||
reflect.Uint32,
|
||||
reflect.Uint64:
|
||||
return strconv.FormatUint(this.any.Uint(), 10)
|
||||
return strconv.FormatUint(v.any.Uint(), 10)
|
||||
case reflect.Float32:
|
||||
return strconv.FormatFloat(this.any.Float(), 'E', -1, 32)
|
||||
return strconv.FormatFloat(v.any.Float(), 'E', -1, 32)
|
||||
case reflect.Float64:
|
||||
return strconv.FormatFloat(this.any.Float(), 'E', -1, 64)
|
||||
return strconv.FormatFloat(v.any.Float(), 'E', -1, 64)
|
||||
}
|
||||
return fmt.Sprintf("unsupport type %s", kind.String())
|
||||
return fmt.Sprintf("unsupported type: %s", kind.String())
|
||||
}
|
||||
|
||||
func (this *anyValue) Set(v string) error {
|
||||
kind := this.any.Kind()
|
||||
func (av *anyValue) Set(v string) error {
|
||||
kind := av.any.Kind()
|
||||
switch kind {
|
||||
case reflect.String:
|
||||
this.any.SetString(v)
|
||||
av.any.SetString(v)
|
||||
case reflect.Float32:
|
||||
return utils.SetValueWithFloatX(this.any, v, 32)
|
||||
return utils.SetValueWithFloatX(av.any, v, 32)
|
||||
case reflect.Float64:
|
||||
return utils.SetValueWithFloatX(this.any, v, 64)
|
||||
return utils.SetValueWithFloatX(av.any, v, 64)
|
||||
case reflect.Int8:
|
||||
return utils.SetValueWithIntX(this.any, v, 8)
|
||||
return utils.SetValueWithIntX(av.any, v, 8)
|
||||
case reflect.Int16:
|
||||
return utils.SetValueWithIntX(this.any, v, 16)
|
||||
return utils.SetValueWithIntX(av.any, v, 16)
|
||||
case reflect.Int, reflect.Int32:
|
||||
return utils.SetValueWithIntX(this.any, v, 32)
|
||||
return utils.SetValueWithIntX(av.any, v, 32)
|
||||
case reflect.Int64:
|
||||
return utils.SetValueWithIntX(this.any, v, 64)
|
||||
return utils.SetValueWithIntX(av.any, v, 64)
|
||||
case reflect.Uint8:
|
||||
return utils.SetValueWithUintX(this.any, v, 8)
|
||||
return utils.SetValueWithUintX(av.any, v, 8)
|
||||
case reflect.Uint16:
|
||||
return utils.SetValueWithUintX(this.any, v, 16)
|
||||
return utils.SetValueWithUintX(av.any, v, 16)
|
||||
case reflect.Uint, reflect.Uint32:
|
||||
return utils.SetValueWithUintX(this.any, v, 32)
|
||||
return utils.SetValueWithUintX(av.any, v, 32)
|
||||
case reflect.Uint64:
|
||||
return utils.SetValueWithUintX(this.any, v, 64)
|
||||
return utils.SetValueWithUintX(av.any, v, 64)
|
||||
default:
|
||||
return fmt.Errorf("Can't support type %s", kind.String())
|
||||
return fmt.Errorf("unsupported type: %s", kind.String())
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -107,19 +107,19 @@ func newSliceValue(v reflect.Value, separator string) *sliceValue {
|
||||
return &sliceValue{value: v, separator: separator}
|
||||
}
|
||||
|
||||
func (this *sliceValue) String() string {
|
||||
return this.value.String()
|
||||
func (sv *sliceValue) String() string {
|
||||
return sv.value.String()
|
||||
}
|
||||
|
||||
func (this *sliceValue) Set(v string) error {
|
||||
sp := this.separator
|
||||
func (sv *sliceValue) Set(v string) error {
|
||||
sp := sv.separator
|
||||
if sp == "" {
|
||||
sp = ":"
|
||||
}
|
||||
return utils.SetValueWithSlice(this.value, v, sp)
|
||||
return utils.SetValueWithSlice(sv.value, v, sp)
|
||||
}
|
||||
|
||||
// errorHanling is a global flag.ErrorHandling
|
||||
// errorHandling is a global flag.ErrorHandling
|
||||
var errorHandling = flag.ExitOnError
|
||||
|
||||
// UsageFunc defines a callback function for printing command usage
|
||||
@ -171,25 +171,25 @@ func NewWith(name string, errHandling flag.ErrorHandling,
|
||||
// Init analyzes the given structure interface, extracts cli definitions from
|
||||
// its tag and installs command flagset by flag APIs. The interface must be a
|
||||
// structure pointer, otherwise will return an error
|
||||
func (this *Command) Init(i interface{}) error {
|
||||
func (c *Command) Init(i interface{}) error {
|
||||
ptrRef := reflect.ValueOf(i)
|
||||
|
||||
if ptrRef.IsNil() || ptrRef.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("Expect a structure pointer type instead of %s",
|
||||
return fmt.Errorf("expect a structure pointer type instead of %s",
|
||||
ptrRef.Kind().String())
|
||||
}
|
||||
|
||||
valueOfStruct := ptrRef.Elem()
|
||||
if valueOfStruct.Kind() != reflect.Struct {
|
||||
return fmt.Errorf("Expect a structure type instead of %s",
|
||||
return fmt.Errorf("expect a structure type instead of %s",
|
||||
valueOfStruct.Kind().String())
|
||||
}
|
||||
|
||||
return this.parseValue(valueOfStruct)
|
||||
return c.parseValue(valueOfStruct)
|
||||
}
|
||||
|
||||
// parseValue parses a reflect.Value object and extracts cli definitions
|
||||
func (this *Command) parseValue(v reflect.Value) error {
|
||||
func (c *Command) parseValue(v reflect.Value) error {
|
||||
typeOfStruct := v.Type()
|
||||
var err error
|
||||
|
||||
@ -200,14 +200,14 @@ func (this *Command) parseValue(v reflect.Value) error {
|
||||
|
||||
if kindOfField == reflect.Ptr {
|
||||
if !valueOfField.IsNil() && valueOfField.CanSet() {
|
||||
cmd := this.createSubCommand(structOfField.Tag)
|
||||
cmd := c.createSubCommand(structOfField.Tag)
|
||||
err = cmd.Init(valueOfField.Interface())
|
||||
}
|
||||
} else if kindOfField == reflect.Struct {
|
||||
cmd := this.createSubCommand(structOfField.Tag)
|
||||
cmd := c.createSubCommand(structOfField.Tag)
|
||||
err = cmd.parseValue(valueOfField)
|
||||
} else {
|
||||
err = this.addFlag(valueOfField, structOfField)
|
||||
err = c.addFlag(valueOfField, structOfField)
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,7 +215,7 @@ func (this *Command) parseValue(v reflect.Value) error {
|
||||
}
|
||||
|
||||
// addFlag installs a command flag variable by flag API
|
||||
func (this *Command) addFlag(v reflect.Value, f reflect.StructField) error {
|
||||
func (c *Command) addFlag(v reflect.Value, f reflect.StructField) error {
|
||||
cmdTag, ok := f.Tag.Lookup("cli")
|
||||
if !ok || cmdTag == "" {
|
||||
return nil
|
||||
@ -232,7 +232,7 @@ func (this *Command) addFlag(v reflect.Value, f reflect.StructField) error {
|
||||
kind := v.Kind()
|
||||
switch kind {
|
||||
case reflect.Bool:
|
||||
this.FlagSet.BoolVar((*bool)(unsafe.Pointer(v.UnsafeAddr())), name,
|
||||
c.FlagSet.BoolVar((*bool)(unsafe.Pointer(v.UnsafeAddr())), name,
|
||||
false, usage)
|
||||
return nil
|
||||
case reflect.String,
|
||||
@ -249,22 +249,22 @@ func (this *Command) addFlag(v reflect.Value, f reflect.StructField) error {
|
||||
reflect.Float32,
|
||||
reflect.Float64:
|
||||
anyValue := newAnyValue(v)
|
||||
this.FlagSet.Var(anyValue, name, usage)
|
||||
c.FlagSet.Var(anyValue, name, usage)
|
||||
case reflect.Slice:
|
||||
sliceValue := newSliceValue(v, f.Tag.Get("separator"))
|
||||
this.FlagSet.Var(sliceValue, name, usage)
|
||||
c.FlagSet.Var(sliceValue, name, usage)
|
||||
default:
|
||||
return fmt.Errorf("Can't support type %s", kind.String())
|
||||
return fmt.Errorf("unsupported type: %s", kind.String())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createSubCommand creates sub-commands
|
||||
func (this *Command) createSubCommand(tag reflect.StructTag) *Command {
|
||||
func (c *Command) createSubCommand(tag reflect.StructTag) *Command {
|
||||
cmdTag, ok := tag.Lookup("cli")
|
||||
if !ok || cmdTag == "" {
|
||||
return this
|
||||
return c
|
||||
}
|
||||
|
||||
cmd := Command{SubCommands: make(map[string]*Command)}
|
||||
@ -284,29 +284,29 @@ func (this *Command) createSubCommand(tag reflect.StructTag) *Command {
|
||||
cmd.FlagSet.Usage = usageHandler(&cmd)
|
||||
}
|
||||
|
||||
this.SubCommands[name] = &cmd
|
||||
c.SubCommands[name] = &cmd
|
||||
return &cmd
|
||||
}
|
||||
|
||||
// Parse parses values from command line and save values into given structure.
|
||||
// The Init(interface{}) function must be called before parsing
|
||||
func (this *Command) Parse(args []string) error {
|
||||
if err := this.FlagSet.Parse(args); err != nil {
|
||||
func (c *Command) Parse(args []string) error {
|
||||
if err := c.FlagSet.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
unprocessed := this.FlagSet.Args()
|
||||
unprocessed := c.FlagSet.Args()
|
||||
if len(unprocessed) < 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if this.SubCommands == nil {
|
||||
return fmt.Errorf("Command: %s is unsupport", unprocessed[0])
|
||||
if c.SubCommands == nil {
|
||||
return fmt.Errorf("unsupported command: %s", unprocessed[0])
|
||||
}
|
||||
|
||||
cmd := this.SubCommands[unprocessed[0]]
|
||||
cmd := c.SubCommands[unprocessed[0]]
|
||||
if cmd == nil {
|
||||
return fmt.Errorf("Command: %s is unsupport", unprocessed[0])
|
||||
return fmt.Errorf("unsupported command: %s", unprocessed[0])
|
||||
}
|
||||
|
||||
return cmd.Parse(unprocessed[1:])
|
||||
|
@ -145,6 +145,7 @@ func TestVariousTypeCommand(t *testing.T) {
|
||||
typesConfig := test.TypesConfig{}
|
||||
cmd := NewWith("Types", flag.ContinueOnError, func(cmd *Command) func() {
|
||||
return func() {
|
||||
// Stub
|
||||
}
|
||||
})
|
||||
assert.NoError(cmd.Init(&typesConfig))
|
||||
|
34
config.go
34
config.go
@ -27,7 +27,7 @@ import (
|
||||
"github.com/eschao/config/cli"
|
||||
"github.com/eschao/config/env"
|
||||
"github.com/eschao/config/utils"
|
||||
"gopkg.in/yaml.v2"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Default configuration file
|
||||
@ -51,13 +51,13 @@ func ParseDefault(i interface{}) error {
|
||||
ptrRef := reflect.ValueOf(i)
|
||||
|
||||
if ptrRef.IsNil() || ptrRef.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("Expect a structure pointer type instead of %s",
|
||||
return fmt.Errorf("expect a structure pointer type instead of %s",
|
||||
ptrRef.Kind().String())
|
||||
}
|
||||
|
||||
valueOfStruct := ptrRef.Elem()
|
||||
if valueOfStruct.Kind() != reflect.Struct {
|
||||
return fmt.Errorf("Expect a structure pointer type instead of %s",
|
||||
return fmt.Errorf("expect a structure pointer type instead of %s",
|
||||
valueOfStruct.Kind().String())
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ func parseValue(v reflect.Value) error {
|
||||
err = utils.SetValueWithSlice(valueOfField, defValue, sp)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("Can't support type: %s", kind.String())
|
||||
return fmt.Errorf("unsupported type: %s", kind.String())
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +153,7 @@ func ParseCli(i interface{}) error {
|
||||
// under the same folder with the fixed order: config.json, config.yaml and
|
||||
// config.properties
|
||||
func ParseConfig(i interface{}, configFlag string) error {
|
||||
configFile := flag.String(configFlag, "", "Specifiy configuration file")
|
||||
configFile := flag.String(configFlag, "", "Specify configuration file")
|
||||
flag.Parse()
|
||||
return ParseConfigFile(i, *configFile)
|
||||
}
|
||||
@ -176,23 +176,23 @@ func ParseConfigFile(i interface{}, configFile string) error {
|
||||
|
||||
switch configType {
|
||||
case JSONConfigType:
|
||||
return parseJSON(i, configFile)
|
||||
err = parseJSON(i, configFile)
|
||||
case YamlConfigType:
|
||||
return parseYaml(i, configFile)
|
||||
err = parseYaml(i, configFile)
|
||||
case PropConfigType:
|
||||
return parseProp(i, configFile)
|
||||
err = parseProp(i, configFile)
|
||||
default:
|
||||
return fmt.Errorf("Can't support config file: %s", configFile)
|
||||
err = fmt.Errorf("unsupported config file: %s", configFile)
|
||||
}
|
||||
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// parseJSON parses JSON file and set structure with its value
|
||||
func parseJSON(i interface{}, jsonFile string) error {
|
||||
raw, err := ioutil.ReadFile(jsonFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Can't open json config file. %s", err.Error())
|
||||
return fmt.Errorf("open json config file: %s", err.Error())
|
||||
}
|
||||
|
||||
return json.Unmarshal(raw, i)
|
||||
@ -202,15 +202,15 @@ func parseJSON(i interface{}, jsonFile string) error {
|
||||
func parseYaml(i interface{}, yamlFile string) error {
|
||||
raw, err := ioutil.ReadFile(yamlFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Can't open yaml config file. %s", err.Error())
|
||||
return fmt.Errorf("open yaml config file: %s", err.Error())
|
||||
}
|
||||
|
||||
return yaml.Unmarshal(raw, i)
|
||||
}
|
||||
|
||||
// parseProp parses Properties file and set structure with its value
|
||||
func parseProp(i interface{}, propFile string) error {
|
||||
return fmt.Errorf("Properties config has not implemented!")
|
||||
func parseProp(_ interface{}, _ /*propFile*/ string) error {
|
||||
return fmt.Errorf("properties config is not implemented")
|
||||
}
|
||||
|
||||
// getDefaultConfigFile returns a existing default config file. The checking
|
||||
@ -219,7 +219,7 @@ func parseProp(i interface{}, propFile string) error {
|
||||
func getDefaultConfigFile() (string, error) {
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Can't find default config file. %s", err.Error())
|
||||
return "", fmt.Errorf("find default config file: %s", err.Error())
|
||||
}
|
||||
|
||||
path := filepath.Dir(exe) + string(filepath.Separator)
|
||||
@ -242,7 +242,7 @@ func getDefaultConfigFile() (string, error) {
|
||||
return propConfig, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("No default config file found in path: %s", path)
|
||||
return "", fmt.Errorf("default config file not found in path: %s", path)
|
||||
}
|
||||
|
||||
// getConfigFileType analyzes config file extension name and return
|
||||
@ -257,5 +257,5 @@ func getConfigFileType(configFile string) (string, error) {
|
||||
return PropConfigType, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Can't support file type: %s", configFile)
|
||||
return "", fmt.Errorf("unsupported file type: %s", configFile)
|
||||
}
|
||||
|
32
env/env.go
vendored
32
env/env.go
vendored
@ -24,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
// Parse parses given structure interface, extracts environment definitions
|
||||
// from its tag and sets structure with defined environement variables
|
||||
// from its tag and sets structure with defined environment variables
|
||||
func Parse(i interface{}) error {
|
||||
return ParseWith(i, "")
|
||||
}
|
||||
@ -36,23 +36,24 @@ func Parse(i interface{}) error {
|
||||
// Host string `env:"HOST"`
|
||||
// }
|
||||
|
||||
// type Server struct {
|
||||
// Server string `env:"SERVER"`
|
||||
// DB Database `env:"DB_"`
|
||||
// }
|
||||
// type Server struct {
|
||||
// Server string `env:"SERVER"`
|
||||
// DB Database `env:"DB_"`
|
||||
// }
|
||||
//
|
||||
// The Server.DB.Host will be mapped to environment variable: DB_HOST which is
|
||||
// concatenated from DB tag in Server struct and Host tag in Database struct
|
||||
func ParseWith(i interface{}, prefix string) error {
|
||||
ptrRef := reflect.ValueOf(i)
|
||||
|
||||
if ptrRef.IsNil() || ptrRef.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("Expect a structure pointer type instead of %s",
|
||||
return fmt.Errorf("expect a structure pointer type instead of %s",
|
||||
ptrRef.Kind().String())
|
||||
}
|
||||
|
||||
valueOfStruct := ptrRef.Elem()
|
||||
if valueOfStruct.Kind() != reflect.Struct {
|
||||
return fmt.Errorf("Expect a structure pointer type instead of %s",
|
||||
return fmt.Errorf("expect a structure pointer type instead of %s",
|
||||
valueOfStruct.Kind().String())
|
||||
}
|
||||
|
||||
@ -80,23 +81,16 @@ func parseValue(v reflect.Value, prefix string) error {
|
||||
err = parseValue(valueOfField, prefix+structOfField.Tag.Get("env"))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = setFieldValue(valueOfField, structOfField, prefix)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// getEnvValue get environment value
|
||||
func getEnvValue(envName string, f reflect.StructField) (string, bool) {
|
||||
//fmt.Printf("Lookup ENV: %s\n", envName)
|
||||
envValue, ok := os.LookupEnv(envName)
|
||||
if !ok {
|
||||
envValue, ok = f.Tag.Lookup("default")
|
||||
}
|
||||
|
||||
return envValue, ok
|
||||
}
|
||||
|
||||
// setFieldValue sets a reflect.Value with environment value
|
||||
func setFieldValue(v reflect.Value, f reflect.StructField, prefix string) error {
|
||||
envName := f.Tag.Get("env")
|
||||
@ -149,7 +143,7 @@ func setFieldValue(v reflect.Value, f reflect.StructField, prefix string) error
|
||||
err = utils.SetValueWithSlice(v, envValue, sp)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("Can't support type: %s", kind.String())
|
||||
return fmt.Errorf("unsupported type: %s", kind.String())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
14
go.mod
Normal file
14
go.mod
Normal file
@ -0,0 +1,14 @@
|
||||
module git.mousesoft.ru/ms/config
|
||||
|
||||
go 1.23
|
||||
|
||||
require (
|
||||
github.com/eschao/config v0.1.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
)
|
17
go.sum
Normal file
17
go.sum
Normal file
@ -0,0 +1,17 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/eschao/config v0.1.0 h1:vtlNamzs6dC9pE0zyplqql16PFUUlst3VttQ+IT2/rk=
|
||||
github.com/eschao/config v0.1.0/go.mod h1:XMilcx0dPfk+tlJowGZPZdmdCRnd7AZuFhYA93tYBgA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
Loading…
Reference in New Issue
Block a user