You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
buildx/vendor/github.com/moby/buildkit/util/wildcard/wildcard.go

88 lines
2.0 KiB
Go

package wildcard
import (
"regexp"
"strings"
"github.com/pkg/errors"
)
// New returns a wildcard object for a string that contains "*" symbols.
func New(s string) (*Wildcard, error) {
reStr, err := Wildcard2Regexp(s)
if err != nil {
return nil, errors.Wrapf(err, "failed to translate wildcard %q to regexp", s)
}
re, err := regexp.Compile(reStr)
if err != nil {
return nil, errors.Wrapf(err, "failed to compile regexp %q (translated from wildcard %q)", reStr, s)
}
w := &Wildcard{
orig: s,
re: re,
}
return w, nil
}
// Wildcard2Regexp translates a wildcard string to a regexp string.
func Wildcard2Regexp(wildcard string) (string, error) {
s := regexp.QuoteMeta(wildcard)
if strings.Contains(s, "\\*\\*") {
return "", errors.New("invalid wildcard: \"**\"")
}
s = strings.ReplaceAll(s, "\\*", "(.*)")
s = "^" + s + "$"
return s, nil
}
// Wildcard is a wildcard matcher object.
type Wildcard struct {
orig string
re *regexp.Regexp
}
// String implements fmt.Stringer.
func (w *Wildcard) String() string {
return w.orig
}
// Match returns a non-nil Match on match.
func (w *Wildcard) Match(q string) *Match {
submatches := w.re.FindStringSubmatch(q)
if len(submatches) == 0 {
return nil
}
m := &Match{
w: w,
Submatches: submatches,
// FIXME: avoid executing regexp twice
idx: w.re.FindStringSubmatchIndex(q),
}
return m
}
// Match is a matched result.
type Match struct {
w *Wildcard
Submatches []string // 0: the entire query, 1: the first submatch, 2: the second submatch, ...
idx []int
}
// String implements fmt.Stringer.
func (m *Match) String() string {
if len(m.Submatches) == 0 {
return ""
}
return m.Submatches[0]
}
// Format formats submatch strings like "$1", "$2".
func (m *Match) Format(f string) (string, error) {
if m.w == nil || len(m.Submatches) == 0 || len(m.idx) == 0 {
return "", errors.New("invalid state")
}
var b []byte
b = m.w.re.ExpandString(b, f, m.Submatches[0], m.idx)
return string(b), nil
}