Bump spf13/pflag

This commit is contained in:
Fabiano Franz 2015-10-01 14:01:48 -03:00
parent a463b34507
commit 64d1e14833
9 changed files with 204 additions and 17 deletions

3
Godeps/Godeps.json generated
View File

@ -535,8 +535,7 @@
},
{
"ImportPath": "github.com/spf13/pflag",
"Comment": "v0.0.1-99-g8e7dc10",
"Rev": "8e7dc108ab3a1ab6ce6d922bbaff5657b88e8e49"
"Rev": "b084184666e02084b8ccb9b704bf0d79c466eb1d"
},
{
"ImportPath": "github.com/stretchr/objx",

View File

@ -6,3 +6,12 @@ go:
- 1.3
- 1.4
- tip
install:
- go get github.com/golang/lint/golint
- export PATH=$GOPATH/bin:$PATH
- go install ./...
script:
- verify/all.sh
- go test ./...

View File

@ -216,24 +216,33 @@ func aliasNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
myFlagSet.SetNormalizeFunc(aliasNormalizeFunc)
```
## Deprecating a flag or its shorthand
It is possible to deprecate a flag, or just its shorthand. Deprecating a flag/shorthand hides it from help text and prints a usage message when the deprecated flag/shorthand is used.
## Deprecating a flag or its shorthand
It is possible to deprecate a flag, or just its shorthand. Deprecating a flag/shorthand hides it from help text and prints a usage message when the deprecated flag/shorthand is used.
**Example #1**: You want to deprecate a flag named "badflag" as well as inform the users what flag they should use instead.
**Example #1**: You want to deprecate a flag named "badflag" as well as inform the users what flag they should use instead.
```go
// deprecate a flag by specifying its name and a usage message
// deprecate a flag by specifying its name and a usage message
flags.MarkDeprecated("badflag", "please use --good-flag instead")
```
This hides "badflag" from help text, and prints `Flag --badflag has been deprecated, please use --good-flag instead` when "badflag" is used.
This hides "badflag" from help text, and prints `Flag --badflag has been deprecated, please use --good-flag instead` when "badflag" is used.
**Example #2**: You want to keep a flag name "noshorthandflag" but deprecate its shortname "n".
**Example #2**: You want to keep a flag name "noshorthandflag" but deprecate its shortname "n".
```go
// deprecate a flag shorthand by specifying its flag name and a usage message
// deprecate a flag shorthand by specifying its flag name and a usage message
flags.MarkShorthandDeprecated("noshorthandflag", "please use --noshorthandflag only")
```
This hides the shortname "n" from help text, and prints `Flag shorthand -n has been deprecated, please use --noshorthandflag only` when the shorthand "n" is used.
This hides the shortname "n" from help text, and prints `Flag shorthand -n has been deprecated, please use --noshorthandflag only` when the shorthand "n" is used.
Note that usage message is essential here, and it should not be empty.
Note that usage message is essential here, and it should not be empty.
## Hidden flags
It is possible to mark a flag as hidden, meaning it will still function as normal, however will not show up in usage/help text.
**Example**: You have a flag named "secretFlag" that you need for internal use only and don't want it showing up in help text, or for its usage text to be available.
```go
// hide a flag by specifying its name
flags.MarkHidden("secretFlag")
```
## More info

View File

@ -140,6 +140,7 @@ type FlagSet struct {
formal map[NormalizedName]*Flag
shorthands map[byte]*Flag
args []string // arguments after flags
argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no --
exitOnError bool // does the program exit if there's an error?
errorHandling ErrorHandling
output io.Writer // nil means stderr; use out() accessor
@ -157,8 +158,9 @@ type Flag struct {
Changed bool // If the user set the value (or if left to default)
NoOptDefVal string //default value (as text); if the flag is on the command line without any options
Deprecated string // If this flag is deprecated, this string is the new or now thing to use
Hidden bool // used by cobra.Command to allow flags to be hidden from help/usage text
ShorthandDeprecated string // If the shorthand of this flag is deprecated, this string is the new or now thing to use
Annotations map[string][]string // used by cobra.Command bash autocomple code
Annotations map[string][]string // used by cobra.Command bash autocomple code
}
// Value is the interface to the dynamic value stored in a flag.
@ -291,6 +293,13 @@ func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval stri
return result, nil
}
// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
// found during arg parsing. This allows your program to know which args were
// before the -- and which came after.
func (f *FlagSet) ArgsLenAtDash() int {
return f.argsLenAtDash
}
// MarkDeprecated indicated that a flag is deprecated in your program. It will
// continue to function but will not show up in help or usage messages. Using
// this flag will also print the given usageMessage.
@ -306,9 +315,9 @@ func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
return nil
}
// Mark the shorthand of a flag deprecated in your program. It will
// continue to function but will not show up in help or usage messages. Using
// this flag will also print the given usageMessage.
// MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your
// program. It will continue to function but will not show up in help or usage
// messages. Using this flag will also print the given usageMessage.
func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
flag := f.Lookup(name)
if flag == nil {
@ -321,6 +330,17 @@ func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) erro
return nil
}
// MarkHidden sets a flag to 'hidden' in your program. It will continue to
// function but will not show up in help or usage messages.
func (f *FlagSet) MarkHidden(name string) error {
flag := f.Lookup(name)
if flag == nil {
return fmt.Errorf("flag %q does not exist", name)
}
flag.Hidden = true
return nil
}
// Lookup returns the Flag structure of the named command-line flag,
// returning nil if none exists.
func Lookup(name string) *Flag {
@ -394,7 +414,7 @@ func (f *FlagSet) FlagUsages() string {
x := new(bytes.Buffer)
f.VisitAll(func(flag *Flag) {
if len(flag.Deprecated) > 0 {
if len(flag.Deprecated) > 0 || flag.Hidden {
return
}
format := ""
@ -728,6 +748,7 @@ func (f *FlagSet) parseArgs(args []string) (err error) {
if s[1] == '-' {
if len(s) == 2 { // "--" terminates the flags
f.argsLenAtDash = len(f.args)
f.args = append(f.args, args...)
break
}
@ -794,12 +815,13 @@ func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
f := &FlagSet{
name: name,
errorHandling: errorHandling,
argsLenAtDash: -1,
interspersed: true,
}
return f
}
// SetIntersperesed sets whether to support interspersed option/non-option arguments.
// SetInterspersed sets whether to support interspersed option/non-option arguments.
func (f *FlagSet) SetInterspersed(interspersed bool) {
f.interspersed = interspersed
}
@ -810,4 +832,5 @@ func (f *FlagSet) SetInterspersed(interspersed bool) {
func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
f.name = name
f.errorHandling = errorHandling
f.argsLenAtDash = -1
}

View File

@ -387,6 +387,9 @@ func TestShorthand(t *testing.T) {
} else if f.Args()[1] != notaflag {
t.Errorf("expected argument %q got %q", notaflag, f.Args()[1])
}
if f.ArgsLenAtDash() != 1 {
t.Errorf("expected argsLenAtDash %d got %d", f.ArgsLenAtDash(), 1)
}
}
func TestParse(t *testing.T) {
@ -424,6 +427,9 @@ func TestChangedHelper(t *testing.T) {
if f.Changed("invalid") {
t.Errorf("--invalid was changed!")
}
if f.ArgsLenAtDash() != -1 {
t.Errorf("Expected argsLenAtDash: %d but got %d", -1, f.ArgsLenAtDash())
}
}
func replaceSeparators(name string, from []string, to string) string {
@ -713,6 +719,9 @@ func TestTermination(t *testing.T) {
if f.Args()[1] != arg2 {
t.Errorf("expected argument %q got %q", arg2, f.Args()[1])
}
if f.ArgsLenAtDash() != 0 {
t.Errorf("expected argsLenAtDash %d got %d", 0, f.ArgsLenAtDash())
}
}
func TestDeprecatedFlagInDocs(t *testing.T) {
@ -831,3 +840,35 @@ func TestMultipleNormalizeFlagNameInvocations(t *testing.T) {
t.Fatal("Expected normalizeFlagNameInvocations to be 1; got ", normalizeFlagNameInvocations)
}
}
//
func TestHiddenFlagInUsage(t *testing.T) {
f := NewFlagSet("bob", ContinueOnError)
f.Bool("secretFlag", true, "shhh")
f.MarkHidden("secretFlag")
out := new(bytes.Buffer)
f.SetOutput(out)
f.PrintDefaults()
if strings.Contains(out.String(), "secretFlag") {
t.Errorf("found hidden flag in usage!")
}
}
//
func TestHiddenFlagUsage(t *testing.T) {
f := NewFlagSet("bob", ContinueOnError)
f.Bool("secretFlag", true, "shhh")
f.MarkHidden("secretFlag")
args := []string{"--secretFlag"}
out, err := parseReturnStderr(t, f, args)
if err != nil {
t.Fatal("expected no error; got ", err)
}
if strings.Contains(out, "shhh") {
t.Errorf("usage message printed when using a hidden flag!")
}
}

View File

@ -60,6 +60,7 @@ func (v *flagValueWrapper) Type() string {
return v.flagType
}
// PFlagFromGoFlag will return a *pflag.Flag given a *flag.Flag
func PFlagFromGoFlag(goflag *goflag.Flag) *Flag {
// Remember the default value as a string; it won't change.
flag := &Flag{
@ -76,6 +77,7 @@ func PFlagFromGoFlag(goflag *goflag.Flag) *Flag {
return flag
}
// AddGoFlag will add the given *flag.Flag to the pflag.FlagSet
func (f *FlagSet) AddGoFlag(goflag *goflag.Flag) {
if f.Lookup(goflag.Name) != nil {
return
@ -84,6 +86,7 @@ func (f *FlagSet) AddGoFlag(goflag *goflag.Flag) {
f.AddFlag(newflag)
}
// AddGoFlagSet will add the given *flag.FlagSet to the pflag.FlagSet
func (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) {
if newSet == nil {
return

View File

@ -0,0 +1,69 @@
#!/bin/bash
set -o errexit
set -o nounset
set -o pipefail
ROOT=$(dirname "${BASH_SOURCE}")/..
# Some useful colors.
if [[ -z "${color_start-}" ]]; then
declare -r color_start="\033["
declare -r color_red="${color_start}0;31m"
declare -r color_yellow="${color_start}0;33m"
declare -r color_green="${color_start}0;32m"
declare -r color_norm="${color_start}0m"
fi
SILENT=true
function is-excluded {
for e in $EXCLUDE; do
if [[ $1 -ef ${BASH_SOURCE} ]]; then
return
fi
if [[ $1 -ef "$ROOT/hack/$e" ]]; then
return
fi
done
return 1
}
while getopts ":v" opt; do
case $opt in
v)
SILENT=false
;;
\?)
echo "Invalid flag: -$OPTARG" >&2
exit 1
;;
esac
done
if $SILENT ; then
echo "Running in the silent mode, run with -v if you want to see script logs."
fi
EXCLUDE="all.sh"
ret=0
for t in `ls $ROOT/verify/*.sh`
do
if is-excluded $t ; then
echo "Skipping $t"
continue
fi
if $SILENT ; then
echo -e "Verifying $t"
if bash "$t" &> /dev/null; then
echo -e "${color_green}SUCCESS${color_norm}"
else
echo -e "${color_red}FAILED${color_norm}"
ret=1
fi
else
bash "$t" || ret=1
fi
done
exit $ret

View File

@ -0,0 +1,19 @@
#!/bin/bash
set -o errexit
set -o nounset
set -o pipefail
ROOT=$(dirname "${BASH_SOURCE}")/..
pushd "${ROOT}" > /dev/null
GOFMT=${GOFMT:-"gofmt"}
bad_files=$(find . -name '*.go' | xargs $GOFMT -s -l)
if [[ -n "${bad_files}" ]]; then
echo "!!! '$GOFMT' needs to be run on the following files: "
echo "${bad_files}"
exit 1
fi
# ex: ts=2 sw=2 et filetype=sh

View File

@ -0,0 +1,15 @@
#!/bin/bash
ROOT=$(dirname "${BASH_SOURCE}")/..
GOLINT=${GOLINT:-"golint"}
pushd "${ROOT}" > /dev/null
bad_files=$($GOLINT -min_confidence=0.9 ./...)
if [[ -n "${bad_files}" ]]; then
echo "!!! '$GOLINT' problems: "
echo "${bad_files}"
exit 1
fi
popd > /dev/null
# ex: ts=2 sw=2 et filetype=sh