-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
## Changes Falling back to `sh` is also what GitHub Actions do if `bash` is not found in the path. It is possible `bash` is not available when running from minimal Docker containers and we must not error out in this case. See: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell. This change renames `interpreter` -> `shell`. ## Tests Unit tests pass.
- Loading branch information
Showing
10 changed files
with
307 additions
and
159 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package exec | ||
|
||
import ( | ||
"errors" | ||
"io" | ||
"os" | ||
) | ||
|
||
type shell interface { | ||
prepare(string) (*execContext, error) | ||
} | ||
|
||
type execContext struct { | ||
executable string | ||
args []string | ||
scriptFile string | ||
} | ||
|
||
func findShell() (shell, error) { | ||
for _, fn := range []func() (shell, error){ | ||
newBashShell, | ||
newShShell, | ||
newCmdShell, | ||
} { | ||
shell, err := fn() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if shell != nil { | ||
return shell, nil | ||
} | ||
} | ||
|
||
return nil, errors.New("no shell found") | ||
} | ||
|
||
func createTempScript(command string, extension string) (string, error) { | ||
file, err := os.CreateTemp(os.TempDir(), "cli-exec*"+extension) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
defer file.Close() | ||
|
||
_, err = io.WriteString(file, command) | ||
if err != nil { | ||
// Try to remove the file if we failed to write to it | ||
os.Remove(file.Name()) | ||
return "", err | ||
} | ||
|
||
return file.Name(), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package exec | ||
|
||
import ( | ||
"errors" | ||
osexec "os/exec" | ||
) | ||
|
||
type bashShell struct { | ||
executable string | ||
} | ||
|
||
func (s bashShell) prepare(command string) (*execContext, error) { | ||
filename, err := createTempScript(command, ".sh") | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &execContext{ | ||
executable: s.executable, | ||
args: []string{"-e", filename}, | ||
scriptFile: filename, | ||
}, nil | ||
} | ||
|
||
func newBashShell() (shell, error) { | ||
out, err := osexec.LookPath("bash") | ||
if err != nil && !errors.Is(err, osexec.ErrNotFound) { | ||
return nil, err | ||
} | ||
|
||
// `bash` is not found, return early. | ||
if out == "" { | ||
return nil, nil | ||
} | ||
|
||
return &bashShell{executable: out}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package exec | ||
|
||
import ( | ||
"runtime" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestBashFound(t *testing.T) { | ||
if runtime.GOOS == "windows" { | ||
t.SkipNow() | ||
} | ||
|
||
shell, err := newBashShell() | ||
assert.NoError(t, err) | ||
assert.NotNil(t, shell) | ||
} | ||
|
||
func TestBashNotFound(t *testing.T) { | ||
if runtime.GOOS == "windows" { | ||
t.SkipNow() | ||
} | ||
|
||
t.Setenv("PATH", "") | ||
|
||
shell, err := newBashShell() | ||
assert.NoError(t, err) | ||
assert.Nil(t, shell) | ||
} |
Oops, something went wrong.