github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/container/selector.go (about)

     1  package container
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/distribution/reference"
     7  
     8  	"github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1"
     9  )
    10  
    11  type MatchType int
    12  
    13  const (
    14  	matchName MatchType = iota
    15  	matchExact
    16  )
    17  
    18  type RefSelector struct {
    19  	ref       reference.Named
    20  	matchType MatchType
    21  }
    22  
    23  func SelectorFromImageMap(spec v1alpha1.ImageMapSpec) (RefSelector, error) {
    24  	ref, err := reference.ParseNormalizedNamed(spec.Selector)
    25  	if err != nil {
    26  		return RefSelector{}, fmt.Errorf("parsing image map spec (%s): %v", spec.Selector, err)
    27  	}
    28  	matchType := matchName
    29  	if spec.MatchExact {
    30  		matchType = matchExact
    31  	}
    32  	return RefSelector{
    33  		ref:       ref,
    34  		matchType: matchType,
    35  	}, nil
    36  }
    37  
    38  func NameSelector(ref reference.Named) RefSelector {
    39  	return NewRefSelector(reference.TrimNamed(ref))
    40  }
    41  
    42  func NewRefSelector(ref reference.Named) RefSelector {
    43  	matchType := matchName
    44  	_, hasTag := ref.(reference.NamedTagged)
    45  	if hasTag {
    46  		matchType = matchExact
    47  	}
    48  	return RefSelector{
    49  		ref:       ref,
    50  		matchType: matchType,
    51  	}
    52  }
    53  
    54  func MustParseSelector(s string) RefSelector {
    55  	return NewRefSelector(MustParseNamed(s))
    56  }
    57  
    58  func MustParseTaggedSelector(s string) RefSelector {
    59  	return NewRefSelector(MustParseNamedTagged(s))
    60  }
    61  
    62  func (s RefSelector) RefsEqual(other RefSelector) bool {
    63  	return s.ref.String() == other.ref.String()
    64  }
    65  
    66  func (s RefSelector) MatchExact() bool {
    67  	return s.matchType == matchExact
    68  }
    69  
    70  func (s RefSelector) WithNameMatch() RefSelector {
    71  	s.matchType = matchName
    72  	return s
    73  }
    74  
    75  func (s RefSelector) WithExactMatch() RefSelector {
    76  	s.matchType = matchExact
    77  	return s
    78  }
    79  
    80  func (s RefSelector) MatchesAny(toMatch []reference.Named) bool {
    81  	for _, ref := range toMatch {
    82  		if s.Matches(ref) {
    83  			return true
    84  		}
    85  	}
    86  	return false
    87  }
    88  
    89  func (s RefSelector) Matches(toMatch reference.Named) bool {
    90  	if s.ref == nil {
    91  		return false
    92  	}
    93  
    94  	if s.matchType == matchName {
    95  		return toMatch.Name() == s.ref.Name()
    96  	}
    97  	return toMatch.String() == s.ref.String()
    98  }
    99  
   100  func (s RefSelector) Empty() bool {
   101  	return s.ref == nil
   102  }
   103  
   104  func (s RefSelector) RefName() string {
   105  	if s.ref == nil {
   106  		return ""
   107  	}
   108  	return s.ref.Name()
   109  }
   110  
   111  func (s RefSelector) RefFamiliarName() string {
   112  	if s.ref == nil {
   113  		return ""
   114  	}
   115  	return reference.FamiliarName(s.ref)
   116  }
   117  
   118  func (s RefSelector) RefFamiliarString() string {
   119  	if s.ref == nil {
   120  		return ""
   121  	}
   122  	return reference.FamiliarString(s.ref)
   123  }
   124  
   125  // AsNamedOnly returns the Ref as a Named, REMOVING THE TAG if one exists
   126  func (s RefSelector) AsNamedOnly() reference.Named {
   127  	return reference.TrimNamed(s.ref)
   128  }
   129  
   130  func (s RefSelector) String() string {
   131  	if s.ref == nil {
   132  		return ""
   133  	}
   134  	return s.ref.String()
   135  }
   136  
   137  func AnyMatch(toMatch []reference.Named, selectors []RefSelector) bool {
   138  	for _, ref := range toMatch {
   139  		for _, sel := range selectors {
   140  			if sel.Matches(ref) {
   141  				return true
   142  			}
   143  		}
   144  	}
   145  	return false
   146  }