每周一库-Viper

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)