Skip to content

Commit

Permalink
Add help strings
Browse files Browse the repository at this point in the history
  • Loading branch information
sgreben committed May 20, 2018
1 parent 1a6b946 commit 758c5af
Show file tree
Hide file tree
Showing 19 changed files with 1,081 additions and 4 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ invalid value "kiwi" for flag -fruit: "kiwi" must be one of [apple banana]
- The original argument string is stored in `.Text` for singular types and in `.Texts` for plural types
- -Set types (`EnumSet`, `StringSet`) de-duplicate provided values.
- -CSV types (`IntsCSV`, `EnumsCSV`) accept comma-separated values and accumulate values across flag instances if their `.Accumulate` field is set to `true`.
- Most types implement `interface{ Help() string }`, which produces a string suitable for inclusion in a help message.

## Types

Expand Down
17 changes: 16 additions & 1 deletion alternative.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package flagvar

import "flag"
import (
"flag"
"fmt"
)

// Alternative tries to parse the argument using `Either`, and if that fails, using `Or`.
// `EitherOk` is true if the first attempt succeed.
Expand All @@ -10,6 +13,18 @@ type Alternative struct {
EitherOk bool
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *Alternative) Help() string {
if fv.Either != nil && fv.Or != nil {
if eitherHelp, ok := fv.Either.(interface{ Help() string }); ok {
if orHelp, ok := fv.Or.(interface{ Help() string }); ok {
return fmt.Sprintf("either %s, or %s", eitherHelp.Help(), orHelp.Help())
}
}
}
return ""
}

// Set is flag.Value.Set
func (fv *Alternative) Set(v string) error {
err := fv.Either.Set(v)
Expand Down
27 changes: 27 additions & 0 deletions assignment.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ type Assignment struct {
Text string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *Assignment) Help() string {
separator := "="
if fv.Separator != "" {
separator = fv.Separator
}
return fmt.Sprintf("a key/value pair KEY%sVALUE", separator)
}

// Set is flag.Value.Set
func (fv *Assignment) Set(v string) error {
separator := "="
Expand Down Expand Up @@ -54,6 +63,15 @@ type Assignments struct {
Texts []string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *Assignments) Help() string {
separator := "="
if fv.Separator != "" {
separator = fv.Separator
}
return fmt.Sprintf("a key/value pair KEY%sVALUE", separator)
}

// Set is flag.Value.Set
func (fv *Assignments) Set(v string) error {
separator := "="
Expand Down Expand Up @@ -88,6 +106,15 @@ type AssignmentsMap struct {
Texts []string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *AssignmentsMap) Help() string {
separator := "="
if fv.Separator != "" {
separator = fv.Separator
}
return fmt.Sprintf("a key/value pair KEY%sVALUE", separator)
}

// Set is flag.Value.Set
func (fv *AssignmentsMap) Set(v string) error {
separator := "="
Expand Down
26 changes: 23 additions & 3 deletions cidr.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package flagvar

import (
"fmt"
"strings"

"net"
Expand All @@ -15,6 +16,11 @@ type CIDR struct {
Text string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *CIDR) Help() string {
return "a CIDR notation IP address and prefix length"
}

// Set is flag.Value.Set
func (fv *CIDR) Set(v string) error {
ip, ipNet, err := net.ParseCIDR(v)
Expand Down Expand Up @@ -42,6 +48,11 @@ type CIDRs struct {
Texts []string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *CIDRs) Help() string {
return "a CIDR notation IP address and prefix length"
}

// Set is flag.Value.Set
func (fv *CIDRs) Set(v string) error {
ip, ipNet, err := net.ParseCIDR(v)
Expand Down Expand Up @@ -74,11 +85,20 @@ type CIDRsCSV struct {
Texts []string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *CIDRsCSV) Help() string {
separator := ","
if fv.Separator != "" {
separator = fv.Separator
}
return fmt.Sprintf("%q-separated list of CIDR notation IP addresses/prefix lengths", separator)
}

// Set is flag.Value.Set
func (fv *CIDRsCSV) Set(v string) error {
separator := fv.Separator
if separator == "" {
separator = ","
separator := ","
if fv.Separator != "" {
separator = fv.Separator
}
if !fv.Accumulate {
fv.Values = fv.Values[:0]
Expand Down
58 changes: 58 additions & 0 deletions enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,20 @@ type Enum struct {
CaseSensitive bool

Value string
Text string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *Enum) Help() string {
if fv.CaseSensitive {
return fmt.Sprintf("one of %v (case-sensitive)", fv.Choices)
}
return fmt.Sprintf("one of %v", fv.Choices)
}

// Set is flag.Value.Set
func (fv *Enum) Set(v string) error {
fv.Text = v
equal := strings.EqualFold
if fv.CaseSensitive {
equal = func(a, b string) bool { return a == b }
Expand All @@ -43,6 +53,15 @@ type Enums struct {
CaseSensitive bool

Values []string
Texts []string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *Enums) Help() string {
if fv.CaseSensitive {
return fmt.Sprintf("one of %v (case-sensitive)", fv.Choices)
}
return fmt.Sprintf("one of %v", fv.Choices)
}

// Set is flag.Value.Set
Expand All @@ -54,6 +73,7 @@ func (fv *Enums) Set(v string) error {
for _, c := range fv.Choices {
if equal(c, v) {
fv.Values = append(fv.Values, c)
fv.Texts = append(fv.Texts, v)
return nil
}
}
Expand All @@ -76,6 +96,19 @@ type EnumsCSV struct {
CaseSensitive bool

Values []string
Texts []string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *EnumsCSV) Help() string {
separator := ","
if fv.Separator != "" {
separator = fv.Separator
}
if fv.CaseSensitive {
return fmt.Sprintf("%q-separated list of values from %v (case-sensitive)", separator, fv.Choices)
}
return fmt.Sprintf("%q-separated list of values from %v", separator, fv.Choices)
}

// Set is flag.Value.Set
Expand Down Expand Up @@ -107,6 +140,7 @@ func (fv *EnumsCSV) Set(v string) error {
return fmt.Errorf(`"%s" must be one of [%s]`, v, strings.Join(fv.Choices, " "))
}
fv.Values = append(fv.Values, value)
fv.Texts = append(fv.Texts, part)
}
return nil
}
Expand All @@ -124,6 +158,15 @@ type EnumSet struct {
CaseSensitive bool

Value map[string]bool
Texts []string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *EnumSet) Help() string {
if fv.CaseSensitive {
return fmt.Sprintf("one of %v (case-sensitive)", fv.Choices)
}
return fmt.Sprintf("one of %v", fv.Choices)
}

// Values returns a string slice of specified values.
Expand Down Expand Up @@ -156,6 +199,7 @@ func (fv *EnumSet) Set(v string) error {
fv.Value = make(map[string]bool)
}
fv.Value[v] = true
fv.Texts = append(fv.Texts, v)
return nil
}

Expand All @@ -176,6 +220,19 @@ type EnumSetCSV struct {
CaseSensitive bool

Value map[string]bool
Texts []string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *EnumSetCSV) Help() string {
separator := ","
if fv.Separator != "" {
separator = fv.Separator
}
if fv.CaseSensitive {
return fmt.Sprintf("%q-separated list of values from %v (case-sensitive)", separator, fv.Choices)
}
return fmt.Sprintf("%q-separated list of values from %v", separator, fv.Choices)
}

// Values returns a string slice of specified values.
Expand Down Expand Up @@ -216,6 +273,7 @@ func (fv *EnumSetCSV) Set(v string) error {
return fmt.Errorf(`"%s" must be one of [%s]`, v, strings.Join(fv.Choices, " "))
}
fv.Value[value] = true
fv.Texts = append(fv.Texts, part)
}
return nil
}
Expand Down
23 changes: 23 additions & 0 deletions floats.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package flagvar

import (
"fmt"
"strconv"
"strings"
)
Expand All @@ -14,6 +15,15 @@ type Floats struct {
Texts []string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *Floats) Help() string {
var bitSize string
if fv.BitSize != 0 {
bitSize = fmt.Sprintf("%d-bit ", fv.BitSize)
}
return fmt.Sprintf("a %sfloat", bitSize)
}

// Set is flag.Value.Set
func (fv *Floats) Set(v string) error {
bitSize := fv.BitSize
Expand Down Expand Up @@ -45,6 +55,19 @@ type FloatsCSV struct {
Texts []string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *FloatsCSV) Help() string {
var bitSize string
if fv.BitSize != 0 {
bitSize = fmt.Sprintf("%d-bit ", fv.BitSize)
}
separator := ","
if fv.Separator != "" {
separator = fv.Separator
}
return fmt.Sprintf("%q-separated list of %sfloats", separator, bitSize)
}

// Set is flag.Value.Set
func (fv *FloatsCSV) Set(v string) error {
bitSize := fv.BitSize
Expand Down
31 changes: 31 additions & 0 deletions glob.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package flagvar

import (
"fmt"
"path/filepath"
"strings"

Expand All @@ -18,6 +19,21 @@ type Glob struct {
Text string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *Glob) Help() string {
separators := []rune{filepath.Separator}
if fv.Separators != nil {
separators = *fv.Separators
}
if len(separators) == 0 {
return "a glob expression"
}
if len(separators) == 1 {
return fmt.Sprintf("a glob expression with separator %q", separators[0])
}
return fmt.Sprintf("a glob expression with separators %q", separators)
}

// Set is flag.Value.Set
func (fv *Glob) Set(v string) error {
separators := fv.Separators
Expand Down Expand Up @@ -48,6 +64,21 @@ type Globs struct {
Texts []string
}

// Help returns a string suitable for inclusion in a flag help message.
func (fv *Globs) Help() string {
separators := []rune{filepath.Separator}
if fv.Separators != nil {
separators = *fv.Separators
}
if len(separators) == 0 {
return "a glob expression"
}
if len(separators) == 1 {
return fmt.Sprintf("a glob expression with separator %q", separators[0])
}
return fmt.Sprintf("a glob expression with separators %q", separators)
}

// Set is flag.Value.Set
func (fv *Globs) Set(v string) error {
separators := fv.Separators
Expand Down
Loading

0 comments on commit 758c5af

Please sign in to comment.