-
Notifications
You must be signed in to change notification settings - Fork 361
/
path.go
125 lines (112 loc) · 2.54 KB
/
path.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package path
import (
"strings"
"github.com/Shopify/go-lua"
"github.com/treeverse/lakefs/pkg/actions/lua/util"
)
const (
SEPARATOR = "/"
HiddenPrefix = "_"
)
func Open(l *lua.State) {
open := func(l *lua.State) int {
lua.NewLibrary(l, library)
return 1
}
lua.Require(l, "path", open, false)
l.Pop(1)
}
var library = []lua.RegistryFunction{
{Name: "parse", Function: parse},
{Name: "join", Function: join},
{Name: "is_hidden", Function: isHidden},
{Name: "default_separator", Function: getDefaultSeparator},
}
func getDefaultSeparator(l *lua.State) int {
l.PushString(SEPARATOR)
return 1
}
func parse(l *lua.State) int {
p := lua.CheckString(l, 1)
sep := SEPARATOR
if !l.IsNone(2) {
sep = lua.CheckString(l, 2)
}
return util.DeepPush(l, Parse(p, sep))
}
func getVarArgs(l *lua.State, from int) (vargs []string) {
for i := from; i <= l.Top(); i++ {
s, ok := l.ToString(i)
if !ok {
lua.Errorf(l, "invalid type, string expected")
panic("unreachable")
}
vargs = append(vargs, s)
}
return
}
func Parse(pth, sep string) map[string]string {
if strings.HasSuffix(pth, sep) {
pth = pth[0 : len(pth)-1]
}
lastIndex := strings.LastIndex(pth, sep)
if lastIndex == -1 {
// no separator
return map[string]string{
"parent": "", // no parent
"base_name": pth,
}
}
parent := pth[0 : lastIndex+1] // include sep
baseName := pth[lastIndex+1:] // don't include sep
return map[string]string{
"parent": parent,
"base_name": baseName,
}
}
func join(l *lua.State) int {
sep := lua.CheckString(l, 1)
parts := getVarArgs(l, 2)
l.PushString(Join(sep, parts...))
return 1
}
// Join joins the parts with the separator.
// Will keep the first part prefix separator (if found) and the last part suffix separator optional.
func Join(sep string, parts ...string) string {
var s string
for i, part := range parts {
// remove prefix sep if not first
if i != 0 {
part = strings.TrimPrefix(part, sep)
}
s += part
// if not last part, make sure we have a suffix sep
if i != len(parts)-1 && !strings.HasSuffix(part, sep) {
s += sep
}
}
return s
}
func IsHidden(pth, sep, prefix string) bool {
for pth != "" {
parsed := Parse(pth, sep)
if strings.HasPrefix(parsed["base_name"], prefix) {
return true
}
pth = parsed["parent"]
}
return false
}
func isHidden(l *lua.State) int {
p := lua.CheckString(l, 1)
sep := SEPARATOR
if !l.IsNone(2) {
sep = lua.CheckString(l, 2)
}
prefix := HiddenPrefix
if !l.IsNone(3) {
prefix = lua.CheckString(l, 3)
}
l.PushBoolean(IsHidden(p, sep, prefix))
return 1
}