master
Raw Download raw file
  1package main
  2
  3import (
  4	"fmt"
  5	"strings"
  6)
  7
  8// Command stores the information for running a command
  9type Command struct {
 10	Command,
 11	Description,
 12	Usage string
 13	Flags                map[string]Flag
 14	PositionalParameters []string
 15	Run                  func(Command) error
 16}
 17
 18type Commands []Command
 19
 20// Flag servers to store command flags for the program commands
 21// if HasArgs is true, then the flag MUST have an argument
 22type Flag struct {
 23	Flag,
 24	Description,
 25	Usage,
 26	Value string
 27	HasArgs bool
 28	Args    []string
 29}
 30
 31// Swap swaps i and j
 32func (commands Commands) Swap(i, j int) {
 33	commands[i], commands[j] = commands[j], commands[i]
 34}
 35
 36// Less returns true if i is less than j
 37func (a Commands) Less(i, j int) bool {
 38	return strings.Compare(a[i].Command, a[j].Command) < 0
 39}
 40
 41// Len returns the number of commands contained
 42// in this struct
 43func (a Commands) Len() int {
 44	return len(a)
 45}
 46
 47// selectCommand takes a string and converts it to the correct command
 48func SelectCommand(str string, commandArray []Command) (Command, error) {
 49	for _, value := range commandArray {
 50		if strings.Compare(value.Command, str) == 0 {
 51			return value, nil
 52		}
 53	}
 54	return Command{}, fmt.Errorf("No command found for: %s", str)
 55}
 56
 57// expandShortOptions takes condensed short options and
 58// expands them into properly formatted short options
 59func expandShortOptions(shorts string) []string {
 60	var options = make([]string, (len(shorts)-1)*2)
 61	for char := range shorts {
 62		options = append(options, "-"+string(char))
 63	}
 64	return options
 65}
 66
 67// parseUserCommands takes a user string and parses it into separate
 68// flags for the specified command, placing the values into the
 69// specified struct. invalid flags cause an error
 70func ParseUserCommands(args []string, command *Command) error {
 71	flagString := ""
 72	for len(args) > 0 {
 73		if strings.HasPrefix(args[0], "-") {
 74			if strings.HasPrefix(args[0], "--") {
 75				flagString = args[0][2:]
 76			} else if len(args[0]) > 2 { // multiple short options at once
 77				args = append(expandShortOptions(args[0]), args...)
 78				continue
 79			} else { // only 1 short option
 80				flagString = args[0][1:]
 81			}
 82			for key, flagValue := range command.Flags {
 83				if flagString == flagValue.Flag {
 84					if flagValue.HasArgs {
 85						if len(args) < 2 {
 86							return fmt.Errorf("Not enough arguments for %s", flagString)
 87						}
 88						flagValue.Value = args[1]
 89					} else {
 90						flagValue.Value = "true"
 91					}
 92					command.Flags[key] = flagValue
 93				}
 94			}
 95		} else { // flags have been handled
 96			command.PositionalParameters = args
 97		}
 98		args = args[1:]
 99	}
100	return nil
101}