diff options
| author | Eyal Posener <[email protected]> | 2019-11-14 06:51:44 +0200 |
|---|---|---|
| committer | Eyal Posener <[email protected]> | 2019-11-18 01:05:47 +0200 |
| commit | 8724aaf18312e54750540a9578e00d61b1c545d8 (patch) | |
| tree | d3e736b4fb279975bbcc017ae1bad53e454c5773 /internal/install/install.go | |
| parent | 05b68ffc813dd10c420993cb1cf927b346c057b8 (diff) | |
V2
Diffstat (limited to 'internal/install/install.go')
| -rw-r--r-- | internal/install/install.go | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/internal/install/install.go b/internal/install/install.go new file mode 100644 index 0000000..e4c5c0e --- /dev/null +++ b/internal/install/install.go @@ -0,0 +1,176 @@ +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 +} |
