mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-13 19:33:55 +03:00
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:
parent
bb0b95dd77
commit
52f21e7261
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user