mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 08:02:15 +03:00
cli: refactor util
package to use internal/errors
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/6508 Co-authored-by: Aravind K P <8335904+scriptonist@users.noreply.github.com> GitOrigin-RevId: 41f4842593a7226966c53ffd6314809adbd72266
This commit is contained in:
parent
3ca779797d
commit
e814260ccc
@ -8,6 +8,8 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
|
||||
)
|
||||
|
||||
// from https://gist.github.com/r0l1/92462b38df26839a3ca324697c8cba04
|
||||
@ -17,76 +19,77 @@ import (
|
||||
// destination file exists, all it's contents will be replaced by the contents
|
||||
// of the source file. The file mode will be copied from the source and
|
||||
// the copied data is synced/flushed to stable storage.
|
||||
func CopyFile(src, dst string) (err error) {
|
||||
func CopyFile(src, dst string) error {
|
||||
var op errors.Op = "util.CopyFile"
|
||||
in, err := os.Open(src)
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
defer in.Close()
|
||||
|
||||
out, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
defer func() {
|
||||
if e := out.Close(); e != nil {
|
||||
err = e
|
||||
err = errors.E(op, e)
|
||||
}
|
||||
}()
|
||||
|
||||
_, err = io.Copy(out, in)
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
err = out.Sync()
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
si, err := os.Stat(src)
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
err = os.Chmod(dst, si.Mode())
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// CopyDir recursively copies a directory tree, attempting to preserve permissions.
|
||||
// Source directory must exist, destination directory must *not* exist.
|
||||
// Symlinks are ignored and skipped.
|
||||
func CopyDir(src string, dst string) (err error) {
|
||||
func CopyDir(src string, dst string) error {
|
||||
var op errors.Op = "util.CopyDir"
|
||||
src = filepath.Clean(src)
|
||||
dst = filepath.Clean(dst)
|
||||
|
||||
si, err := os.Stat(src)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
if !si.IsDir() {
|
||||
return fmt.Errorf("source is not a directory")
|
||||
return errors.E(op, fmt.Errorf("source is not a directory"))
|
||||
}
|
||||
|
||||
_, err = os.Stat(dst)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
if err == nil {
|
||||
return fmt.Errorf("destination already exists")
|
||||
return errors.E(op, fmt.Errorf("destination already exists"))
|
||||
}
|
||||
|
||||
err = os.MkdirAll(dst, si.Mode())
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
entries, err := ioutil.ReadDir(src)
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
for _, entry := range entries {
|
||||
@ -96,7 +99,7 @@ func CopyDir(src string, dst string) (err error) {
|
||||
if entry.IsDir() {
|
||||
err = CopyDir(srcPath, dstPath)
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
} else {
|
||||
// Skip symlinks.
|
||||
@ -106,83 +109,83 @@ func CopyDir(src string, dst string) (err error) {
|
||||
|
||||
err = CopyFile(srcPath, dstPath)
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// CopyFile but with Afero
|
||||
func CopyFileAfero(fs afero.Fs, src, dst string) (err error) {
|
||||
func CopyFileAfero(fs afero.Fs, src, dst string) error {
|
||||
var op errors.Op = "util.CopyFileAfero"
|
||||
in, err := fs.Open(src)
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
defer in.Close()
|
||||
|
||||
out, err := fs.Create(dst)
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
defer func() {
|
||||
if e := out.Close(); e != nil {
|
||||
err = e
|
||||
err = errors.E(op, e)
|
||||
}
|
||||
}()
|
||||
|
||||
_, err = io.Copy(out, in)
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
err = out.Sync()
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
si, err := fs.Stat(src)
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
err = fs.Chmod(dst, si.Mode())
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
// CopyDir but with afero
|
||||
func CopyDirAfero(fs afero.Fs, src string, dst string) (err error) {
|
||||
func CopyDirAfero(fs afero.Fs, src string, dst string) error {
|
||||
var op errors.Op = "util.CopyDirAfero"
|
||||
src = filepath.Clean(src)
|
||||
dst = filepath.Clean(dst)
|
||||
|
||||
si, err := fs.Stat(src)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
if !si.IsDir() {
|
||||
return fmt.Errorf("source is not a directory")
|
||||
return errors.E(op, fmt.Errorf("source is not a directory"))
|
||||
}
|
||||
|
||||
_, err = fs.Stat(dst)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
if err == nil {
|
||||
return fmt.Errorf("destination already exists")
|
||||
return errors.E(op, fmt.Errorf("destination already exists"))
|
||||
}
|
||||
|
||||
err = fs.MkdirAll(dst, si.Mode())
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
entries, err := afero.ReadDir(fs, src)
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
for _, entry := range entries {
|
||||
@ -192,7 +195,7 @@ func CopyDirAfero(fs afero.Fs, src string, dst string) (err error) {
|
||||
if entry.IsDir() {
|
||||
err = CopyDirAfero(fs, srcPath, dstPath)
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
} else {
|
||||
// Skip symlinks.
|
||||
@ -202,10 +205,9 @@ func CopyDirAfero(fs afero.Fs, src string, dst string) (err error) {
|
||||
|
||||
err = CopyFileAfero(fs, srcPath, dstPath)
|
||||
if err != nil {
|
||||
return
|
||||
return errors.E(op, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
@ -1,65 +1,73 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
|
||||
)
|
||||
|
||||
func FSCheckIfDirPathExists(path string) error {
|
||||
var op errors.Op = "util.FSCheckIfDirPathExists"
|
||||
stat, err := os.Lstat(path)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
if !stat.IsDir() {
|
||||
err = errors.New("no such directory")
|
||||
err = errors.E(op, "no such directory")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func FSCopyFile(src, dst string) error {
|
||||
var op errors.Op = "util.FSCopyFile"
|
||||
var err error
|
||||
var srcfd *os.File
|
||||
var dstfd *os.File
|
||||
var srcinfo os.FileInfo
|
||||
|
||||
if srcfd, err = os.Open(src); err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
defer srcfd.Close()
|
||||
|
||||
if dstfd, err = os.Create(dst); err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
defer dstfd.Close()
|
||||
|
||||
if _, err = io.Copy(dstfd, srcfd); err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
if srcinfo, err = os.Stat(src); err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
return os.Chmod(dst, srcinfo.Mode())
|
||||
err = os.Chmod(dst, srcinfo.Mode())
|
||||
if err != nil {
|
||||
return errors.E(op, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func FSCopyDir(src string, dst string) error {
|
||||
var op errors.Op = "util.FSCopyDir"
|
||||
var err error
|
||||
var fds []os.FileInfo
|
||||
var srcinfo os.FileInfo
|
||||
|
||||
if srcinfo, err = os.Stat(src); err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
if err = os.MkdirAll(dst, srcinfo.Mode()); err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
if fds, err = ioutil.ReadDir(src); err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
for _, fd := range fds {
|
||||
srcfp := path.Join(src, fd.Name())
|
||||
|
@ -2,6 +2,8 @@ package util
|
||||
|
||||
import (
|
||||
"github.com/Masterminds/semver"
|
||||
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
|
||||
)
|
||||
|
||||
type VersionFlag struct {
|
||||
@ -15,9 +17,10 @@ func NewVersionFlagValue(p *VersionFlag) *VersionFlag {
|
||||
|
||||
// Set sets the value of the named command-line flag.
|
||||
func (c *VersionFlag) Set(s string) error {
|
||||
var op errors.Op = "util.VersionFlag.Set"
|
||||
v, err := semver.NewVersion(s)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
c.Version = v
|
||||
return nil
|
||||
|
@ -8,6 +8,8 @@ import (
|
||||
"gopkg.in/src-d/go-git.v4"
|
||||
"gopkg.in/src-d/go-git.v4/config"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
|
||||
)
|
||||
|
||||
// Default Codegen Assets constants
|
||||
@ -40,79 +42,93 @@ func NewGitUtil(uri string, path string, refName string) *GitUtil {
|
||||
}
|
||||
|
||||
func (g *GitUtil) EnsureCloned() error {
|
||||
var op errors.Op = "util.GitUtil.EnsureCloned"
|
||||
if g.DisableCloneOrUpdate {
|
||||
g.Logger.Debugf("skipping clone/update for %s", g.URI)
|
||||
return nil
|
||||
}
|
||||
if ok, err := g.IsGitCloned(); err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
} else if !ok {
|
||||
_, err := git.PlainClone(g.Path, false, &git.CloneOptions{
|
||||
URL: g.URI,
|
||||
ReferenceName: g.ReferenceName,
|
||||
})
|
||||
if err != nil && err != git.ErrRepositoryAlreadyExists {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *GitUtil) IsGitCloned() (bool, error) {
|
||||
var op errors.Op = "util.GitUtil.IsGitCloned"
|
||||
f, err := os.Stat(filepath.Join(g.Path, ".git"))
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return err == nil && f.IsDir(), err
|
||||
if err != nil {
|
||||
return false, errors.E(op, err)
|
||||
}
|
||||
return f.IsDir(), nil
|
||||
}
|
||||
|
||||
// EnsureUpdated will ensure the destination path exists and is up to date.
|
||||
func (g *GitUtil) EnsureUpdated() error {
|
||||
var op errors.Op = "util.GitUtil.EnsureUpdated"
|
||||
if g.DisableCloneOrUpdate {
|
||||
g.Logger.Debugf("skipping clone/update for %s", g.URI)
|
||||
return nil
|
||||
}
|
||||
if err := g.EnsureCloned(); err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
return g.updateAndCleanUntracked()
|
||||
if err := g.updateAndCleanUntracked(); err != nil {
|
||||
return errors.E(op, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *GitUtil) updateAndCleanUntracked() error {
|
||||
var op errors.Op = "util.GitUtil.updateAndCleanUntracked"
|
||||
repo, err := git.PlainOpen(g.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
err = repo.Fetch(&git.FetchOptions{
|
||||
RefSpecs: []config.RefSpec{"refs/*:refs/*"},
|
||||
})
|
||||
if err != nil && err != git.NoErrAlreadyUpToDate {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
wt, err := repo.Worktree()
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
err = wt.Checkout(&git.CheckoutOptions{
|
||||
Branch: g.ReferenceName,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
err = wt.Pull(&git.PullOptions{
|
||||
ReferenceName: g.ReferenceName,
|
||||
Force: true,
|
||||
})
|
||||
if err != nil && err != git.NoErrAlreadyUpToDate {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
err = wt.Reset(&git.ResetOptions{
|
||||
Mode: git.HardReset,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
return wt.Clean(&git.CleanOptions{
|
||||
err = wt.Clean(&git.CleanOptions{
|
||||
Dir: true,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.E(op, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -2,53 +2,79 @@ package util
|
||||
|
||||
import (
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
|
||||
)
|
||||
|
||||
func GetYesNoPrompt(message string) (promptResp bool, err error) {
|
||||
var op errors.Op = "util.GetYesNoPrompt"
|
||||
prompt := &survey.Confirm{
|
||||
Message: message,
|
||||
Default: true,
|
||||
}
|
||||
err = survey.AskOne(prompt, &promptResp)
|
||||
return promptResp, err
|
||||
if err != nil {
|
||||
return promptResp, errors.E(op, err)
|
||||
}
|
||||
return promptResp, nil
|
||||
}
|
||||
|
||||
func GetSelectPrompt(message string, options []string) (selection string, err error) {
|
||||
var op errors.Op = "util.GetSelectPrompt"
|
||||
prompt := &survey.Select{
|
||||
Message: message,
|
||||
Options: options,
|
||||
}
|
||||
err = survey.AskOne(prompt, &selection)
|
||||
return selection, err
|
||||
if err != nil {
|
||||
return selection, errors.E(op, err)
|
||||
}
|
||||
return selection, nil
|
||||
}
|
||||
|
||||
func GetInputPrompt(message string) (input string, err error) {
|
||||
var op errors.Op = "util.GetInputPrompt"
|
||||
prompt := &survey.Input{
|
||||
Message: message,
|
||||
}
|
||||
err = survey.AskOne(prompt, &input)
|
||||
return input, err
|
||||
if err != nil {
|
||||
return input, errors.E(op, err)
|
||||
}
|
||||
return input, nil
|
||||
}
|
||||
|
||||
func GetInputPromptWithDefault(message string, def string) (input string, err error) {
|
||||
var op errors.Op = "util.GetInputPromptWithDefault"
|
||||
prompt := &survey.Input{
|
||||
Message: message,
|
||||
Default: def,
|
||||
}
|
||||
err = survey.AskOne(prompt, &input)
|
||||
return input, err
|
||||
if err != nil {
|
||||
return input, errors.E(op, err)
|
||||
}
|
||||
return input, nil
|
||||
}
|
||||
|
||||
func validateDirPath(a interface{}) error {
|
||||
var op errors.Op = "util.validateDirPath"
|
||||
err := FSCheckIfDirPathExists(a.(string))
|
||||
return err
|
||||
if err != nil {
|
||||
return errors.E(op, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetFSPathPrompt(message string, def string) (input string, err error) {
|
||||
var op errors.Op = "util.GetFSPathPrompt"
|
||||
prompt := &survey.Input{
|
||||
Message: message,
|
||||
Default: def,
|
||||
}
|
||||
err = survey.AskOne(prompt, &input, survey.WithValidator(validateDirPath))
|
||||
return input, err
|
||||
if err != nil {
|
||||
return input, errors.E(op, err)
|
||||
}
|
||||
return input, nil
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/httpc"
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
@ -99,17 +100,18 @@ func GetServerState(client *httpc.Client, endpoint string, hasMetadataV3 bool, l
|
||||
}
|
||||
|
||||
func GetServerStatus(versionEndpoint string, httpClient *httpc.Client) (err error) {
|
||||
var op errors.Op = "util.GetServerStatus"
|
||||
req, err := http.NewRequest("GET", versionEndpoint, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create GET request to %s: %w", versionEndpoint, err)
|
||||
return errors.E(op, fmt.Errorf("failed to create GET request to %s: %w", versionEndpoint, err))
|
||||
}
|
||||
var responseBs bytes.Buffer
|
||||
resp, err := httpClient.Do(context.Background(), req, &responseBs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("making http request failed: %w", err)
|
||||
return errors.E(op, fmt.Errorf("making http request failed: %w", err))
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("request failed: url: %s status code: %v status: %s \n%s", versionEndpoint, resp.StatusCode, resp.Status, responseBs.String())
|
||||
return errors.E(op, fmt.Errorf("request failed: url: %s status code: %v status: %s \n%s", versionEndpoint, resp.StatusCode, resp.Status, responseBs.String()))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
|
||||
)
|
||||
|
||||
// from https://gist.github.com/svett/424e6784facc0ba907ae
|
||||
@ -13,20 +15,21 @@ import (
|
||||
// Unzip unzips the archive to target. Both archive and target should be paths
|
||||
// in the filesystem. target is created if it doesn't exist already.
|
||||
func Unzip(archive, target string) error {
|
||||
var op errors.Op = "util.Unzip"
|
||||
reader, err := zip.OpenReader(archive)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(target, 0755); err != nil {
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
for _, file := range reader.File {
|
||||
path := filepath.Join(target, file.Name)
|
||||
if file.FileInfo().IsDir() {
|
||||
if err = os.MkdirAll(path, file.Mode()); err != nil {
|
||||
return fmt.Errorf("error while creating directory and it's parent directories: %w", err)
|
||||
return errors.E(op, fmt.Errorf("error while creating directory and it's parent directories: %w", err))
|
||||
}
|
||||
continue
|
||||
}
|
||||
@ -38,7 +41,7 @@ func Unzip(archive, target string) error {
|
||||
fileReader.Close()
|
||||
}
|
||||
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
|
||||
@ -49,14 +52,14 @@ func Unzip(archive, target string) error {
|
||||
targetFile.Close()
|
||||
}
|
||||
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
if _, err := io.Copy(targetFile, fileReader); err != nil {
|
||||
fileReader.Close()
|
||||
targetFile.Close()
|
||||
|
||||
return err
|
||||
return errors.E(op, err)
|
||||
}
|
||||
|
||||
fileReader.Close()
|
||||
|
Loading…
Reference in New Issue
Block a user