2 Useful support routines (for internal use).
4 These functions aren't really Zero Install specific; they're things we might
5 wish were in the standard library.
10 # Copyright (C) 2007, Thomas Leonard
11 # See the README file for details, or visit http://0install.net.
15 def find_in_path(prog
):
16 """Search $PATH for prog.
17 If prog is an absolute path, return it unmodified.
18 @param prog: name of executable to find
19 @return: the full path of prog, or None if not found
22 if os
.path
.isabs(prog
): return prog
23 for d
in os
.environ
['PATH'].split(':'):
24 path
= os
.path
.join(d
, prog
)
25 if os
.path
.isfile(path
):
29 def read_bytes(fd
, nbytes
, null_ok
= False):
30 """Read exactly nbytes from fd.
31 @param fd: file descriptor to read from
32 @param nbytes: number of bytes to read
33 @param null_ok: if True, it's OK to receive EOF immediately (we then return None)
34 @return: the bytes read
35 @raise Exception: if we received less than nbytes of data
39 got
= os
.read(fd
, nbytes
)
41 if null_ok
and not data
:
43 raise Exception("Unexpected end-of-stream. Data so far %s; expecting %d bytes more."
44 % (repr(data
), nbytes
))
47 logging
.debug("Message received: %s" % repr(data
))
50 def pretty_size(size
):
51 """Format a size for printing.
52 @param size: the size in bytes
53 @type size: int (or None)
54 @return: the formatted size
60 return '%d bytes' % size
62 for unit
in ('Kb', 'Mb', 'Gb', 'Tb'):
66 return '%.1f %s' % (size
, unit
)
69 """Like shutil.rmtree, except that we also delete read-only items.
70 @param root: the root of the subtree to remove
74 for main
, dirs
, files
in os
.walk(root
):