enforceFlagGroupsForCompletion will do the following: - when a flag in a group is present, other flags in the group will be marked required - when none of the flags in a one-required group are present, all flags in the group will be marked required - when a flag in a mutually exclusive group is pres
()
| 223 | // - when a flag in a mutually exclusive group is present, other flags in the group will be marked as hidden |
| 224 | // This allows the standard completion logic to behave appropriately for flag groups |
| 225 | func (c *Command) enforceFlagGroupsForCompletion() { |
| 226 | if c.DisableFlagParsing { |
| 227 | return |
| 228 | } |
| 229 | |
| 230 | flags := c.Flags() |
| 231 | groupStatus := map[string]map[string]bool{} |
| 232 | oneRequiredGroupStatus := map[string]map[string]bool{} |
| 233 | mutuallyExclusiveGroupStatus := map[string]map[string]bool{} |
| 234 | c.Flags().VisitAll(func(pflag *flag.Flag) { |
| 235 | processFlagForGroupAnnotation(flags, pflag, requiredAsGroupAnnotation, groupStatus) |
| 236 | processFlagForGroupAnnotation(flags, pflag, oneRequiredAnnotation, oneRequiredGroupStatus) |
| 237 | processFlagForGroupAnnotation(flags, pflag, mutuallyExclusiveAnnotation, mutuallyExclusiveGroupStatus) |
| 238 | }) |
| 239 | |
| 240 | // If a flag that is part of a group is present, we make all the other flags |
| 241 | // of that group required so that the shell completion suggests them automatically |
| 242 | for flagList, flagnameAndStatus := range groupStatus { |
| 243 | for _, isSet := range flagnameAndStatus { |
| 244 | if isSet { |
| 245 | // One of the flags of the group is set, mark the other ones as required |
| 246 | for _, fName := range strings.Split(flagList, " ") { |
| 247 | _ = c.MarkFlagRequired(fName) |
| 248 | } |
| 249 | } |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | // If none of the flags of a one-required group are present, we make all the flags |
| 254 | // of that group required so that the shell completion suggests them automatically |
| 255 | for flagList, flagnameAndStatus := range oneRequiredGroupStatus { |
| 256 | isSet := false |
| 257 | |
| 258 | for _, isSet = range flagnameAndStatus { |
| 259 | if isSet { |
| 260 | break |
| 261 | } |
| 262 | } |
| 263 | |
| 264 | // None of the flags of the group are set, mark all flags in the group |
| 265 | // as required |
| 266 | if !isSet { |
| 267 | for _, fName := range strings.Split(flagList, " ") { |
| 268 | _ = c.MarkFlagRequired(fName) |
| 269 | } |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | // If a flag that is mutually exclusive to others is present, we hide the other |
| 274 | // flags of that group so the shell completion does not suggest them |
| 275 | for flagList, flagnameAndStatus := range mutuallyExclusiveGroupStatus { |
| 276 | for flagName, isSet := range flagnameAndStatus { |
| 277 | if isSet { |
| 278 | // One of the flags of the mutually exclusive group is set, mark the other ones as hidden |
| 279 | // Don't mark the flag that is already set as hidden because it may be an |
| 280 | // array or slice flag and therefore must continue being suggested |
| 281 | for _, fName := range strings.Split(flagList, " ") { |
| 282 | if fName != flagName { |
no test coverage detected