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