util.py
111 lines
| 2.9 KiB
| text/x-python
|
PythonLexer
/ mercurial / util.py
mpm@selenic.com
|
r419 | # util.py - utility functions and platform specfic implementations | ||
# | ||||
# Copyright 2005 K. Thananchayan <thananck@yahoo.com> | ||||
# | ||||
# This software may be used and distributed according to the terms | ||||
# of the GNU General Public License, incorporated herein by reference. | ||||
import os | ||||
mpm@selenic.com
|
r556 | def unique(g): | ||
seen = {} | ||||
for f in g: | ||||
if f not in seen: | ||||
seen[f] = 1 | ||||
yield f | ||||
mpm@selenic.com
|
r508 | class CommandError(Exception): pass | ||
def explain_exit(code): | ||||
"""return a 2-tuple (desc, code) describing a process's status""" | ||||
if os.WIFEXITED(code): | ||||
val = os.WEXITSTATUS(code) | ||||
return "exited with status %d" % val, val | ||||
elif os.WIFSIGNALED(code): | ||||
val = os.WTERMSIG(code) | ||||
return "killed by signal %d" % val, val | ||||
elif os.WIFSTOPPED(code): | ||||
mark.williamson@cl.cam.ac.uk
|
r667 | val = os.WSTOPSIG(code) | ||
mpm@selenic.com
|
r508 | return "stopped by signal %d" % val, val | ||
raise ValueError("invalid exit code") | ||||
mpm@selenic.com
|
r515 | |||
mpm@selenic.com
|
r521 | def system(cmd, errprefix=None): | ||
mpm@selenic.com
|
r508 | """execute a shell command that must succeed""" | ||
rc = os.system(cmd) | ||||
if rc: | ||||
mpm@selenic.com
|
r521 | errmsg = "%s %s" % (os.path.basename(cmd.split(None, 1)[0]), | ||
explain_exit(rc)[0]) | ||||
if errprefix: | ||||
errmsg = "%s: %s" % (errprefix, errmsg) | ||||
mpm@selenic.com
|
r508 | raise CommandError(errmsg) | ||
mpm@selenic.com
|
r421 | def rename(src, dst): | ||
try: | ||||
os.rename(src, dst) | ||||
except: | ||||
os.unlink(dst) | ||||
os.rename(src, dst) | ||||
Thomas Arendsen Hein
|
r698 | def copytree(src, dst, copyfile): | ||
"""Copy a directory tree, files are copied using 'copyfile'.""" | ||||
names = os.listdir(src) | ||||
os.mkdir(dst) | ||||
for name in names: | ||||
srcname = os.path.join(src, name) | ||||
dstname = os.path.join(dst, name) | ||||
if os.path.isdir(srcname): | ||||
copytree(srcname, dstname, copyfile) | ||||
elif os.path.isfile(srcname): | ||||
copyfile(srcname, dstname) | ||||
else: | ||||
raise IOError("Not a regular file: %r" % srcname) | ||||
mpm@selenic.com
|
r421 | # Platfor specific varients | ||
mpm@selenic.com
|
r419 | if os.name == 'nt': | ||
mpm@selenic.com
|
r461 | nulldev = 'NUL:' | ||
mpm@selenic.com
|
r441 | def is_exec(f, last): | ||
return last | ||||
def set_exec(f, mode): | ||||
pass | ||||
mpm@selenic.com
|
r515 | |||
mpm@selenic.com
|
r419 | def pconvert(path): | ||
return path.replace("\\", "/") | ||||
mpm@selenic.com
|
r422 | |||
def makelock(info, pathname): | ||||
ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL) | ||||
os.write(ld, info) | ||||
os.close(ld) | ||||
def readlock(pathname): | ||||
return file(pathname).read() | ||||
mpm@selenic.com
|
r461 | |||
mpm@selenic.com
|
r419 | else: | ||
mpm@selenic.com
|
r461 | nulldev = '/dev/null' | ||
mpm@selenic.com
|
r441 | def is_exec(f, last): | ||
return (os.stat(f).st_mode & 0100 != 0) | ||||
def set_exec(f, mode): | ||||
s = os.stat(f).st_mode | ||||
if (s & 0100 != 0) == mode: | ||||
return | ||||
if mode: | ||||
# Turn on +x for every +r bit when making a file executable | ||||
# and obey umask. | ||||
umask = os.umask(0) | ||||
os.umask(umask) | ||||
os.chmod(f, s | (s & 0444) >> 2 & ~umask) | ||||
else: | ||||
os.chmod(f, s & 0666) | ||||
mpm@selenic.com
|
r419 | def pconvert(path): | ||
return path | ||||
mpm@selenic.com
|
r422 | def makelock(info, pathname): | ||
os.symlink(info, pathname) | ||||
def readlock(pathname): | ||||
return os.readlink(pathname) | ||||