spf13 / viper

Go configuration with fangs
MIT License
26.27k stars 2k forks source link

Unmarshal function has bool type value lost when converted to structure #1838

Closed Wenrh2004 closed 4 weeks ago

Wenrh2004 commented 1 month ago

Preflight Checklist

Viper Version

1.18.2

Go Version

1.22.3

Config Source

Files

Format

YAML

Repl.it link

No response

Code reproducing the issue

package conf

import (
    "github.com/bytedance/go-tagexpr/v2/validator"
    "github.com/spf13/viper"
    "os"
    "path/filepath"
    "sync"

    "github.com/cloudwego/hertz/pkg/common/hlog"
)

var (
    conf *Config
    once sync.Once
)

type Config struct {
    Env string

    Hertz Hertz `yaml:"hertz"`
    MySQL MySQL `yaml:"mysql"`
    Redis Redis `yaml:"redis"`
}

type MySQL struct {
    PassWord   string `yaml:"password"`
    UserName   string `yaml:"username"`
    Host       string `yaml:"host"`
    DriverName string `yaml:"driver_name"`
    Port       int    `yaml:"port"`
    DataBase   string `yaml:"database"`
}

type Redis struct {
    Address  string `yaml:"address"`
    Password string `yaml:"password"`
    Username string `yaml:"username"`
    DB       int    `yaml:"db"`
}

type Hertz struct {
    Address         string `yaml:"address"`
    EnablePprof     bool   `yaml:"enable_pprof"`
    EnableGzip      bool   `yaml:"enable_gzip"`
    EnableAccessLog bool   `yaml:"enable_access_log"`
    LogLevel        string `yaml:"log_level"`
    LogAsyncWrite   bool   `yaml:"log_async_write"`
    LogFileName     string `yaml:"log_file_name"`
    LogMaxSize      int    `yaml:"log_max_size"`
    LogMaxBackups   int    `yaml:"log_max_backups"`
    LogMaxAge       int    `yaml:"log_max_age"`
}

// GetConf gets configuration instance
func GetConf() *Config {
    once.Do(initConf)
    return conf
}

func initConf() {
    config := viper.New()
    prefix := "conf"
    confFileRelPath := filepath.Join(prefix, filepath.Join(GetEnv(), "conf.yaml"))
    config.SetConfigFile(confFileRelPath)
    if err := config.ReadInConfig(); err != nil {
        panic(err)
    }

    conf = new(Config)
    conf.Env = GetEnv()
    if err := config.Unmarshal(conf); err != nil {
        panic(err)
    }
    if err := validator.Validate(conf); err != nil {
        panic(err)
    }
}

func GetEnv() string {
    e := os.Getenv("GO_ENV")
    if len(e) == 0 {
        return "test"
    }
    return e
}

func LogLevel() hlog.Level {
    level := GetConf().Hertz.LogLevel
    switch level {
    case "trace":
        return hlog.LevelTrace
    case "debug":
        return hlog.LevelDebug
    case "info":
        return hlog.LevelInfo
    case "notice":
        return hlog.LevelNotice
    case "warn":
        return hlog.LevelWarn
    case "error":
        return hlog.LevelError
    case "fatal":
        return hlog.LevelFatal
    default:
        return hlog.LevelInfo
    }
}

Expected Behavior

When the value of the bool type in the Hertz struct is true, it should be true in conf.

Actual Behavior

The value of the bool type in the Hertz struct witch in conf is false, but the value in yaml and viper is true.

Steps To Reproduce

No response

Additional Information

No response

github-actions[bot] commented 1 month ago

👋 Thanks for reporting!

A maintainer will take a look at your issue shortly. 👀

In the meantime: We are working on Viper v2 and we would love to hear your thoughts about what you like or don't like about Viper, so we can improve or fix those issues.

⏰ If you have a couple minutes, please take some time and share your thoughts: https://forms.gle/R6faU74qPRPAzchZ9

📣 If you've already given us your feedback, you can still help by spreading the news, either by sharing the above link or telling people about this on Twitter:

https://twitter.com/sagikazarmark/status/1306904078967074816

Thank you! ❤️

sagikazarmark commented 4 weeks ago

You need to use mapstructure struct tags, not yaml.