Package cheesecake :: Module util
[hide private]
[frames] | no frames]

Source Code for Module cheesecake.util

  1  """Utility functions for Cheesecake project. 
  2  """ 
  3   
  4  import os 
  5  import shutil 
  6  import sys 
  7  import tarfile 
  8  import time 
  9  import zipfile 
 10   
 11  from subprocess import call, ProcessError, Popen, PIPE, STDOUT 
 12   
 13  PAD_TEXT = 40 
 14  PAD_VALUE = 4 
 15   
16 -def run_cmd(cmd, env=None):
17 """Run command and return its return code and its output. 18 19 >>> run_cmd('/bin/true') 20 (0, '') 21 """ 22 arglist = cmd.split() 23 try: 24 p = Popen(arglist, stdout=PIPE, stderr=STDOUT, env=env) 25 except ProcessError, e: 26 return 1, e 27 output = p.communicate()[0] 28 return p.returncode, output
29
30 -def command_successful(cmd):
31 """Returns True if command exited normally, False otherwise. 32 33 >>> command_successful('/bin/true') 34 True 35 >>> command_successful('this-command-doesnt-exist') 36 False 37 """ 38 rc, output = run_cmd(cmd) 39 if rc: 40 return False 41 return True
42
43 -class StdoutRedirector(object):
44 """Redirect stdout to a temporary file. 45 """
46 - def __init__(self, filename=None):
47 if filename: 48 self.fh = open(filename, 'w') 49 else: 50 self.fh = os.tmpfile()
51
52 - def write(self, buf):
53 self.fh.write(buf)
54
55 - def flush(self):
56 self.fh.flush()
57
58 - def read_buffer(self):
59 """Return contents of the temporary file. 60 """ 61 self.fh.seek(0) 62 return self.fh.read()
63
64 -def pad_with_dots(msg, length=PAD_TEXT):
65 """Pad text with dots up to given length. 66 67 >>> pad_with_dots("Hello world", 20) 68 'Hello world ........' 69 >>> pad_with_dots("Exceeding length", 10) 70 'Exceeding length' 71 """ 72 msg_length = len(msg) 73 74 if msg_length >= length: 75 return msg 76 77 msg = msg + " " 78 for i in range(msg_length+1, length): 79 msg += "." 80 return msg
81
82 -def pad_left_spaces(value, length=PAD_VALUE):
83 """Pad value with spaces at left up to given length. 84 85 >>> pad_left_spaces(15, 4) 86 ' 15' 87 >>> pad_left_spaces(123456, 2) 88 '123456' 89 >>> len(pad_left_spaces("")) == PAD_VALUE 90 True 91 """ 92 if not isinstance(value, basestring): 93 value = str(value) 94 diff = length - len(value) 95 return " " * diff + value
96
97 -def pad_right_spaces(value, length=PAD_VALUE):
98 """Pad value with spaces at left up to given length. 99 100 >>> pad_right_spaces(123, 5) 101 '123 ' 102 >>> pad_right_spaces(12.1, 5) 103 '12.1 ' 104 """ 105 if not isinstance(value, basestring): 106 value = str(value) 107 diff = length - len(value) 108 return value + " " * diff
109
110 -def pad_msg(msg, value, msg_length=PAD_TEXT, value_length=PAD_VALUE):
111 """Pad message with dots and pad value with spaces. 112 113 >>> pad_msg("123456", 77, msg_length=10, value_length=4) 114 '123456 ... 77' 115 >>> pad_msg("123", u"45", msg_length=5, value_length=3) 116 u'123 . 45' 117 """ 118 return msg + " " +"." * (msg_length-len(msg)-1) + pad_left_spaces(value, value_length)
119
120 -def pad_line(char="=", length=(PAD_TEXT+PAD_VALUE+1)):
121 """Return line consisting of 'char' characters. 122 123 >>> pad_line('*', 3) 124 '***' 125 >>> pad_line(length=10) 126 '==========' 127 """ 128 return char * length
129
130 -def unzip_package(package, destination):
131 """Unzip given `package` to the `destination` directory. 132 133 Return name of unpacked directory or None on error. 134 """ 135 try: 136 z = zipfile.ZipFile(package) 137 except zipfile.error: 138 return None 139 140 # Get directory structure from zip and create it in destination directory. 141 for name in z.namelist(): 142 (dir, file) = os.path.split(name) 143 unpack_dir = dir 144 target_dir = os.path.join(destination, dir) 145 if not os.path.exists(target_dir): 146 os.makedirs(target_dir) 147 148 # Extract files to directory structure 149 for i, name in enumerate(z.namelist()): 150 if not name.endswith('/'): 151 outfile = open(os.path.join(destination, name), 'wb') 152 outfile.write(z.read(name)) 153 outfile.flush() 154 outfile.close() 155 156 return unpack_dir.split(os.sep)[0]
157
158 -def untar_package(package, destination):
159 """Untar given `package` to the `destination` directory. 160 161 Return name of unpacked directory or None on error. 162 """ 163 try: 164 t = tarfile.open(package) 165 except tarfile.ReadError, e: 166 return None 167 168 for member in t.getmembers(): 169 t.extract(member, destination) 170 171 tarinfo = t.members[0] 172 return tarinfo.name.split(os.sep)[0]
173
174 -def unegg_package(package, destination):
175 """Unpack given egg to the `destination` directory. 176 177 Return name of unpacked directory or None on error. 178 """ 179 if os.path.isdir(package): 180 package_name = os.path.basename(package) 181 destination = os.path.join(destination, package_name) 182 shutil.copytree(package, destination, symlinks=True) 183 return package_name 184 else: 185 return unzip_package(package, destination)
186
187 -def mkdirs(dir):
188 """Make directory with parent directories as needed. 189 190 Don't throw an exception if directory exists. 191 """ 192 parts = dir.split(os.path.sep) 193 for length in xrange(1, len(parts)+1): 194 path = os.path.sep.join([''] + parts[:length]) 195 if not os.path.exists(path): 196 os.mkdir(path)
197
198 -def time_function(function):
199 """Measure function execution time. 200 201 Return (return value, time taken) tuple. 202 203 >>> def fun(x): 204 ... return x*2 205 >>> ret, time_taken = time_function(lambda: fun(5)) 206 >>> ret 207 10 208 """ 209 start = time.time() 210 ret = function() 211 end = time.time() 212 return ret, end-start
213