Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,8 @@ func TestHelp(t *testing.T) {
cli.SubCommands(sub1, sub2),
cli.Flag(new(bool), "delete", 'd', false, "Delete something"),
cli.Flag(new(int), "count", cli.NoShortHand, -1, "Count something"),
cli.Flag(new([]string), "things", cli.NoShortHand, nil, "Names of things"),
cli.Flag(new([]string), "more", cli.NoShortHand, []string{"one", "two"}, "Names of things with a default"),
},
wantErr: false,
},
Expand Down
10 changes: 2 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,11 @@ go.followtheprocess.codes/hue v1.0.0 h1:0fYXAGR1o+w7Vja+Q+iVtqeEP3/CE6ET/pniyl8e
go.followtheprocess.codes/hue v1.0.0/go.mod h1:gSn5xK6KJapih+eFgQk3woo1qg3/rx9XSrAanUIuDr8=
go.followtheprocess.codes/snapshot v0.6.1 h1:cZkQtEjL21BSrHn98Lm0S4yTzcOje/K60Iog/u/A5tM=
go.followtheprocess.codes/snapshot v0.6.1/go.mod h1:CM2E92Ah/j0XL4Z2UyOl7GlSuD0ZLLl8rJCpFylKcIg=
go.followtheprocess.codes/test v0.23.1 h1:VoucCC8qKb6tKnBOCRZ7Ln2Ex1oV+HMXHdZyJ6DURB8=
go.followtheprocess.codes/test v0.23.1/go.mod h1:sL19ttHv+BSJSMtdPXTP05aWwl58ciap0SoLp1hucKk=
go.followtheprocess.codes/test v1.0.0 h1:5m2MPOQpohDC9pf5hgqpH+4ldJP5g+YFVdoGQY41aeU=
go.followtheprocess.codes/test v1.0.0/go.mod h1:e627pR8IhsTV/RfuP/WKYjyL0BmuIbmaw2iKlQBCWrY=
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
44 changes: 39 additions & 5 deletions internal/flag/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func New[T Flaggable](p *T, name string, short rune, value T, usage string) (Fla

// If the default value is not the zero value for the type, it is treated as
// significant and shown to the user
if !isZero(value) {
if !isZeroIsh(value) {
// \t so that defaults get aligned by tabwriter when the command
// dumps the flags
usage += fmt.Sprintf("\t[default: %v]", value)
Expand Down Expand Up @@ -905,8 +905,16 @@ func formatStringSlice(slice []string) string {
return s.String()
}

// isZero reports whether value is the zero value for it's type.
func isZero[T Flaggable](value T) bool {
// isZeroIsh reports whether value is the zero value (ish) for it's type.
//
// "ish" means that empty slices will return true from isZeroIsh despite their official
// zero value being nil. The primary use of isZeroIsh is to determine whether or not
// a default value is worth displaying to the user in the help text, and an empty slice
// is probably not.
func isZeroIsh[T Flaggable](value T) bool { //nolint:cyclop // Not much else we can do here
// Note: all the slice values ([]T) are in their own separate branches because if you
// combine them, the resulting value in the body of the case block is 'any' and
// you cannot do len(any)
switch typ := any(value).(type) {
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr, float32, float64:
return typ == 0
Expand All @@ -916,8 +924,34 @@ func isZero[T Flaggable](value T) bool {
return typ == ""
case bool:
return !typ
case []byte, net.IP, []int, []int8, []int16, []int32, []int64, []uint, []uint16, []uint32, []uint64, []float32, []float64, []string:
return typ == nil
case []byte:
return len(typ) == 0
case net.IP:
return len(typ) == 0
case []int:
return len(typ) == 0
case []int8:
return len(typ) == 0
case []int16:
return len(typ) == 0
case []int32:
return len(typ) == 0
case []int64:
return len(typ) == 0
case []uint:
return len(typ) == 0
case []uint16:
return len(typ) == 0
case []uint32:
return len(typ) == 0
case []uint64:
return len(typ) == 0
case []float32:
return len(typ) == 0
case []float64:
return len(typ) == 0
case []string:
return len(typ) == 0
case time.Time:
var zero time.Time
return typ.Equal(zero)
Expand Down
10 changes: 6 additions & 4 deletions testdata/snapshots/TestHelp/with_subcommands_and_flags.snap.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ Commands:

Options:

N/A --count int Count something [default: -1]
-d --delete bool Delete something
-h --help bool Show help for test
-V --version bool Show version info for test
N/A --count int Count something [default: -1]
-d --delete bool Delete something
-h --help bool Show help for test
N/A --more []string Names of things with a default [default: [one two]]
N/A --things []string Names of things
-V --version bool Show version info for test

Use "test [command] -h/--help" for more information about a command.
Loading