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  }