Skip to content

Commit

Permalink
[skip ci] fix: Determine WinGet installation of chezmoi more robustly
Browse files Browse the repository at this point in the history
  • Loading branch information
bradenhilton committed Aug 23, 2023
1 parent 0ef0128 commit 5682362
Showing 1 changed file with 70 additions and 2 deletions.
72 changes: 70 additions & 2 deletions internal/cmd/upgradecmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"net/http"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strings"
Expand Down Expand Up @@ -545,8 +546,12 @@ func getUpgradeMethod(fileSystem vfs.Stater, executableAbsPath chezmoi.AbsPath)
return upgradeMethodBrewUpgrade, nil
case runtime.GOOS == "linux" && strings.Contains(executableAbsPath.String(), "/.linuxbrew/"):
return upgradeMethodBrewUpgrade, nil
case runtime.GOOS == "windows" && strings.Contains(executableAbsPath.ToSlash().String(), "/WinGet/"):
return upgradeMethodWingetUpgrade, nil
case runtime.GOOS == "windows":
if ok, err := isWinGetInstall(fileSystem, executableAbsPath.String()); err != nil {
return "", err
} else if ok {
return upgradeMethodWingetUpgrade, nil
}
}

// If the executable is in the user's home directory, then always use
Expand Down Expand Up @@ -646,3 +651,66 @@ func getReleaseAssetByName(rr *github.RepositoryRelease, name string) *github.Re
}
return nil
}

type InstallBehavior struct {
PortablePackageUserRoot string `json:"portablePackageUserRoot"`
PortablePackageMachineRoot string `json:"portablePackageMachineRoot"`
DefaultInstallRoot string `json:"defaultInstallRoot"`
}

func (ib *InstallBehavior) Values() []string {
return []string{
ib.PortablePackageUserRoot,
ib.PortablePackageMachineRoot,
ib.DefaultInstallRoot,
}
}

type WinGetSettings struct {
InstallBehavior InstallBehavior `json:"installBehavior"`
}

// isWinGetInstall determines if executableAbsPath contains a WinGet installation path.
func isWinGetInstall(fileSystem vfs.Stater, executableAbsPath string) (bool, error) {
realExecutableAbsPath := executableAbsPath
fi, err := os.Lstat(executableAbsPath)
if err != nil {
return false, err
}
if fi.Mode().Type() == os.ModeSymlink {
realExecutableAbsPath, err = os.Readlink(executableAbsPath)
if err != nil {
return false, err
}
}
winGetSettings := WinGetSettings{
InstallBehavior: InstallBehavior{
PortablePackageUserRoot: os.ExpandEnv(`${LOCALAPPDATA}\Microsoft\WinGet\Packages\`),
PortablePackageMachineRoot: os.ExpandEnv(`${PROGRAMFILES}\WinGet\Packages\`),
},
}
settingsPaths := []string{
os.ExpandEnv(`${LOCALAPPDATA}\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\settings.json`),
os.ExpandEnv(`${LOCALAPPDATA}\Microsoft\WinGet\Settings\settings.json`),
}
for _, settingsPath := range settingsPaths {
if _, err := os.Stat(settingsPath); err == nil {
winGetSettingsContents, err := os.ReadFile(settingsPath)
if err == nil {
if err := chezmoi.FormatJSONC.Unmarshal([]byte(winGetSettingsContents), &winGetSettings); err != nil {
return false, err
}
}
}
}
for _, path := range winGetSettings.InstallBehavior.Values() {
path = filepath.Clean(path)
if path == "." {
continue
}
if ok, _ := vfs.Contains(fileSystem, realExecutableAbsPath, path); ok {
return true, nil
}
}
return false, nil
}

0 comments on commit 5682362

Please sign in to comment.