bugfixes for windows and git bash
This commit is contained in:
parent
e2b9cef690
commit
964972846a
|
@ -6,6 +6,8 @@ Manage PATH on Windows, Mac, and Linux with various Shells
|
||||||
pathman list
|
pathman list
|
||||||
pathman add ~/.local/bin
|
pathman add ~/.local/bin
|
||||||
pathman remove ~/.local/bin
|
pathman remove ~/.local/bin
|
||||||
|
pathman version
|
||||||
|
pathman help
|
||||||
```
|
```
|
||||||
|
|
||||||
Windows: stores PATH in the registry.
|
Windows: stores PATH in the registry.
|
||||||
|
@ -109,7 +111,7 @@ curl https://rootprojects.org/pathman/dist/linux/armv5/pathman -o pathman
|
||||||
```
|
```
|
||||||
mkdir %userprofile%\bin
|
mkdir %userprofile%\bin
|
||||||
move pathman.exe %userprofile%\bin\pathman.exe
|
move pathman.exe %userprofile%\bin\pathman.exe
|
||||||
%userprofile%\bin\pathman.exe ~\bin
|
%userprofile%\bin\pathman.exe add ~\bin
|
||||||
```
|
```
|
||||||
|
|
||||||
**All Others**
|
**All Others**
|
||||||
|
|
|
@ -69,10 +69,11 @@ func initializeShells(home string) error {
|
||||||
|
|
||||||
var hasRC bool
|
var hasRC bool
|
||||||
var nativeMatch *envConfig
|
var nativeMatch *envConfig
|
||||||
|
shell := strings.TrimSuffix(filepath.Base(os.Getenv("SHELL")), ".exe")
|
||||||
for i := range confs {
|
for i := range confs {
|
||||||
c := confs[i]
|
c := confs[i]
|
||||||
|
|
||||||
if filepath.Base(os.Getenv("SHELL")) == c.shell {
|
if shell == c.shell {
|
||||||
nativeMatch = c
|
nativeMatch = c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +104,7 @@ func initializeShells(home string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MacOS is special. It *requires* .bash_profile in order to read .bashrc
|
// MacOS is special. It *requires* .bash_profile in order to read .bashrc
|
||||||
if "darwin" == runtime.GOOS && "bash" == os.Getenv("SHELL") {
|
if "darwin" == runtime.GOOS && "bash" == shell {
|
||||||
if err := ensureBashProfile(home); nil != err {
|
if err := ensureBashProfile(home); nil != err {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
68
pathman.go
68
pathman.go
|
@ -46,36 +46,10 @@ func main() {
|
||||||
entry = os.Args[2]
|
entry = os.Args[2]
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://superuser.com/a/69190/73857
|
|
||||||
// https://github.com/rust-lang-nursery/rustup.rs/issues/686#issuecomment-253982841
|
|
||||||
// exec source $HOME/.profile
|
|
||||||
shell := os.Getenv("SHELL")
|
|
||||||
shell = filepath.Base(shell)
|
|
||||||
switch shell {
|
|
||||||
case "":
|
|
||||||
if strings.HasSuffix(os.Getenv("COMSPEC"), "/cmd.exe") {
|
|
||||||
shell = "cmd"
|
|
||||||
}
|
|
||||||
case "fish":
|
|
||||||
// ignore
|
|
||||||
case "zsh":
|
|
||||||
// ignore
|
|
||||||
case "bash":
|
|
||||||
// ignore
|
|
||||||
default:
|
|
||||||
// warn and try anyway
|
|
||||||
fmt.Fprintf(
|
|
||||||
os.Stderr,
|
|
||||||
"%q isn't a recognized shell. Please open an issue at https://git.rootprojects.org/root/pathman/issues?q=%s",
|
|
||||||
shell,
|
|
||||||
shell,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
home, _ := os.UserHomeDir()
|
home, _ := os.UserHomeDir()
|
||||||
if "" != entry && '~' == entry[0] {
|
if "" != entry && '~' == entry[0] {
|
||||||
// Let windows users not to have to type %USERPROFILE% or \Users\me every time
|
// Let windows users not to have to type %USERPROFILE% or \Users\me every time
|
||||||
entry = strings.Replace(entry, "~", home, 0)
|
entry = strings.Replace(entry, "~", home, 1)
|
||||||
}
|
}
|
||||||
switch action {
|
switch action {
|
||||||
default:
|
default:
|
||||||
|
@ -92,8 +66,10 @@ func main() {
|
||||||
}
|
}
|
||||||
list()
|
list()
|
||||||
case "add":
|
case "add":
|
||||||
|
checkShell()
|
||||||
add(entry)
|
add(entry)
|
||||||
case "remove":
|
case "remove":
|
||||||
|
checkShell()
|
||||||
remove(entry)
|
remove(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,7 +133,7 @@ func add(entry string) {
|
||||||
|
|
||||||
modified, err := addPath(entry)
|
modified, err := addPath(entry)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
fmt.Fprintf(os.Stderr, "failed to add %q to PATH: %s", entry, err)
|
fmt.Fprintf(os.Stderr, "%sfailed to add %q to PATH: %s", pathstore, entry, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +199,38 @@ func remove(entry string) {
|
||||||
fmt.Println(msg + "\n")
|
fmt.Println(msg + "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// warns if this is an unknown / untested shell
|
||||||
|
func checkShell() {
|
||||||
|
// https://superuser.com/a/69190/73857
|
||||||
|
// https://github.com/rust-lang-nursery/rustup.rs/issues/686#issuecomment-253982841
|
||||||
|
// exec source $HOME/.profile
|
||||||
|
shellexe := filepath.Base(os.Getenv("SHELL"))
|
||||||
|
shell := strings.TrimSuffix(shellexe, ".exe")
|
||||||
|
switch shell {
|
||||||
|
case ".":
|
||||||
|
shell = ""
|
||||||
|
fallthrough
|
||||||
|
case "":
|
||||||
|
if strings.HasSuffix(os.Getenv("COMSPEC"), "\\cmd.exe") {
|
||||||
|
shell = "cmd"
|
||||||
|
}
|
||||||
|
case "fish":
|
||||||
|
// ignore
|
||||||
|
case "zsh":
|
||||||
|
// ignore
|
||||||
|
case "bash":
|
||||||
|
// ignore
|
||||||
|
default:
|
||||||
|
// warn and try anyway
|
||||||
|
fmt.Fprintf(
|
||||||
|
os.Stderr,
|
||||||
|
"%q isn't a recognized shell. Please open an issue at https://git.rootprojects.org/root/pathman/issues?q=%s\n",
|
||||||
|
shellexe,
|
||||||
|
shellexe,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Paths returns path entries in the current environment
|
// Paths returns path entries in the current environment
|
||||||
func Paths() []string {
|
func Paths() []string {
|
||||||
cur := os.Getenv("PATH")
|
cur := os.Getenv("PATH")
|
||||||
|
@ -242,7 +250,7 @@ func Paths() []string {
|
||||||
// path entry to the current shell session
|
// path entry to the current shell session
|
||||||
func Add(p string) string {
|
func Add(p string) string {
|
||||||
if isCmdExe() {
|
if isCmdExe() {
|
||||||
return fmt.Sprintf(`PATH %s;%PATH%`, p)
|
return fmt.Sprintf(`PATH %s;%%PATH%%`, strings.Replace(p, "%", "%%", -1))
|
||||||
}
|
}
|
||||||
return fmt.Sprintf(`export PATH="%s:$PATH"`, p)
|
return fmt.Sprintf(`export PATH="%s:$PATH"`, p)
|
||||||
}
|
}
|
||||||
|
@ -257,5 +265,5 @@ func Remove(entries []string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func isCmdExe() bool {
|
func isCmdExe() bool {
|
||||||
return "" == os.Getenv("SHELL") && strings.Contains(strings.ToLower(os.Getenv("COMSPEC")), "/cmd.exe")
|
return "" == os.Getenv("SHELL") && strings.HasSuffix(strings.ToLower(os.Getenv("COMSPEC")), "\\cmd.exe")
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"git.rootprojects.org/root/pathman/envpath"
|
"git.rootprojects.org/root/pathman/envpath"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var pathstore = ""
|
||||||
|
|
||||||
func addPath(p string) (bool, error) {
|
func addPath(p string) (bool, error) {
|
||||||
return envpath.Add(p)
|
return envpath.Add(p)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"git.rootprojects.org/root/pathman/winpath"
|
"git.rootprojects.org/root/pathman/winpath"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var pathstore = "[winpath] "
|
||||||
|
|
||||||
func addPath(p string) (bool, error) {
|
func addPath(p string) (bool, error) {
|
||||||
return winpath.Add(p)
|
return winpath.Add(p)
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ func NormalizePathEntry(pathentry string) (string, string) {
|
||||||
if strings.HasPrefix(strings.ToLower(absentry)+sep, strings.ToLower(home)+sep) {
|
if strings.HasPrefix(strings.ToLower(absentry)+sep, strings.ToLower(home)+sep) {
|
||||||
// %USERPROFILE% is allowed, but only for user PATH
|
// %USERPROFILE% is allowed, but only for user PATH
|
||||||
// https://superuser.com/a/442163/73857
|
// https://superuser.com/a/442163/73857
|
||||||
homeentry = `%USERPROFILE%` + pathentry[len(home):]
|
homeentry = `%USERPROFILE%` + absentry[len(home):]
|
||||||
}
|
}
|
||||||
|
|
||||||
if absentry == pathentry {
|
if absentry == pathentry {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// +build windows,unsafe
|
// +build windows,!nounsafe
|
||||||
|
|
||||||
package winpath
|
package winpath
|
||||||
|
|
||||||
|
|
|
@ -29,12 +29,6 @@ func add(p string) (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
k, err := registry.OpenKey(registry.CURRENT_USER, `Environment`, registry.SET_VALUE)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
defer k.Close()
|
|
||||||
|
|
||||||
cur = append([]string{p}, cur...)
|
cur = append([]string{p}, cur...)
|
||||||
err = write(cur)
|
err = write(cur)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
|
@ -63,7 +57,7 @@ func remove(p string) (bool, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = write(cur)
|
err = write(newpaths)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -74,15 +68,15 @@ func remove(p string) (bool, error) {
|
||||||
func write(cur []string) error {
|
func write(cur []string) error {
|
||||||
// TODO --system to add to the system PATH rather than the user PATH
|
// TODO --system to add to the system PATH rather than the user PATH
|
||||||
|
|
||||||
k, err := registry.OpenKey(registry.CURRENT_USER, `Environment`, registry.QUERY_VALUE)
|
k, err := registry.OpenKey(registry.CURRENT_USER, `Environment`, registry.SET_VALUE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("Can't open HKCU Environment for writes: %s", err)
|
||||||
}
|
}
|
||||||
defer k.Close()
|
defer k.Close()
|
||||||
|
|
||||||
err = k.SetStringValue(`Path`, strings.Join(cur, string(os.PathListSeparator)))
|
err = k.SetStringValue(`Path`, strings.Join(cur, string(os.PathListSeparator)))
|
||||||
if nil != err {
|
if nil != err {
|
||||||
return err
|
return fmt.Errorf("Can't set HKCU Environment[Path]: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = k.Close()
|
err = k.Close()
|
||||||
|
@ -104,7 +98,7 @@ func paths() ([]string, error) {
|
||||||
// TBH, it's a mess to do this on *nix systems.
|
// TBH, it's a mess to do this on *nix systems.
|
||||||
k, err := registry.OpenKey(registry.CURRENT_USER, `Environment`, registry.QUERY_VALUE)
|
k, err := registry.OpenKey(registry.CURRENT_USER, `Environment`, registry.QUERY_VALUE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("Can't open HKCU Environment for reads: %s", err)
|
||||||
}
|
}
|
||||||
defer k.Close()
|
defer k.Close()
|
||||||
|
|
||||||
|
@ -112,7 +106,7 @@ func paths() ([]string, error) {
|
||||||
// PATH, Path, path will all work.
|
// PATH, Path, path will all work.
|
||||||
s, _, err := k.GetStringValue("Path")
|
s, _, err := k.GetStringValue("Path")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("Can't query HKCU Environment[Path]: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ";" on Windows
|
// ";" on Windows
|
||||||
|
|
Loading…
Reference in New Issue