美文网首页
每周一库-Viper

每周一库-Viper

作者: 一斗 | 来源:发表于2019-08-17 10:53 被阅读0次
    package main
    
    import (
        "bytes"
        "encoding/json"
        "flag"
        "fmt"
        "github.com/spf13/pflag"
        "github.com/spf13/viper"
        "gopkg.in/yaml.v2"
        "log"
        "os"
    )
    
    type config struct {
        v *viper.Viper
    }
    
    func main() {
        var c config
        err := LoadConfigFromYaml(&c)
        if err != nil {
            fmt.Println(err)
        }
    
        //err := ReadConfigFormIo(&c)
        //if err != nil {
        //  fmt.Println(err)
        //}
    
        //err := EnvConfigPrefix(&c)
        //if err != nil {
        //  fmt.Println(err)
        //}
    
        //err := SetAndAliases(&c)
        //if err != nil {
        //  fmt.Println(err)
        //}
    
        //err := UmshalStruct(&c)
        //if err != nil {
        //  fmt.Println(err)
        //}
    
        //fmt.Println(YamlStringSettings(&c))
    
        //fmt.Println(JsonStringSettings(&c))
    
        //ReadFromCommandLine()
    
    }
    
    // 直接读取yaml文件
    func LoadConfigFromYaml(c *config) error {
        c.v = viper.New()
        c.v.SetConfigName("config")
        c.v.AddConfigPath("./")
        c.v.SetConfigType("yaml")
    
        if err := c.v.ReadInConfig(); err != nil {
            return err
        }
        log.Printf("age: %s, name: %s \n", c.v.Get("information.age"), c.v.Get("information.name"))
        return nil
    }
    
    // 从IO中读取配置
    func ReadConfigFormIo(c *config) error {
        c.v = viper.New()
        if f, err := os.Open("config.yaml"); err != nil {
            log.Printf("err: %s", err.Error())
            return err
        } else {
            confLength, _ := f.Seek(0, 2)
            configData := make([]byte, confLength)
            f.Seek(0, 0)
            f.Read(configData)
            log.Printf("%s\n", string(configData))
    
            c.v.SetConfigType("yaml")
            if err := c.v.ReadConfig(bytes.NewBuffer(configData)); err != nil {
                log.Fatal(err.Error())
            }
        }
        log.Printf("age: %s, name: %s \n", c.v.Get("information.age"), c.v.Get("information.name"))
        return nil
    }
    
    // 从环境变量中读取配置
    func EnvConfigPrefix(c *config) error {
        c.v = viper.New()
        os.Setenv("LOG_LEVEL", "INFO")
        if nil == c.v.Get("LOG_LEVEL") {
            log.Printf("LOG_LEVEL is nil")
        } else {
            return fmt.Errorf("%s", "get env error")
        }
    
        c.v.BindEnv("LOG_LEVEL")
        log.Printf("LOG_LEVEL is %s", c.v.Get("LOG_LEVEL"))
    
        c.v.AutomaticEnv()
        os.Setenv("DEV_ADDONES", "none")
        log.Printf("DEV_ADDONES: %s", c.v.Get("dev_addones"))
    
        c.v.SetEnvPrefix("DEV")
        os.Setenv("DEV_MODE", "true")
        //c.v.BindEnv("DEV_MODE")
        log.Printf("DEV_MODE: %s", c.v.Get("dev_dev_mode"))
        return nil
    }
    
    // 别名功能
    func SetAndAliases(c *config) error {
        c.v = viper.New()
        c.v.Set("Name","wzp")
        c.v.RegisterAlias("id","Name")
        c.v.Set("id","Mr.Wang")
    
        //我们可以发现当别名对应的值修改之后,原本的key也发生变化
        log.Printf("id %s, name %s",c.v.Get("id"),c.v.Get("name") )
        return nil
    }
    
    // 序列化和反序列化
    type favorite struct {
        Sports []string
        Music []string
        LuckyNumber int
    }
    
    type information struct {
        Name string
        Age int
        Alise []string
        Image string
        Public bool
    }
    
    type YamlConfig struct {
        TimeStamp string
        Author string
        PssWd string
        Information information
        Favorite favorite
    }
    
    //将配置解析为Struct对象
    func UmshalStruct(c *config) error {
        LoadConfigFromYaml(c)
        var cf YamlConfig
        if err := c.v.Unmarshal(&cf); err != nil {
            return err
        }
        fmt.Printf("%#v\n", cf)
        return nil
    }
    
    func YamlStringSettings(c *config) string {
        c.v = viper.New()
        c.v.Set("name", "wzp")
        c.v.Set("age", 18)
        c.v.Set("aliase", []string{"one", "two", "three"})
    
        cf := c.v.AllSettings()
        bs, err := yaml.Marshal(cf)
        if err != nil {
            log.Fatal("unable to marshal config to YAML: %v", err)
        }
        return string(bs)
    }
    
    func JsonStringSettings(c *config) string {
        c.v = viper.New()
        c.v.Set("name", "wzp")
        c.v.Set("age", 18)
        c.v.Set("aliase", []string{"one", "two", "three"})
    
        cf := c.v.AllSettings()
        bs, err := json.Marshal(cf)
        if err != nil {
            log.Fatal("unable to marshal config to JSON: %v", err)
        }
        return string(bs)
    }
    
    // 从command Line中读取配置
    func ReadFromCommandLine() {
        flag.String("mode", "RUN", "please input the mode: RUN or DEBUG")
        pflag.Int("port", 1080, "please input the listen port")
        pflag.String("ip", "127.0.0.1", "please input the bind ip")
        //获取标准包的flag
        pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
        pflag.Parse()
        //BindFlag
        //在pflag.Init key后面使用
        viper.BindPFlag("port", pflag.Lookup("port"))
        log.Printf("set port: %d", viper.GetInt("port"))
    
        viper.BindPFlags(pflag.CommandLine)
        log.Printf("set ip: %s", viper.GetString("ip"))
    
        //可以使用标准的flag也可以使用viper包中自带的pflag,作者建议使用pflag
    }
    

    config.yaml

    TimeStamp: "2018-07-16 10:23:19"
    Author: "WZP"
    PassWd: "Hello"
    Information:
      Name: "Harry"
      Age: "37"
      Alise:
        - "Lion"
        - "NK"
        - "KaQS"
      Image: "/path/header.rpg"
      Public: false
    
    Favorite:
      Sport:
        - "swimming"
        - "football"
      Music:
        - "zui xuan min zu feng"
      LuckyNumber: 99
    

    参考文章

    相关文章

      网友评论

          本文标题:每周一库-Viper

          本文链接:https://www.haomeiwen.com/subject/noyhsctx.html