From 20f7133dfab3f740b114b4e649356580fd30950f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Pi=C3=B1a?= Date: Mon, 26 Aug 2019 12:08:09 -0700 Subject: [PATCH] Check HOMEDRIVE and HOMEPATH for windows, expand vars --- nats.go | 26 ++++++++++++++++++------ nats_test.go | 57 +++++++++++++++++++++++++++++++++++----------------- 2 files changed, 59 insertions(+), 24 deletions(-) diff --git a/nats.go b/nats.go index 2ebfa1a69..b3a87449a 100644 --- a/nats.go +++ b/nats.go @@ -4018,7 +4018,7 @@ func wipeSlice(buf []byte) { } func userFromFile(userFile string) (string, error) { - path, err := expandTildePath(userFile) + path, err := expandPath(userFile) if err != nil { return _EMPTY_, fmt.Errorf("nats: %v", err) } @@ -4032,19 +4032,33 @@ func userFromFile(userFile string) (string, error) { } func homeDir() (string, error) { - envVar := "HOME" if runtime.GOOS == "windows" { - envVar = "USERPROFILE" + homeDrive, homePath := os.Getenv("HOMEDRIVE"), os.Getenv("HOMEPATH") + userProfile := os.Getenv("USERPROFILE") + + var home string + if homeDrive == "" || homePath == "" { + if userProfile == "" { + return _EMPTY_, errors.New("nats: failed to get home dir, require %HOMEDRIVE% and %HOMEPATH% or %USERPROFILE%") + } + home = userProfile + } else { + home = filepath.Join(homeDrive, homePath) + } + + return home, nil } - home := os.Getenv(envVar) + home := os.Getenv("HOME") if home == "" { - return _EMPTY_, fmt.Errorf("nats: failed to get home dir, require %s environment variable", envVar) + return _EMPTY_, errors.New("nats: failed to get home dir, require $HOME") } return home, nil } -func expandTildePath(p string) (string, error) { +func expandPath(p string) (string, error) { + p = os.ExpandEnv(p) + if !strings.HasPrefix(p, "~") { return p, nil } diff --git a/nats_test.go b/nats_test.go index e7d3fd4ee..570766e2a 100644 --- a/nats_test.go +++ b/nats_test.go @@ -98,7 +98,7 @@ func TestVersionMatchesTag(t *testing.T) { } } -func TestExpandTildePath(t *testing.T) { +func TestExpandPath(t *testing.T) { t.Run("unix", func(t *testing.T) { if runtime.GOOS == "windows" { t.SkipNow() @@ -109,15 +109,17 @@ func TestExpandTildePath(t *testing.T) { defer os.Setenv("HOME", origHome) cases := []struct { - path string - home string + path string + home string + testEnv string wantPath string wantErr bool }{ - {path: "/foo/bar", home: "/fizz/buzz", wantPath: "/foo/bar", wantErr: false}, - {path: "foo/bar", home: "/fizz/buzz", wantPath: "foo/bar", wantErr: false}, - {path: "~/fizz", home: "/foo/bar", wantPath: "/foo/bar/fizz", wantErr: false}, + {path: "/foo/bar", home: "/fizz/buzz", wantPath: "/foo/bar"}, + {path: "foo/bar", home: "/fizz/buzz", wantPath: "foo/bar"}, + {path: "~/fizz", home: "/foo/bar", wantPath: "/foo/bar/fizz"}, + {path: "$HOME/fizz", home: "/foo/bar", wantPath: "/foo/bar/fizz"}, // missing HOME env var {path: "~/fizz", wantErr: true}, @@ -125,7 +127,7 @@ func TestExpandTildePath(t *testing.T) { for i, c := range cases { os.Setenv("HOME", c.home) - gotPath, err := expandTildePath(c.path) + gotPath, err := expandPath(c.path) if !c.wantErr && err != nil { t.Error("unexpected error") t.Errorf("case=%d; got=%v; want=%v", i, err, nil) @@ -149,26 +151,45 @@ func TestExpandTildePath(t *testing.T) { } origUserProfile := os.Getenv("USERPROFILE") - defer os.Setenv("USERPROFILE", origUserProfile) + origHomeDrive, origHomePath := os.Getenv("HOMEDRIVE"), os.Getenv("HOMEPATH") + defer func() { + os.Setenv("USERPROFILE", origUserProfile) + os.Setenv("HOMEDRIVE", origHomeDrive) + os.Setenv("HOMEPATH", origHomePath) + }() cases := []struct { - path string - home string + path string + userProfile string + homeDrive string + homePath string wantPath string wantErr bool }{ - {path: "/Foo/Bar", home: `C:\Foo\Bar`, wantPath: "/Foo/Bar", wantErr: false}, - {path: "Foo/Bar", home: `C:\Foo\Bar`, wantPath: "Foo/Bar", wantErr: false}, - {path: "~/Fizz", home: `C:\Foo\Bar`, wantPath: `C:\Foo\Bar\Fizz`, wantErr: false}, - - // missing USERPROFILE env var - {path: "~/fizz", wantErr: true}, + // Missing HOMEDRIVE and HOMEPATH. + {path: "/Foo/Bar", userProfile: `C:\Foo\Bar`, wantPath: "/Foo/Bar"}, + {path: "Foo/Bar", userProfile: `C:\Foo\Bar`, wantPath: "Foo/Bar"}, + {path: "~/Fizz", userProfile: `C:\Foo\Bar`, wantPath: `C:\Foo\Bar\Fizz`}, + {path: `%HOMEDRIVE%%HOMEPATH%\Fizz`, userProfile: `C:\Foo\Bar`, wantPath: `C:\Foo\Bar\Fizz`}, + + // Missing USERPROFILE. + {path: "~/Fizz", homeDrive: "X:", homePath: `\Foo\Bar`, wantPath: `X:\Foo\Bar\Fizz`}, + + // Set all environment variables. HOMEDRIVE and HOMEPATH take + // precedence. + {path: "~/Fizz", userProfile: `C:\Foo\Bar`, + homeDrive: "X:", homePath: `\Foo\Bar`, wantPath: `X:\Foo\Bar\Fizz`}, + + // Missing all environment variables. + {path: "~/Fizz", wantErr: true}, } for i, c := range cases { - os.Setenv("USERPROFILE", c.home) + os.Setenv("USERPROFILE", c.userProfile) + os.Setenv("HOMEDRIVE", c.homeDrive) + os.Setenv("HOMEPATH", c.homePath) - gotPath, err := expandTildePath(c.path) + gotPath, err := expandPath(c.path) if !c.wantErr && err != nil { t.Error("unexpected error") t.Errorf("case=%d; got=%v; want=%v", i, err, nil)