parse.go 1.63 KB
Newer Older
1 2 3
package cli

import (
4
  "fmt"
5 6 7 8 9
  "strings"

  "github.com/jbenet/go-ipfs/commands"
)

10
func Parse(input []string, root *commands.Command) (*commands.Request, error) {
11
  path, input, err := parsePath(input, root)
12
  if err != nil {
13
    return nil, err
14 15
  }

16
  opts, args, err := parseOptions(input)
17
  if err != nil {
18
    return nil, err
19 20
  }

21
  return commands.NewRequest(path, opts, args), nil
22 23
}

24
// parsePath gets the command path from the command line input
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
func parsePath(input []string, root *commands.Command) ([]string, []string, error) {
  cmd := root
  i := 0

  for _, blob := range input {
    if strings.HasPrefix(blob, "-") {
      break
    }

    cmd := cmd.Sub(blob)
    if cmd == nil {
      break
    }

    i++
  }

  return input[:i], input[i:], nil
}

45
// parseOptions parses the raw string values of the given options
46
// returns the parsed options as strings, along with the CLI args
47
func parseOptions(input []string) (map[string]interface{}, []string, error) {
48
  opts := make(map[string]interface{})
49
  args := make([]string, 0)
50 51 52 53

  for i := 0; i < len(input); i++ {
    blob := input[i]

54 55
    if strings.HasPrefix(blob, "-") {
      name := blob[1:]
56 57
      value := ""

58 59 60 61 62
      // support single and double dash
      if strings.HasPrefix(name, "-") {
        name = name[1:]
      }

63 64 65 66 67 68
      if strings.Contains(name, "=") {
        split := strings.SplitN(name, "=", 2)
        name = split[0]
        value = split[1]
      }

69 70 71 72
      if _, ok := opts[name]; ok {
        return nil, nil, fmt.Errorf("Duplicate values for option '%s'", name)
      }

73 74 75
      opts[name] = value

    } else {
76
      args = append(args, blob)
77 78 79
    }
  }

80
  return opts, args, nil
81
}