diff options
| author | Eyal Posener <[email protected]> | 2017-05-08 07:32:13 +0300 |
|---|---|---|
| committer | Eyal Posener <[email protected]> | 2017-05-08 07:32:13 +0300 |
| commit | 5db452a63f1b8ff0319f08986a4a04324647738f (patch) | |
| tree | adcd52253a99c5faf7817a6d2e415430f121d9c7 /cmd/install/bash.go | |
| parent | b2791b736089134d6914c4d4362fbcdeadf1cdab (diff) | |
Install fixups
- remove root installation
- install according to shell type
Closes #7
Diffstat (limited to 'cmd/install/bash.go')
| -rw-r--r-- | cmd/install/bash.go | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/cmd/install/bash.go b/cmd/install/bash.go new file mode 100644 index 0000000..c8bff49 --- /dev/null +++ b/cmd/install/bash.go @@ -0,0 +1,153 @@ +package install + +import ( + "bufio" + "errors" + "fmt" + "io" + "io/ioutil" + "os" + "os/user" + "path/filepath" +) + +type bash struct{} + +func (bash) Install(cmd, bin string) error { + bashRCFileName, err := bashRCFileName() + if err != nil { + return err + } + completeCmd := completeCmd(cmd, bin) + if isInFile(bashRCFileName, completeCmd) { + return errors.New("Already installed in ~/.bashrc") + } + + bashRC, err := os.OpenFile(bashRCFileName, os.O_RDWR|os.O_APPEND, 0) + if err != nil { + return err + } + defer bashRC.Close() + _, err = bashRC.WriteString(fmt.Sprintf("\n%s\n", completeCmd)) + return err +} + +func (bash) Uninstall(cmd, bin string) error { + bashRC, err := bashRCFileName() + if err != nil { + return err + } + backup := bashRC + ".bck" + err = copyFile(bashRC, backup) + if err != nil { + return err + } + completeCmd := completeCmd(cmd, bin) + if !isInFile(bashRC, completeCmd) { + return errors.New("Does not installed in ~/.bashrc") + } + temp, err := uninstallToTemp(bashRC, completeCmd) + if err != nil { + return err + } + + err = copyFile(temp, bashRC) + if err != nil { + return err + } + + return os.Remove(backup) + +} + +func completeCmd(cmd, bin string) string { + return fmt.Sprintf("complete -C %s %s", bin, cmd) +} + +func bashRCFileName() (string, error) { + u, err := user.Current() + if err != nil { + return "", err + } + return filepath.Join(u.HomeDir, ".bashrc"), nil +} + +func isInFile(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 uninstallToTemp(bashRCFileName, completeCmd string) (string, error) { + rf, err := os.Open(bashRCFileName) + if err != nil { + return "", err + } + defer rf.Close() + wf, err := ioutil.TempFile("/tmp", "bashrc-") + 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 == completeCmd { + continue + } + wf.WriteString(str + "\n") + 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 +} |
