github.com/MetalBlockchain/metalgo@v1.11.9/config/viper.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package config
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/base64"
     9  	"fmt"
    10  	"io"
    11  	"os"
    12  	"strings"
    13  
    14  	"github.com/spf13/pflag"
    15  	"github.com/spf13/viper"
    16  )
    17  
    18  const EnvPrefix = "avago"
    19  
    20  var DashesToUnderscores = strings.NewReplacer("-", "_")
    21  
    22  // BuildViper returns the viper environment from parsing config file from
    23  // default search paths and any parsed command line flags
    24  func BuildViper(fs *pflag.FlagSet, args []string) (*viper.Viper, error) {
    25  	if err := deprecateFlags(fs); err != nil {
    26  		return nil, err
    27  	}
    28  	if err := fs.Parse(args); err != nil {
    29  		return nil, err
    30  	}
    31  
    32  	v := viper.New()
    33  	v.AutomaticEnv()
    34  	v.SetEnvKeyReplacer(DashesToUnderscores)
    35  	v.SetEnvPrefix(EnvPrefix)
    36  	if err := v.BindPFlags(fs); err != nil {
    37  		return nil, err
    38  	}
    39  
    40  	// load node configs from flags or file, depending on which flags are set
    41  	switch {
    42  	case v.IsSet(ConfigContentKey):
    43  		configContentB64 := v.GetString(ConfigContentKey)
    44  		configBytes, err := base64.StdEncoding.DecodeString(configContentB64)
    45  		if err != nil {
    46  			return nil, fmt.Errorf("unable to decode base64 content: %w", err)
    47  		}
    48  
    49  		v.SetConfigType(v.GetString(ConfigContentTypeKey))
    50  		if err := v.ReadConfig(bytes.NewBuffer(configBytes)); err != nil {
    51  			return nil, err
    52  		}
    53  
    54  	case v.IsSet(ConfigFileKey):
    55  		filename := GetExpandedArg(v, ConfigFileKey)
    56  		v.SetConfigFile(filename)
    57  		if err := v.ReadInConfig(); err != nil {
    58  			return nil, err
    59  		}
    60  	}
    61  
    62  	// Config deprecations must be after v.ReadInConfig
    63  	deprecateConfigs(v, os.Stdout)
    64  	return v, nil
    65  }
    66  
    67  func deprecateConfigs(v *viper.Viper, output io.Writer) {
    68  	for key, message := range deprecatedKeys {
    69  		if v.InConfig(key) {
    70  			fmt.Fprintf(output, "Config %s has been deprecated, %s\n", key, message)
    71  		}
    72  	}
    73  }