Package conary :: Package build :: Module trovefilter
[hide private]
[frames] | no frames]

Source Code for Module conary.build.trovefilter

  1  # 
  2  # Copyright (c) 2008 rPath, Inc. 
  3  # 
  4  # This program is distributed under the terms of the Common Public License, 
  5  # version 1.0. A copy of this license should have been distributed with this 
  6  # source file in a file called LICENSE. If it is not present, the license 
  7  # is always available at http://www.rpath.com/permanent/licenses/CPL-1.0. 
  8  # 
  9  # This program is distributed in the hope that it will be useful, but 
 10  # without any warranty; without even the implied warranty of merchantability 
 11  # or fitness for a particular purpose. See the Common Public License for 
 12  # full details. 
 13  # 
 14  """ 
 15  This module defines trove filters. 
 16  """ 
 17   
 18  import itertools 
 19  import re 
 20   
 21  from conary.deps import arch, deps 
 22  from conary import versions 
 23   
 24  VT_NONE         = 0 
 25  VT_LABEL        = 1 
 26  VT_BRANCH       = 2 
 27  VT_VERSION      = 3 
 28  VT_REVISION     = 4 
 29  VT_SRC_REVISION = 5 
 30  VT_BIN_REVISION = 6 
 31   
 32   
33 -class AbstractFilter(object):
34 - def match(self, *args, **kwargs):
35 raise NotImplementedError
36 - def __invert__(self):
37 return NotFilter(self)
38 - def __or__(self, filter):
39 return OrFilter(self, filter)
40 - def __and__(self, filter):
41 return AndFilter(self, filter)
42 - def __hash__(self):
43 if 'filters' in self.__dict__: 44 res = None 45 for f in self.filters: 46 res = hash((res, hash(f))) 47 return res 48 else: 49 return object.__hash__(self)
50 __mul__ = __and__ 51 __add__ = __or__ 52 __neg__ = __invert__
53 - def __sub__(self, filter):
54 return OrFilter(self, NotFilter(filter))
55 - def compile(self):
56 pass
57
58 -class AndFilter(AbstractFilter):
59 - def __init__(self, *filters):
60 self.filters = filters
61 - def match(self, *args, **kwargs):
62 for filter in self.filters: 63 if not filter.match(*args, **kwargs): 64 return False 65 return True
66
67 -class OrFilter(AbstractFilter):
68 - def __init__(self, *filters):
69 self.filters = filters
70 - def match(self, *args, **kwargs):
71 for filter in self.filters: 72 if filter.match(*args, **kwargs): 73 return True 74 return False
75
76 -class NotFilter(AbstractFilter):
77 - def __init__(self, filter):
78 self.filter = filter
79 - def match(self, *args, **kwargs):
80 return not self.filter.match(*args, **kwargs)
81
82 -class TroveFilter(AbstractFilter):
83 - def __init__(self, recipe, name = None, version = None, flavor = None):
84 self.compiled = False 85 self.macros = recipe.macros 86 self.name = self.label = self.branch = self.version = self.flavor = \ 87 self.revision = None 88 if name is not None: 89 self._validateRegexp(name, 'name') 90 self.name = name 91 if version is not None: 92 self.version = version 93 if flavor is not None: 94 self.flavor = deps.parseFlavor(flavor)
95
96 - def __eq__(self, filter):
97 return self.name == filter.name and \ 98 self.version == filter.version and \ 99 self.flavor == filter.flavor
100
101 - def __hash__(self):
102 return hash((self.name, self.version, self.flavor))
103
104 - def __str__(self):
105 name = self.name or '' 106 ver = self.version or '' 107 if ver: 108 ver = '=' + ver 109 flv = self.flavor and '[%s]' % self.flavor or '' 110 return "<TroveFilter: '%s%s%s'>" % (name, ver, flv)
111
112 - def _validateRegexp(self, pattern, param):
113 try: 114 re.compile(pattern) 115 except: 116 raise RuntimeError("Bad Regexp: '%s' for %s" % (pattern, param))
117
118 - def _compilePattern(self, pattern):
119 if pattern is not None: 120 if not pattern or pattern[0] != '^': 121 pattern = '^' + pattern 122 if pattern[-1] != '$': 123 pattern += '$' 124 return re.compile(pattern % self.macros)
125
126 - def _getVersionType(self, version):
127 if not version: 128 return VT_NONE 129 if '/' not in version: 130 if '@' not in version: 131 return version.count('-') + VT_REVISION 132 else: 133 return VT_LABEL 134 else: 135 ver = versions.VersionFromString(version) 136 if isinstance(ver, versions.Branch): 137 return VT_BRANCH 138 elif isinstance(ver, versions.Version): 139 return VT_VERSION
140
141 - def _compareVersions(self, versionType, a, b):
142 if not versionType: 143 return True 144 if isinstance(b, str): 145 return a == b 146 if versionType == VT_LABEL: 147 return a == str(b.branch().label()) 148 if versionType == VT_BRANCH: 149 return a == str(b.branch()) 150 if versionType == VT_VERSION: 151 return a == str(b) 152 if versionType == VT_REVISION: 153 return a == str(b.trailingRevision().getVersion()) 154 if versionType == VT_SRC_REVISION: 155 rev = b.trailingRevision() 156 return a == ('%s-%s' % (rev.getVersion(), rev.getSourceCount())) 157 if versionType == VT_BIN_REVISION: 158 return a == str(b.trailingRevision()) 159 return False
160
161 - def _compareFlavors(self, a, b):
162 if a is None: 163 return True 164 if a == b: 165 return True 166 # this doesn't need to account for all flavors that there are, 167 # just the ones that can reasonably co-exist 168 a_arches = [] 169 b_arches = [] 170 for prefArch in set(itertools.chain(*arch.FlavorPreferences.flavorPreferences.values())): 171 prefArch = deps.parseFlavor(prefArch) 172 a_arches.append(a.satisfies(prefArch)) 173 b_arches.append(b.satisfies(prefArch)) 174 if True in a_arches and a_arches != b_arches: 175 # filter specified any kind of arch at all and all 176 # arch definitions match 177 return False 178 if not str(a.difference(b)): 179 # check if characteristics of b completely subsume the filter 180 return True 181 return False
182
183 - def compile(self):
184 self.nameRe = self._compilePattern(self.name) 185 if self.version is not None: 186 version = self.version % self.macros 187 self.versionType = self._getVersionType(version) 188 self.version = self.version and self.version % self.macros 189 else: 190 self.versionType = VT_NONE 191 self.compiled = True
192
193 - def match(self<