From 07e0704ca9d430195a6f519b7e5cee4bfea77c19 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 29 Sep 2022 20:16:36 +0200 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 46409f4df..3be0a5807 100644 --- a/internal/flags/helpers.go +++ b/internal/flags/helpers.go @@ -94,10 +94,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 } }