author | Thomas Arendsen Hein <thomas@intevation.de> |
Fri, 15 Jul 2005 08:32:45 +0100 | |
changeset 706 | 5107a7b6b14a |
parent 705 | 574869103985 |
child 724 | 1c0c413cccdd |
child 725 | c6b912f8b5b2 |
child 737 | 8db4d406b3d3 |
child 740 | d2422f10c136 |
permissions | -rw-r--r-- |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
1 |
# util.py - utility functions and platform specfic implementations |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
2 |
# |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
3 |
# Copyright 2005 K. Thananchayan <thananck@yahoo.com> |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
4 |
# |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
5 |
# This software may be used and distributed according to the terms |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
6 |
# of the GNU General Public License, incorporated herein by reference. |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
7 |
|
704
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
8 |
import os, errno |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
9 |
|
556 | 10 |
def unique(g): |
11 |
seen = {} |
|
12 |
for f in g: |
|
13 |
if f not in seen: |
|
14 |
seen[f] = 1 |
|
15 |
yield f |
|
16 |
||
508 | 17 |
class CommandError(Exception): pass |
18 |
||
19 |
def explain_exit(code): |
|
20 |
"""return a 2-tuple (desc, code) describing a process's status""" |
|
21 |
if os.WIFEXITED(code): |
|
22 |
val = os.WEXITSTATUS(code) |
|
23 |
return "exited with status %d" % val, val |
|
24 |
elif os.WIFSIGNALED(code): |
|
25 |
val = os.WTERMSIG(code) |
|
26 |
return "killed by signal %d" % val, val |
|
27 |
elif os.WIFSTOPPED(code): |
|
667
31a9aa890016
A number of minor fixes to problems that pychecker found.
mark.williamson@cl.cam.ac.uk
parents:
556
diff
changeset
|
28 |
val = os.WSTOPSIG(code) |
508 | 29 |
return "stopped by signal %d" % val, val |
30 |
raise ValueError("invalid exit code") |
|
515 | 31 |
|
521 | 32 |
def system(cmd, errprefix=None): |
508 | 33 |
"""execute a shell command that must succeed""" |
34 |
rc = os.system(cmd) |
|
35 |
if rc: |
|
521 | 36 |
errmsg = "%s %s" % (os.path.basename(cmd.split(None, 1)[0]), |
37 |
explain_exit(rc)[0]) |
|
38 |
if errprefix: |
|
39 |
errmsg = "%s: %s" % (errprefix, errmsg) |
|
508 | 40 |
raise CommandError(errmsg) |
41 |
||
421 | 42 |
def rename(src, dst): |
43 |
try: |
|
44 |
os.rename(src, dst) |
|
45 |
except: |
|
46 |
os.unlink(dst) |
|
47 |
os.rename(src, dst) |
|
48 |
||
698
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
49 |
def copytree(src, dst, copyfile): |
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
50 |
"""Copy a directory tree, files are copied using 'copyfile'.""" |
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
51 |
names = os.listdir(src) |
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
52 |
os.mkdir(dst) |
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
53 |
|
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
54 |
for name in names: |
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
55 |
srcname = os.path.join(src, name) |
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
56 |
dstname = os.path.join(dst, name) |
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
57 |
if os.path.isdir(srcname): |
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
58 |
copytree(srcname, dstname, copyfile) |
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
59 |
elif os.path.isfile(srcname): |
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
60 |
copyfile(srcname, dstname) |
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
61 |
else: |
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
62 |
raise IOError("Not a regular file: %r" % srcname) |
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
63 |
|
704
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
64 |
def _makelock_file(info, pathname): |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
65 |
ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL) |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
66 |
os.write(ld, info) |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
67 |
os.close(ld) |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
68 |
|
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
69 |
def _readlock_file(pathname): |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
70 |
return file(pathname).read() |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
71 |
|
421 | 72 |
# Platfor specific varients |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
73 |
if os.name == 'nt': |
461 | 74 |
nulldev = 'NUL:' |
75 |
||
441 | 76 |
def is_exec(f, last): |
77 |
return last |
|
78 |
||
79 |
def set_exec(f, mode): |
|
80 |
pass |
|
515 | 81 |
|
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
82 |
def pconvert(path): |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
83 |
return path.replace("\\", "/") |
422
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
84 |
|
704
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
85 |
makelock = _makelock_file |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
86 |
readlock = _readlock_file |
461 | 87 |
|
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
88 |
else: |
461 | 89 |
nulldev = '/dev/null' |
90 |
||
441 | 91 |
def is_exec(f, last): |
92 |
return (os.stat(f).st_mode & 0100 != 0) |
|
93 |
||
94 |
def set_exec(f, mode): |
|
95 |
s = os.stat(f).st_mode |
|
96 |
if (s & 0100 != 0) == mode: |
|
97 |
return |
|
98 |
if mode: |
|
99 |
# Turn on +x for every +r bit when making a file executable |
|
100 |
# and obey umask. |
|
101 |
umask = os.umask(0) |
|
102 |
os.umask(umask) |
|
103 |
os.chmod(f, s | (s & 0444) >> 2 & ~umask) |
|
104 |
else: |
|
105 |
os.chmod(f, s & 0666) |
|
106 |
||
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
107 |
def pconvert(path): |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
108 |
return path |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
109 |
|
422
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
110 |
def makelock(info, pathname): |
704
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
111 |
try: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
112 |
os.symlink(info, pathname) |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
113 |
except OSError, why: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
114 |
if why.errno == errno.EEXIST: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
115 |
raise |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
116 |
else: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
117 |
_makelock_file(info, pathname) |
422
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
118 |
|
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
119 |
def readlock(pathname): |
704
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
120 |
try: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
121 |
return os.readlink(pathname) |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
122 |
except OSError, why: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
123 |
if why.errno == errno.EINVAL: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
124 |
return _readlock_file(pathname) |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
125 |
else: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
126 |
raise |