aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/posener/complete/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/posener/complete/cmd')
-rw-r--r--vendor/github.com/posener/complete/cmd/cmd.go128
-rw-r--r--vendor/github.com/posener/complete/cmd/install/bash.go32
-rw-r--r--vendor/github.com/posener/complete/cmd/install/install.go92
-rw-r--r--vendor/github.com/posener/complete/cmd/install/utils.go118
-rw-r--r--vendor/github.com/posener/complete/cmd/install/zsh.go39
5 files changed, 409 insertions, 0 deletions
diff --git a/vendor/github.com/posener/complete/cmd/cmd.go b/vendor/github.com/posener/complete/cmd/cmd.go
new file mode 100644
index 0000000..7137dee
--- /dev/null
+++ b/vendor/github.com/posener/complete/cmd/cmd.go
@@ -0,0 +1,128 @@
1// Package cmd used for command line options for the complete tool
2package cmd
3
4import (
5 "errors"
6 "flag"
7 "fmt"
8 "os"
9 "strings"
10
11 "github.com/posener/complete/cmd/install"
12)
13
14// CLI for command line
15type CLI struct {
16 Name string
17 InstallName string
18 UninstallName string
19
20 install bool
21 uninstall bool
22 yes bool
23}
24
25const (
26 defaultInstallName = "install"
27 defaultUninstallName = "uninstall"
28)
29
30// Run is used when running complete in command line mode.
31// this is used when the complete is not completing words, but to
32// install it or uninstall it.
33func (f *CLI) Run() bool {
34 err := f.validate()
35 if err != nil {
36 os.Stderr.WriteString(err.Error() + "\n")
37 os.Exit(1)
38 }
39
40 switch {
41 case f.install:
42 f.prompt()
43 err = install.Install(f.Name)
44 case f.uninstall:
45 f.prompt()
46 err = install.Uninstall(f.Name)
47 default:
48 // non of the action flags matched,
49 // returning false should make the real program execute
50 return false
51 }
52
53 if err != nil {
54 fmt.Printf("%s failed! %s\n", f.action(), err)
55 os.Exit(3)
56 }
57 fmt.Println("Done!")
58 return true
59}
60
61// prompt use for approval
62// exit if approval was not given
63func (f *CLI) prompt() {
64 defer fmt.Println(f.action() + "ing...")
65 if f.yes {
66 return
67 }
68 fmt.Printf("%s completion for %s? ", f.action(), f.Name)
69 var answer string
70 fmt.Scanln(&answer)
71
72 switch strings.ToLower(answer) {
73 case "y", "yes":
74 return
75 default:
76 fmt.Println("Cancelling...")
77 os.Exit(1)
78 }
79}
80
81// AddFlags adds the CLI flags to the flag set.
82// If flags is nil, the default command line flags will be taken.
83// Pass non-empty strings as installName and uninstallName to override the default
84// flag names.
85func (f *CLI) AddFlags(flags *flag.FlagSet) {
86 if flags == nil {
87 flags = flag.CommandLine
88 }
89
90 if f.InstallName == "" {
91 f.InstallName = defaultInstallName
92 }
93 if f.UninstallName == "" {
94 f.UninstallName = defaultUninstallName
95 }
96
97 if flags.Lookup(f.InstallName) == nil {
98 flags.BoolVar(&f.install, f.InstallName, false,
99 fmt.Sprintf("Install completion for %s command", f.Name))
100 }
101 if flags.Lookup(f.UninstallName) == nil {
102 flags.BoolVar(&f.uninstall, f.UninstallName, false,
103 fmt.Sprintf("Uninstall completion for %s command", f.Name))
104 }
105 if flags.Lookup("y") == nil {
106 flags.BoolVar(&f.yes, "y", false, "Don't prompt user for typing 'yes'")
107 }
108}
109
110// validate the CLI
111func (f *CLI) validate() error {
112 if f.install && f.uninstall {
113 return errors.New("Install and uninstall are mutually exclusive")
114 }
115 return nil
116}
117
118// action name according to the CLI values.
119func (f *CLI) action() string {
120 switch {
121 case f.install:
122 return "Install"
123 case f.uninstall:
124 return "Uninstall"
125 default:
126 return "unknown"
127 }
128}
diff --git a/vendor/github.com/posener/complete/cmd/install/bash.go b/vendor/github.com/posener/complete/cmd/install/bash.go
new file mode 100644
index 0000000..a287f99
--- /dev/null
+++ b/vendor/github.com/posener/complete/cmd/install/bash.go
@@ -0,0 +1,32 @@
1package install
2
3import "fmt"
4
5// (un)install in bash
6// basically adds/remove from .bashrc:
7//
8// complete -C </path/to/completion/command> <command>
9type bash struct {
10 rc string
11}
12
13func (b bash) Install(cmd, bin string) error {
14 completeCmd := b.cmd(cmd, bin)
15 if lineInFile(b.rc, completeCmd) {
16 return fmt.Errorf("already installed in %s", b.rc)
17 }
18 return appendToFile(b.rc, completeCmd)
19}
20
21func (b bash) Uninstall(cmd, bin string) error {
22 completeCmd := b.cmd(cmd, bin)
23 if !lineInFile(b.rc, completeCmd) {
24 return fmt.Errorf("does not installed in %s", b.rc)
25 }
26
27 return removeFromFile(b.rc, completeCmd)
28}
29
30func (bash) cmd(cmd, bin string) string {
31 return fmt.Sprintf("complete -C %s %s", bin, cmd)
32}
diff --git a/vendor/github.com/posener/complete/cmd/install/install.go b/vendor/github.com/posener/complete/cmd/install/install.go
new file mode 100644
index 0000000..082a226
--- /dev/null
+++ b/vendor/github.com/posener/complete/cmd/install/install.go
@@ -0,0 +1,92 @@
1package install
2
3import (
4 "errors"
5 "os"
6 "os/user"
7 "path/filepath"
8
9 "github.com/hashicorp/go-multierror"
10)
11
12type installer interface {
13 Install(cmd, bin string) error
14 Uninstall(cmd, bin string) error
15}
16
17// Install complete command given:
18// cmd: is the command name
19func Install(cmd string) error {
20 is := installers()
21 if len(is) == 0 {
22 return errors.New("Did not find any shells to install")
23 }
24 bin, err := getBinaryPath()
25 if err != nil {
26 return err
27 }
28
29 for _, i := range is {
30 errI := i.Install(cmd, bin)
31 if errI != nil {
32 err = multierror.Append(err, errI)
33 }
34 }
35
36 return err
37}
38
39// Uninstall complete command given:
40// cmd: is the command name
41func Uninstall(cmd string) error {
42 is := installers()
43 if len(is) == 0 {
44 return errors.New("Did not find any shells to uninstall")
45 }
46 bin, err := getBinaryPath()
47 if err != nil {
48 return err
49 }
50
51 for _, i := range is {
52 errI := i.Uninstall(cmd, bin)
53 if errI != nil {
54 multierror.Append(err, errI)
55 }
56 }
57
58 return err
59}
60
61func installers() (i []installer) {
62 for _, rc := range [...]string{".bashrc", ".bash_profile", ".bash_login", ".profile"} {
63 if f := rcFile(rc); f != "" {
64 i = append(i, bash{f})
65 break
66 }
67 }
68 if f := rcFile(".zshrc"); f != "" {
69 i = append(i, zsh{f})
70 }
71 return
72}
73
74func getBinaryPath() (string, error) {
75 bin, err := os.Executable()
76 if err != nil {
77 return "", err
78 }
79 return filepath.Abs(bin)
80}
81
82func rcFile(name string) string {
83 u, err := user.Current()
84 if err != nil {
85 return ""
86 }
87 path := filepath.Join(u.HomeDir, name)
88 if _, err := os.Stat(path); err != nil {
89 return ""
90 }
91 return path
92}
diff --git a/vendor/github.com/posener/complete/cmd/install/utils.go b/vendor/github.com/posener/complete/cmd/install/utils.go
new file mode 100644
index 0000000..2c8b44c
--- /dev/null
+++ b/vendor/github.com/posener/complete/cmd/install/utils.go
@@ -0,0 +1,118 @@
1package install
2
3import (
4 "bufio"
5 "fmt"
6 "io"
7 "io/ioutil"
8 "os"
9)
10
11func lineInFile(name string, lookFor string) bool {
12 f, err := os.Open(name)
13 if err != nil {
14 return false
15 }
16 defer f.Close()
17 r := bufio.NewReader(f)
18 prefix := []byte{}
19 for {
20 line, isPrefix, err := r.ReadLine()
21 if err == io.EOF {
22 return false
23 }
24 if err != nil {
25 return false
26 }
27 if isPrefix {
28 prefix = append(prefix, line...)
29 continue
30 }
31 line = append(prefix, line...)
32 if string(line) == lookFor {
33 return true
34 }
35 prefix = prefix[:0]
36 }
37}
38
39func appendToFile(name string, content string) error {
40 f, err := os.OpenFile(name, os.O_RDWR|os.O_APPEND, 0)
41 if err != nil {
42 return err
43 }
44 defer f.Close()
45 _, err = f.WriteString(fmt.Sprintf("\n%s\n", content))
46 return err
47}
48
49func removeFromFile(name string, content string) error {
50 backup := name + ".bck"
51 err := copyFile(name, backup)
52 if err != nil {
53 return err
54 }
55 temp, err := removeContentToTempFile(name, content)
56 if err != nil {
57 return err
58 }
59
60 err = copyFile(temp, name)
61 if err != nil {
62 return err
63 }
64
65 return os.Remove(backup)
66}
67
68func removeContentToTempFile(name, content string) (string, error) {
69 rf, err := os.Open(name)
70 if err != nil {
71 return "", err
72 }
73 defer rf.Close()
74 wf, err := ioutil.TempFile("/tmp", "complete-")
75 if err != nil {
76 return "", err
77 }
78 defer wf.Close()
79
80 r := bufio.NewReader(rf)
81 prefix := []byte{}
82 for {
83 line, isPrefix, err := r.ReadLine()
84 if err == io.EOF {
85 break
86 }
87 if err != nil {
88 return "", err
89 }
90 if isPrefix {
91 prefix = append(prefix, line...)
92 continue
93 }
94 line = append(prefix, line...)
95 str := string(line)
96 if str == content {
97 continue
98 }
99 wf.WriteString(str + "\n")
100 prefix = prefix[:0]
101 }
102 return wf.Name(), nil
103}
104
105func copyFile(src string, dst string) error {
106 in, err := os.Open(src)
107 if err != nil {
108 return err
109 }
110 defer in.Close()
111 out, err := os.Create(dst)
112 if err != nil {
113 return err
114 }
115 defer out.Close()
116 _, err = io.Copy(out, in)
117 return err
118}
diff --git a/vendor/github.com/posener/complete/cmd/install/zsh.go b/vendor/github.com/posener/complete/cmd/install/zsh.go
new file mode 100644
index 0000000..a625f53
--- /dev/null
+++ b/vendor/github.com/posener/complete/cmd/install/zsh.go
@@ -0,0 +1,39 @@
1package install
2
3import "fmt"
4
5// (un)install in zsh
6// basically adds/remove from .zshrc:
7//
8// autoload -U +X bashcompinit && bashcompinit"
9// complete -C </path/to/completion/command> <command>
10type zsh struct {
11 rc string
12}
13
14func (z zsh) Install(cmd, bin string) error {
15 completeCmd := z.cmd(cmd, bin)
16 if lineInFile(z.rc, completeCmd) {
17 return fmt.Errorf("already installed in %s", z.rc)
18 }
19
20 bashCompInit := "autoload -U +X bashcompinit && bashcompinit"
21 if !lineInFile(z.rc, bashCompInit) {
22 completeCmd = bashCompInit + "\n" + completeCmd
23 }
24
25 return appendToFile(z.rc, completeCmd)
26}
27
28func (z zsh) Uninstall(cmd, bin string) error {
29 completeCmd := z.cmd(cmd, bin)
30 if !lineInFile(z.rc, completeCmd) {
31 return fmt.Errorf("does not installed in %s", z.rc)
32 }
33
34 return removeFromFile(z.rc, completeCmd)
35}
36
37func (zsh) cmd(cmd, bin string) string {
38 return fmt.Sprintf("complete -o nospace -C %s %s", bin, cmd)
39}