diff --git a/pkg/controller/exec/controller.go b/pkg/controller/exec/controller.go index 1bffdf499..53aa4c2b8 100644 --- a/pkg/controller/exec/controller.go +++ b/pkg/controller/exec/controller.go @@ -5,6 +5,7 @@ import ( "io" "log/slog" "os" + "os/exec" "runtime" "time" @@ -28,6 +29,7 @@ type Controller struct { policyReader PolicyReader enabledXSysExec bool vacuum Vacuum + lookPath func(exeName string) (string, error) } type Vacuum interface { @@ -50,6 +52,7 @@ func New(pkgInstaller Installer, whichCtrl WhichController, executor Executor, o fs: fs, policyReader: policyReader, vacuum: vacuum, + lookPath: exec.LookPath, } } diff --git a/pkg/controller/exec/exec.go b/pkg/controller/exec/exec.go index 02873da9a..c02b311cc 100644 --- a/pkg/controller/exec/exec.go +++ b/pkg/controller/exec/exec.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "log/slog" + "strings" "time" "github.com/aquaproj/aqua/v2/pkg/checksum" @@ -69,8 +70,27 @@ func (c *Controller) Exec(ctx context.Context, logger *slog.Logger, param *confi if err := c.updateTimestamp(findResult.Package); err != nil { slogerr.WithError(logger, err).Warn("update the last used datetime") } + exeName, exePath, args, err := c.wrapExec(exeName, findResult.ExePath, args...) + if err != nil { + return err + } + + return c.execCommandWithRetry(ctx, logger, exePath, exeName, args...) +} - return c.execCommandWithRetry(ctx, logger, findResult.ExePath, exeName, args...) +func (c *Controller) wrapExec(exeName, exePath string, args ...string) (string, string, []string, error) { + return wrapExec(c.lookPath, exeName, exePath, args...) +} + +func wrapExec(lookPath func(exeName string) (string, error), exeName, exePath string, args ...string) (string, string, []string, error) { + if !strings.HasSuffix(exePath, ".jar") { + return exeName, exePath, args, nil + } + p, err := lookPath("java") + if err != nil { + return "", "", nil, fmt.Errorf("look up java to execute jar: %w", err) + } + return "java", p, append([]string{"-jar", exePath}, args...), nil } func (c *Controller) updateTimestamp(pkg *config.Package) error { diff --git a/pkg/controller/exec/exec_internal_test.go b/pkg/controller/exec/exec_internal_test.go index cd5a40326..6102e55f2 100644 --- a/pkg/controller/exec/exec_internal_test.go +++ b/pkg/controller/exec/exec_internal_test.go @@ -3,6 +3,7 @@ package exec import ( "log/slog" "os" + "slices" "testing" "github.com/aquaproj/aqua/v2/pkg/osexec" @@ -43,3 +44,76 @@ func TestController_execCommand(t *testing.T) { }) } } + +func Test_wrapExec(t *testing.T) { //nolint:funlen + t.Parallel() + data := []struct { + title string + lookPath func(exeName string) (string, error) + exeName string + exePath string + args []string + expExeName string + expExePath string + expArgs []string + isErr bool + }{ + { + title: "non jar", + exeName: "foo", + exePath: "/usr/bin/foo", + args: []string{"--help"}, + expExeName: "foo", + expExePath: "/usr/bin/foo", + expArgs: []string{"--help"}, + }, + { + title: "jar", + lookPath: func(string) (string, error) { + return "/usr/bin/java", nil + }, + exeName: "app", + exePath: "/path/to/app.jar", + args: []string{"arg1"}, + expExeName: "java", + expExePath: "/usr/bin/java", + expArgs: []string{"-jar", "/path/to/app.jar", "arg1"}, + }, + { + title: "jar without args", + lookPath: func(string) (string, error) { + return "/usr/bin/java", nil + }, + exeName: "app", + exePath: "/path/to/app.jar", + args: []string{}, + expExeName: "java", + expExePath: "/usr/bin/java", + expArgs: []string{"-jar", "/path/to/app.jar"}, + }, + } + for _, d := range data { + t.Run(d.title, func(t *testing.T) { + t.Parallel() + exeName, exePath, args, err := wrapExec(d.lookPath, d.exeName, d.exePath, d.args...) + if err != nil { + if !d.isErr { + t.Fatalf("unexpected error: %v", err) + } + return + } + if d.isErr { + t.Fatalf("expected error, but got none") + } + if exeName != d.expExeName { + t.Fatalf("exeName = %s, want %s", exeName, d.expExeName) + } + if exePath != d.expExePath { + t.Fatalf("exePath = %s, want %s", exePath, d.expExePath) + } + if !slices.Equal(args, d.expArgs) { + t.Fatalf("args = %v, want %v", args, d.expArgs) + } + }) + } +}