summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEyal Posener <[email protected]>2019-11-19 05:16:51 +0200
committerEyal Posener <[email protected]>2019-11-19 05:17:52 +0200
commitc3bfbddfe6b4d133259ee84a9f0f93a7d1b0971e (patch)
treed19ec98986d382d17f040787fb9f851b0b97b6fd
parentca6cedb61484d2a211c105900f663e355b13626a (diff)
Move install package back to project root
-rw-r--r--complete.go2
-rw-r--r--go.sum1
-rw-r--r--internal/arg/arg.go6
-rw-r--r--internal/install/bash.go37
-rw-r--r--internal/install/fish.go69
-rw-r--r--internal/install/install.go176
-rw-r--r--internal/install/utils.go140
-rw-r--r--internal/install/zsh.go44
8 files changed, 6 insertions, 469 deletions
diff --git a/complete.go b/complete.go
index f64abd8..b649ee4 100644
--- a/complete.go
+++ b/complete.go
@@ -7,8 +7,8 @@ import (
"strconv"
"strings"
+ "github.com/posener/complete/v2/install"
"github.com/posener/complete/v2/internal/arg"
- "github.com/posener/complete/v2/internal/install"
"github.com/posener/complete/v2/internal/tokener"
)
diff --git a/go.sum b/go.sum
index 907c6ce..d8739d5 100644
--- a/go.sum
+++ b/go.sum
@@ -8,6 +8,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.2.2 h1:xu2vuFugxm4IfAymbmmVrnEVy29eGUDn8I7HheRseHg=
github.com/posener/complete v1.2.2/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
+github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
diff --git a/internal/arg/arg.go b/internal/arg/arg.go
index f28e4b3..477cb0e 100644
--- a/internal/arg/arg.go
+++ b/internal/arg/arg.go
@@ -1,8 +1,10 @@
package arg
-import "strings"
+import (
+ "strings"
-import "github.com/posener/complete/v2/internal/tokener"
+ "github.com/posener/complete/v2/internal/tokener"
+)
// Arg is typed a command line argument.
type Arg struct {
diff --git a/internal/install/bash.go b/internal/install/bash.go
deleted file mode 100644
index 17c64de..0000000
--- a/internal/install/bash.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package install
-
-import "fmt"
-
-// (un)install in bash
-// basically adds/remove from .bashrc:
-//
-// complete -C </path/to/completion/command> <command>
-type bash struct {
- rc string
-}
-
-func (b bash) IsInstalled(cmd, bin string) bool {
- completeCmd := b.cmd(cmd, bin)
- return lineInFile(b.rc, completeCmd)
-}
-
-func (b bash) Install(cmd, bin string) error {
- if b.IsInstalled(cmd, bin) {
- return fmt.Errorf("already installed in %s", b.rc)
- }
- completeCmd := b.cmd(cmd, bin)
- return appendToFile(b.rc, completeCmd)
-}
-
-func (b bash) Uninstall(cmd, bin string) error {
- if !b.IsInstalled(cmd, bin) {
- return fmt.Errorf("does not installed in %s", b.rc)
- }
-
- completeCmd := b.cmd(cmd, bin)
- return removeFromFile(b.rc, completeCmd)
-}
-
-func (bash) cmd(cmd, bin string) string {
- return fmt.Sprintf("complete -C %s %s", bin, cmd)
-}
diff --git a/internal/install/fish.go b/internal/install/fish.go
deleted file mode 100644
index 2b64bfc..0000000
--- a/internal/install/fish.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package install
-
-import (
- "bytes"
- "fmt"
- "os"
- "path/filepath"
- "text/template"
-)
-
-// (un)install in fish
-
-type fish struct {
- configDir string
-}
-
-func (f fish) IsInstalled(cmd, bin string) bool {
- completionFile := f.getCompletionFilePath(cmd)
- if _, err := os.Stat(completionFile); err == nil {
- return true
- }
- return false
-}
-
-func (f fish) Install(cmd, bin string) error {
- if f.IsInstalled(cmd, bin) {
- return fmt.Errorf("already installed at %s", f.getCompletionFilePath(cmd))
- }
-
- completionFile := f.getCompletionFilePath(cmd)
- completeCmd, err := f.cmd(cmd, bin)
- if err != nil {
- return err
- }
-
- return createFile(completionFile, completeCmd)
-}
-
-func (f fish) Uninstall(cmd, bin string) error {
- if !f.IsInstalled(cmd, bin) {
- return fmt.Errorf("does not installed in %s", f.configDir)
- }
-
- completionFile := f.getCompletionFilePath(cmd)
- return os.Remove(completionFile)
-}
-
-func (f fish) getCompletionFilePath(cmd string) string {
- return filepath.Join(f.configDir, "completions", fmt.Sprintf("%s.fish", cmd))
-}
-
-func (f fish) cmd(cmd, bin string) (string, error) {
- var buf bytes.Buffer
- params := struct{ Cmd, Bin string }{cmd, bin}
- tmpl := template.Must(template.New("cmd").Parse(`
-function __complete_{{.Cmd}}
- set -lx COMP_LINE (commandline -cp)
- test -z (commandline -ct)
- and set COMP_LINE "$COMP_LINE "
- {{.Bin}}
-end
-complete -f -c {{.Cmd}} -a "(__complete_{{.Cmd}})"
-`))
- err := tmpl.Execute(&buf, params)
- if err != nil {
- return "", err
- }
- return buf.String(), nil
-}
diff --git a/internal/install/install.go b/internal/install/install.go
deleted file mode 100644
index e4c5c0e..0000000
--- a/internal/install/install.go
+++ /dev/null
@@ -1,176 +0,0 @@
-package install
-
-import (
- "errors"
- "fmt"
- "io"
- "os"
- "os/user"
- "path/filepath"
- "runtime"
- "strings"
-
- "github.com/hashicorp/go-multierror"
-)
-
-func Run(name string, uninstall, yes bool, out io.Writer, in io.Reader) {
- action := "install"
- if uninstall {
- action = "uninstall"
- }
- if !yes {
- fmt.Fprintf(out, "%s completion for %s? ", action, name)
- var answer string
- fmt.Fscanln(in, &answer)
- switch strings.ToLower(answer) {
- case "y", "yes":
- default:
- fmt.Fprintf(out, "Cancelling...")
- return
- }
- }
- fmt.Fprintf(out, action+"ing...")
-
- if uninstall {
- Uninstall(name)
- } else {
- Install(name)
- }
-}
-
-type installer interface {
- IsInstalled(cmd, bin string) bool
- Install(cmd, bin string) error
- Uninstall(cmd, bin string) error
-}
-
-// Install complete command given:
-// cmd: is the command name
-func Install(cmd string) error {
- is := installers()
- if len(is) == 0 {
- return errors.New("Did not find any shells to install")
- }
- bin, err := getBinaryPath()
- if err != nil {
- return err
- }
-
- for _, i := range is {
- errI := i.Install(cmd, bin)
- if errI != nil {
- err = multierror.Append(err, errI)
- }
- }
-
- return err
-}
-
-// IsInstalled returns true if the completion
-// for the given cmd is installed.
-func IsInstalled(cmd string) bool {
- bin, err := getBinaryPath()
- if err != nil {
- return false
- }
-
- for _, i := range installers() {
- installed := i.IsInstalled(cmd, bin)
- if installed {
- return true
- }
- }
-
- return false
-}
-
-// Uninstall complete command given:
-// cmd: is the command name
-func Uninstall(cmd string) error {
- is := installers()
- if len(is) == 0 {
- return errors.New("Did not find any shells to uninstall")
- }
- bin, err := getBinaryPath()
- if err != nil {
- return err
- }
-
- for _, i := range is {
- errI := i.Uninstall(cmd, bin)
- if errI != nil {
- err = multierror.Append(err, errI)
- }
- }
-
- return err
-}
-
-func installers() (i []installer) {
- // The list of bash config files candidates where it is
- // possible to install the completion command.
- var bashConfFiles []string
- switch runtime.GOOS {
- case "darwin":
- bashConfFiles = []string{".bash_profile"}
- default:
- bashConfFiles = []string{".bashrc", ".bash_profile", ".bash_login", ".profile"}
- }
- for _, rc := range bashConfFiles {
- if f := rcFile(rc); f != "" {
- i = append(i, bash{f})
- break
- }
- }
- if f := rcFile(".zshrc"); f != "" {
- i = append(i, zsh{f})
- }
- if d := fishConfigDir(); d != "" {
- i = append(i, fish{d})
- }
- return
-}
-
-func fishConfigDir() string {
- configDir := filepath.Join(getConfigHomePath(), "fish")
- if configDir == "" {
- return ""
- }
- if info, err := os.Stat(configDir); err != nil || !info.IsDir() {
- return ""
- }
- return configDir
-}
-
-func getConfigHomePath() string {
- u, err := user.Current()
- if err != nil {
- return ""
- }
-
- configHome := os.Getenv("XDG_CONFIG_HOME")
- if configHome == "" {
- return filepath.Join(u.HomeDir, ".config")
- }
- return configHome
-}
-
-func getBinaryPath() (string, error) {
- bin, err := os.Executable()
- if err != nil {
- return "", err
- }
- return filepath.Abs(bin)
-}
-
-func rcFile(name string) string {
- u, err := user.Current()
- if err != nil {
- return ""
- }
- path := filepath.Join(u.HomeDir, name)
- if _, err := os.Stat(path); err != nil {
- return ""
- }
- return path
-}
diff --git a/internal/install/utils.go b/internal/install/utils.go
deleted file mode 100644
index d34ac8c..0000000
--- a/internal/install/utils.go
+++ /dev/null
@@ -1,140 +0,0 @@
-package install
-
-import (
- "bufio"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
-)
-
-func lineInFile(name string, lookFor string) bool {
- f, err := os.Open(name)
- if err != nil {
- return false
- }
- defer f.Close()
- r := bufio.NewReader(f)
- prefix := []byte{}
- for {
- line, isPrefix, err := r.ReadLine()
- if err == io.EOF {
- return false
- }
- if err != nil {
- return false
- }
- if isPrefix {
- prefix = append(prefix, line...)
- continue
- }
- line = append(prefix, line...)
- if string(line) == lookFor {
- return true
- }
- prefix = prefix[:0]
- }
-}
-
-func createFile(name string, content string) error {
- // make sure file directory exists
- if err := os.MkdirAll(filepath.Dir(name), 0775); err != nil {
- return err
- }
-
- // create the file
- f, err := os.Create(name)
- if err != nil {
- return err
- }
- defer f.Close()
-
- // write file content
- _, err = f.WriteString(fmt.Sprintf("%s\n", content))
- return err
-}
-
-func appendToFile(name string, content string) error {
- f, err := os.OpenFile(name, os.O_RDWR|os.O_APPEND, 0)
- if err != nil {
- return err
- }
- defer f.Close()
- _, err = f.WriteString(fmt.Sprintf("\n%s\n", content))
- return err
-}
-
-func removeFromFile(name string, content string) error {
- backup := name + ".bck"
- err := copyFile(name, backup)
- if err != nil {
- return err
- }
- temp, err := removeContentToTempFile(name, content)
- if err != nil {
- return err
- }
-
- err = copyFile(temp, name)
- if err != nil {
- return err
- }
-
- return os.Remove(backup)
-}
-
-func removeContentToTempFile(name, content string) (string, error) {
- rf, err := os.Open(name)
- if err != nil {
- return "", err
- }
- defer rf.Close()
- wf, err := ioutil.TempFile("/tmp", "complete-")
- if err != nil {
- return "", err
- }
- defer wf.Close()
-
- r := bufio.NewReader(rf)
- prefix := []byte{}
- for {
- line, isPrefix, err := r.ReadLine()
- if err == io.EOF {
- break
- }
- if err != nil {
- return "", err
- }
- if isPrefix {
- prefix = append(prefix, line...)
- continue
- }
- line = append(prefix, line...)
- str := string(line)
- if str == content {
- continue
- }
- _, err = wf.WriteString(str + "\n")
- if err != nil {
- return "", err
- }
- prefix = prefix[:0]
- }
- return wf.Name(), nil
-}
-
-func copyFile(src string, dst string) error {
- in, err := os.Open(src)
- if err != nil {
- return err
- }
- defer in.Close()
- out, err := os.Create(dst)
- if err != nil {
- return err
- }
- defer out.Close()
- _, err = io.Copy(out, in)
- return err
-}
diff --git a/internal/install/zsh.go b/internal/install/zsh.go
deleted file mode 100644
index 29950ab..0000000
--- a/internal/install/zsh.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package install
-
-import "fmt"
-
-// (un)install in zsh
-// basically adds/remove from .zshrc:
-//
-// autoload -U +X bashcompinit && bashcompinit"
-// complete -C </path/to/completion/command> <command>
-type zsh struct {
- rc string
-}
-
-func (z zsh) IsInstalled(cmd, bin string) bool {
- completeCmd := z.cmd(cmd, bin)
- return lineInFile(z.rc, completeCmd)
-}
-
-func (z zsh) Install(cmd, bin string) error {
- if z.IsInstalled(cmd, bin) {
- return fmt.Errorf("already installed in %s", z.rc)
- }
-
- completeCmd := z.cmd(cmd, bin)
- bashCompInit := "autoload -U +X bashcompinit && bashcompinit"
- if !lineInFile(z.rc, bashCompInit) {
- completeCmd = bashCompInit + "\n" + completeCmd
- }
-
- return appendToFile(z.rc, completeCmd)
-}
-
-func (z zsh) Uninstall(cmd, bin string) error {
- if !z.IsInstalled(cmd, bin) {
- return fmt.Errorf("does not installed in %s", z.rc)
- }
-
- completeCmd := z.cmd(cmd, bin)
- return removeFromFile(z.rc, completeCmd)
-}
-
-func (zsh) cmd(cmd, bin string) string {
- return fmt.Sprintf("complete -o nospace -C %s %s", bin, cmd)
-}