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) 2009, Thomas Leonard
11 # See the README file for details, or visit http://0install.net.
13 from zeroinstall
import _
16 def find_in_path(prog
):
17 """Search $PATH for prog.
18 If prog is an absolute path, return it unmodified.
19 @param prog: name of executable to find
20 @return: the full path of prog, or None if not found
23 if os
.path
.isabs(prog
): return prog
26 for d
in os
.environ
.get('PATH', '/bin:/usr/bin').split(os
.pathsep
):
27 path
= os
.path
.join(d
, prog
)
28 if os
.path
.isfile(path
):
32 def read_bytes(fd
, nbytes
, null_ok
= False):
33 """Read exactly nbytes from fd.
34 @param fd: file descriptor to read from
35 @param nbytes: number of bytes to read
36 @param null_ok: if True, it's OK to receive EOF immediately (we then return None)
37 @return: the bytes read
38 @raise Exception: if we received less than nbytes of data
42 got
= os
.read(fd
, nbytes
)
44 if null_ok
and not data
:
46 raise Exception(_("Unexpected end-of-stream. Data so far %(data)s; expecting %(bytes)d bytes more.")
47 % {'data': repr(data
), 'bytes': nbytes
})
50 logging
.debug(_("Message received: %s") % repr(data
))
53 def pretty_size(size
):
54 """Format a size for printing.
55 @param size: the size in bytes
56 @type size: int (or None)
57 @return: the formatted size
63 return _('%d bytes') % size
65 for unit
in (_('KB'), _('MB'), _('GB'), _('TB')):
69 return _('%(size).1f %(unit)s') % {'size': size
, 'unit': unit
}
72 """Like shutil.rmtree, except that we also delete read-only items.
73 @param root: the root of the subtree to remove
78 if platform
.system() == 'Windows':
79 for main
, dirs
, files
in os
.walk(root
):
80 for i
in files
+ dirs
:
81 os
.chmod(os
.path
.join(main
, i
), 0o700)
84 for main
, dirs
, files
in os
.walk(root
):