Merge pull request #371 from codegangsta/harshavardhana-hidden-flags

Merging #201 - @harshavardhana's hidden flags impl (and more!)
This commit is contained in:
Dan Buch 2016-05-01 09:18:41 -04:00
commit 784038bca2
8 changed files with 67 additions and 20 deletions

View File

@ -3,6 +3,12 @@
**ATTN**: This project uses [semantic versioning](http://semver.org/). **ATTN**: This project uses [semantic versioning](http://semver.org/).
## [Unreleased] ## [Unreleased]
### Added
- `Hidden` field on all flag struct types to omit from generated help text
### Changed
- `BashCompletionFlag` (`--enable-bash-completion`) is now omitted from
generated help text via the `Hidden` field
## [1.15.0] - 2016-04-30 ## [1.15.0] - 2016-04-30
### Added ### Added

View File

@ -302,6 +302,7 @@ Here is a more complete sample of a command using YAML support:
Description: "testing", Description: "testing",
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
// Action to run // Action to run
return nil
}, },
Flags: []cli.Flag{ Flags: []cli.Flag{
NewIntFlag(cli.IntFlag{Name: "test"}), NewIntFlag(cli.IntFlag{Name: "test"}),
@ -322,16 +323,18 @@ app.Commands = []cli.Command{
Name: "add", Name: "add",
Aliases: []string{"a"}, Aliases: []string{"a"},
Usage: "add a task to the list", Usage: "add a task to the list",
Action: func(c *cli.Context) { Action: func(c *cli.Context) error {
fmt.Println("added task: ", c.Args().First()) fmt.Println("added task: ", c.Args().First())
return nil
}, },
}, },
{ {
Name: "complete", Name: "complete",
Aliases: []string{"c"}, Aliases: []string{"c"},
Usage: "complete a task on the list", Usage: "complete a task on the list",
Action: func(c *cli.Context) { Action: func(c *cli.Context) error {
fmt.Println("completed task: ", c.Args().First()) fmt.Println("completed task: ", c.Args().First())
return nil
}, },
}, },
{ {
@ -342,15 +345,17 @@ app.Commands = []cli.Command{
{ {
Name: "add", Name: "add",
Usage: "add a new template", Usage: "add a new template",
Action: func(c *cli.Context) { Action: func(c *cli.Context) error {
fmt.Println("new task template: ", c.Args().First()) fmt.Println("new task template: ", c.Args().First())
return nil
}, },
}, },
{ {
Name: "remove", Name: "remove",
Usage: "remove an existing template", Usage: "remove an existing template",
Action: func(c *cli.Context) { Action: func(c *cli.Context) error {
fmt.Println("removed task template: ", c.Args().First()) fmt.Println("removed task template: ", c.Args().First())
return nil
}, },
}, },
}, },
@ -450,8 +455,9 @@ app.Commands = []cli.Command{
Name: "complete", Name: "complete",
Aliases: []string{"c"}, Aliases: []string{"c"},
Usage: "complete a task on the list", Usage: "complete a task on the list",
Action: func(c *cli.Context) { Action: func(c *cli.Context) error {
fmt.Println("completed task: ", c.Args().First()) fmt.Println("completed task: ", c.Args().First())
return nil
}, },
BashComplete: func(c *cli.Context) { BashComplete: func(c *cli.Context) {
// This will complete if no args are passed // This will complete if no args are passed

View File

@ -97,9 +97,10 @@ func TestCommandYamlFileTestGlobalEnvVarWinsNested(t *testing.T) {
Aliases: []string{"tc"}, Aliases: []string{"tc"},
Usage: "this is for testing", Usage: "this is for testing",
Description: "testing", Description: "testing",
Action: func(c *cli.Context) { Action: func(c *cli.Context) error {
val := c.Int("top.test") val := c.Int("top.test")
expect(t, val, 10) expect(t, val, 10)
return nil
}, },
Flags: []cli.Flag{ Flags: []cli.Flag{
NewIntFlag(cli.IntFlag{Name: "top.test", EnvVar: "THE_TEST"}), NewIntFlag(cli.IntFlag{Name: "top.test", EnvVar: "THE_TEST"}),
@ -161,9 +162,10 @@ func TestCommandYamlFileTestSpecifiedFlagWinsNested(t *testing.T) {
Aliases: []string{"tc"}, Aliases: []string{"tc"},
Usage: "this is for testing", Usage: "this is for testing",
Description: "testing", Description: "testing",
Action: func(c *cli.Context) { Action: func(c *cli.Context) error {
val := c.Int("top.test") val := c.Int("top.test")
expect(t, val, 7) expect(t, val, 7)
return nil
}, },
Flags: []cli.Flag{ Flags: []cli.Flag{
NewIntFlag(cli.IntFlag{Name: "top.test"}), NewIntFlag(cli.IntFlag{Name: "top.test"}),
@ -225,9 +227,10 @@ func TestCommandYamlFileTestDefaultValueFileWinsNested(t *testing.T) {
Aliases: []string{"tc"}, Aliases: []string{"tc"},
Usage: "this is for testing", Usage: "this is for testing",
Description: "testing", Description: "testing",
Action: func(c *cli.Context) { Action: func(c *cli.Context) error {
val := c.Int("top.test") val := c.Int("top.test")
expect(t, val, 15) expect(t, val, 15)
return nil
}, },
Flags: []cli.Flag{ Flags: []cli.Flag{
NewIntFlag(cli.IntFlag{Name: "top.test", Value: 7}), NewIntFlag(cli.IntFlag{Name: "top.test", Value: 7}),
@ -294,9 +297,10 @@ func TestCommandYamlFileFlagHasDefaultGlobalEnvYamlSetGlobalEnvWinsNested(t *tes
Aliases: []string{"tc"}, Aliases: []string{"tc"},
Usage: "this is for testing", Usage: "this is for testing",
Description: "testing", Description: "testing",
Action: func(c *cli.Context) { Action: func(c *cli.Context) error {
val := c.Int("top.test") val := c.Int("top.test")
expect(t, val, 11) expect(t, val, 11)
return nil
}, },
Flags: []cli.Flag{ Flags: []cli.Flag{
NewIntFlag(cli.IntFlag{Name: "top.test", Value: 7, EnvVar: "THE_TEST"}), NewIntFlag(cli.IntFlag{Name: "top.test", Value: 7, EnvVar: "THE_TEST"}),

5
app.go
View File

@ -366,6 +366,11 @@ func (a *App) Categories() CommandCategories {
return a.categories return a.categories
} }
// VisibleFlags returns a slice of the Flags with Hidden=false
func (a *App) VisibleFlags() []Flag {
return visibleFlags(a.Flags)
}
func (a *App) hasFlag(flag Flag) bool { func (a *App) hasFlag(flag Flag) bool {
for _, f := range a.Flags { for _, f := range a.Flags {
if flag == f { if flag == f {

2
cli.go
View File

@ -10,7 +10,7 @@
// app := cli.NewApp() // app := cli.NewApp()
// app.Name = "greet" // app.Name = "greet"
// app.Usage = "say a greeting" // app.Usage = "say a greeting"
// app.Action = func(c *cli.Context) { // app.Action = func(c *cli.Context) error {
// println("Greetings") // println("Greetings")
// } // }
// //

View File

@ -269,3 +269,8 @@ func (c Command) startApp(ctx *Context) error {
return app.RunAsSubcommand(ctx) return app.RunAsSubcommand(ctx)
} }
// VisibleFlags returns a slice of the Flags with Hidden=false
func (c Command) VisibleFlags() []Flag {
return visibleFlags(c.Flags)
}

23
flag.go
View File

@ -4,6 +4,7 @@ import (
"flag" "flag"
"fmt" "fmt"
"os" "os"
"reflect"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
@ -12,7 +13,8 @@ import (
// This flag enables bash-completion for all commands and subcommands // This flag enables bash-completion for all commands and subcommands
var BashCompletionFlag = BoolFlag{ var BashCompletionFlag = BoolFlag{
Name: "generate-bash-completion", Name: "generate-bash-completion",
Hidden: true,
} }
// This flag prints the version for the application // This flag prints the version for the application
@ -68,6 +70,7 @@ type GenericFlag struct {
Value Generic Value Generic
Usage string Usage string
EnvVar string EnvVar string
Hidden bool
} }
// String returns the string representation of the generic flag to display the // String returns the string representation of the generic flag to display the
@ -138,6 +141,7 @@ type StringSliceFlag struct {
Value *StringSlice Value *StringSlice
Usage string Usage string
EnvVar string EnvVar string
Hidden bool
} }
// String returns the usage // String returns the usage
@ -208,6 +212,7 @@ type IntSliceFlag struct {
Value *IntSlice Value *IntSlice
Usage string Usage string
EnvVar string EnvVar string
Hidden bool
} }
// String returns the usage // String returns the usage
@ -256,6 +261,7 @@ type BoolFlag struct {
Usage string Usage string
EnvVar string EnvVar string
Destination *bool Destination *bool
Hidden bool
} }
// String returns a readable representation of this value (for usage defaults) // String returns a readable representation of this value (for usage defaults)
@ -300,6 +306,7 @@ type BoolTFlag struct {
Usage string Usage string
EnvVar string EnvVar string
Destination *bool Destination *bool
Hidden bool
} }
// String returns a readable representation of this value (for usage defaults) // String returns a readable representation of this value (for usage defaults)
@ -344,6 +351,7 @@ type StringFlag struct {
Usage string Usage string
EnvVar string EnvVar string
Destination *string Destination *string
Hidden bool
} }
// String returns the usage // String returns the usage
@ -393,6 +401,7 @@ type IntFlag struct {
Usage string Usage string
EnvVar string EnvVar string
Destination *int Destination *int
Hidden bool
} }
// String returns the usage // String returns the usage
@ -437,6 +446,7 @@ type DurationFlag struct {
Usage string Usage string
EnvVar string EnvVar string
Destination *time.Duration Destination *time.Duration
Hidden bool
} }
// String returns a readable representation of this value (for usage defaults) // String returns a readable representation of this value (for usage defaults)
@ -481,6 +491,7 @@ type Float64Flag struct {
Usage string Usage string
EnvVar string EnvVar string
Destination *float64 Destination *float64
Hidden bool
} }
// String returns the usage // String returns the usage
@ -516,6 +527,16 @@ func (f Float64Flag) GetName() string {
return f.Name return f.Name
} }
func visibleFlags(fl []Flag) []Flag {
visible := []Flag{}
for _, flag := range fl {
if !reflect.ValueOf(flag).FieldByName("Hidden").Bool() {
visible = append(visible, flag)
}
}
return visible
}
func prefixFor(name string) (prefix string) { func prefixFor(name string) (prefix string) {
if len(name) == 1 { if len(name) == 1 {
prefix = "-" prefix = "-"

18
help.go
View File

@ -15,7 +15,7 @@ var AppHelpTemplate = `NAME:
{{.Name}} - {{.Usage}} {{.Name}} - {{.Usage}}
USAGE: USAGE:
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .Flags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}} {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}
{{if .Version}}{{if not .HideVersion}} {{if .Version}}{{if not .HideVersion}}
VERSION: VERSION:
{{.Version}} {{.Version}}
@ -26,9 +26,9 @@ AUTHOR(S):
COMMANDS:{{range .Categories}}{{if .Name}} COMMANDS:{{range .Categories}}{{if .Name}}
{{.Name}}{{ ":" }}{{end}}{{range .Commands}} {{.Name}}{{ ":" }}{{end}}{{range .Commands}}
{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}{{end}} {{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}{{end}}
{{end}}{{end}}{{if .Flags}} {{end}}{{end}}{{if .VisibleFlags}}
GLOBAL OPTIONS: GLOBAL OPTIONS:
{{range .Flags}}{{.}} {{range .VisibleFlags}}{{.}}
{{end}}{{end}}{{if .Copyright }} {{end}}{{end}}{{if .Copyright }}
COPYRIGHT: COPYRIGHT:
{{.Copyright}} {{.Copyright}}
@ -42,16 +42,16 @@ var CommandHelpTemplate = `NAME:
{{.HelpName}} - {{.Usage}} {{.HelpName}} - {{.Usage}}
USAGE: USAGE:
{{.HelpName}}{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Category}} {{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Category}}
CATEGORY: CATEGORY:
{{.Category}}{{end}}{{if .Description}} {{.Category}}{{end}}{{if .Description}}
DESCRIPTION: DESCRIPTION:
{{.Description}}{{end}}{{if .Flags}} {{.Description}}{{end}}{{if .VisibleFlags}}
OPTIONS: OPTIONS:
{{range .Flags}}{{.}} {{range .VisibleFlags}}{{.}}
{{end}}{{ end }} {{end}}{{ end }}
` `
@ -62,14 +62,14 @@ var SubcommandHelpTemplate = `NAME:
{{.HelpName}} - {{.Usage}} {{.HelpName}} - {{.Usage}}
USAGE: USAGE:
{{.HelpName}} command{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}} {{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}
COMMANDS:{{range .Categories}}{{if .Name}} COMMANDS:{{range .Categories}}{{if .Name}}
{{.Name}}{{ ":" }}{{end}}{{range .Commands}} {{.Name}}{{ ":" }}{{end}}{{range .Commands}}
{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}{{end}} {{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}{{end}}
{{end}}{{if .Flags}} {{end}}{{if .VisibleFlags}}
OPTIONS: OPTIONS:
{{range .Flags}}{{.}} {{range .VisibleFlags}}{{.}}
{{end}}{{end}} {{end}}{{end}}
` `