8
__docformat__ = "restructuredtext"
9
__doc__ = "General Utility functions"
11
def linktree(src, dest, top_exists = False):
12
"""Produces a hard-linked clone of the source.
14
:param src: The directory to clone
16
:param dest: The name of the new directory to create
21
shutil.copymode(src, dest)
22
for my_file in os.listdir(src):
23
srcpath = "%s/%s" % (src, my_file)
24
# avoid trouble if dest is inside src
25
if os.path.samefile(srcpath, dest):
27
destpath = "%s/%s" % (dest, my_file)
28
if os.path.isdir(srcpath) and not os.path.islink(srcpath):
29
linktree(srcpath, destpath)
31
os.link(srcpath, destpath)
35
def __init__(self, final_filename):
36
self.final_filename = final_filename
37
(directory, suffix) = os.path.split(final_filename)
38
(self.fd, self.temp_filename) = tempfile.mkstemp(dir=directory)
39
self.file = os.fdopen(self.fd, "w")
45
os.chmod(self.temp_filename, os.stat(self.final_filename).st_mode)
46
os.rename(self.temp_filename, self.final_filename)
50
def regex_escape(str):
52
special = "\{}()+?$^.*[]|"
54
newstr = string.replace(newstr, char, "\\"+char)
57
def _escape_helper(str, rep):
58
return string.replace(str, rep, "\\"+rep)
61
def safe_unlink(my_file):
62
if my_file is not None:
66
def tmpdir(parent=None):
68
Creates a temporary directory, and returns its name.
70
:return: the directory name
73
return tempfile.mkdtemp("", ",,fai-", parent)
75
class iter_delete_wrapper:
76
def __init__(self, iter, dir):
84
if self.dir is not None:
85
shutil.rmtree(self.dir)
87
def iter_pairs(iterator):
88
"""Returns a seqence of values as a series of pairs of even/odd values
90
:param iter: The iterator to reinterpret as a sequence of pairs
92
:return: iterator of even/odd values
93
:rtype: iter of (val, val)
95
iterator = iterator.__iter__()
98
value = iterator.next()
102
"""Given a series of values, generates the shortest one.
104
:param vals: List of values to examine
105
:type vals: list of str
106
:return: the shortest values, or None for empty sequences.
107
:rtype: str or NoneType
111
if maximum is None or len(value) < len(maximum):
115
def difference_index(atext, btext):
116
"""Find the indext of the first character that differs betweeen two texts
118
:param atext: The first text
120
:param btext: The second text
122
:return: The index, or None if there are no differences within the range
123
:rtype: int or NoneType
126
if len(btext) < length:
128
for i in range(length):
129
if atext[i] != btext[i]:
134
def iter_untar(file, output_dir, compression = "gzip"):
135
"""Untars a file, with incremental status output.
137
:param file: The file to untar
139
:param output_dir: The directory to output to
140
:type output_dir: str
141
:param compression: The compression method: "gzip", "bzip2" or None
142
:type: str or NoneType
143
:return: an iterator of the list of untarred files
146
args = ["-xvf", file, "-C", output_dir]
147
if compression is not None:
148
if (compression != "gzip" and compression != "bzip2"):
149
raise errors.UnknownCompressionMethod(compression)
150
args.append("--"+compression)
151
tar_iter = pybaz.util.exec_safe_iter_stdout("tar", args)
152
for line in tar_iter:
153
yield line.rstrip("\n")
156
def untar_parent(file, output_dir, compression = "gzip"):
157
"""Untars a file, returns the top-level directory in the tar
159
:param file: The file to untar
161
:param output_dir: The directory to output to
162
:type output_dir: str
163
:param compression: The compression method: "gzip", "bzip2" or None
164
:type: str or NoneType
165
:return: The top-level directory of the tar, or None if ambigious
166
:rtype: str or NoneType
168
untar_iter = iter_untar(file, output_dir, compression)
170
parent_dir = untar_iter.next()
171
except StopIteration:
172
raise errors.NoUnambiguousParent(file, parent_dir)
173
for file in untar_iter:
174
if not file.startswith(parent_dir):
175
raise errors.NoUnambiguousParent(file, parent_dir)
179
def cmp_func(function):
180
"""Returns a lambda that uses the output of a function as a cmp key
182
:param function: A function to produce the key value
183
:return: A lambda that uses the output of the function for comparison
185
return lambda x, y: cmp(function(x), function(y))
189
# arch-tag: 0cf2f861-4c7e-4d88-a0dd-378c3241564a