Add ability to use custom Flag types
Users can now use custom flags types (conforming to the Flag interface) in their applications. They can also use custom flags for the three global flags (Help, Version, bash completion).
This commit is contained in:
parent
d70f47eeca
commit
1794792adf
61
app_test.go
61
app_test.go
@ -1520,6 +1520,63 @@ func TestApp_OnUsageError_WithWrongFlagValue_ForSubcommand(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// A custom flag that conforms to the relevant interfaces, but has none of the
|
||||
// fields that the other flag types do.
|
||||
type customBoolFlag struct {
|
||||
Nombre string
|
||||
}
|
||||
|
||||
// Don't use the normal FlagStringer
|
||||
func (c *customBoolFlag) String() string {
|
||||
return "***" + c.Nombre + "***"
|
||||
}
|
||||
|
||||
func (c *customBoolFlag) GetName() string {
|
||||
return c.Nombre
|
||||
}
|
||||
|
||||
func (c *customBoolFlag) Apply(set *flag.FlagSet) {
|
||||
set.String(c.Nombre, c.Nombre, "")
|
||||
}
|
||||
|
||||
func TestCustomFlagsUnused(t *testing.T) {
|
||||
app := NewApp()
|
||||
app.Flags = []Flag{&customBoolFlag{"custom"}}
|
||||
|
||||
err := app.Run([]string{"foo"})
|
||||
if err != nil {
|
||||
t.Errorf("Run returned unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCustomFlagsUsed(t *testing.T) {
|
||||
app := NewApp()
|
||||
app.Flags = []Flag{&customBoolFlag{"custom"}}
|
||||
|
||||
err := app.Run([]string{"foo", "--custom=bar"})
|
||||
if err != nil {
|
||||
t.Errorf("Run returned unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCustomHelpVersionFlags(t *testing.T) {
|
||||
app := NewApp()
|
||||
|
||||
// Be sure to reset the global flags
|
||||
defer func(helpFlag Flag, versionFlag Flag) {
|
||||
HelpFlag = helpFlag
|
||||
VersionFlag = versionFlag
|
||||
}(HelpFlag, VersionFlag)
|
||||
|
||||
HelpFlag = &customBoolFlag{"help-custom"}
|
||||
VersionFlag = &customBoolFlag{"version-custom"}
|
||||
|
||||
err := app.Run([]string{"foo", "--help-custom=bar"})
|
||||
if err != nil {
|
||||
t.Errorf("Run returned unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleAction_WithNonFuncAction(t *testing.T) {
|
||||
app := NewApp()
|
||||
app.Action = 42
|
||||
@ -1642,7 +1699,7 @@ func TestShellCompletionForIncompleteFlags(t *testing.T) {
|
||||
|
||||
for _, flag := range ctx.App.Flags {
|
||||
for _, name := range strings.Split(flag.GetName(), ",") {
|
||||
if name == BashCompletionFlag.Name {
|
||||
if name == BashCompletionFlag.GetName() {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -1659,7 +1716,7 @@ func TestShellCompletionForIncompleteFlags(t *testing.T) {
|
||||
app.Action = func(ctx *Context) error {
|
||||
return fmt.Errorf("should not get here")
|
||||
}
|
||||
err := app.Run([]string{"", "--test-completion", "--" + BashCompletionFlag.Name})
|
||||
err := app.Run([]string{"", "--test-completion", "--" + BashCompletionFlag.GetName()})
|
||||
if err != nil {
|
||||
t.Errorf("app should not return an error: %s", err)
|
||||
}
|
||||
|
12
flag.go
12
flag.go
@ -14,13 +14,13 @@ import (
|
||||
const defaultPlaceholder = "value"
|
||||
|
||||
// BashCompletionFlag enables bash-completion for all commands and subcommands
|
||||
var BashCompletionFlag = BoolFlag{
|
||||
var BashCompletionFlag Flag = BoolFlag{
|
||||
Name: "generate-bash-completion",
|
||||
Hidden: true,
|
||||
}
|
||||
|
||||
// VersionFlag prints the version for the application
|
||||
var VersionFlag = BoolFlag{
|
||||
var VersionFlag Flag = BoolFlag{
|
||||
Name: "version, v",
|
||||
Usage: "print the version",
|
||||
}
|
||||
@ -28,7 +28,7 @@ var VersionFlag = BoolFlag{
|
||||
// HelpFlag prints the help for all commands and subcommands
|
||||
// Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand
|
||||
// unless HideHelp is set to true)
|
||||
var HelpFlag = BoolFlag{
|
||||
var HelpFlag Flag = BoolFlag{
|
||||
Name: "help, h",
|
||||
Usage: "show help",
|
||||
}
|
||||
@ -630,7 +630,8 @@ func (f Float64Flag) ApplyWithError(set *flag.FlagSet) error {
|
||||
func visibleFlags(fl []Flag) []Flag {
|
||||
visible := []Flag{}
|
||||
for _, flag := range fl {
|
||||
if !flagValue(flag).FieldByName("Hidden").Bool() {
|
||||
field := flagValue(flag).FieldByName("Hidden")
|
||||
if !field.IsValid() || !field.Bool() {
|
||||
visible = append(visible, flag)
|
||||
}
|
||||
}
|
||||
@ -723,9 +724,8 @@ func stringifyFlag(f Flag) string {
|
||||
|
||||
needsPlaceholder := false
|
||||
defaultValueString := ""
|
||||
val := fv.FieldByName("Value")
|
||||
|
||||
if val.IsValid() {
|
||||
if val := fv.FieldByName("Value"); val.IsValid() {
|
||||
needsPlaceholder = true
|
||||
defaultValueString = fmt.Sprintf(" (default: %v)", val.Interface())
|
||||
|
||||
|
10
help.go
10
help.go
@ -212,8 +212,8 @@ func printHelp(out io.Writer, templ string, data interface{}) {
|
||||
|
||||
func checkVersion(c *Context) bool {
|
||||
found := false
|
||||
if VersionFlag.Name != "" {
|
||||
eachName(VersionFlag.Name, func(name string) {
|
||||
if VersionFlag.GetName() != "" {
|
||||
eachName(VersionFlag.GetName(), func(name string) {
|
||||
if c.GlobalBool(name) || c.Bool(name) {
|
||||
found = true
|
||||
}
|
||||
@ -224,8 +224,8 @@ func checkVersion(c *Context) bool {
|
||||
|
||||
func checkHelp(c *Context) bool {
|
||||
found := false
|
||||
if HelpFlag.Name != "" {
|
||||
eachName(HelpFlag.Name, func(name string) {
|
||||
if HelpFlag.GetName() != "" {
|
||||
eachName(HelpFlag.GetName(), func(name string) {
|
||||
if c.GlobalBool(name) || c.Bool(name) {
|
||||
found = true
|
||||
}
|
||||
@ -260,7 +260,7 @@ func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) {
|
||||
pos := len(arguments) - 1
|
||||
lastArg := arguments[pos]
|
||||
|
||||
if lastArg != "--"+BashCompletionFlag.Name {
|
||||
if lastArg != "--"+BashCompletionFlag.GetName() {
|
||||
return false, arguments
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user