The default help template relies on the String() method of Flag
to render the flag. For most flag types, String() indirects through
FlagStringer, so that is the best place to customize flag rendering.
FlagStringer was not called for slice flags because their help output
differs from other flags in two ways: there can be multiple default
values, and the flag name is shown two times to indicate that the flag
can be specified multiple times.
To make multiple values work in the FlagStringer, I simply changed
GetValue() to return all values.
Showing the flag more than once is achieved through a new interface,
DocGenerationSliceFlag, which the FlagStringer uses to decide whether
the flag is a slice flag type.
The default help template relies on the String() method of Flag
to render the flag. For most flag types, String() indirects through
FlagStringer, so that is the best place to customize flag rendering.
FlagStringer was not called for slice flags because their help output
differs from other flags in two ways: there can be multiple default
values, and the flag name is shown two times to indicate that the flag
can be specified multiple times.
To make multiple values work in the FlagStringer, I simply changed
GetValue() to return all values.
Showing the flag more than once is achieved through a new interface,
DocGenerationSliceFlag, which the FlagStringer uses to decide whether
the flag is a slice flag type.
The SliceFlag implementation and associated aliases (MultiStringFlag, etc)
extend the existing slice implementations (StringSliceFlag, etc) to support
actual slices as the flag value and destination.
This change also fixes various bugs in the existing implementation. Notably,
the StringSliceFlag.Apply implementation would modify the input (default)
Value, if an env var was set, and no destination was provided. The bugs fixed
in the other three implementations were all already fixed in either
StringSliceFlag, or in one case (ignoring empty env var) in Float64SliceFlag.