From 299561d82aaccd6d5c31449dc77e5c5d5476f440 Mon Sep 17 00:00:00 2001 From: Andrew Nester Date: Thu, 1 Feb 2024 11:41:44 +0000 Subject: [PATCH 1/6] Use CMD on Windows first as a shell to build artifacts --- libs/exec/shell.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/libs/exec/shell.go b/libs/exec/shell.go index 8589aed763..5d00cb3da7 100644 --- a/libs/exec/shell.go +++ b/libs/exec/shell.go @@ -4,6 +4,7 @@ import ( "errors" "io" "os" + "runtime" ) type shell interface { @@ -17,11 +18,21 @@ type execContext struct { } func findShell() (shell, error) { - for _, fn := range []func() (shell, error){ + finders := []func() (shell, error){ newBashShell, newShShell, - newCmdShell, - } { + } + + // If on Windows, first try to find and use CMD as a shell + if runtime.GOOS == "windows" { + finders = []func() (shell, error){ + newCmdShell, + newBashShell, + newShShell, + } + } + + for _, fn := range finders { shell, err := fn() if err != nil { return nil, err From ce695623be3662eef0418395f3a3b743551bcad3 Mon Sep 17 00:00:00 2001 From: Andrew Nester Date: Thu, 1 Feb 2024 12:12:25 +0000 Subject: [PATCH 2/6] Allow specifying executable in artifact section --- bundle/config/artifact.go | 10 +++++++++- libs/exec/exec.go | 29 +++++++++++++++++++++++++++++ libs/exec/shell.go | 17 +++-------------- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/bundle/config/artifact.go b/bundle/config/artifact.go index 2a1a92a150..9b5fe534c9 100644 --- a/bundle/config/artifact.go +++ b/bundle/config/artifact.go @@ -42,6 +42,8 @@ type Artifact struct { Files []ArtifactFile `json:"files,omitempty"` BuildCommand string `json:"build,omitempty"` + Executable exec.ExecutableType `json:"executable,omitempty"` + paths.Paths } @@ -50,7 +52,13 @@ func (a *Artifact) Build(ctx context.Context) ([]byte, error) { return nil, fmt.Errorf("no build property defined") } - e, err := exec.NewCommandExecutor(a.Path) + var e *exec.Executor + var err error + if a.Executable != "" { + e, err = exec.NewCommandExecutorWithExecutable(a.Path, a.Executable) + } else { + e, err = exec.NewCommandExecutor(a.Path) + } if err != nil { return nil, err } diff --git a/libs/exec/exec.go b/libs/exec/exec.go index a85e19ea16..bac9395755 100644 --- a/libs/exec/exec.go +++ b/libs/exec/exec.go @@ -2,11 +2,24 @@ package exec import ( "context" + "fmt" "io" "os" osexec "os/exec" ) +type ExecutableType string + +const BashExecutable ExecutableType = `bash` +const ShExecutable ExecutableType = `sh` +const CmdExecutable ExecutableType = `cmd` + +var finders map[ExecutableType](func() (shell, error)) = map[ExecutableType](func() (shell, error)){ + BashExecutable: newBashShell, + ShExecutable: newBashShell, + CmdExecutable: newBashShell, +} + type Command interface { // Wait for command to terminate. It must have been previously started. Wait() error @@ -61,6 +74,22 @@ func NewCommandExecutor(dir string) (*Executor, error) { }, nil } +func NewCommandExecutorWithExecutable(dir string, execType ExecutableType) (*Executor, error) { + f, ok := finders[execType] + if !ok { + return nil, fmt.Errorf("%s is not supported as an artifact executable", execType) + } + shell, err := f() + if err != nil { + return nil, err + } + + return &Executor{ + shell: shell, + dir: dir, + }, nil +} + func (e *Executor) StartCommand(ctx context.Context, command string) (Command, error) { ec, err := e.shell.prepare(command) if err != nil { diff --git a/libs/exec/shell.go b/libs/exec/shell.go index 5d00cb3da7..8589aed763 100644 --- a/libs/exec/shell.go +++ b/libs/exec/shell.go @@ -4,7 +4,6 @@ import ( "errors" "io" "os" - "runtime" ) type shell interface { @@ -18,21 +17,11 @@ type execContext struct { } func findShell() (shell, error) { - finders := []func() (shell, error){ + for _, fn := range []func() (shell, error){ newBashShell, newShShell, - } - - // If on Windows, first try to find and use CMD as a shell - if runtime.GOOS == "windows" { - finders = []func() (shell, error){ - newCmdShell, - newBashShell, - newShShell, - } - } - - for _, fn := range finders { + newCmdShell, + } { shell, err := fn() if err != nil { return nil, err From 37ad5c26c723682b1e3ad4b4e83b4b14e4da990e Mon Sep 17 00:00:00 2001 From: Andrew Nester Date: Thu, 1 Feb 2024 12:13:26 +0000 Subject: [PATCH 3/6] typo --- libs/exec/exec.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/exec/exec.go b/libs/exec/exec.go index bac9395755..7a613e8410 100644 --- a/libs/exec/exec.go +++ b/libs/exec/exec.go @@ -16,8 +16,8 @@ const CmdExecutable ExecutableType = `cmd` var finders map[ExecutableType](func() (shell, error)) = map[ExecutableType](func() (shell, error)){ BashExecutable: newBashShell, - ShExecutable: newBashShell, - CmdExecutable: newBashShell, + ShExecutable: newShShell, + CmdExecutable: newCmdShell, } type Command interface { From 8459cd9fcb5110070758b7870036427bda53ffde Mon Sep 17 00:00:00 2001 From: Andrew Nester Date: Thu, 1 Feb 2024 12:51:26 +0000 Subject: [PATCH 4/6] added available options --- libs/exec/exec.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/exec/exec.go b/libs/exec/exec.go index 7a613e8410..6636fd9d21 100644 --- a/libs/exec/exec.go +++ b/libs/exec/exec.go @@ -77,7 +77,7 @@ func NewCommandExecutor(dir string) (*Executor, error) { func NewCommandExecutorWithExecutable(dir string, execType ExecutableType) (*Executor, error) { f, ok := finders[execType] if !ok { - return nil, fmt.Errorf("%s is not supported as an artifact executable", execType) + return nil, fmt.Errorf("%s is not supported as an artifact executable, options are: %s, %s or %s", execType, BashExecutable, ShExecutable, CmdExecutable) } shell, err := f() if err != nil { From 2f8d04834876c03658bbd37990da221a858e7b7a Mon Sep 17 00:00:00 2001 From: Andrew Nester Date: Thu, 1 Feb 2024 13:52:52 +0000 Subject: [PATCH 5/6] skip WSL bash --- libs/exec/shell_bash.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libs/exec/shell_bash.go b/libs/exec/shell_bash.go index c8af31b085..12977f268b 100644 --- a/libs/exec/shell_bash.go +++ b/libs/exec/shell_bash.go @@ -3,6 +3,7 @@ package exec import ( "errors" osexec "os/exec" + "strings" ) type bashShell struct { @@ -33,5 +34,10 @@ func newBashShell() (shell, error) { return nil, nil } + // Skipping WSL bash if found one + if strings.Contains(out, `\Windows\System32\bash.exe`) || strings.Contains(out, `\Microsoft\WindowsApps\bash.exe`) { + return nil, nil + } + return &bashShell{executable: out}, nil } From b2e770264507bcd745dd66b12084b88c58068d3e Mon Sep 17 00:00:00 2001 From: Andrew Nester Date: Thu, 1 Feb 2024 13:59:12 +0000 Subject: [PATCH 6/6] set executable --- bundle/config/artifact.go | 1 + libs/exec/exec.go | 4 ++++ libs/exec/shell.go | 1 + libs/exec/shell_bash.go | 4 ++++ libs/exec/shell_cmd.go | 4 ++++ libs/exec/shell_sh.go | 4 ++++ 6 files changed, 18 insertions(+) diff --git a/bundle/config/artifact.go b/bundle/config/artifact.go index 9b5fe534c9..279a8f3b7d 100644 --- a/bundle/config/artifact.go +++ b/bundle/config/artifact.go @@ -58,6 +58,7 @@ func (a *Artifact) Build(ctx context.Context) ([]byte, error) { e, err = exec.NewCommandExecutorWithExecutable(a.Path, a.Executable) } else { e, err = exec.NewCommandExecutor(a.Path) + a.Executable = e.ShellType() } if err != nil { return nil, err diff --git a/libs/exec/exec.go b/libs/exec/exec.go index 6636fd9d21..9767c199a2 100644 --- a/libs/exec/exec.go +++ b/libs/exec/exec.go @@ -128,3 +128,7 @@ func (e *Executor) Exec(ctx context.Context, command string) ([]byte, error) { return res, cmd.Wait() } + +func (e *Executor) ShellType() ExecutableType { + return e.shell.getType() +} diff --git a/libs/exec/shell.go b/libs/exec/shell.go index 8589aed763..f5d1768967 100644 --- a/libs/exec/shell.go +++ b/libs/exec/shell.go @@ -8,6 +8,7 @@ import ( type shell interface { prepare(string) (*execContext, error) + getType() ExecutableType } type execContext struct { diff --git a/libs/exec/shell_bash.go b/libs/exec/shell_bash.go index 12977f268b..bb8c6c514f 100644 --- a/libs/exec/shell_bash.go +++ b/libs/exec/shell_bash.go @@ -41,3 +41,7 @@ func newBashShell() (shell, error) { return &bashShell{executable: out}, nil } + +func (s bashShell) getType() ExecutableType { + return BashExecutable +} diff --git a/libs/exec/shell_cmd.go b/libs/exec/shell_cmd.go index b207c513d7..164d09739f 100644 --- a/libs/exec/shell_cmd.go +++ b/libs/exec/shell_cmd.go @@ -36,3 +36,7 @@ func newCmdShell() (shell, error) { return &cmdShell{executable: out}, nil } + +func (s cmdShell) getType() ExecutableType { + return CmdExecutable +} diff --git a/libs/exec/shell_sh.go b/libs/exec/shell_sh.go index 1181c5e33a..ca42ecfa46 100644 --- a/libs/exec/shell_sh.go +++ b/libs/exec/shell_sh.go @@ -35,3 +35,7 @@ func newShShell() (shell, error) { return &shShell{executable: out}, nil } + +func (s shShell) getType() ExecutableType { + return ShExecutable +}