.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.1-0.20210319172145-bda8f5cee399 / cmd / getgo / path.go
1 // Copyright 2017 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 //go:build !plan9
6 // +build !plan9
7
8 package main
9
10 import (
11         "bufio"
12         "context"
13         "fmt"
14         "os"
15         "os/user"
16         "path/filepath"
17         "runtime"
18         "strings"
19 )
20
21 const (
22         bashConfig = ".bash_profile"
23         zshConfig  = ".zshrc"
24 )
25
26 // appendToPATH adds the given path to the PATH environment variable and
27 // persists it for future sessions.
28 func appendToPATH(value string) error {
29         if isInPATH(value) {
30                 return nil
31         }
32         return persistEnvVar("PATH", pathVar+envSeparator+value)
33 }
34
35 func isInPATH(dir string) bool {
36         p := os.Getenv("PATH")
37
38         paths := strings.Split(p, envSeparator)
39         for _, d := range paths {
40                 if d == dir {
41                         return true
42                 }
43         }
44
45         return false
46 }
47
48 func getHomeDir() (string, error) {
49         home := os.Getenv(homeKey)
50         if home != "" {
51                 return home, nil
52         }
53
54         u, err := user.Current()
55         if err != nil {
56                 return "", err
57         }
58         return u.HomeDir, nil
59 }
60
61 func checkStringExistsFile(filename, value string) (bool, error) {
62         file, err := os.OpenFile(filename, os.O_RDONLY, 0600)
63         if err != nil {
64                 if os.IsNotExist(err) {
65                         return false, nil
66                 }
67                 return false, err
68         }
69         defer file.Close()
70
71         scanner := bufio.NewScanner(file)
72         for scanner.Scan() {
73                 line := scanner.Text()
74                 if line == value {
75                         return true, nil
76                 }
77         }
78
79         return false, scanner.Err()
80 }
81
82 func appendToFile(filename, value string) error {
83         verbosef("Adding %q to %s", value, filename)
84
85         ok, err := checkStringExistsFile(filename, value)
86         if err != nil {
87                 return err
88         }
89         if ok {
90                 // Nothing to do.
91                 return nil
92         }
93
94         f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
95         if err != nil {
96                 return err
97         }
98         defer f.Close()
99
100         _, err = f.WriteString(lineEnding + value + lineEnding)
101         return err
102 }
103
104 func isShell(name string) bool {
105         return strings.Contains(currentShell(), name)
106 }
107
108 // persistEnvVarWindows sets an environment variable in the Windows
109 // registry.
110 func persistEnvVarWindows(name, value string) error {
111         _, err := runCommand(context.Background(), "powershell", "-command",
112                 fmt.Sprintf(`[Environment]::SetEnvironmentVariable("%s", "%s", "User")`, name, value))
113         return err
114 }
115
116 func persistEnvVar(name, value string) error {
117         if runtime.GOOS == "windows" {
118                 if err := persistEnvVarWindows(name, value); err != nil {
119                         return err
120                 }
121
122                 if isShell("cmd.exe") || isShell("powershell.exe") {
123                         return os.Setenv(strings.ToUpper(name), value)
124                 }
125                 // User is in bash, zsh, etc.
126                 // Also set the environment variable in their shell config.
127         }
128
129         rc, err := shellConfigFile()
130         if err != nil {
131                 return err
132         }
133
134         line := fmt.Sprintf("export %s=%s", strings.ToUpper(name), value)
135         if err := appendToFile(rc, line); err != nil {
136                 return err
137         }
138
139         return os.Setenv(strings.ToUpper(name), value)
140 }
141
142 func shellConfigFile() (string, error) {
143         home, err := getHomeDir()
144         if err != nil {
145                 return "", err
146         }
147
148         switch {
149         case isShell("bash"):
150                 return filepath.Join(home, bashConfig), nil
151         case isShell("zsh"):
152                 return filepath.Join(home, zshConfig), nil
153         default:
154                 return "", fmt.Errorf("%q is not a supported shell", currentShell())
155         }
156 }