Skip to content

Commit

Permalink
Add fsext.Abs helper function (#3452)
Browse files Browse the repository at this point in the history
  • Loading branch information
oleiade authored Nov 10, 2023
1 parent 5e83d38 commit d26bde8
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 15 deletions.
16 changes: 1 addition & 15 deletions js/initcontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"net/url"
"path/filepath"

"github.com/dop251/goja"
"github.com/sirupsen/logrus"
Expand All @@ -20,20 +19,7 @@ const cantBeUsedOutsideInitContextMsg = `the "%s" function is only available in
// contents of a file. If the second argument is "b" it returns an ArrayBuffer
// instance, otherwise a string representation.
func openImpl(rt *goja.Runtime, fs fsext.Fs, basePWD *url.URL, filename string, args ...string) (goja.Value, error) {
// Here IsAbs should be enough but unfortunately it doesn't handle absolute paths starting from
// the current drive on windows like `\users\noname\...`. Also it makes it more easy to test and
// will probably be need for archive execution under windows if always consider '/...' as an
// absolute path.
if filename[0] != '/' && filename[0] != '\\' && !filepath.IsAbs(filename) {
filename = filepath.Join(basePWD.Path, filename)
}
filename = filepath.Clean(filename)

if filename[0:1] != fsext.FilePathSeparator {
filename = fsext.FilePathSeparator + filename
}

data, err := readFile(fs, filename)
data, err := readFile(fs, fsext.Abs(basePWD.Path, filename))
if err != nil {
return nil, err
}
Expand Down
28 changes: 28 additions & 0 deletions lib/fsext/filepath.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,31 @@ import (
func JoinFilePath(b, p string) string {
return filepath.Join(b, filepath.Clean("/"+p))
}

// Abs returns an absolute representation of path.
//
// this implementation allows k6 to handle absolute paths starting from
// the current drive on windows like `\users\noname\...`. It makes it easier
// to test and is needed for archive execution under windows (it always consider '/...' as an
// absolute path).
//
// If the path is not absolute it will be joined with root
// to turn it into an absolute path. The root path is assumed
// to be a directory.
//
// Because k6 does not interact with the OS itself, but with
// its own virtual file system, it needs to be able to resolve
// the root path of the file system. In most cases this would be
// the bundle or init environment's working directory.
func Abs(root, path string) string {
if path[0] != '/' && path[0] != '\\' && !filepath.IsAbs(path) {
path = filepath.Join(root, path)
}
path = filepath.Clean(path)

if path[0:1] != FilePathSeparator {
path = FilePathSeparator + path
}

return path
}
56 changes: 56 additions & 0 deletions lib/fsext/filepath_unix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,59 @@ func TestJoinFilePath(t *testing.T) {
})
}
}

func TestAbs(t *testing.T) {
t.Parallel()

type args struct {
root string
path string
}
tests := []struct {
name string
args args
want string
}{
{
name: "absolute path",
args: args{
root: "/",
path: "/test",
},
want: "/test",
},
{
name: "relative path",
args: args{
root: "/",
path: "test",
},
want: "/test",
},
{
name: "relative path with leading dot",
args: args{
root: "/",
path: "./test",
},
want: "/test",
},
{
name: "relative path with leading double dot",
args: args{
root: "/",
path: "../test",
},
want: "/test",
},
}
for _, tt := range tests {
tt := tt

t.Run(tt.name, func(t *testing.T) {
t.Parallel()

assert.Equal(t, tt.want, fsext.Abs(tt.args.root, tt.args.path))
})
}
}
56 changes: 56 additions & 0 deletions lib/fsext/filepath_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,59 @@ func TestJoinFilePath(t *testing.T) {
})
}
}

func TestAbs(t *testing.T) {
t.Parallel()

type args struct {
root string
path string
}
tests := []struct {
name string
args args
want string
}{
{
name: "absolute path",
args: args{
root: "\\",
path: "\\test",
},
want: "\\test",
},
{
name: "relative path",
args: args{
root: "\\",
path: "test",
},
want: "\\test",
},
{
name: "relative path with leading dot",
args: args{
root: "\\",
path: ".\\test",
},
want: "\\test",
},
{
name: "relative path with leading double dot",
args: args{
root: "\\",
path: "..\\test",
},
want: "\\test",
},
}
for _, tt := range tests {
tt := tt

t.Run(tt.name, func(t *testing.T) {
t.Parallel()

assert.Equal(t, tt.want, fsext.Abs(tt.args.root, tt.args.path))
})
}
}

0 comments on commit d26bde8

Please sign in to comment.