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.
93 lines
2.1 KiB
Go
93 lines
2.1 KiB
Go
package sourcepolicy
|
|
|
|
import (
|
|
"regexp"
|
|
|
|
spb "github.com/moby/buildkit/sourcepolicy/pb"
|
|
"github.com/moby/buildkit/util/wildcard"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// Source wraps a a protobuf source in order to store cached state such as the compiled regexes.
|
|
type selectorCache struct {
|
|
*spb.Selector
|
|
|
|
re *regexp.Regexp
|
|
w *wildcardCache
|
|
}
|
|
|
|
// Format formats the provided ref according to the match/type of the source.
|
|
//
|
|
// For example, if the source is a wildcard, the ref will be formatted with the wildcard in the source replacing the parameters in the destination.
|
|
//
|
|
// matcher: wildcard source: "docker.io/library/golang:*" match: "docker.io/library/golang:1.19" format: "docker.io/library/golang:${1}-alpine" result: "docker.io/library/golang:1.19-alpine"
|
|
func (s *selectorCache) Format(match, format string) (string, error) {
|
|
switch s.MatchType {
|
|
case spb.MatchType_EXACT:
|
|
return s.Identifier, nil
|
|
case spb.MatchType_REGEX:
|
|
re, err := s.regex()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return re.ReplaceAllString(match, format), nil
|
|
case spb.MatchType_WILDCARD:
|
|
w, err := s.wildcard()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
m := w.Match(match)
|
|
if m == nil {
|
|
return match, nil
|
|
}
|
|
|
|
return m.Format(format)
|
|
}
|
|
return "", errors.Errorf("unknown match type: %s", s.MatchType)
|
|
}
|
|
|
|
// wildcardCache wraps a wildcard.Wildcard to cache returned matches by ref.
|
|
// This way a match only needs to be computed once per ref.
|
|
type wildcardCache struct {
|
|
w *wildcard.Wildcard
|
|
m map[string]*wildcard.Match
|
|
}
|
|
|
|
func (w *wildcardCache) Match(ref string) *wildcard.Match {
|
|
if w.m == nil {
|
|
w.m = make(map[string]*wildcard.Match)
|
|
}
|
|
|
|
if m, ok := w.m[ref]; ok {
|
|
return m
|
|
}
|
|
|
|
m := w.w.Match(ref)
|
|
w.m[ref] = m
|
|
return m
|
|
}
|
|
|
|
func (s *selectorCache) wildcard() (*wildcardCache, error) {
|
|
if s.w != nil {
|
|
return s.w, nil
|
|
}
|
|
w, err := wildcard.New(s.Identifier)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
s.w = &wildcardCache{w: w}
|
|
return s.w, nil
|
|
}
|
|
|
|
func (s *selectorCache) regex() (*regexp.Regexp, error) {
|
|
if s.re != nil {
|
|
return s.re, nil
|
|
}
|
|
re, err := regexp.Compile(s.Identifier)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
s.re = re
|
|
return re, nil
|
|
}
|