Extract prefix from glob pattern

This commit is contained in:
Ingo Oppermann
2025-03-24 21:02:50 +01:00
parent d54512d927
commit a08d8a0ca8
3 changed files with 58 additions and 8 deletions

View File

@@ -1,19 +1,25 @@
package glob
import "github.com/gobwas/glob"
import (
"strings"
"github.com/gobwas/glob"
)
type Glob interface {
Match(name string) bool
Prefix() string
}
type globber struct {
glob glob.Glob
pattern string
glob glob.Glob
}
func MustCompile(pattern string, separators ...rune) Glob {
g := glob.MustCompile(pattern, separators...)
return &globber{glob: g}
return &globber{pattern: pattern, glob: g}
}
func Compile(pattern string, separators ...rune) (Glob, error) {
@@ -22,13 +28,26 @@ func Compile(pattern string, separators ...rune) (Glob, error) {
return nil, err
}
return &globber{glob: g}, nil
return &globber{pattern: pattern, glob: g}, nil
}
func (g *globber) Match(name string) bool {
return g.glob.Match(name)
}
func (g *globber) Prefix() string {
return Prefix(g.pattern)
}
func Prefix(pattern string) string {
index := strings.IndexAny(pattern, "*[{")
if index == -1 {
return pattern
}
return strings.Clone(pattern[:index])
}
// Match returns whether the name matches the glob pattern, also considering
// one or several optionnal separator. An error is only returned if the pattern
// is invalid.

View File

@@ -12,6 +12,7 @@ import (
"strings"
"time"
"github.com/datarhei/core/v16/glob"
"github.com/datarhei/core/v16/http/api"
httpfs "github.com/datarhei/core/v16/http/fs"
"github.com/datarhei/core/v16/http/handler/util"
@@ -195,6 +196,14 @@ func (h *FSHandler) DeleteFiles(c echo.Context) error {
return api.Err(http.StatusBadRequest, "", "a glob pattern is required")
}
path := "/"
if len(pattern) != 0 {
prefix := glob.Prefix(pattern)
index := strings.LastIndex(prefix, "/")
path = prefix[:index+1]
}
options := fs.ListOptions{
Pattern: pattern,
}
@@ -229,7 +238,7 @@ func (h *FSHandler) DeleteFiles(c echo.Context) error {
}
}
paths, _ := h.FS.Filesystem.RemoveList("/", options)
paths, _ := h.FS.Filesystem.RemoveList(path, options)
if h.FS.Cache != nil {
for _, path := range paths {
@@ -256,6 +265,14 @@ func (h *FSHandler) ListFiles(c echo.Context) error {
sortby := util.DefaultQuery(c, "sort", "none")
order := util.DefaultQuery(c, "order", "asc")
path := "/"
if len(pattern) != 0 {
prefix := glob.Prefix(pattern)
index := strings.LastIndex(prefix, "/")
path = prefix[:index+1]
}
options := fs.ListOptions{
Pattern: pattern,
}
@@ -290,7 +307,7 @@ func (h *FSHandler) ListFiles(c echo.Context) error {
}
}
files := h.FS.Filesystem.List("/", options)
files := h.FS.Filesystem.List(path, options)
var sortFunc func(i, j int) bool

View File

@@ -474,6 +474,7 @@ func (fs *s3Filesystem) RemoveList(path string, options ListOptions) ([]string,
var totalSize int64 = 0
files := []string{}
recursive := false
var compiledPattern glob.Glob
var err error
@@ -483,8 +484,14 @@ func (fs *s3Filesystem) RemoveList(path string, options ListOptions) ([]string,
if err != nil {
return nil, 0
}
if strings.Contains(options.Pattern, "**") {
recursive = true
}
}
recursive = true
objectsCh := make(chan minio.ObjectInfo)
// Send object names that are needed to be removed to objectsCh
@@ -495,7 +502,7 @@ func (fs *s3Filesystem) RemoveList(path string, options ListOptions) ([]string,
WithVersions: false,
WithMetadata: false,
Prefix: path,
Recursive: true,
Recursive: recursive,
MaxKeys: 0,
StartAfter: "",
UseV1: false,
@@ -563,14 +570,21 @@ func (fs *s3Filesystem) List(path string, options ListOptions) []FileInfo {
var compiledPattern glob.Glob
var err error
recursive := false
if len(options.Pattern) != 0 {
compiledPattern, err = glob.Compile(options.Pattern, '/')
if err != nil {
return nil
}
if strings.Contains(options.Pattern, "**") {
recursive = true
}
}
recursive = true
files := []FileInfo{}
ctx, cancel := context.WithCancel(context.Background())
@@ -580,7 +594,7 @@ func (fs *s3Filesystem) List(path string, options ListOptions) []FileInfo {
WithVersions: false,
WithMetadata: false,
Prefix: path,
Recursive: true,
Recursive: recursive,
MaxKeys: 0,
StartAfter: "",
UseV1: false,