Skip to content

Commit

Permalink
Merge pull request #9 from cli/go-1.19-compat
Browse files Browse the repository at this point in the history
Allow relative PATH entries on Go 1.19+
  • Loading branch information
mislav authored Dec 12, 2022
2 parents 7342e94 + e86b61c commit df52b7a
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
go: [1.13, 1.14, 1.15]
go: [1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20]

runs-on: ${{matrix.os}}
steps:
Expand Down
14 changes: 11 additions & 3 deletions lookpath.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
// +build !windows
//go:build !windows && go1.19
// +build !windows,go1.19

package safeexec

import "os/exec"
import (
"errors"
"os/exec"
)

func LookPath(file string) (string, error) {
return exec.LookPath(file)
path, err := exec.LookPath(file)
if errors.Is(err, exec.ErrDot) {
return path, nil
}
return path, err
}
10 changes: 10 additions & 0 deletions lookpath_1.18.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//go:build !windows && !go1.19
// +build !windows,!go1.19

package safeexec

import "os/exec"

func LookPath(file string) (string, error) {
return exec.LookPath(file)
}
52 changes: 43 additions & 9 deletions lookpath_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,97 +16,117 @@ func TestLookPath(t *testing.T) {
t.Fatal(wderr)
}

paths := []string{
filepath.Join(root, "_fixtures", "nonexist"),
filepath.Join(root, "_fixtures", "system"),
}
os.Setenv("PATH", strings.Join(paths, string(filepath.ListSeparator)))

if err := os.Chdir(filepath.Join(root, "_fixtures", "cwd")); err != nil {
t.Fatal(err)
}

testCases := []struct {
desc string
path []string
pathext string
arg string
wants string
wantErr bool
}{
{
desc: "no extension",
desc: "no extension",
path: []string{
filepath.Join(root, "_fixtures", "nonexist"),
filepath.Join(root, "_fixtures", "system"),
},
pathext: "",
arg: "ls",
wants: filepath.Join(root, "_fixtures", "system", "ls"+winonly(".exe")),
wantErr: false,
},
{
desc: "with extension",
path: []string{filepath.Join(root, "_fixtures", "system")},
pathext: "",
arg: "ls.exe",
wants: filepath.Join(root, "_fixtures", "system", "ls.exe"),
wantErr: false,
},
{
desc: "with path",
path: []string{filepath.Join(root, "_fixtures", "system")},
pathext: "",
arg: filepath.Join("..", "system", "ls"),
wants: filepath.Join("..", "system", "ls"+winonly(".exe")),
wantErr: false,
},
{
desc: "with path+extension",
path: []string{filepath.Join(root, "_fixtures", "system")},
pathext: "",
arg: filepath.Join("..", "system", "ls.bat"),
wants: filepath.Join("..", "system", "ls.bat"),
wantErr: false,
},
{
desc: "no extension, PATHEXT",
path: []string{filepath.Join(root, "_fixtures", "system")},
pathext: ".com;.bat",
arg: "ls",
wants: filepath.Join(root, "_fixtures", "system", "ls"+winonly(".bat")),
wantErr: false,
},
{
desc: "with extension, PATHEXT",
path: []string{filepath.Join(root, "_fixtures", "system")},
pathext: ".com;.bat",
arg: "ls.exe",
wants: filepath.Join(root, "_fixtures", "system", "ls.exe"),
wantErr: false,
},
{
desc: "no extension, not found",
desc: "no extension, not found",
path: []string{
filepath.Join(root, "_fixtures", "nonexist"),
filepath.Join(root, "_fixtures", "system"),
},
pathext: "",
arg: "cat",
wants: "",
wantErr: true,
},
{
desc: "with extension, not found",
path: []string{filepath.Join(root, "_fixtures", "system")},
pathext: "",
arg: "cat.exe",
wants: "",
wantErr: true,
},
{
desc: "no extension, PATHEXT, not found",
path: []string{filepath.Join(root, "_fixtures", "system")},
pathext: ".com;.bat",
arg: "cat",
wants: "",
wantErr: true,
},
{
desc: "with extension, PATHEXT, not found",
path: []string{filepath.Join(root, "_fixtures", "system")},
pathext: ".com;.bat",
arg: "cat.exe",
wants: "",
wantErr: true,
},
{
desc: "relative path",
path: []string{filepath.Join("..", "system")},
pathext: "",
arg: "ls",
wants: filepath.Join("..", "system", "ls"+winonly(".exe")),
wantErr: false,
},
}
for _, tC := range testCases {
t.Run(tC.desc, func(t *testing.T) {
os.Setenv("PATHEXT", tC.pathext)
setenv(t, "PATH", strings.Join(tC.path, string(filepath.ListSeparator)))
setenv(t, "PATHEXT", tC.pathext)
got, err := LookPath(tC.arg)

if tC.wantErr != (err != nil) {
Expand All @@ -122,6 +142,20 @@ func TestLookPath(t *testing.T) {
}
}

func setenv(t *testing.T, name, newValue string) {
oldValue, hasOldValue := os.LookupEnv(name)
if err := os.Setenv(name, newValue); err != nil {
t.Errorf("error setting environment variable %s: %v", name, err)
}
t.Cleanup(func() {
if hasOldValue {
_ = os.Setenv(name, oldValue)
} else {
_ = os.Unsetenv(name)
}
})
}

func winonly(s string) string {
if runtime.GOOS == "windows" {
return s
Expand Down

0 comments on commit df52b7a

Please sign in to comment.