pflag icon indicating copy to clipboard operation
pflag copied to clipboard

StringSlice displays default even if "zeroed" DefValue

Open mkyc opened this issue 4 years ago • 1 comments

For multiline descriptions it looks very weird sometimes when (default ....) section is placed at the end of paragraph. There is simple workaround - zero DefValue like this (cobra example): fooCmd.Flags().Lookup("foo-flag").DefValue = "". In most cases it will work and prevent (default ...) part from being added at the end but it doesn't work for StringSlice flag type and there would be something like this generated in usage text:

usage text (default )

mkyc avatar May 14 '21 21:05 mkyc


package main

import (
	"fmt"
	"strings"

	"github.com/spf13/cobra"
	"github.com/spf13/pflag"
)

// CustomStringSlice is a custom flag type for []string
type CustomStringSlice []string

// String returns a string representation of the slice
func (s *CustomStringSlice) String() string {
	return strings.Join(*s, ",")
}

// Set appends a value to the slice
func (s *CustomStringSlice) Set(value string) error {
	*s = append(*s, value)
	return nil
}

// Type returns the type of the flag for help messages
func (s *CustomStringSlice) Type() string {
	return "stringSlice"
}

func main() {
	// Create the root command
	rootCmd := &cobra.Command{
		Use:   "app",
		Short: "A Cobra app with clean StringSlice flag help text",
		Run: func(cmd *cobra.Command, args []string) {
			// Access flags
			standardSlice, _ := cmd.Flags().GetStringSlice("standard-slice")
			customSlice, _ := cmd.Flags().GetStringSlice("custom-slice")
			fmt.Println("Standard slice:", standardSlice)
			fmt.Println("Custom slice:", customSlice)
		},
	}

	// Approach 1: Standard StringSlice with DefValue workaround
	rootCmd.Flags().StringSliceP("standard-slice", "s", []string{}, `A multiline description for the standard string slice flag.
This flag accepts multiple values.
It should not show an awkward (default ) in the help text.`)

	// Manipulate DefValue to suppress default in help text
	if flag := rootCmd.Flags().Lookup("standard-slice"); flag != nil {
		flag.DefValue = ""
	}

	// Approach 2: Custom StringSlice flag type
	var customSlice CustomStringSlice
	rootCmd.Flags().VarP(&customSlice, "custom-slice", "c", `A multiline description for the custom string slice flag.
This flag accepts multiple values.
It uses a custom type to avoid the (default ) issue.`)

	// Optionally set DefValue for custom flag (not strictly necessary)
	if flag := rootCmd.Flags().Lookup("custom-slice"); flag != nil {
		flag.DefValue = ""
	}

	// Execute the command
	if err := rootCmd.Execute(); err != nil {
		fmt.Println("Error:", err)
	}
}

ljluestc avatar May 20 '25 16:05 ljluestc