Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RemoveFlag() function #358

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 27 additions & 5 deletions flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,32 @@ unaffected.
Define flags using flag.String(), Bool(), Int(), etc.

This declares an integer flag, -flagname, stored in the pointer ip, with type *int.

var ip = flag.Int("flagname", 1234, "help message for flagname")

If you like, you can bind the flag to a variable using the Var() functions.

var flagvar int
func init() {
flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
}

Or you can create custom flags that satisfy the Value interface (with
pointer receivers) and couple them to flag parsing by

flag.Var(&flagVal, "name", "help message for flagname")

For such flags, the default value is just the initial value of the variable.

After all flags are defined, call

flag.Parse()

to parse the command line into the defined flags.

Flags may then be used directly. If you're using the flags themselves,
they are all pointers; if you bind to variables, they're values.

fmt.Println("ip has value ", *ip)
fmt.Println("flagvar has value ", flagvar)

Expand All @@ -54,22 +63,26 @@ The arguments are indexed from 0 through flag.NArg()-1.
The pflag package also defines some new functions that are not in flag,
that give one-letter shorthands for flags. You can use these by appending
'P' to the name of any function that defines a flag.

var ip = flag.IntP("flagname", "f", 1234, "help message")
var flagvar bool
func init() {
flag.BoolVarP(&flagvar, "boolname", "b", true, "help message")
}
flag.VarP(&flagval, "varname", "v", "help message")

Shorthand letters can be used with single dashes on the command line.
Boolean shorthand flags can be combined with other shorthand flags.

Command line flag syntax:

--flag // boolean flags only
--flag=x

Unlike the flag package, a single dash before an option means something
different than a double dash. Single dashes signify a series of shorthand
letters for flags. All but the last shorthand letter must be boolean flags.

// boolean flags
-f
-abc
Expand Down Expand Up @@ -150,10 +163,10 @@ type FlagSet struct {

name string
parsed bool
actual map[NormalizedName]*Flag
actual map[NormalizedName]*Flag // the flags after parsing
orderedActual []*Flag
sortedActual []*Flag
formal map[NormalizedName]*Flag
formal map[NormalizedName]*Flag // the flags before parsing
orderedFormal []*Flag
sortedFormal []*Flag
shorthands map[byte]*Flag
Expand Down Expand Up @@ -844,6 +857,15 @@ func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
f.VarPF(value, name, shorthand, usage)
}

// RemoveFlag will remove the flag from the FlagSet
func (f *FlagSet) RemoveFlag(name string) {
normalizedFlagName := f.normalizeFlagName(name)
_, exists := f.formal[normalizedFlagName]
if exists {
delete(f.formal, normalizedFlagName)
}
}

// AddFlag will add the flag to the FlagSet
func (f *FlagSet) AddFlag(flag *Flag) {
normalizedFlagName := f.normalizeFlagName(flag.Name)
Expand Down Expand Up @@ -934,9 +956,9 @@ func (f *FlagSet) usage() {
}
}

//--unknown (args will be empty)
//--unknown --next-flag ... (args will be --next-flag ...)
//--unknown arg ... (args will be arg ...)
// --unknown (args will be empty)
// --unknown --next-flag ... (args will be --next-flag ...)
// --unknown arg ... (args will be arg ...)
func stripUnknownFlagValue(args []string) []string {
if len(args) == 0 {
//--unknown
Expand Down
37 changes: 33 additions & 4 deletions flag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,37 @@ func TestAddFlagSet(t *testing.T) {
}
}

func TestAddFlag(t *testing.T) {
flagSet := NewFlagSet("adding-flags", ContinueOnError)
flag := &Flag{
Name: "a-flag",
Shorthand: "a",
Usage: "the usage",
}
flagSet.AddFlag(flag)

if len(flagSet.formal) != 1 {
t.Errorf("Unexpected result adding a Flag to a FlagSet %v", flagSet)
}
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backfilling this test for AddFlag().


func TestRemoveFlag(t *testing.T) {
flagSet := NewFlagSet("removing-flags", ContinueOnError)
flagSet.String("string1", "a", "enter a string1")
flagSet.String("string2", "b", "enter a string2")

flagSet.RemoveFlag("string1")

if len(flagSet.formal) != 1 {
t.Errorf("Flagset %v should only have 1 formal flag now, but has %d.", flagSet, len(flagSet.formal))
}
flagSet.VisitAll(func(f *Flag) {
if f.Name == "string1" {
t.Errorf("Flag string1 was not removed from %v formal flags.", flagSet)
}
})
}

func TestAnnotation(t *testing.T) {
f := NewFlagSet("shorthand", ContinueOnError)

Expand Down Expand Up @@ -1134,7 +1165,6 @@ func TestMultipleNormalizeFlagNameInvocations(t *testing.T) {
}
}

//
func TestHiddenFlagInUsage(t *testing.T) {
f := NewFlagSet("bob", ContinueOnError)
f.Bool("secretFlag", true, "shhh")
Expand All @@ -1149,7 +1179,6 @@ func TestHiddenFlagInUsage(t *testing.T) {
}
}

//
func TestHiddenFlagUsage(t *testing.T) {
f := NewFlagSet("bob", ContinueOnError)
f.Bool("secretFlag", true, "shhh")
Expand Down Expand Up @@ -1238,8 +1267,8 @@ func TestPrintDefaults(t *testing.T) {
fs.PrintDefaults()
got := buf.String()
if got != defaultOutput {
fmt.Println("\n" + got)
fmt.Println("\n" + defaultOutput)
fmt.Print("\n" + got)
fmt.Print("\n" + defaultOutput)
t.Errorf("got %q want %q\n", got, defaultOutput)
}
}
Expand Down