Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more filepath functions. #62

Merged
merged 7 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go: ['1.14', '1.15', '1.16', '1.17', '1.18', '1.19']
go: ['1.14', '1.15', '1.16', '1.17', '1.18', '1.19', '1.20', '1.21']

services: {}
steps:
Expand Down
153 changes: 134 additions & 19 deletions filepath/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,100 @@ import (
lua "github.com/yuin/gopher-lua"
)

// Abs returns an absolute representation of path.
func Abs(L *lua.LState) int {
path := L.CheckString(1)
ret, err := filepath.Abs(path)
L.Push(lua.LString(ret))
if err != nil {
L.Push(lua.LString(err.Error()))
return 2
}
return 1
}

// Basename lua filepath.basename(path) returns the last element of path
func Basename(L *lua.LState) int {
path := L.CheckString(1)
L.Push(lua.LString(filepath.Base(path)))
return 1
}

// Clean returns the shortest path name equivalent to path
func Clean(L *lua.LState) int {
path := L.CheckString(1)
L.Push(lua.LString(filepath.Clean(path)))
return 1
}

// Dir lua filepath.dir(path) returns all but the last element of path, typically the path's directory
func Dir(L *lua.LState) int {
path := L.CheckString(1)
L.Push(lua.LString(filepath.Dir(path)))
return 1
}

// EvalSymlinks returns the path name after the evaluation of any symbolic link.
func EvalSymlinks(L *lua.LState) int {
path := L.CheckString(1)
ret, err := filepath.EvalSymlinks(path)
L.Push(lua.LString(ret))
if err != nil {
L.Push(lua.LString(err.Error()))
return 2
}
return 1
}

// FromSlash returns the result of replacing each slash ('/') character
// in path with a separator character. Multiple slashes are replaced
// by multiple separators.
func FromSlash(L *lua.LState) int {
path := L.CheckString(1)
L.Push(lua.LString(filepath.FromSlash(path)))
return 1
}

// Ext lua filepath.ext(path) returns the file name extension used by path.
func Ext(L *lua.LState) int {
path := L.CheckString(1)
L.Push(lua.LString(filepath.Ext(path)))
return 1
}

// Join lua fileapth.join(path, ...) joins any number of path elements into a single path, adding a Separator if necessary.
func Join(L *lua.LState) int {
path := L.CheckString(1)
for i := 2; i <= L.GetTop(); i++ {
add := L.CheckAny(i).String()
path = filepath.Join(path, add)
// Glob: filepath.glob(pattern) returns the names of all files matching pattern or nil if there is no matching file.
func Glob(L *lua.LState) int {
pattern := L.CheckString(1)
files, err := filepath.Glob(pattern)
if err != nil {
L.Push(lua.LNil)
L.Push(lua.LString(err.Error()))
return 2
}
L.Push(lua.LString(path))
result := L.CreateTable(len(files), 0)
for _, file := range files {
result.Append(lua.LString(file))
}
L.Push(result)
return 1
}

// Separator lua filepath.separator() OS-specific path separator
func Separator(L *lua.LState) int {
L.Push(lua.LString(filepath.Separator))
// IsAbs reports whether the path is absolute.
func IsAbs(L *lua.LState) int {
path := L.CheckString(1)
L.Push(lua.LBool(filepath.IsAbs(path)))
return 1
}

// Join lua fileapth.join(path, ...) joins any number of path elements into a single path, adding a Separator if necessary.
func Join(L *lua.LState) int {
var elems []string
for i := 1; i <= L.GetTop(); i++ {
elem := L.CheckAny(i).String()
elems = append(elems, elem)
}
path := filepath.Join(elems...)
L.Push(lua.LString(path))
return 1
}

Expand All @@ -51,18 +110,74 @@ func ListSeparator(L *lua.LState) int {
return 1
}

// filepath.glob(pattern) returns the names of all files matching pattern or nil if there is no matching file.
func Glob(L *lua.LState) int {
// Match reports whether name matches the shell file name pattern.
func Match(L *lua.LState) int {
pattern := L.CheckString(1)
files, err := filepath.Glob(pattern)
name := L.CheckString(2)
matched, err := filepath.Match(pattern, name)
L.Push(lua.LBool(matched))
if err != nil {
L.Push(lua.LNil)
return 1
L.Push(lua.LString(err.Error()))
return 2
}
result := L.CreateTable(len(files), 0)
for _, file := range files {
result.Append(lua.LString(file))
return 1
}

// Rel returns a relative path
func Rel(L *lua.LState) int {
basepath := L.CheckString(1)
targpath := L.CheckString(2)
ret, err := filepath.Rel(basepath, targpath)
L.Push(lua.LString(ret))
if err != nil {
L.Push(lua.LString(err.Error()))
return 2
}
L.Push(result)
return 1
}

// Separator lua filepath.separator() OS-specific path separator
func Separator(L *lua.LState) int {
L.Push(lua.LString(filepath.Separator))
return 1
}

// Split splits path immediately following the final Separator,
// separating it into a directory and file name component.
func Split(L *lua.LState) int {
path := L.CheckString(1)
dir, file := filepath.Split(path)
L.Push(lua.LString(dir))
L.Push(lua.LString(file))
return 2
}

func SplitList(L *lua.LState) int {
path := L.CheckString(1)
ret := filepath.SplitList(path)
table := L.CreateTable(len(ret), 0)
for _, part := range ret {
table.Append(lua.LString(part))
}
L.Push(table)
return 1
}

// ToSlash returns the result of replacing each separator character
// in path with a slash ('/') character. Multiple separators are
// replaced by multiple slashes.
func ToSlash(L *lua.LState) int {
path := L.CheckString(1)
L.Push(lua.LString(filepath.ToSlash(path)))
return 1
}

// VolumeName returns leading volume name.
// Given "C:\foo\bar" it returns "C:" on Windows.
// Given "\\host\share\foo" it returns "\\host\share".
// On other platforms it returns "".
func VolumeName(L *lua.LState) int {
path := L.CheckString(1)
L.Push(lua.LString(filepath.VolumeName(path)))
return 1
}
7 changes: 6 additions & 1 deletion filepath/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ package filepath

import (
"github.com/stretchr/testify/assert"
"github.com/vadv/gopher-lua-libs/inspect"
"github.com/vadv/gopher-lua-libs/tests"
"testing"
)

func TestApi(t *testing.T) {
assert.NotZero(t, tests.RunLuaTestFile(t, Preload, "./test/test_api.lua"))
preload := tests.SeveralPreloadFuncs(
Preload,
inspect.Preload,
)
assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua"))
}
17 changes: 14 additions & 3 deletions filepath/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
// Preload adds filepath to the given Lua state's package.preload table. After it
// has been preloaded, it can be loaded using require:
//
// local filepath = require("filepath")
// local filepath = require("filepath")
func Preload(L *lua.LState) {
L.PreloadModule("filepath", Loader)
}
Expand All @@ -21,11 +21,22 @@ func Loader(L *lua.LState) int {
}

var api = map[string]lua.LGFunction{
"dir": Dir,
"abs": Abs,
"basename": Basename,
"clean": Clean,
"dir": Dir,
"eval_symlinks": EvalSymlinks,
"from_slash": FromSlash,
"ext": Ext,
"glob": Glob,
"is_abs": IsAbs,
"join": Join,
"separator": Separator,
"list_separator": ListSeparator,
"match": Match,
"rel": Rel,
"separator": Separator,
"split": Split,
"split_list": SplitList,
"to_slash": ToSlash,
"volume_name": VolumeName,
}
Loading
Loading