pathman/winpath/winpath.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
}