Исправлены замечания линтера, обновлена зависимость 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) | # ---> Go | ||||||
| *.o | # If you prefer the allow list template instead of the deny list, see community template: | ||||||
| *.a | # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore | ||||||
| *.so | # | ||||||
| *.swp | # Binaries for programs and plugins | ||||||
| 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 |  | ||||||
| 
 |  | ||||||
| *.exe | *.exe | ||||||
|  | *.exe~ | ||||||
|  | *.dll | ||||||
|  | *.so | ||||||
|  | *.dylib | ||||||
|  | 
 | ||||||
|  | # Test binary, built with `go test -c` | ||||||
| *.test | *.test | ||||||
| *.prof |  | ||||||
| 
 | 
 | ||||||
| # OS generated files # | # Output of the go coverage tool, specifically when used with LiteIDE | ||||||
| .DS_Store | *.out | ||||||
| .DS_Store? |  | ||||||
| ._* |  | ||||||
| .Spotlight-V100 |  | ||||||
| .Trashes |  | ||||||
| ehthumbs.db |  | ||||||
| Thumbs.db |  | ||||||
| 
 | 
 | ||||||
| # Eclipse generated files # | # Dependency directories (remove the comment below to include it) | ||||||
| .project | vendor/ | ||||||
| .classpath |  | ||||||
| .settings |  | ||||||
| **/target/ |  | ||||||
| */bin/ |  | ||||||
| .metadata/ |  | ||||||
| clientdb.xml |  | ||||||
| # jazz files # |  | ||||||
| .jazzignore |  | ||||||
| .factorypath |  | ||||||
| .gitignore |  | ||||||
| 
 | 
 | ||||||
|  | # 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 | ## Installation | ||||||
| 1. Install [Yaml](https://github.com/go-yaml/yaml) library first: | 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: | 2. Install **config** library: | ||||||
| @ -17,7 +17,7 @@ go get github.com/eschao/config | |||||||
| Like JSON, Yaml, **config** uses tags to define configurations: | Like JSON, Yaml, **config** uses tags to define configurations: | ||||||
| 
 | 
 | ||||||
| | Tag       | Example                                 | Function                                                        | | | Tag       | Example                                 | Function                                                        | | ||||||
| |-----|---------|------| | | --------- | --------------------------------------- | --------------------------------------------------------------- | | ||||||
| | json      | Host string `json:"host"`               | Maps `Host` to a JSON field: **host**                           | | | json      | Host string `json:"host"`               | Maps `Host` to a JSON field: **host**                           | | ||||||
| | yaml      | Host string `yaml:"host"`               | Maps `Host` to a Yaml 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**                 | | | 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} | 	return &anyValue{any: v} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (this *anyValue) String() string { | func (v *anyValue) String() string { | ||||||
| 	kind := this.any.Kind() | 	kind := v.any.Kind() | ||||||
| 	switch kind { | 	switch kind { | ||||||
| 	case reflect.Bool: | 	case reflect.Bool: | ||||||
| 		return strconv.FormatBool(this.any.Bool()) | 		return strconv.FormatBool(v.any.Bool()) | ||||||
| 	case reflect.String: | 	case reflect.String: | ||||||
| 		return this.any.String() | 		return v.any.String() | ||||||
| 	case reflect.Int8, | 	case reflect.Int8, | ||||||
| 		reflect.Int16, | 		reflect.Int16, | ||||||
| 		reflect.Int, | 		reflect.Int, | ||||||
| 		reflect.Int32, | 		reflect.Int32, | ||||||
| 		reflect.Int64: | 		reflect.Int64: | ||||||
| 		return strconv.FormatInt(this.any.Int(), 10) | 		return strconv.FormatInt(v.any.Int(), 10) | ||||||
| 	case reflect.Uint8, | 	case reflect.Uint8, | ||||||
| 		reflect.Uint16, | 		reflect.Uint16, | ||||||
| 		reflect.Uint, | 		reflect.Uint, | ||||||
| 		reflect.Uint32, | 		reflect.Uint32, | ||||||
| 		reflect.Uint64: | 		reflect.Uint64: | ||||||
| 		return strconv.FormatUint(this.any.Uint(), 10) | 		return strconv.FormatUint(v.any.Uint(), 10) | ||||||
| 	case reflect.Float32: | 	case reflect.Float32: | ||||||
| 		return strconv.FormatFloat(this.any.Float(), 'E', -1, 32) | 		return strconv.FormatFloat(v.any.Float(), 'E', -1, 32) | ||||||
| 	case reflect.Float64: | 	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 { | func (av *anyValue) Set(v string) error { | ||||||
| 	kind := this.any.Kind() | 	kind := av.any.Kind() | ||||||
| 	switch kind { | 	switch kind { | ||||||
| 	case reflect.String: | 	case reflect.String: | ||||||
| 		this.any.SetString(v) | 		av.any.SetString(v) | ||||||
| 	case reflect.Float32: | 	case reflect.Float32: | ||||||
| 		return utils.SetValueWithFloatX(this.any, v, 32) | 		return utils.SetValueWithFloatX(av.any, v, 32) | ||||||
| 	case reflect.Float64: | 	case reflect.Float64: | ||||||
| 		return utils.SetValueWithFloatX(this.any, v, 64) | 		return utils.SetValueWithFloatX(av.any, v, 64) | ||||||
| 	case reflect.Int8: | 	case reflect.Int8: | ||||||
| 		return utils.SetValueWithIntX(this.any, v, 8) | 		return utils.SetValueWithIntX(av.any, v, 8) | ||||||
| 	case reflect.Int16: | 	case reflect.Int16: | ||||||
| 		return utils.SetValueWithIntX(this.any, v, 16) | 		return utils.SetValueWithIntX(av.any, v, 16) | ||||||
| 	case reflect.Int, reflect.Int32: | 	case reflect.Int, reflect.Int32: | ||||||
| 		return utils.SetValueWithIntX(this.any, v, 32) | 		return utils.SetValueWithIntX(av.any, v, 32) | ||||||
| 	case reflect.Int64: | 	case reflect.Int64: | ||||||
| 		return utils.SetValueWithIntX(this.any, v, 64) | 		return utils.SetValueWithIntX(av.any, v, 64) | ||||||
| 	case reflect.Uint8: | 	case reflect.Uint8: | ||||||
| 		return utils.SetValueWithUintX(this.any, v, 8) | 		return utils.SetValueWithUintX(av.any, v, 8) | ||||||
| 	case reflect.Uint16: | 	case reflect.Uint16: | ||||||
| 		return utils.SetValueWithUintX(this.any, v, 16) | 		return utils.SetValueWithUintX(av.any, v, 16) | ||||||
| 	case reflect.Uint, reflect.Uint32: | 	case reflect.Uint, reflect.Uint32: | ||||||
| 		return utils.SetValueWithUintX(this.any, v, 32) | 		return utils.SetValueWithUintX(av.any, v, 32) | ||||||
| 	case reflect.Uint64: | 	case reflect.Uint64: | ||||||
| 		return utils.SetValueWithUintX(this.any, v, 64) | 		return utils.SetValueWithUintX(av.any, v, 64) | ||||||
| 	default: | 	default: | ||||||
| 		return fmt.Errorf("Can't support type %s", kind.String()) | 		return fmt.Errorf("unsupported type: %s", kind.String()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
| @ -107,19 +107,19 @@ func newSliceValue(v reflect.Value, separator string) *sliceValue { | |||||||
| 	return &sliceValue{value: v, separator: separator} | 	return &sliceValue{value: v, separator: separator} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (this *sliceValue) String() string { | func (sv *sliceValue) String() string { | ||||||
| 	return this.value.String() | 	return sv.value.String() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (this *sliceValue) Set(v string) error { | func (sv *sliceValue) Set(v string) error { | ||||||
| 	sp := this.separator | 	sp := sv.separator | ||||||
| 	if sp == "" { | 	if sp == "" { | ||||||
| 		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 | var errorHandling = flag.ExitOnError | ||||||
| 
 | 
 | ||||||
| // UsageFunc defines a callback function for printing command usage | // 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 | // Init analyzes the given structure interface, extracts cli definitions from | ||||||
| // its tag and installs command flagset by flag APIs. The interface must be a | // its tag and installs command flagset by flag APIs. The interface must be a | ||||||
| // structure pointer, otherwise will return an error | // 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) | 	ptrRef := reflect.ValueOf(i) | ||||||
| 
 | 
 | ||||||
| 	if ptrRef.IsNil() || ptrRef.Kind() != reflect.Ptr { | 	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()) | 			ptrRef.Kind().String()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	valueOfStruct := ptrRef.Elem() | 	valueOfStruct := ptrRef.Elem() | ||||||
| 	if valueOfStruct.Kind() != reflect.Struct { | 	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()) | 			valueOfStruct.Kind().String()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return this.parseValue(valueOfStruct) | 	return c.parseValue(valueOfStruct) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // parseValue parses a reflect.Value object and extracts cli definitions | // 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() | 	typeOfStruct := v.Type() | ||||||
| 	var err error | 	var err error | ||||||
| 
 | 
 | ||||||
| @ -200,14 +200,14 @@ func (this *Command) parseValue(v reflect.Value) error { | |||||||
| 
 | 
 | ||||||
| 		if kindOfField == reflect.Ptr { | 		if kindOfField == reflect.Ptr { | ||||||
| 			if !valueOfField.IsNil() && valueOfField.CanSet() { | 			if !valueOfField.IsNil() && valueOfField.CanSet() { | ||||||
| 				cmd := this.createSubCommand(structOfField.Tag) | 				cmd := c.createSubCommand(structOfField.Tag) | ||||||
| 				err = cmd.Init(valueOfField.Interface()) | 				err = cmd.Init(valueOfField.Interface()) | ||||||
| 			} | 			} | ||||||
| 		} else if kindOfField == reflect.Struct { | 		} else if kindOfField == reflect.Struct { | ||||||
| 			cmd := this.createSubCommand(structOfField.Tag) | 			cmd := c.createSubCommand(structOfField.Tag) | ||||||
| 			err = cmd.parseValue(valueOfField) | 			err = cmd.parseValue(valueOfField) | ||||||
| 		} else { | 		} 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 | // 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") | 	cmdTag, ok := f.Tag.Lookup("cli") | ||||||
| 	if !ok || cmdTag == "" { | 	if !ok || cmdTag == "" { | ||||||
| 		return nil | 		return nil | ||||||
| @ -232,7 +232,7 @@ func (this *Command) addFlag(v reflect.Value, f reflect.StructField) error { | |||||||
| 	kind := v.Kind() | 	kind := v.Kind() | ||||||
| 	switch kind { | 	switch kind { | ||||||
| 	case reflect.Bool: | 	case reflect.Bool: | ||||||
| 		this.FlagSet.BoolVar((*bool)(unsafe.Pointer(v.UnsafeAddr())), name, | 		c.FlagSet.BoolVar((*bool)(unsafe.Pointer(v.UnsafeAddr())), name, | ||||||
| 			false, usage) | 			false, usage) | ||||||
| 		return nil | 		return nil | ||||||
| 	case reflect.String, | 	case reflect.String, | ||||||
| @ -249,22 +249,22 @@ func (this *Command) addFlag(v reflect.Value, f reflect.StructField) error { | |||||||
| 		reflect.Float32, | 		reflect.Float32, | ||||||
| 		reflect.Float64: | 		reflect.Float64: | ||||||
| 		anyValue := newAnyValue(v) | 		anyValue := newAnyValue(v) | ||||||
| 		this.FlagSet.Var(anyValue, name, usage) | 		c.FlagSet.Var(anyValue, name, usage) | ||||||
| 	case reflect.Slice: | 	case reflect.Slice: | ||||||
| 		sliceValue := newSliceValue(v, f.Tag.Get("separator")) | 		sliceValue := newSliceValue(v, f.Tag.Get("separator")) | ||||||
| 		this.FlagSet.Var(sliceValue, name, usage) | 		c.FlagSet.Var(sliceValue, name, usage) | ||||||
| 	default: | 	default: | ||||||
| 		return fmt.Errorf("Can't support type %s", kind.String()) | 		return fmt.Errorf("unsupported type: %s", kind.String()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // createSubCommand creates sub-commands | // 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") | 	cmdTag, ok := tag.Lookup("cli") | ||||||
| 	if !ok || cmdTag == "" { | 	if !ok || cmdTag == "" { | ||||||
| 		return this | 		return c | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	cmd := Command{SubCommands: make(map[string]*Command)} | 	cmd := Command{SubCommands: make(map[string]*Command)} | ||||||
| @ -284,29 +284,29 @@ func (this *Command) createSubCommand(tag reflect.StructTag) *Command { | |||||||
| 		cmd.FlagSet.Usage = usageHandler(&cmd) | 		cmd.FlagSet.Usage = usageHandler(&cmd) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	this.SubCommands[name] = &cmd | 	c.SubCommands[name] = &cmd | ||||||
| 	return &cmd | 	return &cmd | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Parse parses values from command line and save values into given structure. | // Parse parses values from command line and save values into given structure. | ||||||
| // The Init(interface{}) function must be called before parsing | // The Init(interface{}) function must be called before parsing | ||||||
| func (this *Command) Parse(args []string) error { | func (c *Command) Parse(args []string) error { | ||||||
| 	if err := this.FlagSet.Parse(args); err != nil { | 	if err := c.FlagSet.Parse(args); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	unprocessed := this.FlagSet.Args() | 	unprocessed := c.FlagSet.Args() | ||||||
| 	if len(unprocessed) < 1 { | 	if len(unprocessed) < 1 { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if this.SubCommands == nil { | 	if c.SubCommands == nil { | ||||||
| 		return fmt.Errorf("Command: %s is unsupport", unprocessed[0]) | 		return fmt.Errorf("unsupported command: %s", unprocessed[0]) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	cmd := this.SubCommands[unprocessed[0]] | 	cmd := c.SubCommands[unprocessed[0]] | ||||||
| 	if cmd == nil { | 	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:]) | 	return cmd.Parse(unprocessed[1:]) | ||||||
|  | |||||||
| @ -145,6 +145,7 @@ func TestVariousTypeCommand(t *testing.T) { | |||||||
| 	typesConfig := test.TypesConfig{} | 	typesConfig := test.TypesConfig{} | ||||||
| 	cmd := NewWith("Types", flag.ContinueOnError, func(cmd *Command) func() { | 	cmd := NewWith("Types", flag.ContinueOnError, func(cmd *Command) func() { | ||||||
| 		return func() { | 		return func() { | ||||||
|  | 			// Stub | ||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| 	assert.NoError(cmd.Init(&typesConfig)) | 	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/cli" | ||||||
| 	"github.com/eschao/config/env" | 	"github.com/eschao/config/env" | ||||||
| 	"github.com/eschao/config/utils" | 	"github.com/eschao/config/utils" | ||||||
| 	"gopkg.in/yaml.v2" | 	"gopkg.in/yaml.v3" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Default configuration file | // Default configuration file | ||||||
| @ -51,13 +51,13 @@ func ParseDefault(i interface{}) error { | |||||||
| 	ptrRef := reflect.ValueOf(i) | 	ptrRef := reflect.ValueOf(i) | ||||||
| 
 | 
 | ||||||
| 	if ptrRef.IsNil() || ptrRef.Kind() != reflect.Ptr { | 	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()) | 			ptrRef.Kind().String()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	valueOfStruct := ptrRef.Elem() | 	valueOfStruct := ptrRef.Elem() | ||||||
| 	if valueOfStruct.Kind() != reflect.Struct { | 	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()) | 			valueOfStruct.Kind().String()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -121,7 +121,7 @@ func parseValue(v reflect.Value) error { | |||||||
| 			err = utils.SetValueWithSlice(valueOfField, defValue, sp) | 			err = utils.SetValueWithSlice(valueOfField, defValue, sp) | ||||||
| 
 | 
 | ||||||
| 		default: | 		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 | // under the same folder with the fixed order: config.json, config.yaml and | ||||||
| // config.properties | // config.properties | ||||||
| func ParseConfig(i interface{}, configFlag string) error { | func ParseConfig(i interface{}, configFlag string) error { | ||||||
| 	configFile := flag.String(configFlag, "", "Specifiy configuration file") | 	configFile := flag.String(configFlag, "", "Specify configuration file") | ||||||
| 	flag.Parse() | 	flag.Parse() | ||||||
| 	return ParseConfigFile(i, *configFile) | 	return ParseConfigFile(i, *configFile) | ||||||
| } | } | ||||||
| @ -176,23 +176,23 @@ func ParseConfigFile(i interface{}, configFile string) error { | |||||||
| 
 | 
 | ||||||
| 	switch configType { | 	switch configType { | ||||||
| 	case JSONConfigType: | 	case JSONConfigType: | ||||||
| 		return parseJSON(i, configFile) | 		err = parseJSON(i, configFile) | ||||||
| 	case YamlConfigType: | 	case YamlConfigType: | ||||||
| 		return parseYaml(i, configFile) | 		err = parseYaml(i, configFile) | ||||||
| 	case PropConfigType: | 	case PropConfigType: | ||||||
| 		return parseProp(i, configFile) | 		err = parseProp(i, configFile) | ||||||
| 	default: | 	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 | // parseJSON parses JSON file and set structure with its value | ||||||
| func parseJSON(i interface{}, jsonFile string) error { | func parseJSON(i interface{}, jsonFile string) error { | ||||||
| 	raw, err := ioutil.ReadFile(jsonFile) | 	raw, err := ioutil.ReadFile(jsonFile) | ||||||
| 	if err != nil { | 	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) | 	return json.Unmarshal(raw, i) | ||||||
| @ -202,15 +202,15 @@ func parseJSON(i interface{}, jsonFile string) error { | |||||||
| func parseYaml(i interface{}, yamlFile string) error { | func parseYaml(i interface{}, yamlFile string) error { | ||||||
| 	raw, err := ioutil.ReadFile(yamlFile) | 	raw, err := ioutil.ReadFile(yamlFile) | ||||||
| 	if err != nil { | 	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) | 	return yaml.Unmarshal(raw, i) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // parseProp parses Properties file and set structure with its value | // parseProp parses Properties file and set structure with its value | ||||||
| func parseProp(i interface{}, propFile string) error { | func parseProp(_ interface{}, _ /*propFile*/ string) error { | ||||||
| 	return fmt.Errorf("Properties config has not implemented!") | 	return fmt.Errorf("properties config is not implemented") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // getDefaultConfigFile returns a existing default config file. The checking | // getDefaultConfigFile returns a existing default config file. The checking | ||||||
| @ -219,7 +219,7 @@ func parseProp(i interface{}, propFile string) error { | |||||||
| func getDefaultConfigFile() (string, error) { | func getDefaultConfigFile() (string, error) { | ||||||
| 	exe, err := os.Executable() | 	exe, err := os.Executable() | ||||||
| 	if err != nil { | 	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) | 	path := filepath.Dir(exe) + string(filepath.Separator) | ||||||
| @ -242,7 +242,7 @@ func getDefaultConfigFile() (string, error) { | |||||||
| 		return propConfig, nil | 		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 | // getConfigFileType analyzes config file extension name and return | ||||||
| @ -257,5 +257,5 @@ func getConfigFileType(configFile string) (string, error) { | |||||||
| 		return PropConfigType, nil | 		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 | // 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 { | func Parse(i interface{}) error { | ||||||
| 	return ParseWith(i, "") | 	return ParseWith(i, "") | ||||||
| } | } | ||||||
| @ -40,19 +40,20 @@ func Parse(i interface{}) error { | |||||||
| //	  Server string `env:"SERVER"` | //	  Server string `env:"SERVER"` | ||||||
| //	  DB     Database `env:"DB_"` | //	  DB     Database `env:"DB_"` | ||||||
| //	} | //	} | ||||||
|  | // | ||||||
| // The Server.DB.Host will be mapped to environment variable: DB_HOST which is | // 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 | // concatenated from DB tag in Server struct and Host tag in Database struct | ||||||
| func ParseWith(i interface{}, prefix string) error { | func ParseWith(i interface{}, prefix string) error { | ||||||
| 	ptrRef := reflect.ValueOf(i) | 	ptrRef := reflect.ValueOf(i) | ||||||
| 
 | 
 | ||||||
| 	if ptrRef.IsNil() || ptrRef.Kind() != reflect.Ptr { | 	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()) | 			ptrRef.Kind().String()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	valueOfStruct := ptrRef.Elem() | 	valueOfStruct := ptrRef.Elem() | ||||||
| 	if valueOfStruct.Kind() != reflect.Struct { | 	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()) | 			valueOfStruct.Kind().String()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -80,23 +81,16 @@ func parseValue(v reflect.Value, prefix string) error { | |||||||
| 			err = parseValue(valueOfField, prefix+structOfField.Tag.Get("env")) | 			err = parseValue(valueOfField, prefix+structOfField.Tag.Get("env")) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		err = setFieldValue(valueOfField, structOfField, prefix) | 		err = setFieldValue(valueOfField, structOfField, prefix) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return err | 	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 | // setFieldValue sets a reflect.Value with environment value | ||||||
| func setFieldValue(v reflect.Value, f reflect.StructField, prefix string) error { | func setFieldValue(v reflect.Value, f reflect.StructField, prefix string) error { | ||||||
| 	envName := f.Tag.Get("env") | 	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) | 		err = utils.SetValueWithSlice(v, envValue, sp) | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
| 		return fmt.Errorf("Can't support type: %s", kind.String()) | 		return fmt.Errorf("unsupported type: %s", kind.String()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err != nil { | 	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