github.com/l3x/learn-fp-go@v0.0.0-20171228022418-7639825d0b71/4-purely-functional/ch10-monads/01_car_steps/src/utils/options.go (about)

     1  package utils
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"github.com/BurntSushi/toml"
     7  	"reflect"
     8  	"strconv"
     9  	"github.com/pkg/errors"
    10  )
    11  
    12  type Conf struct {
    13  	DataFilepath     string   `toml:"data_filepath"`
    14  	AppEnv           string   `toml:"app_env"`
    15  	LogLevel         string   `toml:"log_level"`
    16  	LogVerbose       bool     `toml:"log_verbose"`
    17  	LogDebugChars    string   `toml:"log_debug_chars"`
    18  	LogDebugInfo     bool     `toml:"log_debug_info"`
    19  	LogTimeTrack     bool     `toml:"log_timetrack"`
    20  	I18nFilename     string   `toml:"i18n_filename"`
    21  }
    22  
    23  var Config Conf
    24  
    25  func GetOptions() bool {
    26  	var configFile string
    27  	flag.StringVar(&configFile, "config", "", "Configuration file")
    28  	flag.StringVar(&Config.DataFilepath, "data-filepath", "./data/cars.base64", "Full path to the file containing the base64 car strings")
    29  	flag.StringVar(&Config.AppEnv, "development", "development", "Runtime environment. Determines whether to run semver scripts or expect env vars")
    30  	flag.StringVar(&Config.LogLevel, "log-level", "INFO", "Log level options: PANC, FATL, ERRO, WARN, INFO, DEBG")
    31  	flag.BoolVar(&Config.LogVerbose, "log-verbose", false, "Whether to include timestamps and log level on all log entries")
    32  	flag.StringVar(&Config.LogDebugChars, "log-debug-chars", ">>", "The character(s) used to preface debug lines")
    33  	flag.BoolVar(&Config.LogDebugInfo, "log-debug-info", true, "Whether to log debug output to the log (set to true for debug purposes)")
    34  	flag.BoolVar(&Config.LogTimeTrack, "log-timetrack", true, "Enable or disable logging of utils/TimeTrack() (For benchmarking/debugging)")
    35  	flag.StringVar(&Config.I18nFilename, "i18n-filename", "en-us.all.json", "i18n translation file name, see github.com/nicksnyder/go-i18n")
    36  	flag.Parse()
    37  	if configFile != "" {
    38  		if _, err := toml.DecodeFile(configFile, &Config); err != nil {
    39  			HandlePanic(errors.Wrap(err, "unable to read config file"))
    40  		}
    41  	}
    42  	return true
    43  }
    44  
    45  type Datastore interface {}
    46  
    47  
    48  func UpdateConfigVal(d Datastore, key, val string) (oldValue string) {
    49  	Debug.Printf("key (%s), val (%v)\n", key, val)
    50  	value := reflect.ValueOf(d)
    51  	if value.Kind() != reflect.Ptr {
    52  		panic("not a pointer")
    53  	}
    54  	valElem := value.Elem()
    55  	for i := 0; i < valElem.NumField(); i++ {
    56  		tag := valElem.Type().Field(i).Tag
    57  		field := valElem.Field(i)
    58  		switch tag.Get("toml") {
    59  		case key:
    60  			if fmt.Sprintf("%v", field.Kind()) == "int" {
    61  				oldValue = strconv.FormatInt(field.Int(), 10)
    62  				intVal, err := strconv.Atoi(val)
    63  				if err != nil {
    64  					fmt.Printf("could not parse int, key(%s) val(%s)", key, val)
    65  				} else {
    66  					field.SetInt(int64(intVal))
    67  				}
    68  			} else if fmt.Sprintf("%v", field.Kind()) == "bool" {
    69  				oldValue = strconv.FormatBool(field.Bool())
    70  				b, err := strconv.ParseBool(val)
    71  				if err != nil {
    72  					fmt.Printf("could not parse bool, key(%s) val(%s)", key, val)
    73  				} else {
    74  					field.SetBool(b)
    75  				}
    76  			} else {
    77  				// Currently only supports bool, int and string
    78  				oldValue = field.String()
    79  				field.SetString(val)
    80  			}
    81  		}
    82  	}
    83  	return
    84  }
    85