From 8549c9c02f590bd41e6a7a33936562ddc67dc9a6 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Fri, 22 Nov 2024 23:22:38 +0800 Subject: [PATCH] internal/flags: fix issue with stringslice migration (#25830) This fixes a cornercase bug where the flag migration would mess up the value of StringSlice flags. --- internal/flags/helpers.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/internal/flags/helpers.go b/internal/flags/helpers.go index 4642b82c45a72..60dceb980be12 100644 --- a/internal/flags/helpers.go +++ b/internal/flags/helpers.go @@ -83,10 +83,34 @@ func MigrateGlobalFlags(ctx *cli.Context) { } func doMigrateFlags(ctx *cli.Context) { + // Figure out if there are any aliases of commands. If there are, we want + // to ignore them when iterating over the flags. + var aliases = make(map[string]bool) + for _, fl := range ctx.Command.Flags { + for _, alias := range fl.Names()[1:] { + aliases[alias] = true + } + } for _, name := range ctx.FlagNames() { for _, parent := range ctx.Lineage()[1:] { if parent.IsSet(name) { - ctx.Set(name, parent.String(name)) + // When iterating across the lineage, we will be served both + // the 'canon' and alias formats of all commmands. In most cases, + // it's fine to set it in the ctx multiple times (one for each + // name), however, the Slice-flags are not fine. + // The slice-flags accumulate, so if we set it once as + // "foo" and once as alias "F", then both will be present in the slice. + if _, isAlias := aliases[name]; isAlias { + continue + } + // If it is a string-slice, we need to set it as + // "alfa, beta, gamma" instead of "[alfa beta gamma]", in order + // for the backing StringSlice to parse it properly. + if result := parent.StringSlice(name); len(result) > 0 { + ctx.Set(name, strings.Join(result, ",")) + } else { + ctx.Set(name, parent.String(name)) + } break } }