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 err = 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 if d := fishConfigDir(); d != "" { 72 i = append(i, fish{d}) 73 } 74 return 75} 76 77func fishConfigDir() string { 78 configDir := filepath.Join(getConfigHomePath(), "fish") 79 if configDir == "" { 80 return "" 81 } 82 if info, err := os.Stat(configDir); err != nil || !info.IsDir() { 83 return "" 84 } 85 return configDir 86} 87 88func getConfigHomePath() string { 89 u, err := user.Current() 90 if err != nil { 91 return "" 92 } 93 94 configHome := os.Getenv("XDG_CONFIG_HOME") 95 if configHome == "" { 96 return filepath.Join(u.HomeDir, ".config") 97 } 98 return configHome 99} 100 101func getBinaryPath() (string, error) { 102 bin, err := os.Executable() 103 if err != nil { 104 return "", err 105 } 106 return filepath.Abs(bin) 107} 108 109func rcFile(name string) string { 110 u, err := user.Current() 111 if err != nil { 112 return "" 113 } 114 path := filepath.Join(u.HomeDir, name) 115 if _, err := os.Stat(path); err != nil { 116 return "" 117 } 118 return path 119} 120