author | mpm@selenic.com |
Fri, 23 Sep 2005 19:46:12 -0700 | |
changeset 1346 | 88a9c75dc76a |
parent 1343 | 0f4e53e8c66b |
child 1377 | 854775b27d1a |
permissions | -rw-r--r-- |
1082 | 1 |
""" |
2 |
util.py - Mercurial utility functions and platform specfic implementations |
|
3 |
||
4 |
Copyright 2005 K. Thananchayan <thananck@yahoo.com> |
|
5 |
||
6 |
This software may be used and distributed according to the terms |
|
7 |
of the GNU General Public License, incorporated herein by reference. |
|
8 |
||
9 |
This contains helper routines that are independent of the SCM core and hide |
|
10 |
platform-specific details from the core. |
|
11 |
""" |
|
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
12 |
|
704
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
13 |
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
|
14 |
from demandload import * |
1320
5f277e73778f
Fix up representation of dates in hgweb.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1312
diff
changeset
|
15 |
demandload(globals(), "re cStringIO shutil popen2 tempfile threading time") |
1258 | 16 |
|
1293
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
17 |
def pipefilter(s, cmd): |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
18 |
'''filter string S through command CMD, returning its output''' |
1258 | 19 |
(pout, pin) = popen2.popen2(cmd, -1, 'b') |
20 |
def writer(): |
|
21 |
pin.write(s) |
|
22 |
pin.close() |
|
23 |
||
24 |
# we should use select instead on UNIX, but this will work on most |
|
25 |
# systems, including Windows |
|
26 |
w = threading.Thread(target=writer) |
|
27 |
w.start() |
|
28 |
f = pout.read() |
|
29 |
pout.close() |
|
30 |
w.join() |
|
31 |
return f |
|
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
32 |
|
1293
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
33 |
def tempfilter(s, cmd): |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
34 |
'''filter string S through a pair of temporary files with CMD. |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
35 |
CMD is used as a template to create the real command to be run, |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
36 |
with the strings INFILE and OUTFILE replaced by the real names of |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
37 |
the temporary files generated.''' |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
38 |
inname, outname = None, None |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
39 |
try: |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
40 |
infd, inname = tempfile.mkstemp(prefix='hgfin') |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
41 |
fp = os.fdopen(infd, 'wb') |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
42 |
fp.write(s) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
43 |
fp.close() |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
44 |
outfd, outname = tempfile.mkstemp(prefix='hgfout') |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
45 |
os.close(outfd) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
46 |
cmd = cmd.replace('INFILE', inname) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
47 |
cmd = cmd.replace('OUTFILE', outname) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
48 |
code = os.system(cmd) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
49 |
if code: raise Abort("command '%s' failed: %s" % |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
50 |
(cmd, explain_exit(code))) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
51 |
return open(outname, 'rb').read() |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
52 |
finally: |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
53 |
try: |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
54 |
if inname: os.unlink(inname) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
55 |
except: pass |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
56 |
try: |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
57 |
if outname: os.unlink(outname) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
58 |
except: pass |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
59 |
|
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
60 |
filtertable = { |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
61 |
'tempfile:': tempfilter, |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
62 |
'pipe:': pipefilter, |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
63 |
} |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
64 |
|
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
65 |
def filter(s, cmd): |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
66 |
"filter a string through a command that transforms its input to its output" |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
67 |
for name, fn in filtertable.iteritems(): |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
68 |
if cmd.startswith(name): |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
69 |
return fn(s, cmd[len(name):].lstrip()) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
70 |
return pipefilter(s, cmd) |
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
71 |
|
1285
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
72 |
def patch(strip, patchname, ui): |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
73 |
"""apply the patch <patchname> to the working directory. |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
74 |
a list of patched files is returned""" |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
75 |
fp = os.popen('patch -p%d < "%s"' % (strip, patchname)) |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
76 |
files = {} |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
77 |
for line in fp: |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
78 |
line = line.rstrip() |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
79 |
ui.status("%s\n" % line) |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
80 |
if line.startswith('patching file '): |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
81 |
pf = parse_patch_output(line) |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
82 |
files.setdefault(pf, 1) |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
83 |
code = fp.close() |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
84 |
if code: |
1293
a6ffcebd3315
Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1292
diff
changeset
|
85 |
raise Abort("patch command failed: %s" % explain_exit(code)) |
1285
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
86 |
return files.keys() |
1308
2073e5a71008
Cleanup of tabs and trailing spaces.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1285
diff
changeset
|
87 |
|
1015
22571b8d35d3
Add automatic binary file detection to diff and export
mpm@selenic.com
parents:
917
diff
changeset
|
88 |
def binary(s): |
1082 | 89 |
"""return true if a string is binary data using diff's heuristic""" |
1015
22571b8d35d3
Add automatic binary file detection to diff and export
mpm@selenic.com
parents:
917
diff
changeset
|
90 |
if s and '\0' in s[:4096]: |
22571b8d35d3
Add automatic binary file detection to diff and export
mpm@selenic.com
parents:
917
diff
changeset
|
91 |
return True |
22571b8d35d3
Add automatic binary file detection to diff and export
mpm@selenic.com
parents:
917
diff
changeset
|
92 |
return False |
22571b8d35d3
Add automatic binary file detection to diff and export
mpm@selenic.com
parents:
917
diff
changeset
|
93 |
|
556 | 94 |
def unique(g): |
1082 | 95 |
"""return the uniq elements of iterable g""" |
556 | 96 |
seen = {} |
97 |
for f in g: |
|
98 |
if f not in seen: |
|
99 |
seen[f] = 1 |
|
100 |
yield f |
|
101 |
||
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
102 |
class Abort(Exception): |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
103 |
"""Raised if a command needs to print an error and exit.""" |
508 | 104 |
|
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
105 |
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
|
106 |
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
|
107 |
|
1062 | 108 |
def globre(pat, head='^', tail='$'): |
724
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
109 |
"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
|
110 |
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
|
111 |
res = '' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
112 |
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
|
113 |
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
|
114 |
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
|
115 |
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
|
116 |
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
|
117 |
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
|
118 |
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
|
119 |
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
|
120 |
res += '.*' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
121 |
else: |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
122 |
res += '[^/]*' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
123 |
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
|
124 |
res += '.' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
125 |
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
|
126 |
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
|
127 |
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
|
128 |
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
|
129 |
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
|
130 |
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
|
131 |
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
|
132 |
res += '\\[' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
133 |
else: |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
134 |
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
|
135 |
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
|
136 |
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
|
137 |
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
|
138 |
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
|
139 |
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
|
140 |
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
|
141 |
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
|
142 |
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
|
143 |
res += '(?:' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
144 |
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
|
145 |
res += ')' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
146 |
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
|
147 |
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
|
148 |
res += '|' |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
149 |
else: |
1c0c413cccdd
Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents:
705
diff
changeset
|
150 |
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
|
151 |
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
|
152 |
|
812
b65af904d6d7
Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents:
782
diff
changeset
|
153 |
_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
|
154 |
|
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
|
155 |
def pathto(n1, n2): |
886
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
156 |
'''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
|
157 |
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
|
158 |
if not n1: return localpath(n2) |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
159 |
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
|
160 |
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
|
161 |
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
|
162 |
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
|
163 |
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
|
164 |
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
|
165 |
|
1081
8b7d63489db3
Change canonpath to not know about repo objects
mpm@selenic.com
parents:
1075
diff
changeset
|
166 |
def canonpath(root, cwd, myname): |
1082 | 167 |
"""return the canonical path of myname, given cwd and root""" |
1081
8b7d63489db3
Change canonpath to not know about repo objects
mpm@selenic.com
parents:
1075
diff
changeset
|
168 |
rootsep = root + os.sep |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
169 |
name = myname |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
170 |
if not name.startswith(os.sep): |
1081
8b7d63489db3
Change canonpath to not know about repo objects
mpm@selenic.com
parents:
1075
diff
changeset
|
171 |
name = os.path.join(root, cwd, name) |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
172 |
name = os.path.normpath(name) |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
173 |
if name.startswith(rootsep): |
886
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
174 |
return pconvert(name[len(rootsep):]) |
1081
8b7d63489db3
Change canonpath to not know about repo objects
mpm@selenic.com
parents:
1075
diff
changeset
|
175 |
elif name == root: |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
176 |
return '' |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
177 |
else: |
1081
8b7d63489db3
Change canonpath to not know about repo objects
mpm@selenic.com
parents:
1075
diff
changeset
|
178 |
raise Abort('%s not under root' % myname) |
897 | 179 |
|
1270
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
180 |
def matcher(canonroot, cwd='', names=['.'], inc=[], exc=[], head=''): |
1082 | 181 |
"""build a function to match a set of file patterns |
182 |
||
183 |
arguments: |
|
184 |
canonroot - the canonical root of the tree you're matching against |
|
185 |
cwd - the current working directory, if relevant |
|
186 |
names - patterns to find |
|
187 |
inc - patterns to include |
|
188 |
exc - patterns to exclude |
|
189 |
head - a regex to prepend to patterns to control whether a match is rooted |
|
190 |
||
191 |
a pattern is one of: |
|
1270
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
192 |
'glob:<rooted glob>' |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
193 |
're:<rooted regexp>' |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
194 |
'path:<rooted path>' |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
195 |
'relglob:<relative glob>' |
1082 | 196 |
'relpath:<relative path>' |
1270
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
197 |
'relre:<relative regexp>' |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
198 |
'<rooted path or regexp>' |
1082 | 199 |
|
200 |
returns: |
|
201 |
a 3-tuple containing |
|
202 |
- list of explicit non-pattern names passed in |
|
203 |
- a bool match(filename) function |
|
204 |
- a bool indicating if any patterns were passed in |
|
205 |
||
206 |
todo: |
|
207 |
make head regex a rooted bool |
|
208 |
""" |
|
209 |
||
820
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
210 |
def patkind(name): |
1270
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
211 |
for prefix in 're', 'glob', 'path', 'relglob', 'relpath', 'relre': |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
212 |
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
|
213 |
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
|
214 |
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
|
215 |
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
|
216 |
|
888
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
217 |
def regex(kind, name, tail): |
742 | 218 |
'''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
|
219 |
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
|
220 |
return name |
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
221 |
elif kind == 'path': |
888
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
222 |
return '^' + re.escape(name) + '(?:/|$)' |
1270
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
223 |
elif kind == 'relglob': |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
224 |
return head + globre(name, '(?:|.*/)', tail) |
888
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
225 |
elif kind == 'relpath': |
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
226 |
return head + re.escape(name) + tail |
1270
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
227 |
elif kind == 'relre': |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
228 |
if name.startswith('^'): |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
229 |
return name |
fc3b41570082
Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1258
diff
changeset
|
230 |
return '.*' + name |
742 | 231 |
return head + globre(name, '', tail) |
232 |
||
233 |
def matchfn(pats, tail): |
|
234 |
"""build a matching function from a set of patterns""" |
|
235 |
if pats: |
|
888
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
236 |
pat = '(?:%s)' % '|'.join([regex(k, p, tail) for (k, p) in pats]) |
742 | 237 |
return re.compile(pat).match |
238 |
||
820
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
239 |
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
|
240 |
'''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
|
241 |
root = [] |
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
242 |
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
|
243 |
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
|
244 |
root.append(p) |
886
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
245 |
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
|
246 |
|
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
247 |
pats = [] |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
248 |
files = [] |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
249 |
roots = [] |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
250 |
for kind, name in map(patkind, names): |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
251 |
if kind in ('glob', 'relpath'): |
1081
8b7d63489db3
Change canonpath to not know about repo objects
mpm@selenic.com
parents:
1075
diff
changeset
|
252 |
name = canonpath(canonroot, cwd, name) |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
253 |
if name == '': |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
254 |
kind, name = 'glob', '**' |
888
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
255 |
if kind in ('glob', 'path', 're'): |
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
256 |
pats.append((kind, name)) |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
257 |
if kind == 'glob': |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
258 |
root = globprefix(name) |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
259 |
if root: roots.append(root) |
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
260 |
elif kind == 'relpath': |
888
e7a943e8c52b
Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
886
diff
changeset
|
261 |
files.append((kind, name)) |
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
262 |
roots.append(name) |
897 | 263 |
|
820
89985a1b3427
Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents:
814
diff
changeset
|
264 |
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
|
265 |
filematch = matchfn(files, '(?:/|$)') or always |
897 | 266 |
incmatch = always |
267 |
if inc: |
|
268 |
incmatch = matchfn(map(patkind, inc), '(?:/|$)') |
|
269 |
excmatch = lambda fn: False |
|
270 |
if exc: |
|
271 |
excmatch = matchfn(map(patkind, exc), '(?:/|$)') |
|
742 | 272 |
|
1031
503aaf19a040
Rewrite log command. New version is faster and more featureful.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1015
diff
changeset
|
273 |
return (roots, |
503aaf19a040
Rewrite log command. New version is faster and more featureful.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1015
diff
changeset
|
274 |
lambda fn: (incmatch(fn) and not excmatch(fn) and |
503aaf19a040
Rewrite log command. New version is faster and more featureful.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1015
diff
changeset
|
275 |
(fn.endswith('/') or |
503aaf19a040
Rewrite log command. New version is faster and more featureful.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1015
diff
changeset
|
276 |
(not pats and not files) or |
503aaf19a040
Rewrite log command. New version is faster and more featureful.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1015
diff
changeset
|
277 |
(pats and patmatch(fn)) or |
503aaf19a040
Rewrite log command. New version is faster and more featureful.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1015
diff
changeset
|
278 |
(files and filematch(fn)))), |
503aaf19a040
Rewrite log command. New version is faster and more featureful.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1015
diff
changeset
|
279 |
(inc or exc or (pats and pats != [('glob', '**')])) and True) |
742 | 280 |
|
521 | 281 |
def system(cmd, errprefix=None): |
508 | 282 |
"""execute a shell command that must succeed""" |
283 |
rc = os.system(cmd) |
|
284 |
if rc: |
|
521 | 285 |
errmsg = "%s %s" % (os.path.basename(cmd.split(None, 1)[0]), |
286 |
explain_exit(rc)[0]) |
|
287 |
if errprefix: |
|
288 |
errmsg = "%s: %s" % (errprefix, errmsg) |
|
870
a82eae840447
Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents:
869
diff
changeset
|
289 |
raise Abort(errmsg) |
508 | 290 |
|
421 | 291 |
def rename(src, dst): |
1082 | 292 |
"""forcibly rename a file""" |
421 | 293 |
try: |
294 |
os.rename(src, dst) |
|
295 |
except: |
|
296 |
os.unlink(dst) |
|
297 |
os.rename(src, dst) |
|
298 |
||
1241
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
299 |
def copyfiles(src, dst, hardlink=None): |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
300 |
"""Copy a directory tree using hardlinks if possible""" |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
301 |
|
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
302 |
if hardlink is None: |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
303 |
hardlink = (os.stat(src).st_dev == |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
304 |
os.stat(os.path.dirname(dst)).st_dev) |
698
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
305 |
|
1207 | 306 |
if os.path.isdir(src): |
307 |
os.mkdir(dst) |
|
308 |
for name in os.listdir(src): |
|
309 |
srcname = os.path.join(src, name) |
|
310 |
dstname = os.path.join(dst, name) |
|
1241
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
311 |
copyfiles(srcname, dstname, hardlink) |
1207 | 312 |
else: |
1241
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
313 |
if hardlink: |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
314 |
try: |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
315 |
os_link(src, dst) |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
316 |
except: |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
317 |
hardlink = False |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
318 |
shutil.copy2(src, dst) |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
319 |
else: |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
320 |
shutil.copy2(src, dst) |
698
df78d8ccac4c
Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
667
diff
changeset
|
321 |
|
1090 | 322 |
def opener(base): |
323 |
""" |
|
324 |
return a function that opens files relative to base |
|
325 |
||
326 |
this function is used to hide the details of COW semantics and |
|
327 |
remote file access from higher level code. |
|
328 |
""" |
|
329 |
p = base |
|
1329
8f06817bf266
Allow files to be opened in text mode, even on Windows.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1321
diff
changeset
|
330 |
def o(path, mode="r", text=False): |
1090 | 331 |
f = os.path.join(p, path) |
332 |
||
1329
8f06817bf266
Allow files to be opened in text mode, even on Windows.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1321
diff
changeset
|
333 |
if not text: |
8f06817bf266
Allow files to be opened in text mode, even on Windows.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1321
diff
changeset
|
334 |
mode += "b" # for that other OS |
1090 | 335 |
|
336 |
if mode[0] != "r": |
|
337 |
try: |
|
1241
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
338 |
nlink = nlinks(f) |
1090 | 339 |
except OSError: |
340 |
d = os.path.dirname(f) |
|
341 |
if not os.path.isdir(d): |
|
342 |
os.makedirs(d) |
|
343 |
else: |
|
1241
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
344 |
if nlink > 1: |
1090 | 345 |
file(f + ".tmp", "wb").write(file(f, "rb").read()) |
346 |
rename(f+".tmp", f) |
|
347 |
||
348 |
return file(f, mode) |
|
349 |
||
350 |
return o |
|
351 |
||
704
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
352 |
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
|
353 |
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
|
354 |
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
|
355 |
os.close(ld) |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
356 |
|
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
357 |
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
|
358 |
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
|
359 |
|
1241
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
360 |
def nlinks(pathname): |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
361 |
"""Return number of hardlinks for the given file.""" |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
362 |
return os.stat(pathname).st_nlink |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
363 |
|
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
364 |
if hasattr(os, 'link'): |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
365 |
os_link = os.link |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
366 |
else: |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
367 |
def os_link(src, dst): |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
368 |
raise OSError(0, "Hardlinks not supported") |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
369 |
|
1082 | 370 |
# Platform specific variants |
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
371 |
if os.name == 'nt': |
461 | 372 |
nulldev = 'NUL:' |
373 |
||
1292
141951276ba1
Use platform-appropriate rc file names.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1285
diff
changeset
|
374 |
rcpath = (r'c:\mercurial\mercurial.ini', |
141951276ba1
Use platform-appropriate rc file names.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1285
diff
changeset
|
375 |
os.path.join(os.path.expanduser('~'), 'mercurial.ini')) |
141951276ba1
Use platform-appropriate rc file names.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1285
diff
changeset
|
376 |
|
1285
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
377 |
def parse_patch_output(output_line): |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
378 |
"""parses the output produced by patch and returns the file name""" |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
379 |
pf = output_line[14:] |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
380 |
if pf[0] == '`': |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
381 |
pf = pf[1:-1] # Remove the quotes |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
382 |
return pf |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
383 |
|
1241
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
384 |
try: # ActivePython can create hard links using win32file module |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
385 |
import win32file |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
386 |
|
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
387 |
def os_link(src, dst): # NB will only succeed on NTFS |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
388 |
win32file.CreateHardLink(dst, src) |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
389 |
|
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
390 |
def nlinks(pathname): |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
391 |
"""Return number of hardlinks for the given file.""" |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
392 |
try: |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
393 |
fh = win32file.CreateFile(pathname, |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
394 |
win32file.GENERIC_READ, win32file.FILE_SHARE_READ, |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
395 |
None, win32file.OPEN_EXISTING, 0, None) |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
396 |
res = win32file.GetFileInformationByHandle(fh) |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
397 |
fh.Close() |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
398 |
return res[7] |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
399 |
except: |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
400 |
return os.stat(pathname).st_nlink |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
401 |
|
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
402 |
except ImportError: |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
403 |
pass |
3b4f05ff3130
Add support for cloning with hardlinks on windows.
Stephen Darnell
parents:
1207
diff
changeset
|
404 |
|
441 | 405 |
def is_exec(f, last): |
406 |
return last |
|
407 |
||
408 |
def set_exec(f, mode): |
|
409 |
pass |
|
515 | 410 |
|
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
411 |
def pconvert(path): |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
412 |
return path.replace("\\", "/") |
422
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
413 |
|
886
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
414 |
def localpath(path): |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
415 |
return path.replace('/', '\\') |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
416 |
|
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
417 |
def normpath(path): |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
418 |
return pconvert(os.path.normpath(path)) |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
419 |
|
704
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
420 |
makelock = _makelock_file |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
421 |
readlock = _readlock_file |
461 | 422 |
|
782
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
423 |
def explain_exit(code): |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
424 |
return "exited with status %d" % code, code |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
425 |
|
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
426 |
else: |
461 | 427 |
nulldev = '/dev/null' |
428 |
||
1343
0f4e53e8c66b
Add support for /etc/mercurial/hgrc.d/*.rc
mpm@selenic.com
parents:
1329
diff
changeset
|
429 |
hgrcd = '/etc/mercurial/hgrc.d' |
0f4e53e8c66b
Add support for /etc/mercurial/hgrc.d/*.rc
mpm@selenic.com
parents:
1329
diff
changeset
|
430 |
hgrcs = [] |
0f4e53e8c66b
Add support for /etc/mercurial/hgrc.d/*.rc
mpm@selenic.com
parents:
1329
diff
changeset
|
431 |
if os.path.isdir(hgrcd): |
0f4e53e8c66b
Add support for /etc/mercurial/hgrc.d/*.rc
mpm@selenic.com
parents:
1329
diff
changeset
|
432 |
hgrcs = [f for f in os.listdir(hgrcd) if f.endswith(".rc")] |
0f4e53e8c66b
Add support for /etc/mercurial/hgrc.d/*.rc
mpm@selenic.com
parents:
1329
diff
changeset
|
433 |
rcpath = map(os.path.normpath, hgrcs + |
0f4e53e8c66b
Add support for /etc/mercurial/hgrc.d/*.rc
mpm@selenic.com
parents:
1329
diff
changeset
|
434 |
['/etc/mercurial/hgrc', os.path.expanduser('~/.hgrc')]) |
1292
141951276ba1
Use platform-appropriate rc file names.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1285
diff
changeset
|
435 |
|
1285
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
436 |
def parse_patch_output(output_line): |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
437 |
"""parses the output produced by patch and returns the file name""" |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
438 |
return output_line[14:] |
1546c2aa6b30
Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents:
1270
diff
changeset
|
439 |
|
441 | 440 |
def is_exec(f, last): |
1082 | 441 |
"""check whether a file is executable""" |
441 | 442 |
return (os.stat(f).st_mode & 0100 != 0) |
443 |
||
444 |
def set_exec(f, mode): |
|
445 |
s = os.stat(f).st_mode |
|
446 |
if (s & 0100 != 0) == mode: |
|
447 |
return |
|
448 |
if mode: |
|
449 |
# Turn on +x for every +r bit when making a file executable |
|
450 |
# and obey umask. |
|
451 |
umask = os.umask(0) |
|
452 |
os.umask(umask) |
|
453 |
os.chmod(f, s | (s & 0444) >> 2 & ~umask) |
|
454 |
else: |
|
455 |
os.chmod(f, s & 0666) |
|
456 |
||
419
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
457 |
def pconvert(path): |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
458 |
return path |
28511fc21073
[PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff
changeset
|
459 |
|
886
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
460 |
def localpath(path): |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
461 |
return path |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
462 |
|
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
463 |
normpath = os.path.normpath |
509de8ab6f31
Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents:
884
diff
changeset
|
464 |
|
422
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
465 |
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
|
466 |
try: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
467 |
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
|
468 |
except OSError, why: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
469 |
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
|
470 |
raise |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
471 |
else: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
472 |
_makelock_file(info, pathname) |
422
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
473 |
|
10c43444a38e
[PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents:
421
diff
changeset
|
474 |
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
|
475 |
try: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
476 |
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
|
477 |
except OSError, why: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
478 |
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
|
479 |
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
|
480 |
else: |
5ca319a641e1
Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
698
diff
changeset
|
481 |
raise |
782
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
482 |
|
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
483 |
def explain_exit(code): |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
484 |
"""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
|
485 |
if os.WIFEXITED(code): |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
486 |
val = os.WEXITSTATUS(code) |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
487 |
return "exited with status %d" % val, val |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
488 |
elif os.WIFSIGNALED(code): |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
489 |
val = os.WTERMSIG(code) |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
490 |
return "killed by signal %d" % val, val |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
491 |
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
|
492 |
val = os.WSTOPSIG(code) |
782
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
493 |
return "stopped by signal %d" % val, val |
cdb9e95b2fab
Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents:
742
diff
changeset
|
494 |
raise ValueError("invalid exit code") |
1199
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
495 |
|
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
496 |
class chunkbuffer(object): |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
497 |
"""Allow arbitrary sized chunks of data to be efficiently read from an |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
498 |
iterator over chunks of arbitrary size.""" |
1200 | 499 |
|
1199
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
500 |
def __init__(self, in_iter, targetsize = 2**16): |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
501 |
"""in_iter is the iterator that's iterating over the input chunks. |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
502 |
targetsize is how big a buffer to try to maintain.""" |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
503 |
self.in_iter = iter(in_iter) |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
504 |
self.buf = '' |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
505 |
self.targetsize = int(targetsize) |
1200 | 506 |
if self.targetsize <= 0: |
507 |
raise ValueError("targetsize must be greater than 0, was %d" % |
|
508 |
targetsize) |
|
1199
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
509 |
self.iterempty = False |
1200 | 510 |
|
1199
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
511 |
def fillbuf(self): |
1200 | 512 |
"""Ignore target size; read every chunk from iterator until empty.""" |
1199
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
513 |
if not self.iterempty: |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
514 |
collector = cStringIO.StringIO() |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
515 |
collector.write(self.buf) |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
516 |
for ch in self.in_iter: |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
517 |
collector.write(ch) |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
518 |
self.buf = collector.getvalue() |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
519 |
self.iterempty = True |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
520 |
|
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
521 |
def read(self, l): |
1200 | 522 |
"""Read L bytes of data from the iterator of chunks of data. |
1308
2073e5a71008
Cleanup of tabs and trailing spaces.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1285
diff
changeset
|
523 |
Returns less than L bytes if the iterator runs dry.""" |
1199
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
524 |
if l > len(self.buf) and not self.iterempty: |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
525 |
# Clamp to a multiple of self.targetsize |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
526 |
targetsize = self.targetsize * ((l // self.targetsize) + 1) |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
527 |
collector = cStringIO.StringIO() |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
528 |
collector.write(self.buf) |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
529 |
collected = len(self.buf) |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
530 |
for chunk in self.in_iter: |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
531 |
collector.write(chunk) |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
532 |
collected += len(chunk) |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
533 |
if collected >= targetsize: |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
534 |
break |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
535 |
if collected < targetsize: |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
536 |
self.iterempty = True |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
537 |
self.buf = collector.getvalue() |
1200 | 538 |
s, self.buf = self.buf[:l], buffer(self.buf, l) |
1199
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
539 |
return s |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
540 |
|
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
541 |
def filechunkiter(f, size = 65536): |
1200 | 542 |
"""Create a generator that produces all the data in the file size |
543 |
(default 65536) bytes at a time. Chunks may be less than size |
|
544 |
bytes if the chunk is the last chunk in the file, or the file is a |
|
545 |
socket or some other type of file that sometimes reads less data |
|
546 |
than is requested.""" |
|
1199
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
547 |
s = f.read(size) |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
548 |
while len(s) >= 0: |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
549 |
yield s |
78ceaf83f28f
Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents:
1169
diff
changeset
|
550 |
s = f.read(size) |
1320
5f277e73778f
Fix up representation of dates in hgweb.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1312
diff
changeset
|
551 |
|
1321
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
552 |
def makedate(): |
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
553 |
t = time.time() |
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
554 |
if time.daylight: tz = time.altzone |
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
555 |
else: tz = time.timezone |
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
556 |
return t, tz |
1329
8f06817bf266
Allow files to be opened in text mode, even on Windows.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1321
diff
changeset
|
557 |
|
1321
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
558 |
def datestr(date=None, format='%c'): |
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
559 |
"""represent a (unixtime, offset) tuple as a localized time. |
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
560 |
unixtime is seconds since the epoch, and offset is the time zone's |
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
561 |
number of seconds away from UTC.""" |
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
562 |
t, tz = date or makedate() |
1320
5f277e73778f
Fix up representation of dates in hgweb.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1312
diff
changeset
|
563 |
return ("%s %+03d%02d" % |
5f277e73778f
Fix up representation of dates in hgweb.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1312
diff
changeset
|
564 |
(time.strftime(format, time.gmtime(float(t) - tz)), |
5f277e73778f
Fix up representation of dates in hgweb.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1312
diff
changeset
|
565 |
-tz / 3600, |
5f277e73778f
Fix up representation of dates in hgweb.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1312
diff
changeset
|
566 |
((-tz % 3600) / 60))) |