Skip to content

Commit

Permalink
set usage message from description tag (#70)
Browse files Browse the repository at this point in the history
set usage message in flags backend from description tag
  • Loading branch information
steamrolla authored and rogpeppe committed Sep 19, 2019
1 parent a955922 commit 63a14d4
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 22 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,13 @@ The `flags` backend allows to load individual configuration keys from the comman

A `short` option is also supported.

To update usage message on the command line, provide a `description` to the given field.

```go
type Config struct {
Host string `config:"host,short=h"`
Port uint32 `config:"port,short=p"`
Timeout time.Duration `config:"timeout"`
Timeout time.Duration `config:"timeout,description=timeout (in seconds) for failure"`
}
```

Expand All @@ -183,7 +185,7 @@ Usage of ./bin:
-p int
(default 5656)
-timeout duration
(default 10s)
timeout (in seconds) for failure (default 10s)
```

## License
Expand Down
31 changes: 18 additions & 13 deletions backend/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package flags
import (
"context"
"flag"
"fmt"
"reflect"
"time"

Expand Down Expand Up @@ -33,9 +34,9 @@ func (b *Backend) LoadStruct(ctx context.Context, cfg *confita.StructConfig) err
switch {
case f.Value.Type().String() == "time.Duration":
var val time.Duration
flag.DurationVar(&val, f.Key, time.Duration(f.Default.Int()), "")
flag.DurationVar(&val, f.Key, time.Duration(f.Default.Int()), f.Description)
if f.Short != "" {
flag.DurationVar(&val, f.Short, time.Duration(f.Default.Int()), "")
flag.DurationVar(&val, f.Short, time.Duration(f.Default.Int()), shortDesc(f.Description))
}
// this function must be executed after the flag.Parse call.
defer func() {
Expand All @@ -46,9 +47,9 @@ func (b *Backend) LoadStruct(ctx context.Context, cfg *confita.StructConfig) err
}()
case k == reflect.Bool:
var val bool
flag.BoolVar(&val, f.Key, f.Default.Bool(), "")
flag.BoolVar(&val, f.Key, f.Default.Bool(), f.Description)
if f.Short != "" {
flag.BoolVar(&val, f.Short, f.Default.Bool(), "")
flag.BoolVar(&val, f.Short, f.Default.Bool(), shortDesc(f.Description))
}
defer func() {
if isFlagSet(f) {
Expand All @@ -57,9 +58,9 @@ func (b *Backend) LoadStruct(ctx context.Context, cfg *confita.StructConfig) err
}()
case k >= reflect.Int && k <= reflect.Int64:
var val int
flag.IntVar(&val, f.Key, int(f.Default.Int()), "")
flag.IntVar(&val, f.Key, int(f.Default.Int()), f.Description)
if f.Short != "" {
flag.IntVar(&val, f.Short, int(f.Default.Int()), "")
flag.IntVar(&val, f.Short, int(f.Default.Int()), shortDesc(f.Description))
}
defer func() {
if isFlagSet(f) {
Expand All @@ -68,9 +69,9 @@ func (b *Backend) LoadStruct(ctx context.Context, cfg *confita.StructConfig) err
}()
case k >= reflect.Uint && k <= reflect.Uint64:
var val uint64
flag.Uint64Var(&val, f.Key, f.Default.Uint(), "")
flag.Uint64Var(&val, f.Key, f.Default.Uint(), f.Description)
if f.Short != "" {
flag.Uint64Var(&val, f.Short, f.Default.Uint(), "")
flag.Uint64Var(&val, f.Short, f.Default.Uint(), shortDesc(f.Description))
}
defer func() {
if isFlagSet(f) {
Expand All @@ -79,9 +80,9 @@ func (b *Backend) LoadStruct(ctx context.Context, cfg *confita.StructConfig) err
}()
case k >= reflect.Float32 && k <= reflect.Float64:
var val float64
flag.Float64Var(&val, f.Key, f.Default.Float(), "")
flag.Float64Var(&val, f.Key, f.Default.Float(), f.Description)
if f.Short != "" {
flag.Float64Var(&val, f.Short, f.Default.Float(), "")
flag.Float64Var(&val, f.Short, f.Default.Float(), shortDesc(f.Description))
}
defer func() {
if isFlagSet(f) {
Expand All @@ -90,17 +91,17 @@ func (b *Backend) LoadStruct(ctx context.Context, cfg *confita.StructConfig) err
}()
case k == reflect.String:
var val string
flag.StringVar(&val, f.Key, f.Default.String(), "")
flag.StringVar(&val, f.Key, f.Default.String(), f.Description)
if f.Short != "" {
flag.StringVar(&val, f.Short, f.Default.String(), "")
flag.StringVar(&val, f.Short, f.Default.String(), shortDesc(f.Description))
}
defer func() {
if isFlagSet(f) {
f.Value.SetString(val)
}
}()
default:
flag.Var(&flagValue{f}, f.Key, "")
flag.Var(&flagValue{f}, f.Key, f.Description)
}
}

Expand Down Expand Up @@ -135,6 +136,10 @@ func (b *Backend) Name() string {
return "flags"
}

func shortDesc(description string) string {
return fmt.Sprintf("%s (short)", description)
}

func isFlagSet(config *confita.FieldConfig) bool {
flagset := make(map[*confita.FieldConfig]bool)
flag.Visit(func(f *flag.Flag) { flagset[config] = true })
Expand Down
20 changes: 13 additions & 7 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ func (l *Loader) parseStruct(ref reflect.Value) *StructConfig {
continue
}

if strings.HasPrefix(opt, "description=") {
f.Description = opt[len("description="):]
continue
}

if strings.HasPrefix(opt, "backend=") {
f.Backend = opt[len("backend="):]
}
Expand Down Expand Up @@ -242,13 +247,14 @@ type StructConfig struct {

// FieldConfig holds informations about a struct field.
type FieldConfig struct {
Name string
Short string
Key string
Value reflect.Value
Default reflect.Value
Required bool
Backend string
Name string
Short string
Key string
Description string
Value reflect.Value
Default reflect.Value
Required bool
Backend string
}

// Set converts data into f.Value.
Expand Down

0 comments on commit 63a14d4

Please sign in to comment.