1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16  import re, types 
 17   
 18  from buildbot.util import ComparableMixin, NotABranch 
 21   
 22       
 23       
 24       
 25      compare_attrs = ('filter_fn', 'checks') 
 26   
 27 -    def __init__(self, 
 28               
 29              filter_fn=None, 
 30               
 31               
 32               
 33               
 34               
 35               
 36              project=None, project_re=None, project_fn=None, 
 37              repository=None, repository_re=None, repository_fn=None, 
 38              branch=NotABranch, branch_re=None, branch_fn=None, 
 39              category=None, category_re=None, category_fn=None): 
  40          def mklist(x): 
 41              if x is not None and type(x) is not types.ListType: 
 42                  return [ x ] 
 43              return x 
  44          def mklist_br(x):  
 45              if x is NotABranch: 
 46                  return None 
 47              if type(x) is not types.ListType: 
 48                  return [ x ] 
 49              return x 
  50          def mkre(r): 
 51              if r is not None and not hasattr(r, 'match'): 
 52                  r = re.compile(r) 
 53              return r 
 54   
 55          self.filter_fn = filter_fn 
 56          self.checks = [ 
 57                  (mklist(project), mkre(project_re), project_fn, "project"), 
 58                  (mklist(repository), mkre(repository_re), repository_fn, "repository"), 
 59                  (mklist_br(branch), mkre(branch_re), branch_fn, "branch"), 
 60                  (mklist(category), mkre(category_re), category_fn, "category"), 
 61              ] 
 62   
 64          if self.filter_fn is not None and not self.filter_fn(change): 
 65              return False 
 66          for (filt_list, filt_re, filt_fn, chg_attr) in self.checks: 
 67              chg_val = getattr(change, chg_attr, '') 
 68              if filt_list is not None and chg_val not in filt_list: 
 69                  return False 
 70              if filt_re is not None and (chg_val is None or not filt_re.match(chg_val)): 
 71                  return False 
 72              if filt_fn is not None and not filt_fn(chg_val): 
 73                  return False 
 74          return True 
  75   
 77          checks = [] 
 78          for (filt_list, filt_re, filt_fn, chg_attr) in self.checks: 
 79              if filt_list is not None and len(filt_list) == 1: 
 80                  checks.append('%s == %s' % (chg_attr, filt_list[0])) 
 81              elif filt_list is not None: 
 82                  checks.append('%s in %r' % (chg_attr, filt_list)) 
 83              if filt_re is not None : 
 84                  checks.append('%s ~/%s/' % (chg_attr, filt_re)) 
 85              if filt_fn is not None : 
 86                  checks.append('%s(%s)' % (filt_fn.__name__, chg_attr)) 
 87   
 88          return "<%s on %s>" % (self.__class__.__name__, ' and '.join(checks)) 
  89   
 90      @staticmethod 
 93   
 94          """ 
 95          Static method to create a filter based on constructor args 
 96          change_filter, branch, and categories; use default values @code{None}, 
 97          @code{NotABranch}, and @code{None}, respectively.  These arguments are 
 98          interpreted as documented for the 
 99          L{buildbot.schedulers.basic.Scheduler} class. 
100   
101          @returns: L{ChangeFilter} instance or None for not filtering 
102          """ 
103   
104           
105          if change_filter: 
106              if (branch is not NotABranch or categories is not None): 
107                  raise RuntimeError("cannot specify both change_filter and " 
108                                     "branch or categories") 
109              return change_filter 
110          elif branch is not NotABranch or categories: 
111               
112              cfargs = {} 
113              if branch is not NotABranch: cfargs['branch'] = branch 
114              if categories: cfargs['category'] = categories 
115              return ChangeFilter(**cfargs) 
116          else: 
117              return None 
 118