From 6460802bfd729f2985c70ba98489440b350e295c Mon Sep 17 00:00:00 2001 From: c84c <616846+c84c@users.noreply.github.com> Date: Tue, 17 May 2022 13:45:02 +0200 Subject: [PATCH] fix(plugin install): copy executable by renaming and swap executable instead of copy/create --- commands/pluginhelper.go | 2 +- util/file.go | 32 +++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/commands/pluginhelper.go b/commands/pluginhelper.go index 5c54b17..4ae0a86 100644 --- a/commands/pluginhelper.go +++ b/commands/pluginhelper.go @@ -105,7 +105,7 @@ func UpdateCLI(pluginPkg string, updateOption int) error { cliExe = cliExe + ".exe" } - err = util.Copy(filepath.Join(cliCmdPath, cliExe), exPath, false) + err = util.SwapFile(filepath.Join(cliCmdPath, cliExe), exPath) if err != nil { //fmt.Fprintf(os.Stderr, "Error: %v\n", osErr) return err diff --git a/util/file.go b/util/file.go index 242d4f7..de379a1 100644 --- a/util/file.go +++ b/util/file.go @@ -171,4 +171,34 @@ func DeleteFile(path string) error { } return nil -} \ No newline at end of file +} + +// SwapFile is like a copy but use a temporary file and rename it +// to allow running executable replacement. +// Thanks to https://gist.github.com/fenollp/7e31e6462b10c96aef443351bce6aea7 +func SwapFile(src, dst string) error { + srcInfo, err := os.Stat(src) + if err != nil { + return err + } + destDir := filepath.Dir(dst) + tmpFile := filepath.Join(destDir, "exe_swap") + + defer DeleteFile(tmpFile) + + data, err := ioutil.ReadFile(src) + if err != nil { + return err + } + + if err := ioutil.WriteFile(tmpFile, data, srcInfo.Mode()); err != nil { + return err + } + + if err := os.Rename(tmpFile, dst); err != nil { + return err + } + + return nil + +}