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.
22 bashConfig = ".bash_profile"
26 // appendToPATH adds the given path to the PATH environment variable and
27 // persists it for future sessions.
28 func appendToPATH(value string) error {
32 return persistEnvVar("PATH", pathVar+envSeparator+value)
35 func isInPATH(dir string) bool {
36 p := os.Getenv("PATH")
38 paths := strings.Split(p, envSeparator)
39 for _, d := range paths {
48 func getHomeDir() (string, error) {
49 home := os.Getenv(homeKey)
54 u, err := user.Current()
61 func checkStringExistsFile(filename, value string) (bool, error) {
62 file, err := os.OpenFile(filename, os.O_RDONLY, 0600)
64 if os.IsNotExist(err) {
71 scanner := bufio.NewScanner(file)
73 line := scanner.Text()
79 return false, scanner.Err()
82 func appendToFile(filename, value string) error {
83 verbosef("Adding %q to %s", value, filename)
85 ok, err := checkStringExistsFile(filename, value)
94 f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
100 _, err = f.WriteString(lineEnding + value + lineEnding)
104 func isShell(name string) bool {
105 return strings.Contains(currentShell(), name)
108 // persistEnvVarWindows sets an environment variable in the Windows
110 func persistEnvVarWindows(name, value string) error {
111 _, err := runCommand(context.Background(), "powershell", "-command",
112 fmt.Sprintf(`[Environment]::SetEnvironmentVariable("%s", "%s", "User")`, name, value))
116 func persistEnvVar(name, value string) error {
117 if runtime.GOOS == "windows" {
118 if err := persistEnvVarWindows(name, value); err != nil {
122 if isShell("cmd.exe") || isShell("powershell.exe") {
123 return os.Setenv(strings.ToUpper(name), value)
125 // User is in bash, zsh, etc.
126 // Also set the environment variable in their shell config.
129 rc, err := shellConfigFile()
134 line := fmt.Sprintf("export %s=%s", strings.ToUpper(name), value)
135 if err := appendToFile(rc, line); err != nil {
139 return os.Setenv(strings.ToUpper(name), value)
142 func shellConfigFile() (string, error) {
143 home, err := getHomeDir()
149 case isShell("bash"):
150 return filepath.Join(home, bashConfig), nil
152 return filepath.Join(home, zshConfig), nil
154 return "", fmt.Errorf("%q is not a supported shell", currentShell())