addPluginCommands is a recursive method that adds each different level of sub-commands and flags for the plugins that have provided such information
(plug plugin.Plugin, baseCmd *cobra.Command, cmds *pluginCommand)
| 239 | // addPluginCommands is a recursive method that adds each different level |
| 240 | // of sub-commands and flags for the plugins that have provided such information |
| 241 | func addPluginCommands(plug plugin.Plugin, baseCmd *cobra.Command, cmds *pluginCommand) { |
| 242 | if cmds == nil { |
| 243 | return |
| 244 | } |
| 245 | |
| 246 | if len(cmds.Name) == 0 { |
| 247 | slog.Debug("sub-command name field missing", slog.String("commandPath", baseCmd.CommandPath())) |
| 248 | return |
| 249 | } |
| 250 | |
| 251 | baseCmd.Use = cmds.Name |
| 252 | baseCmd.ValidArgs = cmds.ValidArgs |
| 253 | // Setup the same dynamic completion for each plugin sub-command. |
| 254 | // This is because if dynamic completion is triggered, there is a single executable |
| 255 | // to call (plugin.complete), so every sub-commands calls it in the same fashion. |
| 256 | if cmds.Commands == nil { |
| 257 | // Only setup dynamic completion if there are no sub-commands. This avoids |
| 258 | // calling plugin.complete at every completion, which greatly simplifies |
| 259 | // development of plugin.complete for plugin developers. |
| 260 | baseCmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { |
| 261 | return pluginDynamicComp(plug, cmd, args, toComplete) |
| 262 | } |
| 263 | } |
| 264 | |
| 265 | // Create fake flags. |
| 266 | if len(cmds.Flags) > 0 { |
| 267 | // The flags can be created with any type, since we only need them for completion. |
| 268 | // pflag does not allow to create short flags without a corresponding long form |
| 269 | // so we look for all short flags and match them to any long flag. This will allow |
| 270 | // plugins to provide short flags without a long form. |
| 271 | // If there are more short-flags than long ones, we'll create an extra long flag with |
| 272 | // the same single letter as the short form. |
| 273 | shorts := []string{} |
| 274 | longs := []string{} |
| 275 | for _, flag := range cmds.Flags { |
| 276 | if len(flag) == 1 { |
| 277 | shorts = append(shorts, flag) |
| 278 | } else { |
| 279 | longs = append(longs, flag) |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | f := baseCmd.Flags() |
| 284 | if len(longs) >= len(shorts) { |
| 285 | for i := range longs { |
| 286 | if i < len(shorts) { |
| 287 | f.BoolP(longs[i], shorts[i], false, "") |
| 288 | } else { |
| 289 | f.Bool(longs[i], false, "") |
| 290 | } |
| 291 | } |
| 292 | } else { |
| 293 | for i := range shorts { |
| 294 | if i < len(longs) { |
| 295 | f.BoolP(longs[i], shorts[i], false, "") |
| 296 | } else { |
| 297 | // Create a long flag with the same name as the short flag. |
| 298 | // Not a perfect solution, but it's better than ignoring the extra short flags. |
no test coverage detected
searching dependent graphs…