Merge lp:~chipaca/ubuntu-push/conflag-maybe into lp:ubuntu-push

Proposed by John Lenton
Status: Work in progress
Proposed branch: lp:~chipaca/ubuntu-push/conflag-maybe
Merge into: lp:ubuntu-push
Diff against target: 110 lines (+40/-3)
2 files modified
config/config.go (+35/-3)
config/config_test.go (+5/-0)
To merge this branch: bzr merge lp:~chipaca/ubuntu-push/conflag-maybe
Reviewer Review Type Date Requested Status
Samuele Pedroni Needs Fixing
Review via email: mp+203643@code.launchpad.net

Description of the change

Toying with the idea of doing this.

With it, let's say you have a little program `conflag.go` that looked like

    package main

    import (
            "flag"
            "launchpad.net/ubuntu-push/config"
            "os"
            "fmt"
            "log"
    )

    type Config struct {
            Stuff string `help:"Blah blah"`
            SomeTimeout config.ConfigTimeDuration `json:"some_timeout" help:"How long to wait."`
    }

    func main() {
            cfgFName := "config.json"
            cfgF, err := os.Open(cfgFName)
            if err != nil {
                    log.Fatal(err)
            }
            cfg := &Config{}
            err = config.ReadConfig(cfgF, cfg)
            if err != nil {
                    log.Fatal(err)
            }
            flag.Parse()
            fmt.Println(cfg)
    }

and a `config.json` that looked like

    { "stuff": "Yackity yack", "some_timeout": "2s" }

then

    $ ./conflag -help
    Usage of ./conflag:
      -some_timeout=2s: How long to wait.
      -stuff="Yackity yack": Blah blah

    $ ./conflag
    &{Yackity yack 2s}
    $ ./conflag -some_timeout=42m
    &{Yackity yack 42m0s}

To post a comment you must log in.
Revision history for this message
Samuele Pedroni (pedronis) wrote :

I was thinking of trying something similar at some point

in this form is mostly missing tests,

and I wonder if allowing for supplying things with the command line means it's ok if they are left out from the config? or it the idea that the config should have defaults?

doing the former needs two passes over the values though,

should the functionality be opt-in?

btw flag supports TimeDuration flags, wondering if it means there's a way not to have to turn ConfigTimeDuration in a Value

review: Needs Fixing

Unmerged revisions

29. By John Lenton

hmm... maybe.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'config/config.go'
--- config/config.go 2014-01-21 21:35:21 +0000
+++ config/config.go 2014-01-29 00:24:21 +0000
@@ -20,6 +20,7 @@
20import (20import (
21 "encoding/json"21 "encoding/json"
22 "errors"22 "errors"
23 "flag"
23 "fmt"24 "fmt"
24 "io"25 "io"
25 "io/ioutil"26 "io/ioutil"
@@ -90,6 +91,18 @@
90 if err != nil {91 if err != nil {
91 return fmt.Errorf("%s: %v", configName, err)92 return fmt.Errorf("%s: %v", configName, err)
92 }93 }
94 help := fld.Tag.Get("help")
95 switch dest.(type) {
96 default:
97 val, ok := dest.(flag.Value)
98 if ok {
99 flag.Var(val, configName, help)
100 }
101 case *string:
102 flag.StringVar(dest.(*string), configName, *(dest.(*string)), help)
103 case *int:
104 flag.IntVar(dest.(*int), configName, *(dest.(*int)), help)
105 }
93 }106 }
94 return nil107 return nil
95}108}
@@ -121,12 +134,15 @@
121134
122func (ctd *ConfigTimeDuration) UnmarshalJSON(b []byte) error {135func (ctd *ConfigTimeDuration) UnmarshalJSON(b []byte) error {
123 var enc string136 var enc string
124 var v time.Duration
125 err := json.Unmarshal(b, &enc)137 err := json.Unmarshal(b, &enc)
126 if err != nil {138 if err != nil {
127 return err139 return err
128 }140 }
129 v, err = time.ParseDuration(enc)141 return ctd.Set(enc)
142}
143
144func (ctd *ConfigTimeDuration) Set(enc string) error {
145 v, err := time.ParseDuration(enc)
130 if err != nil {146 if err != nil {
131 return err147 return err
132 }148 }
@@ -148,7 +164,11 @@
148 if err != nil {164 if err != nil {
149 return err165 return err
150 }166 }
151 _, _, err = net.SplitHostPort(enc)167 return chp.Set(enc)
168}
169
170func (chp *ConfigHostPort) Set(enc string) error {
171 _, _, err := net.SplitHostPort(enc)
152 if err != nil {172 if err != nil {
153 return err173 return err
154 }174 }
@@ -156,6 +176,10 @@
156 return nil176 return nil
157}177}
158178
179func (chp *ConfigHostPort) String() string {
180 return string(*chp)
181}
182
159// HostPort returns the host:port string held in chp.183// HostPort returns the host:port string held in chp.
160func (chp ConfigHostPort) HostPort() string {184func (chp ConfigHostPort) HostPort() string {
161 return string(chp)185 return string(chp)
@@ -177,6 +201,14 @@
177 return nil201 return nil
178}202}
179203
204func (cqs *ConfigQueueSize) Set(value string) error {
205 return cqs.UnmarshalJSON([]byte(value))
206}
207
208func (cqs *ConfigQueueSize) String() string {
209 return string(uint(*cqs))
210}
211
180// QueueSize returns the queue size held in cqs.212// QueueSize returns the queue size held in cqs.
181func (cqs ConfigQueueSize) QueueSize() uint {213func (cqs ConfigQueueSize) QueueSize() uint {
182 return uint(cqs)214 return uint(cqs)
183215
=== modified file 'config/config_test.go'
--- config/config_test.go 2014-01-21 21:35:21 +0000
+++ config/config_test.go 2014-01-29 00:24:21 +0000
@@ -18,6 +18,7 @@
1818
19import (19import (
20 "bytes"20 "bytes"
21 "flag"
21 "io/ioutil"22 "io/ioutil"
22 . "launchpad.net/gocheck"23 . "launchpad.net/gocheck"
23 "os"24 "os"
@@ -39,6 +40,10 @@
39 C []string `json:"c_list"`40 C []string `json:"c_list"`
40}41}
4142
43func (s *configSuite) SetUpTest(c *C) {
44 flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
45}
46
42func (s *configSuite) TestReadConfig(c *C) {47func (s *configSuite) TestReadConfig(c *C) {
43 buf := bytes.NewBufferString(`{"a": 1, "b": "foo", "c_list": ["c", "d", "e"]}`)48 buf := bytes.NewBufferString(`{"a": 1, "b": "foo", "c_list": ["c", "d", "e"]}`)
44 var cfg testConfig149 var cfg testConfig1

Subscribers

People subscribed via source and target branches