go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/vpython/spec/match.go (about) 1 // Copyright 2017 The LUCI Authors. 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 spec 16 17 import ( 18 "go.chromium.org/luci/vpython/api/vpython" 19 ) 20 21 // PackageMatches returns true if the package's match constraints are compatible 22 // with tags. A package matches if: 23 // 24 // - None of the tags matches any of the "not_match_tag" entries, and 25 // - Every "match_tag" entry matches at least one tag. 26 // 27 // As a special case, if the package doesn't specify any match tags, it will 28 // always match regardless of the supplied PEP425 tags. This handles the default 29 // case where the user specifies no constraints. 30 // 31 // See PEP425Matches for information about how tags are matched. 32 func PackageMatches(pkg *vpython.Spec_Package, tags []*vpython.PEP425Tag) bool { 33 // If any "not_match_tag" matches, then this package does not match. 34 for _, matchTag := range pkg.NotMatchTag { 35 if PEP425Matches(matchTag, tags) { 36 return false 37 } 38 } 39 40 // If we have no match tags, or if a match tag matches a host tag, then the 41 // package matches. 42 if len(pkg.MatchTag) == 0 { 43 return true 44 } 45 for _, matchTag := range pkg.MatchTag { 46 if PEP425Matches(matchTag, tags) { 47 return true 48 } 49 } 50 return false 51 } 52 53 // PEP425Matches returns true if match matches at least one of the tags in tags. 54 // 55 // A match is determined if the non-zero fields in match equal the equivalent 56 // fields in a tag. 57 func PEP425Matches(match *vpython.PEP425Tag, tags []*vpython.PEP425Tag) bool { 58 // Special case: empty match matches nothing. 59 if match.IsZero() { 60 return false 61 } 62 63 for _, tag := range tags { 64 if v := match.Python; v != "" && tag.Python != v { 65 continue 66 } 67 if v := match.Abi; v != "" && tag.Abi != v { 68 continue 69 } 70 if v := match.Platform; v != "" && tag.Platform != v { 71 continue 72 } 73 return true 74 } 75 76 return false 77 }