release/v1.0.1 #4
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							| @ -5,5 +5,6 @@ go 1.14 | ||||
| require ( | ||||
| 	git.trj.tw/golang/utils v0.0.0-20190225142552-b019626f0349 | ||||
| 	github.com/BurntSushi/toml v0.3.1 | ||||
| 	github.com/otakukaze/envconfig v1.0.4 | ||||
| 	gopkg.in/yaml.v2 v2.3.0 | ||||
| ) | ||||
|  | ||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							| @ -2,6 +2,8 @@ git.trj.tw/golang/utils v0.0.0-20190225142552-b019626f0349 h1:V6ifeiJ3ExnjaUylTO | ||||
| git.trj.tw/golang/utils v0.0.0-20190225142552-b019626f0349/go.mod h1:yE+qbsUsijCTdwsaQRkPT1CXYk7ftMzXsCaaYx/0QI0= | ||||
| github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= | ||||
| github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||||
| github.com/otakukaze/envconfig v1.0.4 h1:/rZ8xq1vFpgWzqsqUkk61doDGNv9pIXqrog/mCvSx8Y= | ||||
| github.com/otakukaze/envconfig v1.0.4/go.mod h1:v2dNv5NX1Lakw3FTAkbxYURyaiOy68M8QpMTZz+ogfs= | ||||
| 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.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= | ||||
|  | ||||
							
								
								
									
										77
									
								
								loader.go
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								loader.go
									
									
									
									
									
								
							| @ -9,6 +9,7 @@ import ( | ||||
| 
 | ||||
| 	"git.trj.tw/golang/utils" | ||||
| 	"github.com/BurntSushi/toml" | ||||
| 	"github.com/otakukaze/envconfig" | ||||
| 	"gopkg.in/yaml.v2" | ||||
| ) | ||||
| 
 | ||||
| @ -27,6 +28,7 @@ type ConfigFile struct { | ||||
| 
 | ||||
| type LoadOptions struct { | ||||
| 	ConfigFile *ConfigFile | ||||
| 	FromEnv    bool | ||||
| } | ||||
| 
 | ||||
| func Load(i interface{}, opts *LoadOptions) error { | ||||
| @ -50,48 +52,51 @@ func Load(i interface{}, opts *LoadOptions) error { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	// no config file | ||||
| 	if opts.ConfigFile == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	// load config file | ||||
| 	if opts.ConfigFile != nil { | ||||
| 		if opts.ConfigFile.Path == "" { | ||||
| 			return errors.New("config file path empty") | ||||
| 		} | ||||
| 
 | ||||
| 	if opts.ConfigFile.Path == "" { | ||||
| 		return errors.New("config file path empty") | ||||
| 	} | ||||
| 		// resolve file path | ||||
| 		opts.ConfigFile.Path = utils.ParsePath(opts.ConfigFile.Path) | ||||
| 		// check file exists | ||||
| 		if !utils.CheckExists(opts.ConfigFile.Path, false) { | ||||
| 			return errors.New("config file not found") | ||||
| 		} | ||||
| 
 | ||||
| 	// resolve file path | ||||
| 	opts.ConfigFile.Path = utils.ParsePath(opts.ConfigFile.Path) | ||||
| 	// check file exists | ||||
| 	if !utils.CheckExists(opts.ConfigFile.Path, false) { | ||||
| 		return errors.New("config file not found") | ||||
| 	} | ||||
| 
 | ||||
| 	filebyte, err := ioutil.ReadFile(opts.ConfigFile.Path) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	switch opts.ConfigFile.Type { | ||||
| 	case ConfigFileTypeJSON: | ||||
| 		err := json.Unmarshal(filebyte, i) | ||||
| 		filebyte, err := ioutil.ReadFile(opts.ConfigFile.Path) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		break | ||||
| 	case ConfigFileTypeTOML: | ||||
| 		err := toml.Unmarshal(filebyte, i) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 
 | ||||
| 		switch opts.ConfigFile.Type { | ||||
| 		case ConfigFileTypeJSON: | ||||
| 			err := json.Unmarshal(filebyte, i) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			break | ||||
| 		case ConfigFileTypeTOML: | ||||
| 			err := toml.Unmarshal(filebyte, i) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			break | ||||
| 		case ConfigFileTypeYAML: | ||||
| 			err := yaml.Unmarshal(filebyte, i) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			break | ||||
| 		default: | ||||
| 			return errors.New("file type not impl") | ||||
| 		} | ||||
| 		break | ||||
| 	case ConfigFileTypeYAML: | ||||
| 		err := yaml.Unmarshal(filebyte, i) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		break | ||||
| 	default: | ||||
| 		return errors.New("file type not impl") | ||||
| 	} | ||||
| 
 | ||||
| 	// load config from env | ||||
| 	if opts.FromEnv { | ||||
| 		envconfig.Parse(i) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| package confloader | ||||
| 
 | ||||
| import ( | ||||
| 	"os" | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
| ) | ||||
| @ -13,8 +14,8 @@ func TestLoad(t *testing.T) { | ||||
| 		Key string `json:"key" yaml:"key" toml:"key"` | ||||
| 	} | ||||
| 	type Config struct { | ||||
| 		StrKey   string   `json:"strKey" yaml:"strKey" toml:"strKey" default:"def value"` | ||||
| 		IntKey   int      `json:"intKey" yaml:"intKey" toml:"intKey"` | ||||
| 		StrKey   string   `json:"strKey" yaml:"strKey" toml:"strKey" default:"def value" env:"TEST_STR"` | ||||
| 		IntKey   int      `json:"intKey" yaml:"intKey" toml:"intKey" env:"TEST_INT"` | ||||
| 		BoolKey  bool     `json:"boolKey" yaml:"boolKey" toml:"boolKey"` | ||||
| 		FloatKey float64  `json:"floatKey" yaml:"floatKey" toml:"floatKey"` | ||||
| 		StrArr   []string `json:"strArr" yaml:"strArr" toml:"strArr" default:"arrval" length:"1"` | ||||
| @ -23,6 +24,9 @@ func TestLoad(t *testing.T) { | ||||
| 		ArrObj   []ArrObj `json:"arrObj" yaml:"arrObj" toml:"arrObj"` | ||||
| 	} | ||||
| 
 | ||||
| 	os.Setenv("TEST_STR", "string value2") | ||||
| 	os.Setenv("TEST_INT", "2000") | ||||
| 
 | ||||
| 	expected := Config{ | ||||
| 		StrKey:   "string value", | ||||
| 		IntKey:   1000, | ||||
| @ -35,8 +39,20 @@ func TestLoad(t *testing.T) { | ||||
| 		}, | ||||
| 		ArrObj: []ArrObj{{Key: "val"}}, | ||||
| 	} | ||||
| 	expectedWithEnv := Config{ | ||||
| 		StrKey:   "string value2", | ||||
| 		IntKey:   2000, | ||||
| 		BoolKey:  true, | ||||
| 		FloatKey: 1.2345, | ||||
| 		StrArr:   []string{"arr1"}, | ||||
| 		StrArr2:  []string{"arrval2", "arrval2"}, | ||||
| 		ObjKey: ObjKey{ | ||||
| 			Name: "name", | ||||
| 		}, | ||||
| 		ArrObj: []ArrObj{{Key: "val"}}, | ||||
| 	} | ||||
| 
 | ||||
| 	src := Config{} | ||||
| 	// src := Config{} | ||||
| 
 | ||||
| 	type args struct { | ||||
| 		i    interface{} | ||||
| @ -51,7 +67,7 @@ func TestLoad(t *testing.T) { | ||||
| 		{ | ||||
| 			name: "test load json file with default", | ||||
| 			args: args{ | ||||
| 				i: &src, | ||||
| 				i: &Config{}, | ||||
| 				opts: &LoadOptions{ | ||||
| 					ConfigFile: &ConfigFile{ | ||||
| 						Type: ConfigFileTypeJSON, | ||||
| @ -64,7 +80,7 @@ func TestLoad(t *testing.T) { | ||||
| 		{ | ||||
| 			name: "test load yaml file with default", | ||||
| 			args: args{ | ||||
| 				i: &src, | ||||
| 				i: &Config{}, | ||||
| 				opts: &LoadOptions{ | ||||
| 					ConfigFile: &ConfigFile{ | ||||
| 						Type: ConfigFileTypeYAML, | ||||
| @ -77,7 +93,7 @@ func TestLoad(t *testing.T) { | ||||
| 		{ | ||||
| 			name: "test load toml file with default", | ||||
| 			args: args{ | ||||
| 				i: &src, | ||||
| 				i: &Config{}, | ||||
| 				opts: &LoadOptions{ | ||||
| 					ConfigFile: &ConfigFile{ | ||||
| 						Type: ConfigFileTypeTOML, | ||||
| @ -87,14 +103,34 @@ func TestLoad(t *testing.T) { | ||||
| 			}, | ||||
| 			wantErr: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "test load json file with default and env", | ||||
| 			args: args{ | ||||
| 				i: &Config{}, | ||||
| 				opts: &LoadOptions{ | ||||
| 					ConfigFile: &ConfigFile{ | ||||
| 						Type: ConfigFileTypeJSON, | ||||
| 						Path: "./test/config.json", | ||||
| 					}, | ||||
| 					FromEnv: true, | ||||
| 				}, | ||||
| 			}, | ||||
| 			wantErr: false, | ||||
| 		}, | ||||
| 	} | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			if err := Load(tt.args.i, tt.args.opts); (err != nil) != tt.wantErr { | ||||
| 				t.Errorf("Load() error = %v, wantErr %v", err, tt.wantErr) | ||||
| 			} | ||||
| 			if !reflect.DeepEqual(src, expected) { | ||||
| 				t.Errorf("Load and expected not match") | ||||
| 			if tt.args.opts != nil && tt.args.opts.FromEnv { | ||||
| 				if !reflect.DeepEqual(tt.args.i, expectedWithEnv) { | ||||
| 					t.Errorf("Load and expected not match") | ||||
| 				} | ||||
| 			} else { | ||||
| 				if !reflect.DeepEqual(tt.args.i, expected) { | ||||
| 					t.Errorf("Load and expected not match") | ||||
| 				} | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user