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