{"action":"created","issue":{"url":"https://api.github.com/repos/jessevdk/go-flags/issues/163","repository_url":"https://api.github.com/repos/jessevdk/go-flags","labels_url":"https://api.github.com/repos/jessevdk/go-flags/issues/163/labels{/name}","comments_url":"https://api.github.com/repos/jessevdk/go-flags/issues/163/comments","events_url":"https://api.github.com/repos/jessevdk/go-flags/issues/163/events","html_url":"https://github.com/jessevdk/go-flags/pull/163","id":136764466,"number":163,"title":"Option new methods","user":{"login":"pierrec","id":368228,"avatar_url":"https://avatars.githubusercontent.com/u/368228?v=3","gravatar_id":"","url":"https://api.github.com/users/pierrec","html_url":"https://github.com/pierrec","followers_url":"https://api.github.com/users/pierrec/followers","following_url":"https://api.github.com/users/pierrec/following{/other_user}","gists_url":"https://api.github.com/users/pierrec/gists{/gist_id}","starred_url":"https://api.github.com/users/pierrec/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pierrec/subscriptions","organizations_url":"https://api.github.com/users/pierrec/orgs","repos_url":"https://api.github.com/users/pierrec/repos","events_url":"https://api.github.com/users/pierrec/events{/privacy}","received_events_url":"https://api.github.com/users/pierrec/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2016-02-26T17:47:39Z","updated_at":"2016-02-27T21:06:09Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/jessevdk/go-flags/pulls/163","html_url":"https://github.com/jessevdk/go-flags/pull/163","diff_url":"https://github.com/jessevdk/go-flags/pull/163.diff","patch_url":"https://github.com/jessevdk/go-flags/pull/163.patch"},"body":"Hopefully, this is helpful for everyone...\r\n\r\n- added Option.Field() method to recover the struct field associated with the option\r\n- added Option.IsSetDefault() to help distinguish cases where the option was really set or set with default values"},"comment":{"url":"https://api.github.com/repos/jessevdk/go-flags/issues/comments/189726176","html_url":"https://github.com/jessevdk/go-flags/pull/163#issuecomment-189726176","issue_url":"https://api.github.com/repos/jessevdk/go-flags/issues/163","id":189726176,"user":{"login":"pierrec","id":368228,"avatar_url":"https://avatars.githubusercontent.com/u/368228?v=3","gravatar_id":"","url":"https://api.github.com/users/pierrec","html_url":"https://github.com/pierrec","followers_url":"https://api.github.com/users/pierrec/followers","following_url":"https://api.github.com/users/pierrec/following{/other_user}","gists_url":"https://api.github.com/users/pierrec/gists{/gist_id}","starred_url":"https://api.github.com/users/pierrec/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pierrec/subscriptions","organizations_url":"https://api.github.com/users/pierrec/orgs","repos_url":"https://api.github.com/users/pierrec/repos","events_url":"https://api.github.com/users/pierrec/events{/privacy}","received_events_url":"https://api.github.com/users/pierrec/received_events","type":"User","site_admin":false},"created_at":"2016-02-27T21:06:09Z","updated_at":"2016-02-27T21:06:09Z","body":"Ah yes it does, although it is not straightforward.\r\n\r\nHere is a working example based on the one in #120:\r\n```\r\npackage main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"log\"\r\n\r\n\t\"github.com/jessevdk/go-flags\"\r\n)\r\n\r\ntype opts struct {\r\n\tConfig string `long:\"config\" no-ini:\"true\"`\r\n\tHost   string `long:\"host\" default:\"localhost\"`\r\n}\r\n\r\nfunc main() {\r\n\toptions := &opts{}\r\n\r\n\t// parse cli options\r\n\tp := flags.NewParser(options, flags.Default)\r\n\tif _, err := p.Parse(); err != nil {\r\n\t\tlog.Fatal(err)\r\n\t}\r\n\r\n\tif options.Config == \"\" {\r\n\t\t// no config file: nothing else to do\r\n\t\tfmt.Printf(\"%+v\\n\", options)\r\n\t\treturn\r\n\t}\r\n\r\n\t// config file specified:\r\n\t// - load it in a separate options struct\r\n\t// - any set file option overwrites the default cli one\r\n\tinip := flags.NewParser(&opts{}, flags.Default)\r\n\tif err := flags.NewIniParser(inip).ParseFile(options.Config); err != nil {\r\n\t\tlog.Fatal(err)\r\n\t}\r\n\r\n\t// compare and set all options\r\n\tvar walk func([]*flags.Group)\r\n\twalk = func(groups []*flags.Group) {\r\n\t\tfor _, g := range groups {\r\n\t\t\twalk(g.Groups())\r\n\t\t\tfor _, o := range g.Options() {\r\n\t\t\t\tif !o.IsSet() {\r\n\t\t\t\t\t// option not set in the config file, ignore\r\n\t\t\t\t\tcontinue\r\n\t\t\t\t}\r\n\t\t\t\t// cli corresponding option\r\n\t\t\t\too := p.Command.Group.FindOptionByLongName(o.LongNameWithNamespace())\r\n\t\t\t\tif !oo.IsSetDefault() {\r\n\t\t\t\t\t// cli option set, it prevails\r\n\t\t\t\t\tcontinue\r\n\t\t\t\t}\r\n\t\t\t\t// file option overwrites cli default value\r\n\t\t\t\too.Field().Set(o.Field())\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\twalk(inip.Command.Groups())\r\n\r\n\tfmt.Printf(\"%+v\\n\", options)\r\n}\r\n```\r\n\r\nThe output:\r\n```\r\n$ ./tmp\r\n&{Config: Host:localhost}\r\n$ ./tmp --host google.com\r\n&{Config: Host:google.com}\r\n$ cat a.ini \r\nHost = github.com\r\n$ ./tmp --config a.ini \r\n&{Config:a.ini Host:github.com}\r\n$ ./tmp --config a.ini --host google.com\r\n&{Config:a.ini Host:google.com}\r\n$ ./tmp --host google.com --config a.ini \r\n&{Config:a.ini Host:google.com}\r\n```"}}