root/branches/mk/cheesecake/util.py

Revision 78, 4.6 kB (checked in by mk, 7 years ago)

Fixed installation index bugs.

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