Skip to content

Commit

Permalink
snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
bradenhilton committed Aug 23, 2023
1 parent 5682362 commit acead27
Show file tree
Hide file tree
Showing 2 changed files with 423 additions and 102 deletions.
105 changes: 3 additions & 102 deletions internal/cmd/upgradecmd.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build !noupgrade
//go:build !noupgrade && !windows

package cmd

Expand All @@ -15,7 +15,6 @@ import (
"net/http"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strings"
Expand All @@ -34,7 +33,6 @@ const (
upgradeMethodReplaceExecutable = "replace-executable"
upgradeMethodSnapRefresh = "snap-refresh"
upgradeMethodUpgradePackage = "upgrade-package"
upgradeMethodWingetUpgrade = "winget-upgrade"
upgradeMethodSudoPrefix = "sudo-"

libcTypeGlibc = "glibc"
Expand Down Expand Up @@ -195,10 +193,6 @@ func (c *Config) runUpgradeCmd(cmd *cobra.Command, args []string) error {
if err := c.upgradePackage(ctx, version, rr, useSudo); err != nil {
return err
}
case upgradeMethodWingetUpgrade:
if err := c.wingetUpgrade(); err != nil {
return err
}
case upgradeMethodSudoPrefix + upgradeMethodUpgradePackage:
useSudo := true
if err := c.upgradePackage(ctx, version, rr, useSudo); err != nil {
Expand Down Expand Up @@ -337,15 +331,6 @@ func (c *Config) replaceExecutable(
var archiveFormat chezmoi.ArchiveFormat
var archiveName string
switch {
case runtime.GOOS == "windows":
archiveFormat = chezmoi.ArchiveFormatZip
archiveName = fmt.Sprintf(
"%s_%s_%s_%s.zip",
c.upgrade.repo,
releaseVersion,
runtime.GOOS,
runtime.GOARCH,
)
case runtime.GOOS == "linux" && runtime.GOARCH == "amd64":
archiveFormat = chezmoi.ArchiveFormatTarGz
var libc string
Expand Down Expand Up @@ -395,19 +380,15 @@ func (c *Config) replaceExecutable(
// Extract the executable from the archive.
var executableData []byte
walkArchiveFunc := func(name string, info fs.FileInfo, r io.Reader, linkname string) error {
switch {
case runtime.GOOS != "windows" && name == c.upgrade.repo:
fallthrough
case runtime.GOOS == "windows" && name == c.upgrade.repo+".exe":
if name == c.upgrade.repo {
var err error
executableData, err = io.ReadAll(r)
if err != nil {
return err
}
return fs.SkipAll
default:
return nil
}
return nil
}
if err = chezmoi.WalkArchive(archiveData, archiveFormat, walkArchiveFunc); err != nil {
return
Expand All @@ -417,12 +398,6 @@ func (c *Config) replaceExecutable(
return
}

// Replace the executable.
if runtime.GOOS == "windows" {
if err = c.baseSystem.Rename(executableFilenameAbsPath, executableFilenameAbsPath.Append(".old")); err != nil {
return
}
}
err = c.baseSystem.WriteFile(executableFilenameAbsPath, executableData, 0o755)

return
Expand Down Expand Up @@ -533,11 +508,6 @@ func (c *Config) verifyChecksum(
return nil
}

func (c *Config) wingetUpgrade() error {
wingetArgs := []string{"upgrade", "--id", fmt.Sprintf("%s.%s", c.upgrade.owner, c.upgrade.repo), "--source", "winget"}
return c.run(chezmoi.EmptyAbsPath, "winget", wingetArgs)
}

// getUpgradeMethod attempts to determine the method by which chezmoi can be
// upgraded by looking at how it was installed.
func getUpgradeMethod(fileSystem vfs.Stater, executableAbsPath chezmoi.AbsPath) (string, error) {
Expand All @@ -546,12 +516,6 @@ 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":
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 @@ -651,66 +615,3 @@ 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
}
Loading

0 comments on commit acead27

Please sign in to comment.