github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/internal/util/function/matcher.go (about) 1 // Copyright 2022 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package function 16 17 import ( 18 "fmt" 19 20 "github.com/GoogleContainerTools/kpt/porch/api/porch/v1alpha1" 21 ) 22 23 type Matcher interface { 24 Match(v1alpha1.Function) bool 25 } 26 27 var _ Matcher = TypeMatcher{} 28 var _ Matcher = KeywordsMatcher{} 29 30 type TypeMatcher struct { 31 FnType string 32 } 33 34 // Match determines whether the `function` (which can be multi-typed), belongs 35 // to the matcher's FnType. type value should only be `validator` or `mutator`. 36 func (m TypeMatcher) Match(function v1alpha1.Function) bool { 37 if m.FnType == "" { 38 // type is not given, shown all functions. 39 return true 40 } 41 for _, actualType := range function.Spec.FunctionTypes { 42 if string(actualType) == m.FnType { 43 return true 44 } 45 } 46 return false 47 } 48 49 type KeywordsMatcher struct { 50 Keywords []string 51 } 52 53 // Match determines whether the `function` has keywords which match the matcher's `Keywords`. 54 // Experimental: This logic may change to only if all function keywords are found from matcher's `Keywords`, 55 // can it claims a match (return true). 56 func (m KeywordsMatcher) Match(function v1alpha1.Function) bool { 57 if len(m.Keywords) == 0 { 58 // Accept all functions if keywords are not given. 59 return true 60 } 61 for _, actual := range function.Spec.Keywords { 62 for _, expected := range m.Keywords { 63 if actual == expected { 64 return true 65 } 66 } 67 } 68 return false 69 } 70 71 func MatchFunctions(functions []v1alpha1.Function, matchers ...Matcher) []v1alpha1.Function { 72 var suggestedFunctions []v1alpha1.Function 73 for _, function := range functions { 74 match := true 75 for _, matcher := range matchers { 76 if !matcher.Match(function) { 77 match = false 78 } 79 } 80 if match { 81 suggestedFunctions = append(suggestedFunctions, function) 82 } 83 } 84 return suggestedFunctions 85 } 86 87 // GetNames returns the list of function names. 88 // - Porch function name is <PackageRepository>:<ImageName>:<Version>. e.g. kpt-functions:set-annotation:v0.1 89 // - Catalog v2 function name is trimed to only contain <ImageName>:<Version>, and exclude gcr.io/kpt-fn. e.g. set-annotation:v0.1 90 func GetNames(functions []v1alpha1.Function) []string { 91 var names []string 92 for _, function := range functions { 93 var name string 94 if function.Namespace == CatalogV2 { 95 name = function.Name 96 } else { 97 name = fmt.Sprintf("%v:%v", function.Namespace, function.Name) 98 } 99 names = append(names, name) 100 } 101 return names 102 }