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