diff --git a/vendor/github.com/jessevdk/go-flags/completion.go b/vendor/github.com/jessevdk/go-flags/completion.go
new file mode 100644
index 0000000..7a7a08b
--- /dev/null
+++ b/vendor/github.com/jessevdk/go-flags/completion.go
@@ -0,0 +1,309 @@
+package flags
+
+import (
+	"fmt"
+	"path/filepath"
+	"reflect"
+	"sort"
+	"strings"
+	"unicode/utf8"
+)
+
+// Completion is a type containing information of a completion.
+type Completion struct {
+	// The completed item
+	Item string
+
+	// A description of the completed item (optional)
+	Description string
+}
+
+type completions []Completion
+
+func (c completions) Len() int {
+	return len(c)
+}
+
+func (c completions) Less(i, j int) bool {
+	return c[i].Item < c[j].Item
+}
+
+func (c completions) Swap(i, j int) {
+	c[i], c[j] = c[j], c[i]
+}
+
+// Completer is an interface which can be implemented by types
+// to provide custom command line argument completion.
+type Completer interface {
+	// Complete receives a prefix representing a (partial) value
+	// for its type and should provide a list of possible valid
+	// completions.
+	Complete(match string) []Completion
+}
+
+type completion struct {
+	parser *Parser
+}
+
+// Filename is a string alias which provides filename completion.
+type Filename string
+
+func completionsWithoutDescriptions(items []string) []Completion {
+	ret := make([]Completion, len(items))
+
+	for i, v := range items {
+		ret[i].Item = v
+	}
+
+	return ret
+}
+
+// Complete returns a list of existing files with the given
+// prefix.
+func (f *Filename) Complete(match string) []Completion {
+	ret, _ := filepath.Glob(match + "*")
+	return completionsWithoutDescriptions(ret)
+}
+
+func (c *completion) skipPositional(s *parseState, n int) {
+	if n >= len(s.positional) {
+		s.positional = nil
+	} else {
+		s.positional = s.positional[n:]
+	}
+}
+
+func (c *completion) completeOptionNames(s *parseState, prefix string, match string, short bool) []Completion {
+	if short && len(match) != 0 {
+		return []Completion{
+			Completion{
+				Item: prefix + match,
+			},
+		}
+	}
+
+	var results []Completion
+	repeats := map[string]bool{}
+
+	for name, opt := range s.lookup.longNames {
+		if strings.HasPrefix(name, match) && !opt.Hidden {
+			results = append(results, Completion{
+				Item:        defaultLongOptDelimiter + name,
+				Description: opt.Description,
+			})
+
+			if short {
+				repeats[string(opt.ShortName)] = true
+			}
+		}
+	}
+
+	if short {
+		for name, opt := range s.lookup.shortNames {
+			if _, exist := repeats[name]; !exist && strings.HasPrefix(name, match) && !opt.Hidden {
+				results = append(results, Completion{
+					Item:        string(defaultShortOptDelimiter) + name,
+					Description: opt.Description,
+				})
+			}
+		}
+	}
+
+	return results
+}
+
+func (c *completion) completeNamesForLongPrefix(s *parseState, prefix string, match string) []Completion {
+	return c.completeOptionNames(s, prefix, match, false)
+}
+
+func (c *completion) completeNamesForShortPrefix(s *parseState, prefix string, match string) []Completion {
+	return c.completeOptionNames(s, prefix, match, true)
+}
+
+func (c *completion) completeCommands(s *parseState, match string) []Completion {
+	n := make([]Completion, 0, len(s.command.commands))
+
+	for _, cmd := range s.command.commands {
+		if cmd.data != c && strings.HasPrefix(cmd.Name, match) {
+			n = append(n, Completion{
+				Item:        cmd.Name,
+				Description: cmd.ShortDescription,
+			})
+		}
+	}
+
+	return n
+}
+
+func (c *completion) completeValue(value reflect.Value, prefix string, match string) []Completion {
+	if value.Kind() == reflect.Slice {
+		value = reflect.New(value.Type().Elem())
+	}
+	i := value.Interface()
+
+	var ret []Completion
+
+	if cmp, ok := i.(Completer); ok {
+		ret = cmp.Complete(match)
+	} else if value.CanAddr() {
+		if cmp, ok = value.Addr().Interface().(Completer); ok {
+			ret = cmp.Complete(match)
+		}
+	}
+
+	for i, v := range ret {
+		ret[i].Item = prefix + v.Item
+	}
+
+	return ret
+}
+
+func (c *completion) complete(args []string) []Completion {
+	if len(args) == 0 {
+		args = []string{""}
+	}
+
+	s := &parseState{
+		args: args,
+	}
+
+	c.parser.fillParseState(s)
+
+	var opt *Option
+
+	for len(s.args) > 1 {
+		arg := s.pop()
+
+		if (c.parser.Options&PassDoubleDash) != None && arg == "--" {
+			opt = nil
+			c.skipPositional(s, len(s.args)-1)
+
+			break
+		}
+
+		if argumentIsOption(arg) {
+			prefix, optname, islong := stripOptionPrefix(arg)
+			optname, _, argument := splitOption(prefix, optname, islong)
+
+			if argument == nil {
+				var o *Option
+				canarg := true
+
+				if islong {
+					o = s.lookup.longNames[optname]
+				} else {
+					for i, r := range optname {
+						sname := string(r)
+						o = s.lookup.shortNames[sname]
+
+						if o == nil {
+							break
+						}
+
+						if i == 0 && o.canArgument() && len(optname) != len(sname) {
+							canarg = false
+							break
+						}
+					}
+				}
+
+				if o == nil && (c.parser.Options&PassAfterNonOption) != None {
+					opt = nil
+					c.skipPositional(s, len(s.args)-1)
+
+					break
+				} else if o != nil && o.canArgument() && !o.OptionalArgument && canarg {
+					if len(s.args) > 1 {
+						s.pop()
+					} else {
+						opt = o
+					}
+				}
+			}
+		} else {
+			if len(s.positional) > 0 {
+				if !s.positional[0].isRemaining() {
+					// Don't advance beyond a remaining positional arg (because
+					// it consumes all subsequent args).
+					s.positional = s.positional[1:]
+				}
+			} else if cmd, ok := s.lookup.commands[arg]; ok {
+				cmd.fillParseState(s)
+			}
+
+			opt = nil
+		}
+	}
+
+	lastarg := s.args[len(s.args)-1]
+	var ret []Completion
+
+	if opt != nil {
+		// Completion for the argument of 'opt'
+		ret = c.completeValue(opt.value, "", lastarg)
+	} else if argumentStartsOption(lastarg) {
+		// Complete the option
+		prefix, optname, islong := stripOptionPrefix(lastarg)
+		optname, split, argument := splitOption(prefix, optname, islong)
+
+		if argument == nil && !islong {
+			rname, n := utf8.DecodeRuneInString(optname)
+			sname := string(rname)
+
+			if opt := s.lookup.shortNames[sname]; opt != nil && opt.canArgument() {
+				ret = c.completeValue(opt.value, prefix+sname, optname[n:])
+			} else {
+				ret = c.completeNamesForShortPrefix(s, prefix, optname)
+			}
+		} else if argument != nil {
+			if islong {
+				opt = s.lookup.longNames[optname]
+			} else {
+				opt = s.lookup.shortNames[optname]
+			}
+
+			if opt != nil {
+				ret = c.completeValue(opt.value, prefix+optname+split, *argument)
+			}
+		} else if islong {
+			ret = c.completeNamesForLongPrefix(s, prefix, optname)
+		} else {
+			ret = c.completeNamesForShortPrefix(s, prefix, optname)
+		}
+	} else if len(s.positional) > 0 {
+		// Complete for positional argument
+		ret = c.completeValue(s.positional[0].value, "", lastarg)
+	} else if len(s.command.commands) > 0 {
+		// Complete for command
+		ret = c.completeCommands(s, lastarg)
+	}
+
+	sort.Sort(completions(ret))
+	return ret
+}
+
+func (c *completion) print(items []Completion, showDescriptions bool) {
+	if showDescriptions && len(items) > 1 {
+		maxl := 0
+
+		for _, v := range items {
+			if len(v.Item) > maxl {
+				maxl = len(v.Item)
+			}
+		}
+
+		for _, v := range items {
+			fmt.Printf("%s", v.Item)
+
+			if len(v.Description) > 0 {
+				fmt.Printf("%s  # %s", strings.Repeat(" ", maxl-len(v.Item)), v.Description)
+			}
+
+			fmt.Printf("\n")
+		}
+	} else {
+		for _, v := range items {
+			fmt.Println(v.Item)
+		}
+	}
+}
