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
参考文章