Skip to content

Commit

Permalink
Merge branch 'main' into issue_1500
Browse files Browse the repository at this point in the history
  • Loading branch information
dearchap committed Oct 6, 2022
2 parents a27294d + 2a4809f commit fb23ff4
Show file tree
Hide file tree
Showing 18 changed files with 424 additions and 226 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/cli.yml
Expand Up @@ -40,6 +40,8 @@ jobs:
GFLAGS: -tags urfave_cli_no_docs
- run: make check-binary-size
- run: make yamlfmt
- if: matrix.go == '1.19.x' && matrix.os == 'ubuntu-latest'
run: make generate
- run: make diffcheck
- if: matrix.go == '1.19.x' && matrix.os == 'ubuntu-latest'
run: make v2diff
Expand Down
2 changes: 1 addition & 1 deletion app_test.go
Expand Up @@ -177,7 +177,7 @@ func ExampleApp_Run_commandHelp() {
// greet describeit - use it to see a description
//
// USAGE:
// greet describeit [command options] [arguments...]
// greet describeit [arguments...]
//
// DESCRIPTION:
// This is how we describe describeit the function
Expand Down
11 changes: 11 additions & 0 deletions command.go
Expand Up @@ -295,6 +295,17 @@ func (c *Command) startApp(ctx *Context) error {
return app.RunAsSubcommand(ctx)
}

// VisibleCommands returns a slice of the Commands with Hidden=false
func (c *Command) VisibleCommands() []*Command {
var ret []*Command
for _, command := range c.Subcommands {
if !command.Hidden {
ret = append(ret, command)
}
}
return ret
}

// VisibleFlagCategories returns a slice containing all the visible flag categories with the flags they contain
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory {
if c.flagCategories == nil {
Expand Down
27 changes: 27 additions & 0 deletions command_test.go
Expand Up @@ -422,3 +422,30 @@ func TestCommand_CanAddVFlagOnCommands(t *testing.T) {
err := app.Run([]string{"foo", "bar"})
expect(t, err, nil)
}

func TestCommand_VisibleSubcCommands(t *testing.T) {

subc1 := &Command{
Name: "subc1",
Usage: "subc1 command1",
}
subc3 := &Command{
Name: "subc3",
Usage: "subc3 command2",
}
c := &Command{
Name: "bar",
Usage: "this is for testing",
Subcommands: []*Command{
subc1,
{
Name: "subc2",
Usage: "subc2 command2",
Hidden: true,
},
subc3,
},
}

expect(t, c.VisibleCommands(), []*Command{subc1, subc3})
}
29 changes: 13 additions & 16 deletions flag.go
Expand Up @@ -129,6 +129,14 @@ type DocGenerationFlag interface {
GetEnvVars() []string
}

// DocGenerationSliceFlag extends DocGenerationFlag for slice-based flags.
type DocGenerationSliceFlag interface {
DocGenerationFlag

// IsSliceFlag returns true for flags that can be given multiple times.
IsSliceFlag() bool
}

// VisibleFlag is an interface that allows to check if a flag is visible
type VisibleFlag interface {
Flag
Expand Down Expand Up @@ -325,24 +333,13 @@ func stringifyFlag(f Flag) string {

usageWithDefault := strings.TrimSpace(usage + defaultValueString)

return withEnvHint(df.GetEnvVars(),
fmt.Sprintf("%s\t%s", prefixedNames(df.Names(), placeholder), usageWithDefault))
}

func stringifySliceFlag(usage string, names, defaultVals []string) string {
placeholder, usage := unquoteUsage(usage)
if placeholder == "" {
placeholder = defaultPlaceholder
}

defaultVal := ""
if len(defaultVals) > 0 {
defaultVal = fmt.Sprintf(formatDefault("%s"), strings.Join(defaultVals, ", "))
pn := prefixedNames(df.Names(), placeholder)
sliceFlag, ok := f.(DocGenerationSliceFlag)
if ok && sliceFlag.IsSliceFlag() {
pn = pn + " [ " + pn + " ]"
}

usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal))
pn := prefixedNames(names, placeholder)
return fmt.Sprintf("%s [ %s ]\t%s", pn, pn, usageWithDefault)
return withEnvHint(df.GetEnvVars(), fmt.Sprintf("%s\t%s", pn, usageWithDefault))
}

func hasFlag(flags []Flag, fl Flag) bool {
Expand Down
28 changes: 12 additions & 16 deletions flag_float64_slice.go
Expand Up @@ -83,7 +83,7 @@ func (f *Float64Slice) Get() interface{} {
// String returns a readable representation of this value
// (for usage defaults)
func (f *Float64SliceFlag) String() string {
return withEnvHint(f.GetEnvVars(), f.stringify())
return FlagStringer(f)
}

// TakesValue returns true if the flag takes a value, otherwise false
Expand All @@ -104,10 +104,13 @@ func (f *Float64SliceFlag) GetCategory() string {
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *Float64SliceFlag) GetValue() string {
if f.Value != nil {
return f.Value.String()
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, strings.TrimRight(strings.TrimRight(fmt.Sprintf("%f", i), "0"), "."))
}
}
return ""
return strings.Join(defaultVals, ", ")
}

// GetDefaultText returns the default text for this flag
Expand All @@ -123,6 +126,11 @@ func (f *Float64SliceFlag) GetEnvVars() []string {
return f.EnvVars
}

// IsSliceFlag implements DocGenerationSliceFlag.
func (f *Float64SliceFlag) IsSliceFlag() bool {
return true
}

// Apply populates the flag given the flag set and environment
func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
// apply any default
Expand Down Expand Up @@ -169,18 +177,6 @@ func (f *Float64SliceFlag) Get(ctx *Context) []float64 {
return ctx.Float64Slice(f.Name)
}

func (f *Float64SliceFlag) stringify() string {
var defaultVals []string

if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, strings.TrimRight(strings.TrimRight(fmt.Sprintf("%f", i), "0"), "."))
}
}

return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
}

// RunAction executes flag action if set
func (f *Float64SliceFlag) RunAction(c *Context) error {
if f.Action != nil {
Expand Down
4 changes: 4 additions & 0 deletions flag_generic.go
Expand Up @@ -62,6 +62,10 @@ func (f *GenericFlag) Apply(set *flag.FlagSet) error {
}

for _, name := range f.Names() {
if f.Destination != nil {
set.Var(f.Destination, name, f.Usage)
continue
}
set.Var(f.Value, name, f.Usage)
}

Expand Down
27 changes: 12 additions & 15 deletions flag_int64_slice.go
Expand Up @@ -84,7 +84,7 @@ func (i *Int64Slice) Get() interface{} {
// String returns a readable representation of this value
// (for usage defaults)
func (f *Int64SliceFlag) String() string {
return withEnvHint(f.GetEnvVars(), f.stringify())
return FlagStringer(f)
}

// TakesValue returns true of the flag takes a value, otherwise false
Expand All @@ -105,10 +105,13 @@ func (f *Int64SliceFlag) GetCategory() string {
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *Int64SliceFlag) GetValue() string {
if f.Value != nil {
return f.Value.String()
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, strconv.FormatInt(i, 10))
}
}
return ""
return strings.Join(defaultVals, ", ")
}

// GetDefaultText returns the default text for this flag
Expand All @@ -124,6 +127,11 @@ func (f *Int64SliceFlag) GetEnvVars() []string {
return f.EnvVars
}

// IsSliceFlag implements DocGenerationSliceFlag.
func (f *Int64SliceFlag) IsSliceFlag() bool {
return true
}

// Apply populates the flag given the flag set and environment
func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
// apply any default
Expand Down Expand Up @@ -168,17 +176,6 @@ func (f *Int64SliceFlag) Get(ctx *Context) []int64 {
return ctx.Int64Slice(f.Name)
}

func (f *Int64SliceFlag) stringify() string {
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, strconv.FormatInt(i, 10))
}
}

return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
}

// RunAction executes flag action if set
func (f *Int64SliceFlag) RunAction(c *Context) error {
if f.Action != nil {
Expand Down
27 changes: 12 additions & 15 deletions flag_int_slice.go
Expand Up @@ -95,7 +95,7 @@ func (i *IntSlice) Get() interface{} {
// String returns a readable representation of this value
// (for usage defaults)
func (f *IntSliceFlag) String() string {
return withEnvHint(f.GetEnvVars(), f.stringify())
return FlagStringer(f)
}

// TakesValue returns true of the flag takes a value, otherwise false
Expand All @@ -116,10 +116,13 @@ func (f *IntSliceFlag) GetCategory() string {
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *IntSliceFlag) GetValue() string {
if f.Value != nil {
return f.Value.String()
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, strconv.Itoa(i))
}
}
return ""
return strings.Join(defaultVals, ", ")
}

// GetDefaultText returns the default text for this flag
Expand All @@ -135,6 +138,11 @@ func (f *IntSliceFlag) GetEnvVars() []string {
return f.EnvVars
}

// IsSliceFlag implements DocGenerationSliceFlag.
func (f *IntSliceFlag) IsSliceFlag() bool {
return true
}

// Apply populates the flag given the flag set and environment
func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
// apply any default
Expand Down Expand Up @@ -188,17 +196,6 @@ func (f *IntSliceFlag) RunAction(c *Context) error {
return nil
}

func (f *IntSliceFlag) stringify() string {
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, strconv.Itoa(i))
}
}

return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
}

// IntSlice looks up the value of a local IntSliceFlag, returns
// nil if not found
func (cCtx *Context) IntSlice(name string) []int {
Expand Down
31 changes: 14 additions & 17 deletions flag_string_slice.go
Expand Up @@ -74,7 +74,7 @@ func (s *StringSlice) Get() interface{} {
// String returns a readable representation of this value
// (for usage defaults)
func (f *StringSliceFlag) String() string {
return withEnvHint(f.GetEnvVars(), f.stringify())
return FlagStringer(f)
}

// TakesValue returns true of the flag takes a value, otherwise false
Expand All @@ -95,10 +95,15 @@ func (f *StringSliceFlag) GetCategory() string {
// GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all.
func (f *StringSliceFlag) GetValue() string {
if f.Value != nil {
return f.Value.String()
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, s := range f.Value.Value() {
if len(s) > 0 {
defaultVals = append(defaultVals, strconv.Quote(s))
}
}
}
return ""
return strings.Join(defaultVals, ", ")
}

// GetDefaultText returns the default text for this flag
Expand All @@ -114,6 +119,11 @@ func (f *StringSliceFlag) GetEnvVars() []string {
return f.EnvVars
}

// IsSliceFlag implements DocGenerationSliceFlag.
func (f *StringSliceFlag) IsSliceFlag() bool {
return true
}

// Apply populates the flag given the flag set and environment
func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
// apply any default
Expand Down Expand Up @@ -158,19 +168,6 @@ func (f *StringSliceFlag) Get(ctx *Context) []string {
return ctx.StringSlice(f.Name)
}

func (f *StringSliceFlag) stringify() string {
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, s := range f.Value.Value() {
if len(s) > 0 {
defaultVals = append(defaultVals, strconv.Quote(s))
}
}
}

return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
}

// RunAction executes flag action if set
func (f *StringSliceFlag) RunAction(c *Context) error {
if f.Action != nil {
Expand Down

0 comments on commit fb23ff4

Please sign in to comment.