Skip to content

Commit

Permalink
improve compatibility with go/flag
Browse files Browse the repository at this point in the history
go/flag in go 1.13 has a public Output() function and a Name() function
- change out() to Output() (adjusting the rest of the file)
- add Name() and tests for it

From: @mckern (spf13#220) re: out/Output:
This brings behavior inline with go's flag library, and allows for
printing output directly to whatever the current FlagSet is using for
output. This change will make it easier to correctly emit output to
stdout or stderr (e.g. a user has requested a help screen, which
should emit to stdout since it's the desired outcome).
  • Loading branch information
Chloe Kudryavtsev committed Feb 19, 2020
1 parent 2e9d26c commit d981dfb
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 11 deletions.
29 changes: 18 additions & 11 deletions flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ type FlagSet struct {
args []string // arguments after flags
argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no --
errorHandling ErrorHandling
output io.Writer // nil means stderr; use out() accessor
output io.Writer // nil means stderr; use Output() accessor
interspersed bool // allow interspersed option/non-option args
normalizeNameFunc func(f *FlagSet, name string) NormalizedName

Expand Down Expand Up @@ -255,13 +255,20 @@ func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
return n(f, name)
}

func (f *FlagSet) out() io.Writer {
// Output returns the destination for usage and error messages. os.Stderr is returned if
// output was not set or was set to nil.
func (f *FlagSet) Output() io.Writer {
if f.output == nil {
return os.Stderr
}
return f.output
}

// Name returns the name of the flag set.
func (f *FlagSet) Name() string {
return f.name
}

// SetOutput sets the destination for usage and error messages.
// If output is nil, os.Stderr is used.
func (f *FlagSet) SetOutput(output io.Writer) {
Expand Down Expand Up @@ -358,7 +365,7 @@ func (f *FlagSet) ShorthandLookup(name string) *Flag {
}
if len(name) > 1 {
msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
fmt.Fprintf(f.out(), msg)
fmt.Fprintf(f.Output(), msg)
panic(msg)
}
c := name[0]
Expand Down Expand Up @@ -482,7 +489,7 @@ func (f *FlagSet) Set(name, value string) error {
}

if flag.Deprecated != "" {
fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
fmt.Fprintf(f.Output(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
}
return nil
}
Expand Down Expand Up @@ -523,7 +530,7 @@ func Set(name, value string) error {
// otherwise, the default values of all defined flags in the set.
func (f *FlagSet) PrintDefaults() {
usages := f.FlagUsages()
fmt.Fprint(f.out(), usages)
fmt.Fprint(f.Output(), usages)
}

// defaultIsZeroValue returns true if the default value for this flag represents
Expand Down Expand Up @@ -758,7 +765,7 @@ func PrintDefaults() {

// defaultUsage is the default function to print a usage message.
func defaultUsage(f *FlagSet) {
fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name)
f.PrintDefaults()
}

Expand Down Expand Up @@ -844,7 +851,7 @@ func (f *FlagSet) AddFlag(flag *Flag) {
_, alreadyThere := f.formal[normalizedFlagName]
if alreadyThere {
msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
fmt.Fprintln(f.out(), msg)
fmt.Fprintln(f.Output(), msg)
panic(msg) // Happens only if flags are declared with identical names
}
if f.formal == nil {
Expand All @@ -860,7 +867,7 @@ func (f *FlagSet) AddFlag(flag *Flag) {
}
if len(flag.Shorthand) > 1 {
msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
fmt.Fprintf(f.out(), msg)
fmt.Fprintf(f.Output(), msg)
panic(msg)
}
if f.shorthands == nil {
Expand All @@ -870,7 +877,7 @@ func (f *FlagSet) AddFlag(flag *Flag) {
used, alreadyThere := f.shorthands[c]
if alreadyThere {
msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
fmt.Fprintf(f.out(), msg)
fmt.Fprintf(f.Output(), msg)
panic(msg)
}
f.shorthands[c] = flag
Expand Down Expand Up @@ -909,7 +916,7 @@ func VarP(value Value, name, shorthand, usage string) {
func (f *FlagSet) failf(format string, a ...interface{}) error {
err := fmt.Errorf(format, a...)
if f.errorHandling != ContinueOnError {
fmt.Fprintln(f.out(), err)
fmt.Fprintln(f.Output(), err)
f.usage()
}
return err
Expand Down Expand Up @@ -1060,7 +1067,7 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse
}

if flag.ShorthandDeprecated != "" {
fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
fmt.Fprintf(f.Output(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
}

err = fn(flag, value)
Expand Down
7 changes: 7 additions & 0 deletions flag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@ func TestAddFlagSet(t *testing.T) {
oldSet := NewFlagSet("old", ContinueOnError)
newSet := NewFlagSet("new", ContinueOnError)

if oldSet.Name() != "old" {
t.Errorf("When reading a flagset's name, expected %s, but found %s", "old", oldSet.Name())
}
if newSet.Name() != "new" {
t.Errorf("When reading a flagset's name, expected %s, but found %s", "new", newSet.Name())
}

oldSet.String("flag1", "flag1", "flag1")
oldSet.String("flag2", "flag2", "flag2")

Expand Down

0 comments on commit d981dfb

Please sign in to comment.