performUpdate downloads and installs the update
(status *UpdateStatus)
| 113 | |
| 114 | // performUpdate downloads and installs the update |
| 115 | func performUpdate(status *UpdateStatus) error { |
| 116 | if !status.HasUpdate { |
| 117 | return fmt.Errorf("no update available") |
| 118 | } |
| 119 | |
| 120 | // Get latest release info again to get checksum |
| 121 | release, err := getLatestRelease() |
| 122 | if err != nil { |
| 123 | return err |
| 124 | } |
| 125 | |
| 126 | // Get checksum |
| 127 | checksum, err := downloadChecksum(release, status.AssetName+checksumExtension) |
| 128 | if err != nil { |
| 129 | return fmt.Errorf("error downloading checksum: %v", err) |
| 130 | } |
| 131 | |
| 132 | // Get current executable path |
| 133 | executable, err := os.Executable() |
| 134 | if err != nil { |
| 135 | return fmt.Errorf("error getting executable path: %v", err) |
| 136 | } |
| 137 | |
| 138 | // Download and verify binary |
| 139 | tmpFile := executable + ".new" |
| 140 | if err := downloadAndVerifyFile(status.DownloadURL, tmpFile, strings.TrimSpace(string(checksum))); err != nil { |
| 141 | os.Remove(tmpFile) |
| 142 | return fmt.Errorf("error downloading update: %v", err) |
| 143 | } |
| 144 | |
| 145 | // Make new file executable |
| 146 | if err := os.Chmod(tmpFile, 0755); err != nil { |
| 147 | os.Remove(tmpFile) // Clean up |
| 148 | return fmt.Errorf("error setting permissions: %v", err) |
| 149 | } |
| 150 | |
| 151 | // Test that the new binary is executable by running it with --version |
| 152 | execCmd := exec.Command(tmpFile, "--help") |
| 153 | if err := execCmd.Run(); err != nil { |
| 154 | os.Remove(tmpFile) // Clean up |
| 155 | return fmt.Errorf("error verifying new binary: %v", err) |
| 156 | } |
| 157 | |
| 158 | // Replace the current executable |
| 159 | if err := replaceExecutable(executable, tmpFile); err != nil { |
| 160 | os.Remove(tmpFile) |
| 161 | return fmt.Errorf("error installing new version: %v", err) |
| 162 | } |
| 163 | |
| 164 | return nil |
| 165 | } |
| 166 | |
| 167 | // replaceExecutable safely replaces the current executable with the new one |
| 168 | func replaceExecutable(currentPath, newPath string) error { |
no test coverage detected