diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..173454b --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +# Created by .ignore support plugin (hsz.mobi) +### Example user template template +### Example user template + +# IntelliJ project files +.idea +*.iml +out +gen diff --git a/grconfig.go b/grconfig.go new file mode 100644 index 0000000..14fdc4f --- /dev/null +++ b/grconfig.go @@ -0,0 +1,104 @@ +package grconfig + +import ( + "bytes" + "os" + "path" + "reflect" + "strconv" + "strings" +) + +type ConfigerChannelInterface interface { + Item(item string, t interface{}) (err error) + String(item string) string +} + +type Configer struct { + channels map[string]ConfigerChannelInterface + root string +} + +func New(root string) *Configer { + return &Configer{root: root, channels: map[string]ConfigerChannelInterface{}} +} + +func (conf *Configer) getData(item string) (ch ConfigerChannelInterface, err error) { + + var ok bool + env := os.Getenv("CENTER_RUNMODE") + chunks := strings.SplitN(item, ".", 2) + + if len(chunks) < 2 { + panic("Item string error") + } + + if strings.TrimSpace(env) == "" { + env = "" + } + + if ch, ok = conf.channels[chunks[0]]; !ok { + + var fd *os.File + var buf bytes.Buffer + + // @TODO 检查配置 + fpath := path.Join(conf.root, env, chunks[0]+"."+"yaml") + + if fd, err = os.Open(fpath); err != nil { + return nil, err + } + + if _, err = buf.ReadFrom(fd); err != nil { + return nil, err + } + + // @TODO + ch = &ConfigerChannelYAML{ + tmp: parseYAML(buf), + filename: chunks[0], + } + conf.channels[chunks[0]] = ch + } + + return +} + +func (conf *Configer) Item(item string, t interface{}) (err error) { + ch, err1 := conf.getData(item) + if err1 != nil { + return err1 + } + return ch.Item(item, t) +} + +func (conf *Configer) String(item string) string { + ch, err1 := conf.getData(item) + if err1 != nil { + return "" + } + return ch.String(item) +} + +func recursiveParse(item string, v interface{}) interface{} { + + chunks := strings.SplitN(item, ".", 2) + + if n, err := strconv.Atoi(chunks[0]); err == nil { + + if tmp, ok := v.([]interface{}); reflect.TypeOf(v).Kind() == reflect.Slice && ok { + v = tmp[n] + } + } else { + + if tmp, ok := v.(map[interface{}]interface{}); reflect.TypeOf(v).Kind() == reflect.Map && ok { + v = tmp[chunks[0]] + } + } + + if len(chunks) <= 1 { + return v + } + + return recursiveParse(chunks[1], v) +} diff --git a/grconfig_test.go b/grconfig_test.go new file mode 100644 index 0000000..fb3c90e --- /dev/null +++ b/grconfig_test.go @@ -0,0 +1,38 @@ +package grconfig + +import ( + "fmt" + "log" + "lot.gaore.com/library/common" + "testing" +) + +type Config struct { + ServerUrl string `yaml:"server_url"` + AccessKey string `yaml:"access_key"` + SecretKey string `yaml:"secret_key"` + InstanceId string `yaml:"instance_id"` +} + +func TestNewConfig(t *testing.T) { + var m1 Config + var m2 Config + c := New(common.GetCwd("conf")) + err := c.Item("mqtt.default", &m1) + log.Println(fmt.Sprintf("%+v", m1.ServerUrl)) + if err != nil { + t.Error(err) + } + + err = c.Item("mqtt.backup", &m2) + log.Println(fmt.Sprintf("%+v", m2.ServerUrl)) + if err != nil { + t.Error(err) + } + + if c.String("mqtt.default.instance_id") == "" { + t.Error("Empty String") + } + + log.Println(c.String("mqtt.default.instance_id")) +} diff --git a/ini.go b/ini.go new file mode 100644 index 0000000..cbdc235 --- /dev/null +++ b/ini.go @@ -0,0 +1 @@ +package grconfig diff --git a/json.go b/json.go new file mode 100644 index 0000000..cbdc235 --- /dev/null +++ b/json.go @@ -0,0 +1 @@ +package grconfig diff --git a/xml.go b/xml.go new file mode 100644 index 0000000..30a8dea --- /dev/null +++ b/xml.go @@ -0,0 +1,17 @@ +package grconfig + +import "bytes" + +type ConfigerChannelXML struct { + io bytes.Buffer + filename string + adapter string +} + +func (c ConfigerChannelXML) Item(item string, t interface{}) (err error) { + panic("implement me") +} + +func (c ConfigerChannelXML) String(s string) string { + panic("implement me") +} diff --git a/yaml.go b/yaml.go new file mode 100644 index 0000000..52c2ee7 --- /dev/null +++ b/yaml.go @@ -0,0 +1,41 @@ +package grconfig + +import ( + "bytes" + "errors" + "gopkg.in/yaml.v2" + "strings" +) + +type ConfigerChannelYAML struct { + tmp interface{} + filename string + adapter string +} + +func (conf *ConfigerChannelYAML) String(item string) string { + chunks := strings.SplitN(item, ".", 2) + target := recursiveParse(chunks[1], conf.tmp) + if str, ok := target.(string); ok { + return str + } + return "" +} + +func (conf *ConfigerChannelYAML) Item(item string, t interface{}) (err error) { + chunks := strings.SplitN(item, ".", 2) + target := recursiveParse(chunks[1], conf.tmp) + if target == nil { + err = errors.New("item doesn't exists") + return + } + out, _ := yaml.Marshal(target) + err = yaml.Unmarshal(out, t) + return +} + +func parseYAML(buf bytes.Buffer) interface{} { + var v interface{} + yaml.Unmarshal(buf.Bytes(), &v) + return v +}