Package buildbot :: Package util
[frames] | no frames]

Source Code for Package buildbot.util

  1  # -*- test-case-name: buildbot.test.test_util -*- 
  2   
  3  from twisted.internet.defer import Deferred 
  4  from twisted.spread import pb 
  5  from twisted.python import threadable 
  6  import time, re, string 
  7   
8 -def naturalSort(l):
9 """Returns a sorted copy of l, so that numbers in strings are sorted in the 10 proper order. 11 12 e.g. ['foo10', 'foo1', 'foo2'] will be sorted as ['foo1', 'foo2', 'foo10'] 13 instead of the default ['foo1', 'foo10', 'foo2']""" 14 l = l[:] 15 def try_int(s): 16 try: 17 return int(s) 18 except: 19 return s
20 def key_func(item): 21 return [try_int(s) for s in re.split('(\d+)', item)] 22 # prepend integer keys to each element, sort them, then strip the keys 23 keyed_l = [ (key_func(i), i) for i in l ] 24 keyed_l.sort() 25 l = [ i[1] for i in keyed_l ] 26 return l 27
28 -def now(_reactor=None):
29 if _reactor and hasattr(_reactor, "seconds"): 30 return _reactor.seconds() 31 else: 32 return time.time()
33
34 -def formatInterval(eta):
35 eta_parts = [] 36 if eta > 3600: 37 eta_parts.append("%d hrs" % (eta / 3600)) 38 eta %= 3600 39 if eta > 60: 40 eta_parts.append("%d mins" % (eta / 60)) 41 eta %= 60 42 eta_parts.append("%d secs" % eta) 43 return ", ".join(eta_parts)
44
45 -class ComparableMixin:
46 """Specify a list of attributes that are 'important'. These will be used 47 for all comparison operations.""" 48 49 compare_attrs = [] 50
51 - class _None: pass
52
53 - def __hash__(self):
54 alist = [self.__class__] + \ 55 [getattr(self, name, self._None) for name in self.compare_attrs] 56 return hash(tuple(map(str,alist)))
57
58 - def __cmp__(self, them):
59 result = cmp(type(self), type(them)) 60 if result: 61 return result 62 63 result = cmp(self.__class__.__name__, them.__class__.__name__) 64 if result: 65 return result 66 67 assert self.compare_attrs == them.compare_attrs 68 self_list= [getattr(self, name, self._None) for name in self.compare_attrs] 69 them_list= [getattr(them, name, self._None) for name in self.compare_attrs] 70 return cmp(self_list, them_list)
71 72 # Remove potentially harmful characters from builder name if it is to be 73 # used as the build dir. 74 badchars_map = string.maketrans("\t !#$%&'()*+,./:;<=>?@[\\]^{|}~", 75 "______________________________")
76 -def safeTranslate(str):
77 if isinstance(str, unicode): 78 str = str.encode('utf8') 79 return str.translate(badchars_map)
80
81 -def remove_userpassword(url):
82 if '@' not in url: 83 return url 84 if '://' not in url: 85 return url 86 87 # urlparse would've been nice, but doesn't support ssh... sigh 88 protocol_url = url.split('://') 89 protocol = protocol_url[0] 90 repo_url = protocol_url[1].split('@')[-1] 91 92 return protocol + '://' + repo_url
93
94 -class LRUCache:
95 """ 96 A simple least-recently-used cache, with a fixed maximum size. Note that 97 an item's memory will not necessarily be free if other code maintains a reference 98 to it, but this class will "lose track" of it all the same. Without caution, this 99 can lead to duplicate items in memory simultaneously. 100 """ 101 102 synchronized = ["get", "add"] 103
104 - def __init__(self, max_size=50):
105 self._max_size = max_size 106 self._cache = {} # basic LRU cache 107 self._cached_ids = [] # = [LRU .. MRU]
108
109 - def get(self, id):
110 thing = self._cache.get(id, None) 111 if thing is not None: 112 self._cached_ids.remove(id) 113 self._cached_ids.append(id) 114 return thing
115 __getitem__ = get 116
117 - def add(self, id, thing):
118 if id in self._cache: 119 self._cached_ids.remove(id) 120 self._cached_ids.append(id) 121 return 122 while len(self._cached_ids) >= self._max_size: 123 del self._cache[self._cached_ids.pop(0)] 124 self._cache[id] = thing 125 self._cached_ids.append(id)
126 __setitem__ = add
127 128 threadable.synchronize(LRUCache) 129 130
131 -def none_or_str(x):
132 """Cast X to a str if it is not None""" 133 if x is not None and not isinstance(x, str): 134 return str(x) 135 return x
136 137 # place a working json module at 'buildbot.util.json'. Code is from 138 # Paul Wise <pabs@debian.org>: 139 # http://lists.debian.org/debian-python/2010/02/msg00016.html 140 try: 141 import json # python 2.6 142 except ImportError: 143 import simplejson as json # python 2.4 to 2.5 144 try: 145 _tmp = json.loads 146 except AttributeError: 147 import warnings 148 import sys 149 warnings.warn("Use simplejson, not the old json module.") 150 sys.modules.pop('json') # get rid of the bad json module 151 import simplejson as json 152 153 # changes and schedulers consider None to be a legitimate name for a branch, 154 # which makes default function keyword arguments hard to handle. This value 155 # is always false.
156 -class NotABranch:
157 - def __nonzero__(self):
158 return False
159 NotABranch = NotABranch() 160