github.com/packtpublishing/learning-functional-programming-in-go@v0.0.0-20230130084745-8b849f6d58c4/Chapter06/04_onion/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 AppEnv string `toml:"app_env"` 14 ProjectRoot string `toml:"project_root_dir"` 15 DownloadDir string `toml:"download_dir"` 16 GcpSourceDir string `toml:"gcp_source_dir"` 17 GcpSourceKeyFile string `toml:"gcp_source_key_file"` 18 GcpSourceProjectId string `toml:"gcp_source_project_id"` 19 GcpSinkDir string `toml:"gcp_sink_dir"` 20 GcpSinkKeyFile string `toml:"gcp_sink_key_file"` 21 GcpSinkProjectId string `toml:"gcp_sink_project_id"` 22 SourceBucketName string `toml:"source_bucket_name"` 23 SinkBucketName string `toml:"sink_bucket_name"` 24 ApiPort string `toml:"api_port"` 25 LogTimeTrack bool `toml:"log_timetrack"` 26 LogFullStackTrace bool `toml:"log_full_stack_trace"` 27 LogDebugInfo bool `toml:"log_debug_info"` 28 LogDebugInfoForTests bool `toml:"log_debug_info_for_tests"` 29 } 30 31 var Config Conf 32 33 func GetOptions() bool { 34 var configFile string 35 36 flag.StringVar(&configFile, "config", "", "Configuration file") 37 flag.StringVar(&Config.AppEnv, "onion-env", "development", "Runtime environment. Determines whether to run semver scripts or expect env vars") 38 flag.StringVar(&Config.ProjectRoot, "project-root", "/Users/lex/clients/packt/dev/fp-go/2-design-patterns/ch06-onion-arch/04_onion", "Project Root directory (required). Must be absolute path") 39 flag.StringVar(&Config.DownloadDir, "download-dir", "/Users/lex/clients/packt/dev/fp-go/2-design-patterns/ch06-onion-arch/04_onion/downloads", "Where files are downloaded") 40 flag.StringVar(&Config.GcpSourceDir, "gcp_source_dir", "source-events", "Source log file host names (parent directory names in Google Cloud bucket") 41 flag.StringVar(&Config.GcpSourceKeyFile, "gcp-source-key-file", "/Users/lex/clients/packt/dev/fp-go/2-design-patterns/ch06-onion-arch/04_onion/keys/google-cloud-storage/source/onion-source-key.json", "Google Cloud Platform source key file") 42 flag.StringVar(&Config.GcpSourceProjectId, "gcp-source-project-id", "onion-xxxx", "Google Cloud Platform source project id") 43 flag.StringVar(&Config.GcpSourceDir, "gcp_sink_dir", "sink-events", "Source log file host names (parent directory names in Google Cloud bucket") 44 flag.StringVar(&Config.GcpSinkKeyFile, "gcp-sink-key-file", "/Users/lex/clients/packt/dev/fp-go/2-design-patterns/ch06-onion-arch/04_onion/keys/google-cloud-storage/sink/onion-sink-key.json", "Google Cloud Platform sink key file") 45 flag.StringVar(&Config.GcpSinkProjectId, "gcp_sink_project_id", "xxxx-999999", "Google Cloud Platform sink project id") 46 flag.StringVar(&Config.SourceBucketName, "source_bucket_name", "onion-logs", "Cloud bucket where the log files to be processed") 47 flag.StringVar(&Config.SinkBucketName, "sink_bucket_name", "lexttc3-my-backup-bucket", "Cloud bucket where they are to be copied after processing") 48 flag.StringVar(&Config.ApiPort, "api-port", "8080", "Port that the API listens on") 49 flag.BoolVar(&Config.LogTimeTrack, "log-timetrack", true, "Enable or disable logging of utils/TimeTrack() (For benchmarking/debugging)") 50 flag.BoolVar(&Config.LogFullStackTrace, "log-full-stack-trace", false, "Print version information and exit") 51 flag.BoolVar(&Config.LogDebugInfo, "log-debug-info", false, "Whether to log debug output to the log (set to true for debug purposes)") 52 flag.BoolVar(&Config.LogDebugInfoForTests, "log-debug-info-for-tests", true, "Whether to log debug output to the log when running tests (set to true for debug purposes)") 53 54 flag.Parse() 55 56 if configFile != "" { 57 if _, err := toml.DecodeFile(configFile, &Config); err != nil { 58 HandlePanic(errors.Wrap(err, "unable to read config file")) 59 } 60 } 61 return true 62 } 63 64 type Datastore interface {} 65 66 67 // UpdateConfigVal returns string representation of old config value 68 func UpdateConfigVal(d Datastore, key, val string) (oldValue string) { 69 Debug.Printf("key (%s), val (%v)\n", key, val) 70 value := reflect.ValueOf(d) 71 if value.Kind() != reflect.Ptr { 72 panic("not a pointer") 73 } 74 valElem := value.Elem() 75 //this loops through the fields 76 for i := 0; i < valElem.NumField(); i++ { // iterates through every struct type field 77 tag := valElem.Type().Field(i).Tag // returns the tag string 78 field := valElem.Field(i) // returns the content of the struct type field 79 switch tag.Get("toml") { 80 case key: 81 if fmt.Sprintf("%v", field.Kind()) == "int" { 82 oldValue = strconv.FormatInt(field.Int(), 10) 83 intVal, err := strconv.Atoi(val) 84 if err != nil { 85 fmt.Printf("could not parse int, key(%s) val(%s)", key, val) 86 } else { 87 field.SetInt(int64(intVal)) 88 } 89 } else if fmt.Sprintf("%v", field.Kind()) == "bool" { 90 oldValue = strconv.FormatBool(field.Bool()) 91 b, err := strconv.ParseBool(val) 92 if err != nil { 93 fmt.Printf("could not parse bool, key(%s) val(%s)", key, val) 94 } else { 95 field.SetBool(b) 96 } 97 } else { 98 // Currently only supports bool, int and string 99 oldValue = field.String() 100 field.SetString(val) 101 } 102 } 103 } 104 return 105 } 106