mapstructure tags not used by Viper when writing to YAML

531 Views Asked by At

I have structs defined as follows

type config struct {
    Contexts       map[string]Context `mapstructure:"contexts"`
    CurrentContext string             `mapstructure:"current-context"`
    Tokens         []Token            `mapstructure:"tokens"`
}

type Context struct {
    Endpoint         string   `mapstructure:"endpoint,omitempty"`
    Token            string   `mapstructure:"token,omitempty"`
    Platform         string   `mapstructure:"platform"`
    Components       []string `mapstructure:"components,omitempty"`
    Channel          string   `mapstructure:"channel,omitempty"`
    Version          string   `mapstructure:"version,omitempty"`
    EnforcedProvider string   `mapstructure:"enforced-provider,omitempty"`
}

I'm writing to a YAML config file as follows

configObj.Contexts[contextName] = context

viper.Set("contexts", configObj.Contexts)
viper.Set("current-context", configObj.CurrentContext)
viper.Set("tokens", configObj.Tokens)

err = viper.WriteConfig()
if err != nil {
    return err
}

The mapstructure tags I have defined are not written to the YAML file, instead the field names are written in lower case. This is especially a problem with the EnforcedProvider field which is written as enforcedprovider instead of enforced-provider.

enter image description here

How do I make it so that the mapstructure tag is used ?

1

There are 1 best solutions below

1
LeGEC On

The documentation mentions mapstructure tags in its Unmarshaling section, but not in its WriteConfig section.

It looks like WriteConfig will go through one of the default encoders :


If you know you will read/write from yaml files only, the simplest way is to set yaml tags on your struct (following the documentation of the gopkg.in/yaml.v2 package) :

type config {
    Contexts       map[string]Context `yaml:"contexts"`
    CurrentContext string             `yaml:"current-context"`
    Tokens         []Token            `yaml:"tokens"`
}

type Context struct {
    Endpoint         string   `yaml:"endpoint,omitempty"`
    Token            string   `yaml:"token,omitempty"`
    Platform         string   `yaml:"platform"`
    Components       []string `yaml:"components,omitempty"`
    Channel          string   `yaml:"channel,omitempty"`
    Version          string   `yaml:"version,omitempty"`
    EnforcedProvider string   `yaml:"enforced-provider,omitempty"`
}