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

View File

@@ -12,6 +12,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/datarhei/core/v16/glob"
"github.com/datarhei/core/v16/http/api" "github.com/datarhei/core/v16/http/api"
httpfs "github.com/datarhei/core/v16/http/fs" httpfs "github.com/datarhei/core/v16/http/fs"
"github.com/datarhei/core/v16/http/handler/util" "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") 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{ options := fs.ListOptions{
Pattern: pattern, 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 { if h.FS.Cache != nil {
for _, path := range paths { for _, path := range paths {
@@ -256,6 +265,14 @@ func (h *FSHandler) ListFiles(c echo.Context) error {
sortby := util.DefaultQuery(c, "sort", "none") sortby := util.DefaultQuery(c, "sort", "none")
order := util.DefaultQuery(c, "order", "asc") 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{ options := fs.ListOptions{
Pattern: pattern, 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 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 var totalSize int64 = 0
files := []string{} files := []string{}
recursive := false
var compiledPattern glob.Glob var compiledPattern glob.Glob
var err error var err error
@@ -483,7 +484,13 @@ func (fs *s3Filesystem) RemoveList(path string, options ListOptions) ([]string,
if err != nil { if err != nil {
return nil, 0 return nil, 0
} }
if strings.Contains(options.Pattern, "**") {
recursive = true
} }
}
recursive = true
objectsCh := make(chan minio.ObjectInfo) objectsCh := make(chan minio.ObjectInfo)
@@ -495,7 +502,7 @@ func (fs *s3Filesystem) RemoveList(path string, options ListOptions) ([]string,
WithVersions: false, WithVersions: false,
WithMetadata: false, WithMetadata: false,
Prefix: path, Prefix: path,
Recursive: true, Recursive: recursive,
MaxKeys: 0, MaxKeys: 0,
StartAfter: "", StartAfter: "",
UseV1: false, UseV1: false,
@@ -563,13 +570,20 @@ func (fs *s3Filesystem) List(path string, options ListOptions) []FileInfo {
var compiledPattern glob.Glob var compiledPattern glob.Glob
var err error var err error
recursive := false
if len(options.Pattern) != 0 { if len(options.Pattern) != 0 {
compiledPattern, err = glob.Compile(options.Pattern, '/') compiledPattern, err = glob.Compile(options.Pattern, '/')
if err != nil { if err != nil {
return nil return nil
} }
if strings.Contains(options.Pattern, "**") {
recursive = true
} }
}
recursive = true
files := []FileInfo{} files := []FileInfo{}
@@ -580,7 +594,7 @@ func (fs *s3Filesystem) List(path string, options ListOptions) []FileInfo {
WithVersions: false, WithVersions: false,
WithMetadata: false, WithMetadata: false,
Prefix: path, Prefix: path,
Recursive: true, Recursive: recursive,
MaxKeys: 0, MaxKeys: 0,
StartAfter: "", StartAfter: "",
UseV1: false, UseV1: false,