I use json file to configure my program arguments and use flag package to configure the same arguments.
When some argument parsed by json file and flag at the same time, I wish use the arguments parsed through flag.
The trouble is that the json file path is also parsed through flag.
The json path can be obtained after calling flag.parse(), but the arguments is also parsed, then Unmarshal json will overwrite the arguments of flag parsing.
example json:
{
"opt1": 1,
"opt2": "hello"
}
example code:
var Config = struct {
Opt1 int `json:"opt1"`
Opt2 string `json:"opt2"`
}{
Opt1: 0,
Opt2: "none",
}
func main() {
// parse config file path
var configFile string
flag.StringVar(&configFile, "config", "", "config file path")
// parse options
flag.IntVar(&Config.Opt1, "opt1", Config.Opt1, "")
flag.StringVar(&Config.Opt2, "opt2", Config.Opt2, "")
// parse flags
flag.Parse()
// load config options from config.json file
if configFile != "" {
if data, err := ioutil.ReadFile(configFile); err != nil {
fmt.Printf("read config file error: %v\n", err)
} else if err = json.Unmarshal(data, &Config); err != nil {
fmt.Printf("parse config file error: %v\n", err)
}
}
fmt.Printf("%+v", Config)
}
program example output:
./foo.exe -opt2 world
out: {Opt1:0 Opt2:world}
./foo.exe -config config.json
out: {Opt1:1 Opt2:hello}
./foo.exe -config config.json -opt2 world
real out: {Opt1:1 Opt2:hello}
hope out: {Opt1:1 Opt2:world}