cli: refactor update package to use internal/errors

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/6524
Co-authored-by: Aravind K P <8335904+scriptonist@users.noreply.github.com>
GitOrigin-RevId: 919262c2618a1319441ce3730802c06bd5bd450a
This commit is contained in:
Mohd Bilal 2022-11-02 12:49:24 +05:30 committed by hasura-bot
parent bb0b95dd77
commit 52f21e7261
3 changed files with 29 additions and 20 deletions

View File

@ -1,10 +1,11 @@
package update
import (
"fmt"
"io/ioutil"
"time"
"github.com/pkg/errors"
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
)
const (
@ -25,9 +26,10 @@ func getTimeFromFileIfExists(path string) time.Time {
}
func writeTimeToFile(path string, inputTime time.Time) error {
var op errors.Op = "update.writeTimeToFile"
err := ioutil.WriteFile(path, []byte(inputTime.Format(timeLayout)), 0644)
if err != nil {
return errors.Wrap(err, "failed writing current time to file")
return errors.E(op, fmt.Errorf("failed writing current time to file: %w", err))
}
return nil
}

View File

@ -6,16 +6,19 @@ package update
import (
"syscall"
"unsafe"
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
)
func hideFile(path string) error {
var op errors.Op = "update.hideFile"
kernel32 := syscall.NewLazyDLL("kernel32.dll")
setFileAttributes := kernel32.NewProc("SetFileAttributesW")
r1, _, err := setFileAttributes.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), 2)
if r1 == 0 {
return err
return errors.E(op, err)
} else {
return nil
}

View File

@ -16,7 +16,8 @@ import (
"github.com/kardianos/osext"
"github.com/Masterminds/semver"
"github.com/pkg/errors"
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
)
const updateCheckURL = "https://releases.hasura.io/graphql-engine?agent=cli"
@ -27,19 +28,20 @@ type updateCheckResponse struct {
}
func getLatestVersion() (*semver.Version, *semver.Version, error) {
var op errors.Op = "update.getLatestVersion"
res, err := http.Get(updateCheckURL)
if err != nil {
return nil, nil, errors.Wrap(err, "update check request")
return nil, nil, errors.E(op, fmt.Errorf("update check request: %w", err))
}
defer res.Body.Close()
var response updateCheckResponse
err = json.NewDecoder(res.Body).Decode(&response)
if err != nil {
return nil, nil, errors.Wrap(err, "decoding update check response")
return nil, nil, errors.E(op, fmt.Errorf("decoding update check response: %w", err))
}
if response.Latest == nil && response.PreRelease == nil {
return nil, nil, fmt.Errorf("expected version info not found at %s", updateCheckURL)
return nil, nil, errors.E(op, fmt.Errorf("expected version info not found at %s", updateCheckURL))
}
return response.Latest, response.PreRelease, nil
@ -59,14 +61,15 @@ func buildAssetURL(v string) string {
}
func downloadAsset(url, fileName, filePath string) (*os.File, error) {
var op errors.Op = "update.downloadAsset"
res, err := http.Get(url)
if err != nil {
return nil, errors.Wrap(err, "downloading asset")
return nil, errors.E(op, errors.KindNetwork, fmt.Errorf("downloading asset: %w", err))
}
defer res.Body.Close()
if res.StatusCode != 200 {
return nil, errors.New("could not find the release asset")
return nil, errors.E(op, errors.E("could not find the release asset"))
}
asset, err := os.OpenFile(
@ -75,13 +78,13 @@ func downloadAsset(url, fileName, filePath string) (*os.File, error) {
0755,
)
if err != nil {
return nil, errors.Wrap(err, "creating new binary file")
return nil, errors.E(op, fmt.Errorf("creating new binary file: %w", err))
}
defer asset.Close()
_, err = io.Copy(asset, res.Body)
if err != nil {
return nil, errors.Wrap(err, "saving downloaded file")
return nil, errors.E(op, fmt.Errorf("saving downloaded file: %w", err))
}
return asset, nil
@ -89,6 +92,7 @@ func downloadAsset(url, fileName, filePath string) (*os.File, error) {
// HasUpdate tells us if there is a new stable or prerelease update available.
func HasUpdate(currentVersion *semver.Version, timeFile string) (bool, *semver.Version, bool, *semver.Version, error) {
var op errors.Op = "update.HasUpdate"
if timeFile != "" {
defer func() {
if err := writeTimeToFile(timeFile, time.Now().UTC()); err != nil {
@ -99,7 +103,7 @@ func HasUpdate(currentVersion *semver.Version, timeFile string) (bool, *semver.V
latestVersion, preReleaseVersion, err := getLatestVersion()
if err != nil {
return false, nil, false, nil, errors.Wrap(err, "get latest version")
return false, nil, false, nil, errors.E(op, fmt.Errorf("get latest version: %w", err))
}
return latestVersion.GreaterThan(currentVersion), latestVersion, preReleaseVersion.GreaterThan(currentVersion), preReleaseVersion, nil
@ -107,10 +111,11 @@ func HasUpdate(currentVersion *semver.Version, timeFile string) (bool, *semver.V
// ApplyUpdate downloads and applies the update indicated by version v.
func ApplyUpdate(v *semver.Version) error {
var op errors.Op = "update.ApplyUpdate"
// get the current executable
exe, err := osext.Executable()
if err != nil {
return errors.Wrap(err, "find executable")
return errors.E(op, fmt.Errorf("find executable: %w", err))
}
// extract the filename and path
@ -122,7 +127,7 @@ func ApplyUpdate(v *semver.Version) error {
buildAssetURL(v.String()), "."+exeName+".new", exePath,
)
if err != nil {
return errors.Wrap(err, "download asset")
return errors.E(op, fmt.Errorf("download asset: %w", err))
}
// get the downloaded binary name and build the absolute path
@ -140,7 +145,7 @@ func ApplyUpdate(v *semver.Version) error {
// rename the current binary as old binary
err = os.Rename(exe, oldExe)
if err != nil {
return errors.Wrap(err, "rename exe to old")
return errors.E(op, fmt.Errorf("rename exe to old: %w", err))
}
// rename the new binary as the current binary
@ -156,13 +161,12 @@ func ApplyUpdate(v *semver.Version) error {
rerr := os.Rename(oldExe, exe)
if rerr != nil {
// rolling back failed, ask user to re-install cli
return errors.Wrap(
rerr,
"rename old to exe: inconsistent state, re-install cli",
)
return errors.E(op, fmt.Errorf(
"rename old to exe: inconsistent state, re-install cli: %w",
rerr))
}
// rolled back, throw update error
return errors.Wrap(err, "rename new to exe")
return errors.E(op, fmt.Errorf("rename new to exe: %w", err))
}
// rename success, remove the old binary