diff --git a/.golangci.yml b/.golangci.yml index a4714a8..cddee3e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -21,10 +21,12 @@ linters: - lll # Auto formatters do this and what they can't do I don't care about - maintidx # This is just the inverse of complexity... which is cyclop - nestif # cyclop does this + - nlreturn # Similar to wsl, I think best left to judgement - nonamedreturns # Named returns are often helpful, it's naked returns that are the issue - paralleltest # I've never had Go tests take longer than a few seconds, it's fine - varnamelen # Lots of false positives of things that are fine - wrapcheck # Not every error must be wrapped + - wsl # Very aggressive, some of this I like but tend to do anyway issues: exclude-rules: diff --git a/docs/img/namedargs.gif b/docs/img/namedargs.gif index 065462a..c95cec0 100644 Binary files a/docs/img/namedargs.gif and b/docs/img/namedargs.gif differ diff --git a/docs/img/quickstart.gif b/docs/img/quickstart.gif index 23db19a..e73f3e6 100644 Binary files a/docs/img/quickstart.gif and b/docs/img/quickstart.gif differ diff --git a/docs/img/subcommands.gif b/docs/img/subcommands.gif index 8db753e..d1547e7 100644 Binary files a/docs/img/subcommands.gif and b/docs/img/subcommands.gif differ diff --git a/internal/flag/flag.go b/internal/flag/flag.go index 937b392..e0ad02d 100644 --- a/internal/flag/flag.go +++ b/internal/flag/flag.go @@ -103,6 +103,12 @@ func New[T Flaggable](p *T, name string, short rune, value T, usage string) (Fla *p = value + // 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) { + usage += fmt.Sprintf(" [default: %v]", value) + } + flag := Flag[T]{ value: p, name: name, @@ -625,3 +631,29 @@ func formatFloat[T ~float32 | ~float64](bits int) func(T) string { return strconv.FormatFloat(float64(in), 'g', -1, bits) } } + +// isZero reports whether value is the zero value for it's type. +func isZero[T Flaggable](value T) bool { + switch typ := any(value).(type) { + case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr, float32, float64: + return typ == 0 + case Count: + return typ == Count(0) + case string: + return typ == "" + case bool: + return !typ + case []byte: + return typ == nil + case time.Time: + var zero time.Time + return typ.Equal(zero) + case time.Duration: + var zero time.Duration + return typ == zero + case net.IP: + return typ == nil + default: + return false + } +} diff --git a/internal/flag/set.go b/internal/flag/set.go index e8f7834..bee66ed 100644 --- a/internal/flag/set.go +++ b/internal/flag/set.go @@ -13,10 +13,6 @@ import ( // Set is a set of command line flags. type Set struct { - // Note: flags and shorthands are different "views" to the same *Entry, the Entry - // is not duplicated, it's just two maps to the same pointer so we can look up - // using either - flags map[string]Value // The actual stored flags, can lookup by name shorthands map[rune]Value // The flags by shorthand args []string // Arguments minus flags or flag values diff --git a/option.go b/option.go index 8c6dc70..e9bbacb 100644 --- a/option.go +++ b/option.go @@ -451,10 +451,15 @@ func Allow(validator ArgValidator) Option { return option(f) } -// Flag is an [Option] that adds a flag to a [Command], storing its value in a variable. +// Flag is an [Option] that adds a flag to a [Command], storing its value in a variable via it's +// pointer 'p'. // // The variable is set when the flag is parsed during command execution. The value provided -// in the call to [Flag] is used as the default value. +// by the 'value' argument to [Flag] is used as the default value, which will be used if the +// flag value was not given via the command line. +// +// If the default value is not the zero value for the type T, the flags usage message will +// show the default value in the commands help text. // // To add a long flag only (e.g. --delete with no -d option), pass [NoShortHand] for "short". // diff --git a/testdata/snapshots/TestHelp/with_subcommands_and_flags.snap.txt b/testdata/snapshots/TestHelp/with_subcommands_and_flags.snap.txt index f83f55d..4d4ee24 100644 --- a/testdata/snapshots/TestHelp/with_subcommands_and_flags.snap.txt +++ b/testdata/snapshots/TestHelp/with_subcommands_and_flags.snap.txt @@ -9,7 +9,7 @@ Commands: sub2 Do another thing Options: - N/A --count int Count something + 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