From b1d8a4387c2f1d0005ee362b9456623240ac9d10 Mon Sep 17 00:00:00 2001 From: Guido Schmidt Date: Wed, 10 Apr 2024 21:36:40 +0200 Subject: [PATCH 1/7] FIX #71: old symlink should be removed on Windows --- cli/use.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cli/use.go b/cli/use.go index a2d3c68..2030009 100644 --- a/cli/use.go +++ b/cli/use.go @@ -41,8 +41,9 @@ func (z *ZVM) setBin(ver string) error { bin_dir := filepath.Join(z.baseDir, "bin") // Remove "bin" dir only if it already exists - - if _, err := os.Stat(bin_dir); errors.Is(err, fs.ErrExist) { + // According to https://stackoverflow.com/a/12518877/598919 + // errors.Is(err, os.ErrNotExist) should be used + if _, err := os.Stat(bin_dir); !errors.Is(err, os.ErrNotExist) { fmt.Printf("Removing old %s", bin_dir) if err := os.Remove(bin_dir); err != nil { return err From 3a3e733f67dcb96ef00a801f2ec56f2bf87763fe Mon Sep 17 00:00:00 2001 From: Guido Schmidt Date: Wed, 10 Apr 2024 21:41:31 +0200 Subject: [PATCH 2/7] FIX: remove unused import to be able to build --- cli/use.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/use.go b/cli/use.go index 2030009..c7bf14d 100644 --- a/cli/use.go +++ b/cli/use.go @@ -8,7 +8,6 @@ import ( "bufio" "errors" "fmt" - "io/fs" "os" "path/filepath" "strings" From 0f06492fff966c8bc391ea5da6a9f6311135ae64 Mon Sep 17 00:00:00 2001 From: Guido Schmidt Date: Wed, 10 Apr 2024 22:08:25 +0200 Subject: [PATCH 3/7] FIX: switch to use os.Lstat --- cli/use.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cli/use.go b/cli/use.go index c7bf14d..5aa1789 100644 --- a/cli/use.go +++ b/cli/use.go @@ -39,10 +39,11 @@ func (z *ZVM) setBin(ver string) error { version_path := filepath.Join(z.baseDir, ver) bin_dir := filepath.Join(z.baseDir, "bin") - // Remove "bin" dir only if it already exists - // According to https://stackoverflow.com/a/12518877/598919 - // errors.Is(err, os.ErrNotExist) should be used - if _, err := os.Stat(bin_dir); !errors.Is(err, os.ErrNotExist) { + // Came across https://pkg.go.dev/os#Lstat + // which is specifically to check symbolic links. + // Seemed like the more appropriate solution here + stat, err := os.Lstat(bin_dir); + if errors.Is(err, os.ErrExist) || stat != nil { fmt.Printf("Removing old %s", bin_dir) if err := os.Remove(bin_dir); err != nil { return err From 257cc256b6877a61e8cea572a81720e4ee6e0cb0 Mon Sep 17 00:00:00 2001 From: Tristan Isham Date: Wed, 10 Apr 2024 17:27:30 -0400 Subject: [PATCH 4/7] Update install.sh --- install.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 install.sh diff --git a/install.sh b/install.sh old mode 100755 new mode 100644 From e1064b0fb8e192ea9befb55970a528b688a95222 Mon Sep 17 00:00:00 2001 From: Tristan Isham Date: Wed, 10 Apr 2024 17:37:13 -0400 Subject: [PATCH 5/7] Handle Admin/Stat Removes forced upgrade to Stat for Windows users who are already admin or have enabled symlinks for regular users. --- cli/meta/symlink_win.go | 25 ++++++++++++------------- cli/use.go | 4 +++- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/cli/meta/symlink_win.go b/cli/meta/symlink_win.go index 62eb074..22287fe 100644 --- a/cli/meta/symlink_win.go +++ b/cli/meta/symlink_win.go @@ -19,7 +19,6 @@ import ( "golang.org/x/sys/windows" ) - func becomeAdmin() error { verb := "runas" exe, _ := os.Executable() @@ -51,23 +50,23 @@ func isAdmin() bool { // but with automatic privilege escalation on windows // for systems that do not support non-admin symlinks. func Symlink(oldname, newname string) error { - - // Check if already admin first - if isAdmin() { - if err := os.Symlink(oldname, newname); err != nil { - return errors.Join(ErrEscalatedSymlink, err) - } - return nil - } else { - // If not already admin, try to become admin - if err := becomeAdmin(); err != nil { + // Attempt to do a regular symlink if allowed by user's permissions + if err := os.Symlink(oldname, newname); err != nil { + // Check if already admin first + if isAdmin() { if err := os.Symlink(oldname, newname); err != nil { return errors.Join(ErrEscalatedSymlink, err) } + return nil + } else { + // If not already admin, try to become admin + if err := becomeAdmin(); err != nil { + if err := os.Symlink(oldname, newname); err != nil { + return errors.Join(ErrEscalatedSymlink, err) + } + } } } - - return nil } diff --git a/cli/use.go b/cli/use.go index 5aa1789..6ee996f 100644 --- a/cli/use.go +++ b/cli/use.go @@ -43,11 +43,13 @@ func (z *ZVM) setBin(ver string) error { // which is specifically to check symbolic links. // Seemed like the more appropriate solution here stat, err := os.Lstat(bin_dir); - if errors.Is(err, os.ErrExist) || stat != nil { + if err == nil { fmt.Printf("Removing old %s", bin_dir) if err := os.Remove(bin_dir); err != nil { return err } + } else { + return fmt.Errorf("%w: %s", err, stat.Name()) } if err := meta.Symlink(version_path, bin_dir); err != nil { From 2b1050787a08258c2de8a86fc763f7407ad9423b Mon Sep 17 00:00:00 2001 From: Tristan Isham Date: Wed, 10 Apr 2024 17:46:25 -0400 Subject: [PATCH 6/7] Create use_test.go Test for if we can find Symlinks --- cli/use_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 cli/use_test.go diff --git a/cli/use_test.go b/cli/use_test.go new file mode 100644 index 0000000..beddb58 --- /dev/null +++ b/cli/use_test.go @@ -0,0 +1,19 @@ +package cli + +import ( + "os" + "testing" +) + +func TestSymlinkExists(t *testing.T) { + if err := os.Symlink("use_test.go", "symlink.test"); err != nil { + t.Error(err) + } + + stat, err := os.Lstat("symlink.test"); + if err != nil { + t.Errorf("%q: %s", err, stat.Name()) + } + + defer os.Remove("symlink.test") +} \ No newline at end of file From e87630f2f80ec0255cee1c837a23923b0d10a5f0 Mon Sep 17 00:00:00 2001 From: Tristan Isham Date: Wed, 10 Apr 2024 17:49:32 -0400 Subject: [PATCH 7/7] Update version.go --- cli/meta/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/meta/version.go b/cli/meta/version.go index e157f41..43eb1c1 100644 --- a/cli/meta/version.go +++ b/cli/meta/version.go @@ -9,7 +9,7 @@ import ( ) const ( - VERSION = "v0.6.2" + VERSION = "v0.6.3" )