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