Исправлены замечания линтера, обновлена зависимость 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" | ||||
|     ] | ||||
| } | ||||
| @ -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: | ||||
| @ -17,7 +17,7 @@ go get github.com/eschao/config | ||||
| 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**                 | | ||||
|  | ||||
							
								
								
									
										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) | ||||
| } | ||||
|  | ||||
							
								
								
									
										24
									
								
								env/env.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								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, "") | ||||
| } | ||||
| @ -40,19 +40,20 @@ func Parse(i interface{}) error { | ||||
| //	  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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user