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
1=== modified file 'config/config.go'
2--- config/config.go 2014-01-21 21:35:21 +0000
3+++ config/config.go 2014-01-29 00:24:21 +0000
4@@ -20,6 +20,7 @@
5 import (
6 "encoding/json"
7 "errors"
8+ "flag"
9 "fmt"
10 "io"
11 "io/ioutil"
12@@ -90,6 +91,18 @@
13 if err != nil {
14 return fmt.Errorf("%s: %v", configName, err)
15 }
16+ help := fld.Tag.Get("help")
17+ switch dest.(type) {
18+ default:
19+ val, ok := dest.(flag.Value)
20+ if ok {
21+ flag.Var(val, configName, help)
22+ }
23+ case *string:
24+ flag.StringVar(dest.(*string), configName, *(dest.(*string)), help)
25+ case *int:
26+ flag.IntVar(dest.(*int), configName, *(dest.(*int)), help)
27+ }
28 }
29 return nil
30 }
31@@ -121,12 +134,15 @@
32
33 func (ctd *ConfigTimeDuration) UnmarshalJSON(b []byte) error {
34 var enc string
35- var v time.Duration
36 err := json.Unmarshal(b, &enc)
37 if err != nil {
38 return err
39 }
40- v, err = time.ParseDuration(enc)
41+ return ctd.Set(enc)
42+}
43+
44+func (ctd *ConfigTimeDuration) Set(enc string) error {
45+ v, err := time.ParseDuration(enc)
46 if err != nil {
47 return err
48 }
49@@ -148,7 +164,11 @@
50 if err != nil {
51 return err
52 }
53- _, _, err = net.SplitHostPort(enc)
54+ return chp.Set(enc)
55+}
56+
57+func (chp *ConfigHostPort) Set(enc string) error {
58+ _, _, err := net.SplitHostPort(enc)
59 if err != nil {
60 return err
61 }
62@@ -156,6 +176,10 @@
63 return nil
64 }
65
66+func (chp *ConfigHostPort) String() string {
67+ return string(*chp)
68+}
69+
70 // HostPort returns the host:port string held in chp.
71 func (chp ConfigHostPort) HostPort() string {
72 return string(chp)
73@@ -177,6 +201,14 @@
74 return nil
75 }
76
77+func (cqs *ConfigQueueSize) Set(value string) error {
78+ return cqs.UnmarshalJSON([]byte(value))
79+}
80+
81+func (cqs *ConfigQueueSize) String() string {
82+ return string(uint(*cqs))
83+}
84+
85 // QueueSize returns the queue size held in cqs.
86 func (cqs ConfigQueueSize) QueueSize() uint {
87 return uint(cqs)
88
89=== modified file 'config/config_test.go'
90--- config/config_test.go 2014-01-21 21:35:21 +0000
91+++ config/config_test.go 2014-01-29 00:24:21 +0000
92@@ -18,6 +18,7 @@
93
94 import (
95 "bytes"
96+ "flag"
97 "io/ioutil"
98 . "launchpad.net/gocheck"
99 "os"
100@@ -39,6 +40,10 @@
101 C []string `json:"c_list"`
102 }
103
104+func (s *configSuite) SetUpTest(c *C) {
105+ flag.CommandLine = flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
106+}
107+
108 func (s *configSuite) TestReadConfig(c *C) {
109 buf := bytes.NewBufferString(`{"a": 1, "b": "foo", "c_list": ["c", "d", "e"]}`)
110 var cfg testConfig1

Subscribers

People subscribed via source and target branches