95 lines
2.6 KiB
Go
95 lines
2.6 KiB
Go
// Package winpath is useful for managing PATH as part of the Environment
|
|
// in the Windows HKey Local User registry. It returns an error for most
|
|
// operations on non-Windows systems.
|
|
package winpath
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
// ErrWrongPlatform indicates that this was not built for Windows
|
|
var ErrWrongPlatform = fmt.Errorf("method not implemented on this platform")
|
|
|
|
// sendmsg uses a syscall to broadcast the registry change so that
|
|
// new shells will get the new PATH immediately, without a reboot
|
|
var sendmsg func()
|
|
|
|
// Paths returns all PATHs according to the Windows HKLU registry
|
|
// (or nil on non-windows platforms)
|
|
func Paths() ([]string, error) {
|
|
return paths()
|
|
}
|
|
|
|
// Add will rewrite the Windows registry HKLU Environment,
|
|
// prepending the given directory path to the user's PATH.
|
|
// It will return whether the PATH was modified and an
|
|
// error if it should have been modified, but wasn't.
|
|
func Add(p string) (bool, error) {
|
|
return add(p)
|
|
}
|
|
|
|
// Remove will rewrite the Windows registry HKLU Environment
|
|
// without the given directory path.
|
|
// It will return whether the PATH was modified and an
|
|
// error if it should have been modified, but wasn't.
|
|
func Remove(p string) (bool, error) {
|
|
return remove(p)
|
|
}
|
|
|
|
// NormalizePathEntry will return the given directory path relative
|
|
// from its absolute path to the %USERPROFILE% (home) directory.
|
|
func NormalizePathEntry(pathentry string) (string, string) {
|
|
home, err := os.UserHomeDir()
|
|
if nil != err {
|
|
fmt.Fprintf(os.Stderr, "Couldn't get HOME directory. That's an unrecoverable hard fail.")
|
|
panic(err)
|
|
}
|
|
|
|
sep := string(os.PathSeparator)
|
|
absentry, _ := filepath.Abs(pathentry)
|
|
home, _ = filepath.Abs(home)
|
|
|
|
var homeentry string
|
|
if strings.HasPrefix(strings.ToLower(absentry)+sep, strings.ToLower(home)+sep) {
|
|
// %USERPROFILE% is allowed, but only for user PATH
|
|
// https://superuser.com/a/442163/73857
|
|
homeentry = `%USERPROFILE%` + absentry[len(home):]
|
|
}
|
|
|
|
if absentry == pathentry {
|
|
absentry = ""
|
|
}
|
|
if homeentry == pathentry {
|
|
homeentry = ""
|
|
}
|
|
|
|
return absentry, homeentry
|
|
}
|
|
|
|
// IndexOf searches the given path list for first occurence
|
|
// of the given path entry and returns the index, or -1
|
|
func IndexOf(paths []string, p string) int {
|
|
abspath, homepath := NormalizePathEntry(p)
|
|
|
|
index := -1
|
|
for i := range paths {
|
|
if strings.ToLower(p) == strings.ToLower(paths[i]) {
|
|
index = i
|
|
break
|
|
}
|
|
if strings.ToLower(abspath) == strings.ToLower(paths[i]) {
|
|
index = i
|
|
break
|
|
}
|
|
if strings.ToLower(homepath) == strings.ToLower(paths[i]) {
|
|
index = i
|
|
break
|
|
}
|
|
}
|
|
|
|
return index
|
|
}
|