Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: merge code of exec and which command #366

Merged
merged 1 commit into from
Oct 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 16 additions & 1 deletion pkg/cli/exec.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
package cli

import (
"errors"
"fmt"
"path/filepath"

"github.com/suzuki-shunsuke/aqua/pkg/controller"
"github.com/urfave/cli/v2"
)

var errCommandIsRequired = errors.New("command is required")

func parseExecArgs(args []string) (string, []string, error) {
if len(args) == 0 {
return "", nil, errCommandIsRequired
}
return filepath.Base(args[0]), args[1:], nil
}

func (runner *Runner) execAction(c *cli.Context) error {
param := &controller.Param{}
if err := runner.setCLIArg(c, param); err != nil {
Expand All @@ -17,6 +28,10 @@ func (runner *Runner) execAction(c *cli.Context) error {
if err != nil {
return fmt.Errorf("initialize a controller: %w", err)
}
exeName, args, err := parseExecArgs(c.Args().Slice())
if err != nil {
return err
}

return ctrl.Exec(c.Context, param, c.Args().Slice()) //nolint:wrapcheck
return ctrl.Exec(c.Context, param, exeName, args) //nolint:wrapcheck
}
7 changes: 6 additions & 1 deletion pkg/cli/which.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,10 @@ func (runner *Runner) whichAction(c *cli.Context) error {
return fmt.Errorf("initialize a controller: %w", err)
}

return ctrl.Which(c.Context, param, c.Args().Slice()) //nolint:wrapcheck
exeName, _, err := parseExecArgs(c.Args().Slice())
if err != nil {
return err
}

return ctrl.Which(c.Context, param, exeName) //nolint:wrapcheck
}
1 change: 0 additions & 1 deletion pkg/controller/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ var (
errTypeAssertionGitHubContentRegistry = errors.New("registry.GetType() is github_content, but registry isn't *GitHubContentRegistry")
errInvalidPackageType = errors.New("package type is invalid")
errGitHubTokenIsRequired = errors.New("GITHUB_TOKEN is required for the type `github_release`")
errCommandIsRequired = errors.New("command is required")
errCommandIsNotFound = errors.New("command is not found")
errGitHubContentMustBeFile = errors.New("ref must be not a directory but a file")
errUnsupportedRegistryType = errors.New("unsupported registry type")
Expand Down
90 changes: 6 additions & 84 deletions pkg/controller/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"

"github.com/sirupsen/logrus"
"github.com/suzuki-shunsuke/go-error-with-exit-code/ecerror"
"github.com/suzuki-shunsuke/go-timeout/timeout"
"github.com/suzuki-shunsuke/logrus-error/logerr"
)

func getGlobalConfigFilePaths() []string {
Expand All @@ -26,79 +24,17 @@ func getGlobalConfigFilePaths() []string {
return paths
}

func (ctrl *Controller) Exec(ctx context.Context, param *Param, args []string) error { //nolint:cyclop
if len(args) == 0 {
return errCommandIsRequired
}

exeName := filepath.Base(args[0])
fields := logrus.Fields{
"exe_name": exeName,
}

wd, err := os.Getwd()
func (ctrl *Controller) Exec(ctx context.Context, param *Param, exeName string, args []string) error {
which, err := ctrl.which(ctx, param, exeName)
if err != nil {
return fmt.Errorf("get the current directory: %w", logerr.WithFields(err, fields))
return err
}

if cfgFilePath := ctrl.getConfigFilePath(wd, param.ConfigFilePath); cfgFilePath != "" {
pkg, pkgInfo, file, err := ctrl.findExecFile(ctx, cfgFilePath, exeName)
if err != nil {
if which.Package != nil {
if err := ctrl.installPackage(ctx, which.PkgInfo, which.Package, false); err != nil {
return err
}
if pkg != nil {
return ctrl.installAndExec(ctx, pkgInfo, pkg, file, args)
}
}

for _, cfgFilePath := range getGlobalConfigFilePaths() {
if _, err := os.Stat(cfgFilePath); err == nil {
pkg, pkgInfo, file, err := ctrl.findExecFile(ctx, cfgFilePath, exeName)
if err != nil {
return err
}
if pkg != nil {
return ctrl.installAndExec(ctx, pkgInfo, pkg, file, args)
}
}
}

cfgFilePath := ctrl.ConfigFinder.FindGlobal(ctrl.RootDir)
if _, err := os.Stat(cfgFilePath); err != nil {
return ctrl.findAndExecExtCommand(ctx, exeName, args[1:])
}

pkg, pkgInfo, file, err := ctrl.findExecFile(ctx, cfgFilePath, exeName)
if err != nil {
return err
}
if pkg == nil {
return ctrl.findAndExecExtCommand(ctx, exeName, args[1:])
}
return ctrl.installAndExec(ctx, pkgInfo, pkg, file, args)
}

func (ctrl *Controller) findAndExecExtCommand(ctx context.Context, exeName string, args []string) error {
exePath := lookPath(exeName)
if exePath == "" {
return logerr.WithFields(errCommandIsNotFound, logrus.Fields{ //nolint:wrapcheck
"exe_name": exeName,
})
}
return ctrl.execCommand(ctx, exePath, args)
}

func (ctrl *Controller) installAndExec(ctx context.Context, pkgInfo *MergedPackageInfo, pkg *Package, file *File, args []string) error {
fileSrc, err := pkgInfo.GetFileSrc(pkg, file)
if err != nil {
return fmt.Errorf("get file_src: %w", err)
}

if err := ctrl.installPackage(ctx, pkgInfo, pkg, false); err != nil {
return err
}

return ctrl.exec(ctx, pkg, pkgInfo, fileSrc, args[1:])
return ctrl.execCommand(ctx, which.ExePath, args)
}

func (ctrl *Controller) findExecFileFromPkg(registries map[string]*RegistryContent, exeName string, pkg *Package) (*MergedPackageInfo, *File) {
Expand Down Expand Up @@ -159,20 +95,6 @@ func (ctrl *Controller) findExecFile(ctx context.Context, cfgFilePath, exeName s
return nil, nil, nil, nil
}

func (ctrl *Controller) exec(ctx context.Context, pkg *Package, pkgInfo *MergedPackageInfo, src string, args []string) error {
pkgPath, err := pkgInfo.GetPkgPath(ctrl.RootDir, pkg)
if err != nil {
return fmt.Errorf("get pkg install path: %w", err)
}
exePath := filepath.Join(pkgPath, src)

if _, err := os.Stat(exePath); err != nil {
return fmt.Errorf("file.src is invalid. file isn't found %s: %w", exePath, err)
}

return ctrl.execCommand(ctx, exePath, args)
}

func (ctrl *Controller) execCommand(ctx context.Context, exePath string, args []string) error {
cmd := exec.Command(exePath, args...)
cmd.Stdin = ctrl.Stdin
Expand Down
61 changes: 39 additions & 22 deletions pkg/controller/which.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,39 @@ import (
"github.com/suzuki-shunsuke/logrus-error/logerr"
)

func (ctrl *Controller) Which(ctx context.Context, param *Param, args []string) error { //nolint:cyclop,funlen
if len(args) == 0 {
return errCommandIsRequired
func (ctrl *Controller) Which(ctx context.Context, param *Param, exeName string) error {
which, err := ctrl.which(ctx, param, exeName)
if err != nil {
return err
}
fmt.Fprintln(ctrl.Stdout, which.ExePath)
return nil
}

exeName := filepath.Base(args[0])
type Which struct {
Package *Package
PkgInfo *MergedPackageInfo
File *File
ExePath string
}

func (ctrl *Controller) which(ctx context.Context, param *Param, exeName string) (*Which, error) { //nolint:cyclop,funlen
fields := logrus.Fields{
"exe_name": exeName,
}

wd, err := os.Getwd()
if err != nil {
return fmt.Errorf("get the current directory: %w", logerr.WithFields(err, fields))
return nil, fmt.Errorf("get the current directory: %w", logerr.WithFields(err, fields))
}

if cfgFilePath := ctrl.getConfigFilePath(wd, param.ConfigFilePath); cfgFilePath != "" {
pkg, pkgInfo, file, err := ctrl.findExecFile(ctx, cfgFilePath, exeName)
if err != nil {
return err
return nil, err
}
if pkg != nil {
return ctrl.which(pkg, pkgInfo, file)
return ctrl.whichFile(pkg, pkgInfo, file)
}
}

Expand All @@ -41,52 +52,58 @@ func (ctrl *Controller) Which(ctx context.Context, param *Param, args []string)
}
pkg, pkgInfo, file, err := ctrl.findExecFile(ctx, cfgFilePath, exeName)
if err != nil {
return err
return nil, err
}
if pkg != nil {
return ctrl.which(pkg, pkgInfo, file)
return ctrl.whichFile(pkg, pkgInfo, file)
}
}

cfgFilePath := ctrl.ConfigFinder.FindGlobal(ctrl.RootDir)
if _, err := os.Stat(cfgFilePath); err != nil {
exePath := lookPath(exeName)
if exePath == "" {
return logerr.WithFields(errCommandIsNotFound, logrus.Fields{ //nolint:wrapcheck
return nil, logerr.WithFields(errCommandIsNotFound, logrus.Fields{ //nolint:wrapcheck
"exe_name": exeName,
})
}
fmt.Fprintln(ctrl.Stdout, exePath)
return nil
return &Which{
ExePath: exePath,
}, nil
}

pkg, pkgInfo, file, err := ctrl.findExecFile(ctx, cfgFilePath, exeName)
if err != nil {
return err
return nil, err
}
if pkg == nil {
exePath := lookPath(exeName)
if exePath == "" {
return logerr.WithFields(errCommandIsNotFound, logrus.Fields{ //nolint:wrapcheck
return nil, logerr.WithFields(errCommandIsNotFound, logrus.Fields{ //nolint:wrapcheck
"exe_name": exeName,
})
}
fmt.Fprintln(ctrl.Stdout, exePath)
return nil
return &Which{
ExePath: exePath,
}, nil
}

return ctrl.which(pkg, pkgInfo, file)
return ctrl.whichFile(pkg, pkgInfo, file)
}

func (ctrl *Controller) which(pkg *Package, pkgInfo *MergedPackageInfo, file *File) error {
func (ctrl *Controller) whichFile(pkg *Package, pkgInfo *MergedPackageInfo, file *File) (*Which, error) {
fileSrc, err := pkgInfo.GetFileSrc(pkg, file)
if err != nil {
return fmt.Errorf("get file_src: %w", err)
return nil, fmt.Errorf("get file_src: %w", err)
}
pkgPath, err := pkgInfo.GetPkgPath(ctrl.RootDir, pkg)
if err != nil {
return fmt.Errorf("get pkg install path: %w", err)
return nil, fmt.Errorf("get pkg install path: %w", err)
}
fmt.Fprintln(ctrl.Stdout, filepath.Join(pkgPath, fileSrc))
return nil
return &Which{
Package: pkg,
PkgInfo: pkgInfo,
File: file,
ExePath: filepath.Join(pkgPath, fileSrc),
}, nil
}