Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,22 @@ func (e *InvalidValueError) GetValue() string {
return e.value
}

// LongFlagSingleDashError is returned when a registered long flag name is
// passed with a single leading dash (e.g. -name instead of --name).
type LongFlagSingleDashError struct {
name string
}

// Error implements error.
func (e *LongFlagSingleDashError) Error() string {
return fmt.Sprintf("flag %q must be specified as --%s (not -%s)", e.name, e.name, e.name)
}

// GetName returns the long flag name that was mistyped.
func (e *LongFlagSingleDashError) GetName() string {
return e.name
}

// InvalidSyntaxError is the error returned when a bad flag name is passed on
// the command line.
type InvalidSyntaxError struct {
Expand Down
12 changes: 12 additions & 0 deletions flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,18 @@ func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []stri
a = args
shorthands := s[1:]

if len(shorthands) > 1 {
flagName := shorthands
if eq := strings.IndexByte(flagName, '='); eq >= 0 {
flagName = flagName[:eq]
}
if !isGotestShorthandFlag(flagName) {
if _, exists := f.formal[f.normalizeFlagName(flagName)]; exists {
return a, f.fail(&LongFlagSingleDashError{name: flagName})
}
}
}

// "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
for len(shorthands) > 0 {
shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
Expand Down
36 changes: 36 additions & 0 deletions flag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package pflag

import (
"bytes"
"errors"
"fmt"
"io"
"io/ioutil"
Expand Down Expand Up @@ -1461,3 +1462,38 @@ func TestVisitFlagOrder(t *testing.T) {
i++
})
}

func TestParseRejectsSingleDashLongFlag(t *testing.T) {
f := NewFlagSet("test", ContinueOnError)
var name string
f.StringVarP(&name, "name", "n", "", "name of configuration")

err := f.Parse([]string{"-name", "wrong"})
if err == nil {
t.Fatal("expected error for -name mistyped long flag")
}
var longDash *LongFlagSingleDashError
if !errors.As(err, &longDash) {
t.Fatalf("expected LongFlagSingleDashError, got %T: %v", err, err)
}
if name != "" {
t.Fatalf("expected name to stay empty, got %q", name)
}

err = f.Parse([]string{"-name=wrong"})
if err == nil {
t.Fatal("expected error for -name= mistyped long flag")
}
if !errors.As(err, &longDash) {
t.Fatalf("expected LongFlagSingleDashError, got %T: %v", err, err)
}

f = NewFlagSet("test", ContinueOnError)
f.StringVarP(&name, "name", "n", "", "name of configuration")
if err := f.Parse([]string{"-n", "value"}); err != nil {
t.Fatalf("expected -n value to parse: %v", err)
}
if name != "value" {
t.Fatalf("expected name=value, got %q", name)
}
}