refactor: add built-in install

This commit is contained in:
Jan De Dobbeleer 2024-06-30 13:13:34 +02:00 committed by Jan De Dobbeleer
parent 75710391ea
commit 083625ec85
5 changed files with 87 additions and 7 deletions

View file

@ -35,7 +35,6 @@ require (
github.com/goccy/go-yaml v1.11.3
github.com/gookit/goutil v0.6.15
github.com/hashicorp/hcl/v2 v2.21.0
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf
github.com/mattn/go-runewidth v0.0.15
github.com/pelletier/go-toml/v2 v2.2.2
github.com/spf13/cobra v1.8.1

View file

@ -86,8 +86,6 @@ github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8=
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jandedobbeleer/clipboard v0.1.4-1 h1:rJehm5W0a3hvjcxyB3snqLBV4yvMBBc12JyMP7ngNQw=

View file

@ -1,11 +1,13 @@
package upgrade
import (
"bytes"
"fmt"
"io"
"os"
"path/filepath"
"runtime"
"github.com/inconshreveable/go-update"
"github.com/jandedobbeleer/oh-my-posh/src/platform"
)
@ -33,7 +35,57 @@ func install() error {
defer data.Close()
return update.Apply(data, update.Options{
TargetPath: executable,
})
newBytes, err := io.ReadAll(data)
if err != nil {
return err
}
targetDir := filepath.Dir(executable)
fileName := filepath.Base(executable)
newPath := filepath.Join(targetDir, fmt.Sprintf(".%s.new", fileName))
fp, err := os.OpenFile(newPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0775)
if err != nil {
return err
}
defer fp.Close()
_, err = io.Copy(fp, bytes.NewReader(newBytes))
if err != nil {
return err
}
// windows will have a lock when we do not close the file
fp.Close()
oldPath := filepath.Join(targetDir, fmt.Sprintf(".%s.old", fileName))
_ = os.Remove(oldPath)
err = os.Rename(executable, oldPath)
if err != nil {
return err
}
err = os.Rename(newPath, executable)
if err != nil {
// rollback
rerr := os.Rename(oldPath, executable)
if rerr != nil {
return rerr
}
return err
}
removeErr := os.Remove(oldPath)
// hide the old executable if we can't remove it
if removeErr != nil {
_ = hideFile(oldPath)
}
return nil
}

View file

@ -0,0 +1,7 @@
//go:build !windows
package upgrade
func hideFile(_ string) error {
return nil
}

View file

@ -0,0 +1,24 @@
package upgrade
import (
"syscall"
"unsafe"
)
func hideFile(path string) error {
kernel32 := syscall.NewLazyDLL("kernel32.dll")
setFileAttributes := kernel32.NewProc("SetFileAttributesW")
ptr, err := syscall.UTF16PtrFromString(path)
if err != nil {
return err
}
r1, _, err := setFileAttributes.Call(uintptr(unsafe.Pointer(ptr)), 2)
if r1 == 0 {
return err
}
return nil
}