### Install Viper using Go Modules Source: https://github.com/spf13/viper/blob/master/README.md This command installs the Viper library using Go Modules, the standard dependency management system for Go. It ensures that the correct version of Viper is available for your project. ```shell go get github.com/spf13/viper ``` -------------------------------- ### Execute Go Text Templates Stored in Viper Configs Source: https://github.com/spf13/viper/wiki/Tips-and-tricks This Go example shows how to use the viper-template library to store and execute Go text templates within Viper configurations. It defines custom functions and data structures to dynamically process template variables, allowing for complex configuration logic. ```go package main import ( "fmt" "text/template" "github.com/spf13/viper" vl "github.com/sv-tools/viper-template" ) func main() { v := viper.New() v.Set("foo", `{{ Get "bar" }}`) v.Set("bar", `{{ Mul . 2 }}`) type Data struct { Bar int } data := Data{ Bar: 42, } funcs := template.FuncMap{ "Mul": func(d *Data, v int) int { return d.Bar * v }, } val, err := vl.Get( "foo", vl.WithViper(v), vl.WithData(&data), vl.WithFuncs(funcs), ) if err != nil { panic(err) } fmt.Println(val) // Output: 84 } ``` -------------------------------- ### Create Multiple Independent Viper Instances (Go) Source: https://github.com/spf13/viper/blob/master/README.md Demonstrates how to create and manage multiple independent Viper instances. Each instance can have its own distinct configuration, allowing for isolation of settings. This is useful when different parts of an application or different applications need separate configurations. The example shows setting default values for a specific key in two separate instances. ```go x := viper.New() y := viper.New() x.SetDefault("ContentDir", "content") y.SetDefault("ContentDir", "foobar") ``` -------------------------------- ### Go: Read Configuration from io.Reader (e.g., byte buffer) Source: https://context7.com/spf13/viper/llms.txt This Go example shows how to load configuration directly from an io.Reader, such as a byte buffer or an HTTP response body. It specifies the configuration type (e.g., 'yaml') and then uses `viper.ReadConfig` to parse the data. This is useful for embedded configurations or testing. ```go package main import ( "bytes" "fmt" "github.com/spf13/viper" ) func main() { v ``` -------------------------------- ### Go: Bind Command-Line Flags with pflag Source: https://context7.com/spf13/viper/llms.txt This Go example shows how to bind command-line flags, defined using the `pflag` library (often used with Cobra), to Viper's configuration system. It covers defining flags, parsing them, binding all flags to Viper using `viper.BindPFlags`, and optionally binding individual flags. Command-line flags generally have the highest precedence. ```go package main import ( "fmt" "github.com/spf13/pflag" "github.com/spf13/viper" ) func main() { // Define command-line flags pflag.Int("port", 8080, "Port to run server on") pflag.String("host", "localhost", "Host to bind to") pflag.Bool("verbose", false, "Enable verbose logging") pflag.Parse() // Bind all pflags to viper v ``` -------------------------------- ### Encrypt and Decrypt Configuration using Crypt Source: https://github.com/spf13/viper/blob/master/README.md Provides bash commands to install the 'crypt' helper tool and use it for encrypting and decrypting configuration files. This is useful for securely storing sensitive configuration values in remote key/value stores. ```bash go get github.com/sagikazarmark/crypt/bin/crypt crypt set -plaintext /config/hugo.json /Users/hugo/settings/config.json crypt get -plaintext /config/hugo.json ``` -------------------------------- ### Bind All pflags to Viper Source: https://github.com/spf13/viper/blob/master/README.md Binds all command-line flags defined in pflag.CommandLine to Viper. This allows Viper to manage all flags, and values can be retrieved using Viper's Get methods instead of pflag's. ```go package main import ( "github.com/spf13/pflag" "github.com/spf13/viper" ) func main() { pflag.Int("flagname", 1234, "help message for flagname") pflag.Parse() v.BindPFlags(pflag.CommandLine) i := viper.GetInt("flagname") // Retrieve values from viper instead of pflag } ``` -------------------------------- ### Watch Remote Key/Value Store Changes (Go) Source: https://github.com/spf13/viper/blob/master/README.md Shows how to set up a new Viper instance, add a remote provider (e.g., etcd), read initial configuration, unmarshal it, and then continuously watch for remote configuration changes in a goroutine. It handles errors during remote config reads and unmarshals updated configurations. Dependencies include Viper, time, and log packages. ```go // Alternatively, you can create a new viper instance var runtime_viper = viper.New() runtime_viper.AddRemoteProvider("etcd", "http://127.0.0.1:4001", "/config/hugo.yml") runtim ``` -------------------------------- ### Add and Read Encrypted Remote Configuration (Go) Source: https://github.com/spf13/viper/blob/master/README.md Demonstrates how to add a secure remote configuration provider (e.g., etcd) with encryption using a GPG key, set the configuration type, and read the remote configuration. Dependencies include the Viper library. ```go viper.AddSecureRemoteProvider("etcd","http://127.0.0.1:4001","/config/hugo.json","/etc/secrets/mykeyring.gpg") viper.SetConfigType("json") // because there is no file extension in a stream of bytes, supported extensions are "json", "toml", "yaml", "yml", "properties", "props", "prop", "env", "dotenv" err := viper.ReadRemoteConfig() ``` -------------------------------- ### Write Configuration Files with Viper Source: https://github.com/spf13/viper/blob/master/README.md Demonstrates how to write the current Viper configuration to a file. It includes methods for writing to a configured path or a specific path, and a safe version that prevents overwriting existing files. ```go // Writes current config to the path set by `AddConfigPath` and `SetConfigName` vDper.WriteConfig() vDper.SafeWriteConfig() // Like the above, but will error if the config file exists // Writes current config to a specific place vDper.WriteConfigAs("/path/to/my/.config") // Will error since it has already been written vDper.SafeWriteConfigAs("/path/to/my/.config") vDper.SafeWriteConfigAs("/path/to/my/.other_config") ``` -------------------------------- ### Enable Go Modules Source: https://github.com/spf13/viper/blob/master/TROUBLESHOOTING.md This command sets an environment variable to enable Go Modules, which is the recommended dependency management system for Viper. It helps resolve package not found errors by ensuring correct dependency resolution. ```bash export GO111MODULE=on ``` -------------------------------- ### Integrate Standard Library flag with pflag and Viper Source: https://github.com/spf13/viper/blob/master/README.md Demonstrates how to integrate Go's standard library 'flag' package with pflag, and then bind these flags to Viper. This allows using standard flags while still leveraging Viper's configuration management capabilities. ```go package main import ( "flag" "github.com/spf13/pflag" "github.com/spf13/viper" ) func main() { // Using standard library "flag" package flag.Int("flagname", 1234, "help message for flagname") // Pass standard library flags to pflag pflag.CommandLine.AddGoFlagSet(flag.CommandLine) pflag.Parse() // Viper takes over v.BindPFlags(pflag.CommandLine) } ``` -------------------------------- ### Implement Custom File Finder with Viper and Locafero Source: https://context7.com/spf13/viper/llms.txt Details how to integrate a custom file finder using the locafero library with Viper. This allows for advanced configuration file discovery based on specific search paths and file naming patterns, overriding Viper's default file search behavior. It uses afero for filesystem abstraction. ```go package main import ( "fmt" "github.com/sagikazarmark/locafero" "github.com/spf13/afero" "github.com/spf13/viper" ) func main() { fs := afero.NewOsFs() // Define custom finder with specific paths and file patterns finder := locafero.Finder{ Paths: []string{ "/etc/myapp", "/home/user/.config/myapp", ".", }, Names: locafero.NameWithExtensions("config", viper.SupportedExts...), Type: locafero.FileTypeFile, } // Create Viper instance with custom finder v := viper.NewWithOptions(viper.WithFinder(finder)) v.SetFs(fs) err := v.ReadInConfig() if err != nil { fmt.Printf("Error: %v\n", err) return } fmt.Println("Config loaded from:", v.ConfigFileUsed()) fmt.Println("App Name:", v.GetString("app.name")) } ``` -------------------------------- ### Manage Multiple Isolated Viper Instances Source: https://context7.com/spf13/viper/llms.txt Illustrates how to create and manage multiple, independent Viper instances. This is useful for organizing configurations for different application components, environments, or microservices, ensuring that settings from one instance do not interfere with others. It also shows how to use a custom key delimiter. ```go package main import ( "fmt" "github.com/spf13/viper" ) func main() { // Create separate instances for different purposes appConfig := viper.New() appConfig.SetConfigName("app") appConfig.AddConfigPath("./config") appConfig.SetDefault("server.port", 8080) appConfig.ReadInConfig() dbConfig := viper.New() dbConfig.SetConfigName("database") dbConfig.AddConfigPath("./config") dbConfig.SetDefault("database.pool.size", 10) dbConfig.ReadInConfig() // Each instance maintains separate configuration fmt.Println("App Server Port:", appConfig.GetInt("server.port")) fmt.Println("DB Pool Size:", dbConfig.GetInt("database.pool.size")) // Custom key delimiter for special cases customConfig := viper.NewWithOptions(viper.KeyDelimiter("::")) customConfig.Set("chart::values::ingress", "enabled") fmt.Println("Custom Key:", customConfig.GetString("chart::values::ingress")) } ``` -------------------------------- ### Write Configuration Files with Viper Source: https://context7.com/spf13/viper/llms.txt Demonstrates how to save the current Viper configuration state to files. It includes methods for writing to the original config file, safely writing to a new file without overwriting, and forcing a write to a specific file with a given format. This is useful for persisting changes or creating backups. ```go package main import ( "fmt" "log" "github.com/spf13/viper" ) func main() { // Set configuration values programmatically v.Set("database.host", "localhost") v.Set("database.port", 5432) v.Set("server.port", 8080) v.Set("features.analytics", true) // Write to the originally loaded config file err := viper.WriteConfig() if err != nil { log.Printf("Error writing config: %v", err) } // Write to a new file without overwriting existing err = viper.SafeWriteConfigAs("./config.backup.yaml") if err != nil { log.Printf("Error writing backup: %v", err) } // Force write to specific file v.SetConfigType("json") err = viper.WriteConfigAs("./config.json") if err != nil { log.Printf("Error writing JSON config: %v", err) } fmt.Println("Configuration files written successfully") } ``` -------------------------------- ### Reading Configuration Files with Viper Source: https://github.com/spf13/viper/blob/master/README.md This Go code snippet demonstrates how to configure Viper to read configuration files. It involves setting the configuration file name, specifying multiple search paths, and then attempting to read the configuration. Error handling for file reading is also included. ```go // Name of the config file without an extension (Viper will intuit the type // from an extension on the actual file) viper.SetConfigName("config") // Add search paths to find the file viper.AddConfigPath("/etc/appname/") viper.AddConfigPath("$HOME/.appname") viper.AddConfigPath(".") // Find and read the config file err := viper.ReadInConfig() // Handle errors if err != nil { panic(fmt.Errorf("fatal error config file: %w", err)) } ``` ```go var fileLookupError viper.FileLookupError if err := viper.ReadInConfig(); err != nil { if errors.As(err, &fileLookupError) { // Indicates an explicitly set config file is not found (such as with // using `viper.SetConfigFile`) or that no config file was found in // any search path (such as when using `viper.AddConfigPath`) } else { // Config file was found but another error was produced } } // Config file found and successfully parsed ``` -------------------------------- ### Extract Configuration Subsets with Viper Source: https://context7.com/spf13/viper/llms.txt Extracts subsections of a configuration into new Viper instances, enabling modular component configuration. The `Sub` method takes a key path to the desired subsection. It returns a new Viper instance representing that subset, which can then be used independently. ```go package main import ( "bytes" "fmt" "github.com/spf13/viper" ) type CacheConfig struct { ItemSize int `mapstructure:"item-size"` MaxItems int `mapstructure:"max-items"` } func NewCache(v *viper.Viper) *CacheConfig { return &CacheConfig{ ItemSize: v.GetInt("item-size"), MaxItems: v.GetInt("max-items"), } } func main() { v := viper.New() v.SetConfigType("yaml") config := []byte(` cache: cache1: item-size: 64 max-items: 100 cache2: item-size: 128 max-items: 200 `) v.ReadConfig(bytes.NewReader(config)) // Extract sub-configuration cache1Config := v.Sub("cache.cache1") if cache1Config == nil { panic("cache1 configuration not found") } cache1 := NewCache(cache1Config) fmt.Printf("Cache1 - ItemSize: %d, MaxItems: %d\n", cache1.ItemSize, cache1.MaxItems) cache2Config := v.Sub("cache.cache2") if cache2Config == nil { panic("cache2 configuration not found") } cache2 := NewCache(cache2Config) fmt.Printf("Cache2 - ItemSize: %d, MaxItems: %d\n", cache2.ItemSize, cache2.MaxItems) } ``` -------------------------------- ### Go: Bind Configuration to Environment Variables Source: https://context7.com/spf13/viper/llms.txt This Go code demonstrates how to integrate environment variables with Viper for configuration. It shows setting an environment variable prefix (`viper.SetEnvPrefix`), binding specific keys (`viper.BindEnv`), and enabling automatic environment variable detection (`viper.AutomaticEnv`). Environment variables typically override other configuration sources. ```go package main import ( "fmt" "os" "github.com/spf13/viper" ) func main() { // Set environment variable prefix v ``` -------------------------------- ### Marshal Viper Settings to YAML String (Go) Source: https://github.com/spf13/viper/blob/master/README.md This function marshals all settings currently held by a Viper instance into a YAML formatted string. It utilizes the `AllSettings` method to retrieve all configurations and then `yaml.Marshal` to convert them into a byte slice, which is then cast to a string. Error handling for the marshaling process is included. ```go import ( yaml "go.yaml.in/yaml/v3" ) func yamlStringSettings() string { c := viper.AllSettings() bs, err := yaml.Marshal(c) if err != nil { log.Fatalf("unable to marshal config to YAML: %v", err) } return string(bs) } ``` -------------------------------- ### Retrieve Remote Configuration from Etcd/Consul with Viper Source: https://context7.com/spf13/viper/llms.txt Shows how to fetch configuration settings from distributed key-value stores like Etcd or Consul. It covers configuring the remote provider, reading configuration, handling secure remote providers with GPG, and setting up watchers to detect changes in the remote configuration. This enables dynamic configuration updates without restarting the application. ```go package main import ( "fmt" "log" "github.com/spf13/viper" _ "github.com/spf13/viper/remote" ) func main() { // Configure remote provider v.AddRemoteProvider("etcd", "http://127.0.0.1:4001", "/config/myapp.json") v.SetConfigType("json") // Read from remote config err := viper.ReadRemoteConfig() if err != nil { log.Fatalf("Error reading remote config: %v", err) } fmt.Println("Database Host:", viper.GetString("database.host")) fmt.Println("API Key:", viper.GetString("api.key")) // For encrypted configs v.AddSecureRemoteProvider("etcd", "http://127.0.0.1:4001", "/config/secure.json", "/etc/secrets/keyring.gpg") // Watch remote config for changes err = viper.WatchRemoteConfig() if err != nil { log.Fatalf("Error watching remote config: %v", err) } } ``` -------------------------------- ### Go: Read Configuration Files from Multiple Paths Source: https://context7.com/spf13/viper/llms.txt This Go code snippet demonstrates how to configure Viper to read configuration files from various directories. It specifies the configuration file name (without extension) and adds multiple search paths. Viper automatically detects the file format. Errors during reading are logged. ```go package main import ( "fmt" "log" "github.com/spf13/viper" ) func main() { // Set configuration file name without extension v ``` -------------------------------- ### Enable Remote Key/Value Store Support in Viper Source: https://github.com/spf13/viper/blob/master/README.md Enables remote configuration support in Viper by performing a blank import of the 'viper/remote' package. This makes Viper capable of reading configurations from various remote sources. ```go import _ "github.com/spf13/viper/remote" // Viper can now read configurations from remote key/value stores. ``` -------------------------------- ### Watch and Re-read Configuration Files with Viper Source: https://github.com/spf13/viper/blob/master/README.md Enables applications to monitor configuration files for changes and re-read them without restarting. It requires configuration paths to be set beforehand and allows registering a callback function for change events. ```go // All config paths must be defined prior to calling `WatchConfig()` vDper.AddConfigPath("$HOME/.appname") vDper.OnConfigChange(func(e fsnotify.Event) { fmt.Println("Config file changed:", e.Name) }) vDper.WatchConfig() ``` -------------------------------- ### Run Viper Test Suite (Shell) Source: https://github.com/spf13/viper/blob/master/README.md This command executes the test suite for the Viper project. It's part of the development workflow to ensure the library's stability and correctness. The `make test` command typically invokes Go's built-in testing framework. ```shell make test ``` -------------------------------- ### Work with Environment Variables in Viper Source: https://github.com/spf13/viper/blob/master/README.md Provides comprehensive support for environment variables as a configuration source. It allows setting a prefix for environment variables and automatically binding them to configuration keys. Environment variables are case-sensitive. ```go // Tells Viper to use this prefix when reading environment variables vDper.SetEnvPrefix("spf") // Viper will look for "SPF_ID", automatically uppercasing the prefix and key vDper.BindEnv("id") // Alternatively, we can search for any environment variable prefixed and load // them in vDper.AutomaticEnv() os.Setenv("SPF_ID", "13") id := vDper.Get("id") // 13 ``` -------------------------------- ### Go: Set Default Configuration Values Source: https://context7.com/spf13/viper/llms.txt This Go snippet illustrates how to define default values for configuration settings using `viper.SetDefault`. These defaults are used as fallbacks when a configuration value is not found in other sources like config files or environment variables. It demonstrates setting defaults for strings, integers, durations, and maps. ```go package main import ( "fmt" "github.com/spf13/viper" ) func main() { // Set default values v ``` -------------------------------- ### Watch Configuration File Changes with Viper Source: https://context7.com/spf13/viper/llms.txt Monitors specified configuration files for changes and automatically reloads the configuration. It supports registering a callback function that executes when a change is detected. This is useful for live configuration updates without restarting the application. It requires a config file to be set and watched. ```go package main import ( "fmt" "time" "github.com/fsnotify/fsnotify" "github.com/spf13/viper" ) func main() { v := viper.New() v.SetConfigFile("./config.yaml") // Assumes a config.yaml exists in the same directory v.SetConfigType("yaml") // Initial read if err := v.ReadInConfig(); err != nil { panic(fmt.Errorf("error reading config: %w", err)) } // Set up change handler v.OnConfigChange(func(e fsnotify.Event) { fmt.Printf("Config file changed: %s\n", e.Name) // Re-read the config to apply changes if err := v.ReadInConfig(); err != nil { fmt.Println("Error reading config after change: ", err) return } fmt.Println("New server port:", v.GetInt("server.port")) fmt.Println("New debug mode:", v.GetBool("debug")) }) // Start watching v.WatchConfig() // Application continues running fmt.Println("Watching for config changes...") fmt.Println("Current port:", v.GetInt("server.port")) // Keep application running to demonstrate watching time.Sleep(5 * time.Minute) } ``` -------------------------------- ### Implement FlagValueSet Interface for Viper Source: https://github.com/spf13/viper/blob/master/README.md Demonstrates implementing the FlagValueSet interface for custom flag set management within Viper. This allows Viper to iterate over and manage collections of custom flags. ```go // Implementing FlagValueSet type myFlagSet struct { flags []myFlag } func (f myFlagSet) VisitAll(fn func(FlagValue)) { for _, flag := range flags { fn(flag) } } fSet := myFlagSet{ flags: []myFlag{myFlag{}, myFlag{}}, } v.BindFlagValues("my-flags", fSet) ``` -------------------------------- ### Format Viper Code (Shell) Source: https://github.com/spf13/viper/blob/master/README.md This command automatically formats the Go code within the Viper project according to standard Go formatting conventions. It helps in maintaining a consistent code style across the project. This command can fix some linter violations. ```shell make fmt ``` -------------------------------- ### Customize Unmarshaling with Mapstructure Options in Go Source: https://github.com/spf13/viper/wiki/Tips-and-tricks This Go snippet demonstrates how to customize the unmarshaling process in Viper by providing options to the mapstructure decoder. It specifically shows how to enable an error for unused fields in the configuration file, which can help catch typos or outdated configuration keys. ```go import "github.com/mitchellh/mapstructure" import "github.com/spf13/viper" // ... inside a function or method ... v.Unmarshal(&f.d, func(config *mapstructure.DecoderConfig) { config.ErrorUnused = true }) ``` -------------------------------- ### Implement FlagValue Interface for Viper Source: https://github.com/spf13/viper/blob/master/README.md Shows how to implement the FlagValue interface to allow Viper to directly interact with custom flag implementations without relying on pflag. This provides a way to manage custom flag types within Viper. ```go // Implementing FlagValue type myFlag struct {} func (f myFlag) HasChanged() bool { return false } func (f myFlag) Name() string { return "my-flag-name" } func (f myFlag) ValueString() string { return "my-flag-value" } func (f myFlag) ValueType() string { return "string" } v.BindFlagValue("my-flag-name", myFlag{}) ``` -------------------------------- ### Custom File Finder Interface and Usage in Viper Source: https://github.com/spf13/viper/blob/master/UPGRADE.md Defines the Finder interface for custom configuration file searching within Viper. Shows how to supply a custom implementation using WithFinder, allowing for flexible file discovery. This feature enhances Viper's adaptability to different project structures and file system requirements. ```go // Finder looks for files and directories in an [afero.Fs] filesystem. type Finder interface { Find(fsys afero.Fs) ([]string, error) } v := viper.NewWithOptions( viper.WithFinder(&MyFinder{}), ) ``` -------------------------------- ### Set Default Configuration Values with Viper Source: https://github.com/spf13/viper/blob/master/README.md Defines default values for configuration keys. These defaults are used when a key has not been explicitly set through other configuration sources. This is useful for providing sensible fallback values. ```go vDper.SetDefault("ContentDir", "content") vDper.SetDefault("LayoutDir", "layouts") vDper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"}) ``` -------------------------------- ### Read Configuration from io.Reader with Viper Source: https://github.com/spf13/viper/blob/master/README.md Allows reading configuration data directly from an io.Reader, such as a byte slice. This is useful for implementing custom configuration sources or reading configuration embedded within an application. The configuration type must be set first. ```go vDper.SetConfigType("yaml") var yamlExample = []byte(` hacker: true hobbies: - skateboarding - snowboarding - go name: steve `) vDper.ReadConfig(bytes.NewBuffer(yamlExample)) vDper.Get("name") // "steve" ``` -------------------------------- ### Register and Use Aliases in Viper Source: https://github.com/spf13/viper/blob/master/README.md Permits a single configuration value to be referenced by multiple keys using aliases. This is useful for maintaining backward compatibility or providing alternative names for configuration options. ```go vDper.RegisterAlias("loud", "Verbose") vDper.Set("verbose", true) // Same result as next line vDper.Set("loud", true) // Same result as prior line vDper.GetBool("loud") // true vDper.GetBool("verbose") // true ``` -------------------------------- ### Unmarshal Configuration to Go Structs with Viper Source: https://context7.com/spf13/viper/llms.txt Decodes an entire configuration or specific subsets into Go structs. It leverages mapstructure tags for mapping configuration keys to struct fields. This function requires a Viper instance with configuration loaded and a target struct pointer for unmarshaling. ```go package main import ( "bytes" "fmt" "log" "time" "github.com/spf13/viper" ) type Config struct { Database DatabaseConfig Server ServerConfig } type DatabaseConfig struct { Host string Port int Username string Password string Timeout time.Duration } type ServerConfig struct { Port int Host string TLS bool Timeouts TimeoutConfig } type TimeoutConfig struct { Read time.Duration `mapstructure:"read_timeout"` Write time.Duration `mapstructure:"write_timeout"` } func main() { v := viper.New() v.SetConfigType("yaml") configData := []byte(` database: host: db.example.com port: 5432 username: admin password: secret timeout: 10s server: port: 8080 host: 0.0.0.0 tls: true timeouts: read_timeout: 30s write_timeout: 60s `) if err := v.ReadConfig(bytes.NewReader(configData)); err != nil { log.Fatal(err) } var config Config if err := v.Unmarshal(&config); err != nil { log.Fatalf("Unable to decode config: %v", err) } fmt.Printf("Database: %s:%d\n", config.Database.Host, config.Database.Port) fmt.Printf("Server: %s:%d (TLS: %v)\n", config.Server.Host, config.Server.Port, config.Server.TLS) fmt.Printf("Read Timeout: %v\n", config.Server.Timeouts.Read) } ``` -------------------------------- ### Set Configuration Overrides with Viper Source: https://github.com/spf13/viper/blob/master/README.md Enables explicitly setting configuration values within the application logic. This allows overriding values from other sources when needed. It supports setting simple keys and nested keys. ```go vDper.Set("verbose", true) vDper.Set("host.port", 5899) // Set an embedded key ``` -------------------------------- ### Register Aliases for Configuration Keys in Viper Source: https://context7.com/spf13/viper/llms.txt Explains how to register aliases for existing configuration keys using Viper. This feature is valuable for backward compatibility during refactoring, allowing applications to access configuration values using either the old or new key names. Changes made through an alias are reflected in the original key. ```go package main import ( "fmt" "github.com/spf13/viper" ) func main() { // Set original values v.Set("verbose", true) v.Set("database.hostname", "db.example.com") // Register aliases for backward compatibility v.RegisterAlias("loud", "verbose") v.RegisterAlias("db.host", "database.hostname") // Access via either key fmt.Println("verbose:", viper.GetBool("verbose")) fmt.Println("loud:", viper.GetBool("loud")) // Setting via alias affects the original key v.Set("loud", false) fmt.Println("verbose after setting loud:", viper.GetBool("verbose")) fmt.Println("database.hostname:", viper.GetString("database.hostname")) fmt.Println("db.host:", viper.GetString("db.host")) } ``` -------------------------------- ### Read Remote Configuration from Consul Source: https://github.com/spf13/viper/blob/master/README.md Demonstrates reading configuration from Consul. It specifies the Consul agent address and the key where the configuration is stored. The configuration type must be explicitly set, and values can then be accessed via Viper. ```go viper.AddRemoteProvider("consul", "localhost:8500", "MY_CONSUL_KEY") v.SetConfigType("json") // Need to explicitly set this to json err := v.ReadRemoteConfig() fmt.Println(viper.Get("port")) // 8080 ``` -------------------------------- ### Registering Custom Codecs with Viper Source: https://github.com/spf13/viper/blob/master/UPGRADE.md Demonstrates how to register custom codecs with Viper's CodecRegistry. This allows Viper to handle configuration data in formats beyond the built-in ones. A custom codec is registered with a specific format name, and the registry is then passed to Viper during initialization using WithCodecRegistry. ```go codecRegistry := viper.NewCodecRegistry() codecRegistry.RegisterCodec("myformat", &MyCodec{}) v := viper.NewWithOptions( viper.WithCodecRegistry(codecRegistry), ) ``` -------------------------------- ### Read Remote Configuration from etcd Source: https://github.com/spf13/viper/blob/master/README.md Configures Viper to read configuration from an etcd server. It specifies the etcd endpoint, the configuration path, and the configuration type. The configuration is then read remotely. ```go viper.AddRemoteProvider("etcd", "http://127.0.0.1:4001", "/config/hugo.json") v.SetConfigType("json") // because there is no file extension in a stream of bytes, supported extensions are "json", "toml", "yaml", "yml", "properties", "props", "prop", "env", "dotenv" err := v.ReadRemoteConfig() ``` -------------------------------- ### Build with YAML v3 Support Source: https://github.com/spf13/viper/blob/master/TROUBLESHOOTING.md This build tag enables support for YAML v3, which can resolve issues with unquoted 'y' and 'n' characters being misinterpreted as boolean values in YAML files. This is a workaround for YAML 1.1 behavior. ```bash go build -tags "viper_yaml3" ``` -------------------------------- ### Read Remote Configuration from etcd3 Source: https://github.com/spf13/viper/blob/master/README.md Configures Viper to read configuration from an etcd3 server. Similar to etcd, it sets the provider, endpoint, configuration path, and type before reading the remote configuration. ```go viper.AddRemoteProvider("etcd3", "http://127.0.0.1:4001", "/config/hugo.json") v.SetConfigType("json") // because there is no file extension in a stream of bytes, supported extensions are "json", "toml", "yaml", "yml", "properties", "props", "prop", "env", "dotenv" err := v.ReadRemoteConfig() ``` -------------------------------- ### Run Viper Linters (Shell) Source: https://github.com/spf13/viper/blob/master/README.md This command runs linters against the Viper project code to check for style issues and potential bugs. The `-j` option can be passed to run linters in parallel for faster execution. This is a crucial step for maintaining code quality. ```shell make lint # pass -j option to run them in parallel ``` -------------------------------- ### Registering Removed Codecs (HCL, Java Properties, INI) in Viper Source: https://github.com/spf13/viper/blob/master/UPGRADE.md Shows how to re-enable support for HCL, Java properties, and INI configuration formats in Viper by importing them from the 'github.com/go-viper/encoding' package. This involves creating a custom CodecRegistry and registering the respective codecs for each format, allowing Viper to parse these files when specified. ```go import ( "github.com/go-viper/encoding/hcl" "github.com/go-viper/encoding/javaproperties" "github.com/go-viper/encoding/ini" ) codecRegistry := viper.NewCodecRegistry() { codec := hcl.Codec{} codecRegistry.RegisterCodec("hcl", codec) codecRegistry.RegisterCodec("tfvars", codec) } { codec := &javaproperties.Codec{} codecRegistry.RegisterCodec("properties", codec) codecRegistry.RegisterCodec("props", codec) codecRegistry.RegisterCodec("prop", codec) } codecRegistry.RegisterCodec("ini", ini.Codec{}) v := viper.NewWithOptions( viper.WithCodecRegistry(codecRegistry), ) ``` -------------------------------- ### Custom Encoder, Decoder, and Codec Interfaces for Viper Source: https://github.com/spf13/viper/blob/master/UPGRADE.md Introduces the Encoder, Decoder, and Codec interfaces, enabling customization of Viper's data encoding and decoding layers. These interfaces allow users to define how configuration data is serialized and deserialized, supporting custom file formats or processing logic. The default implementations handle JSON, TOML, YAML, and Dotenv. ```go // Encoder encodes Viper's internal data structures into a byte representation. type Encoder interface { Encode(v map[string]any) ([]byte, error) } // Decoder decodes the contents of a byte slice into Viper's internal data structures. type Decoder interface { Decode(b []byte, v map[string]any) error } // Codec combines [Encoder] and [Decoder] interfaces. type Codec interface { Encoder Decoder } ``` -------------------------------- ### Read Remote Configuration from Firestore Source: https://github.com/spf13/viper/blob/master/README.md Sets up Viper to read configuration from Google Cloud Firestore. It requires the Google Cloud Project ID and the path to the configuration document. The configuration type also needs to be specified. ```go viper.AddRemoteProvider("firestore", "google-cloud-project-id", "collection/document") v.SetConfigType("json") // Config's format: "json", "toml", "yaml", "yml" err := v.ReadRemoteConfig() ``` -------------------------------- ### Read Remote Configuration from NATS Source: https://github.com/spf13/viper/blob/master/README.md Configures Viper to fetch configuration from a NATS server. It specifies the NATS endpoint and the subject to subscribe to for configuration updates. The configuration type is set to JSON. ```go viper.AddRemoteProvider("nats", "nats://127.0.0.1:4222", "myapp.config") v.SetConfigType("json") err := v.ReadRemoteConfig() ``` -------------------------------- ### Access Nested Configuration Values with Dot Notation in Viper Source: https://context7.com/spf13/viper/llms.txt Retrieves deeply nested configuration values using string keys with dot notation. This function can access values within nested objects and arrays. It requires the configuration to be loaded into Viper first and returns values based on their expected types (e.g., GetString, GetInt, GetBool). ```go package main import ( "bytes" "fmt" "github.com/spf13/viper" ) func main() { v := viper.New() v.SetConfigType("json") configJSON := []byte(`{ "app": { "name": "MyApp", "version": "1.0.0", "features": { "authentication": { "enabled": true, "providers": ["oauth", "saml"] }, "analytics": { "enabled": false } } }, "servers": [ {"name": "primary", "host": "server1.example.com", "port": 8080}, {"name": "backup", "host": "server2.example.com", "port": 8080} ] }`) v.ReadConfig(bytes.NewReader(configJSON)) // Access nested values with dot notation fmt.Println("App Name:", v.GetString("app.name")) fmt.Println("Auth Enabled:", v.GetBool("app.features.authentication.enabled")) fmt.Println("Auth Providers:", v.GetStringSlice("app.features.authentication.providers")) // Access array elements by index fmt.Println("Primary Server:", v.GetString("servers.0.host")) fmt.Println("Backup Port:", v.GetInt("servers.1.port")) } ``` -------------------------------- ### Bind Individual pflag to Viper Source: https://github.com/spf13/viper/blob/master/README.md Binds an individual pflag to Viper, allowing configuration values to be accessed through Viper after they are set by the flag. This is useful for integrating Cobra or other pflag-based CLI frameworks with Viper. ```go package main import ( "github.com/spf13/cobra" "github.com/spf13/viper" ) var serverCmd = &cobra.Command{ Use: "server", Short: "Runs the server", } func main() { serverCmd.Flags().Int("port", 1138, "Port to run Application server on") v.BindPFlag("port", serverCmd.Flags().Lookup("port")) // Configuration can now be accessed via viper.Get("port") } ``` -------------------------------- ### Updating mapstructure Import Path in Viper Source: https://github.com/spf13/viper/blob/master/UPGRADE.md Provides guidance on updating the import path for the mapstructure dependency when migrating to newer Viper versions. The original 'github.com/mitchellh/mapstructure' has been replaced by a fork at 'github.com/go-viper/mapstructure/v2' due to the original repository being archived. This change is crucial for maintaining compatibility when directly using mapstructure configurations. ```diff - import "github.com/mitchellh/mapstructure" + import "github.com/go-viper/mapstructure/v2" ``` ```go err := viper.Unmarshal(&appConfig, func(config *mapstructure.DecoderConfig) { config.TagName = "yaml" }) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.