github.com/wawandco/oxpecker@v1.5.7-0.20210910201653-5958d4afdd89/tools/cli/help/command.go (about) 1 package help 2 3 import ( 4 "context" 5 "errors" 6 7 "github.com/wawandco/oxpecker/plugins" 8 ) 9 10 var ( 11 // Help is a Command 12 _ plugins.Command = (*Command)(nil) 13 14 ErrSubCommandNotFound = errors.New("subcommand not found") 15 ) 16 17 // Help command that prints 18 type Command struct { 19 commands []plugins.Command 20 } 21 22 func (h Command) Name() string { 23 return "help" 24 } 25 26 func (c Command) Alias() string { 27 return "h" 28 } 29 30 func (h Command) ParentName() string { 31 return "" 32 } 33 34 // HelpText for the Help command 35 func (h Command) HelpText() string { 36 return "prints help text for the commands registered" 37 } 38 39 // Run the help command 40 func (h *Command) Run(ctx context.Context, root string, args []string) error { 41 command, names := h.findCommand(args) 42 if command == nil { 43 h.printTopLevel() 44 return nil 45 } 46 47 h.printSingle(command, names) 48 49 return nil 50 } 51 52 func (h *Command) findCommand(args []string) (plugins.Command, []string) { 53 if len(args) < 2 { 54 return nil, nil 55 } 56 57 var commands = h.commands 58 var command plugins.Command 59 var argIndex = 1 60 var fndNames []string 61 62 for { 63 var name = args[argIndex] 64 for _, c := range commands { 65 // TODO: If its a subcommand check also the SubcommandName 66 a, ok := c.(plugins.Aliaser) 67 if !ok { 68 if c.Name() != name { 69 continue 70 } 71 fndNames = append(fndNames, c.Name()) 72 command = c 73 break 74 } 75 76 if a.Alias() != name && c.Name() != name { 77 continue 78 } 79 80 if c.Name() == name { 81 fndNames = append(fndNames, c.Name()) 82 command = c 83 break 84 } 85 86 if a.Alias() == name { 87 fndNames = append(fndNames, a.Alias()) 88 command = c 89 } 90 break 91 } 92 93 argIndex++ 94 if argIndex >= len(args) { 95 break 96 } 97 98 sc, ok := command.(plugins.Subcommander) 99 if !ok { 100 break 101 } 102 103 commands = sc.Subcommands() 104 } 105 106 return command, fndNames 107 } 108 109 // Receive the plugins and stores the Commands for 110 // later usage on the help text. 111 func (h *Command) Receive(pl []plugins.Plugin) { 112 for _, plugin := range pl { 113 ht, ok := plugin.(plugins.Command) 114 if ok && ht.ParentName() == "" { 115 h.commands = append(h.commands, ht) 116 } 117 } 118 }