Mercurial > hg
annotate mercurial/util.py @ 937:e4f1b76831b2
Whitespace
author | mpm@selenic.com |
---|---|
date | Wed, 17 Aug 2005 16:37:04 -0800 |
parents | 7f3f55903496 |
children | 22571b8d35d3 |
rev | line source |
---|---|
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 |
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
9 from demandload import * |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
10 demandload(globals(), "re") |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
11 |
556 | 12 def unique(g): |
13 seen = {} | |
14 for f in g: | |
15 if f not in seen: | |
16 seen[f] = 1 | |
17 yield f | |
18 | |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
19 class Abort(Exception): |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
20 """Raised if a command needs to print an error and exit.""" |
508 | 21 |
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
22 def always(fn): return True |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
23 def never(fn): return False |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
24 |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
25 def globre(pat, head = '^', tail = '$'): |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
26 "convert a glob pattern into a regexp" |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
27 i, n = 0, len(pat) |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
28 res = '' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
29 group = False |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
30 def peek(): return i < n and pat[i] |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
31 while i < n: |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
32 c = pat[i] |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
33 i = i+1 |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
34 if c == '*': |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
35 if peek() == '*': |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
36 i += 1 |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
37 res += '.*' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
38 else: |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
39 res += '[^/]*' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
40 elif c == '?': |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
41 res += '.' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
42 elif c == '[': |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
43 j = i |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
44 if j < n and pat[j] in '!]': |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
45 j += 1 |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
46 while j < n and pat[j] != ']': |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
47 j += 1 |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
48 if j >= n: |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
49 res += '\\[' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
50 else: |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
51 stuff = pat[i:j].replace('\\','\\\\') |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
52 i = j + 1 |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
53 if stuff[0] == '!': |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
54 stuff = '^' + stuff[1:] |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
55 elif stuff[0] == '^': |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
56 stuff = '\\' + stuff |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
57 res = '%s[%s]' % (res, stuff) |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
58 elif c == '{': |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
59 group = True |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
60 res += '(?:' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
61 elif c == '}' and group: |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
62 res += ')' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
63 group = False |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
64 elif c == ',' and group: |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
65 res += '|' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
66 else: |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
67 res += re.escape(c) |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
68 return head + res + tail |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
69 |
812
b65af904d6d7
Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents:
782
diff
changeset
|
70 _globchars = {'[': 1, '{': 1, '*': 1, '?': 1} |
b65af904d6d7
Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents:
782
diff
changeset
|
71 |
884
087771ebe2e6
Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents:
878
diff
changeset
|
72 def pathto(n1, n2): |
886
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
73 '''return the relative path from one place to another. |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
74 this returns a path in the form used by the local filesystem, not hg.''' |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
75 if not n1: return localpath(n2) |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
76 a, b = n1.split('/'), n2.split('/') |
884
087771ebe2e6
Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents:
878
diff
changeset
|
77 a.reverse(), b.reverse() |
087771ebe2e6
Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents:
878
diff
changeset
|
78 while a and b and a[-1] == b[-1]: |
087771ebe2e6
Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents:
878
diff
changeset
|
79 a.pop(), b.pop() |
087771ebe2e6
Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents:
878
diff
changeset
|
80 b.reverse() |
087771ebe2e6
Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents:
878
diff
changeset
|
81 return os.sep.join((['..'] * len(a)) + b) |
087771ebe2e6
Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents:
878
diff
changeset
|
82 |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
83 def canonpath(repo, cwd, myname): |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
84 rootsep = repo.root + os.sep |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
85 name = myname |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
86 if not name.startswith(os.sep): |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
87 name = os.path.join(repo.root, cwd, name) |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
88 name = os.path.normpath(name) |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
89 if name.startswith(rootsep): |
886
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
90 return pconvert(name[len(rootsep):]) |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
91 elif name == repo.root: |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
92 return '' |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
93 else: |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
94 raise Abort('%s not under repository root' % myname) |
897 | 95 |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
96 def matcher(repo, cwd, names, inc, exc, head = ''): |
820
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
97 def patkind(name): |
888
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
98 for prefix in 're:', 'glob:', 'path:', 'relpath:': |
820
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
99 if name.startswith(prefix): return name.split(':', 1) |
812
b65af904d6d7
Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents:
782
diff
changeset
|
100 for c in name: |
820
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
101 if c in _globchars: return 'glob', name |
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
102 return 'relpath', name |
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
103 |
888
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
104 def regex(kind, name, tail): |
742 | 105 '''convert a pattern into a regular expression''' |
820
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
106 if kind == 're': |
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
107 return name |
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
108 elif kind == 'path': |
888
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
109 return '^' + re.escape(name) + '(?:/|$)' |
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
110 elif kind == 'relpath': |
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
111 return head + re.escape(name) + tail |
742 | 112 return head + globre(name, '', tail) |
113 | |
114 def matchfn(pats, tail): | |
115 """build a matching function from a set of patterns""" | |
116 if pats: | |
888
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
117 pat = '(?:%s)' % '|'.join([regex(k, p, tail) for (k, p) in pats]) |
742 | 118 return re.compile(pat).match |
119 | |
820
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
120 def globprefix(pat): |
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
121 '''return the non-glob prefix of a path, e.g. foo/* -> foo''' |
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
122 root = [] |
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
123 for p in pat.split(os.sep): |
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
124 if patkind(p)[0] == 'glob': break |
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
125 root.append(p) |
886
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
126 return '/'.join(root) |
820
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
127 |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
128 pats = [] |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
129 files = [] |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
130 roots = [] |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
131 for kind, name in map(patkind, names): |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
132 if kind in ('glob', 'relpath'): |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
133 name = canonpath(repo, cwd, name) |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
134 if name == '': |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
135 kind, name = 'glob', '**' |
888
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
136 if kind in ('glob', 'path', 're'): |
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
137 pats.append((kind, name)) |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
138 if kind == 'glob': |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
139 root = globprefix(name) |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
140 if root: roots.append(root) |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
141 elif kind == 'relpath': |
888
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
142 files.append((kind, name)) |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
143 roots.append(name) |
897 | 144 |
820
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
145 patmatch = matchfn(pats, '$') or always |
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
146 filematch = matchfn(files, '(?:/|$)') or always |
897 | 147 incmatch = always |
148 if inc: | |
149 incmatch = matchfn(map(patkind, inc), '(?:/|$)') | |
150 excmatch = lambda fn: False | |
151 if exc: | |
152 excmatch = matchfn(map(patkind, exc), '(?:/|$)') | |
742 | 153 |
820
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
154 return roots, lambda fn: (incmatch(fn) and not excmatch(fn) and |
812
b65af904d6d7
Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents:
782
diff
changeset
|
155 (fn.endswith('/') or |
b65af904d6d7
Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents:
782
diff
changeset
|
156 (not pats and not files) or |
b65af904d6d7
Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents:
782
diff
changeset
|
157 (pats and patmatch(fn)) or |
b65af904d6d7
Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents:
782
diff
changeset
|
158 (files and filematch(fn)))) |
742 | 159 |
521 | 160 def system(cmd, errprefix=None): |
508 | 161 """execute a shell command that must succeed""" |
162 rc = os.system(cmd) | |
163 if rc: | |
521 | 164 errmsg = "%s %s" % (os.path.basename(cmd.split(None, 1)[0]), |
165 explain_exit(rc)[0]) | |
166 if errprefix: | |
167 errmsg = "%s: %s" % (errprefix, errmsg) | |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
168 raise Abort(errmsg) |
508 | 169 |
421 | 170 def rename(src, dst): |
171 try: | |
172 os.rename(src, dst) | |
173 except: | |
174 os.unlink(dst) | |
175 os.rename(src, dst) | |
176 | |
698
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
177 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
|
178 """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
|
179 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
|
180 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
|
181 |
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
182 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
|
183 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
|
184 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
|
185 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
|
186 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
|
187 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
|
188 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
|
189 else: |
917 | 190 pass |
698
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
191 |
704
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
192 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
|
193 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
|
194 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
|
195 os.close(ld) |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
196 |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
197 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
|
198 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
|
199 |
421 | 200 # Platfor specific varients |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
201 if os.name == 'nt': |
461 | 202 nulldev = 'NUL:' |
203 | |
441 | 204 def is_exec(f, last): |
205 return last | |
206 | |
207 def set_exec(f, mode): | |
208 pass | |
515 | 209 |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
210 def pconvert(path): |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
211 return path.replace("\\", "/") |
422
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
212 |
886
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
213 def localpath(path): |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
214 return path.replace('/', '\\') |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
215 |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
216 def normpath(path): |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
217 return pconvert(os.path.normpath(path)) |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
218 |
704
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
219 makelock = _makelock_file |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
220 readlock = _readlock_file |
461 | 221 |
782
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
222 def explain_exit(code): |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
223 return "exited with status %d" % code, code |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
224 |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
225 else: |
461 | 226 nulldev = '/dev/null' |
227 | |
441 | 228 def is_exec(f, last): |
229 return (os.stat(f).st_mode & 0100 != 0) | |
230 | |
231 def set_exec(f, mode): | |
232 s = os.stat(f).st_mode | |
233 if (s & 0100 != 0) == mode: | |
234 return | |
235 if mode: | |
236 # Turn on +x for every +r bit when making a file executable | |
237 # and obey umask. | |
238 umask = os.umask(0) | |
239 os.umask(umask) | |
240 os.chmod(f, s | (s & 0444) >> 2 & ~umask) | |
241 else: | |
242 os.chmod(f, s & 0666) | |
243 | |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
244 def pconvert(path): |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
245 return path |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
246 |
886
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
247 def localpath(path): |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
248 return path |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
249 |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
250 normpath = os.path.normpath |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
251 |
422
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
252 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
|
253 try: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
254 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
|
255 except OSError, why: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
256 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
|
257 raise |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
258 else: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
259 _makelock_file(info, pathname) |
422
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
260 |
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
261 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
|
262 try: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
263 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
|
264 except OSError, why: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
265 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
|
266 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
|
267 else: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
268 raise |
782
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
269 |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
270 def explain_exit(code): |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
271 """return a 2-tuple (desc, code) describing a process's status""" |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
272 if os.WIFEXITED(code): |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
273 val = os.WEXITSTATUS(code) |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
274 return "exited with status %d" % val, val |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
275 elif os.WIFSIGNALED(code): |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
276 val = os.WTERMSIG(code) |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
277 return "killed by signal %d" % val, val |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
278 elif os.WIFSTOPPED(code): |
912
302f83b85054
Minor tweak: os.STOPSIG -> os.WSTOPSIG. Pychecker spotted this one.
mark.williamson@cl.cam.ac.uk
parents:
897
diff
changeset
|
279 val = os.WSTOPSIG(code) |
782
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
280 return "stopped by signal %d" % val, val |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
281 raise ValueError("invalid exit code") |