annotate mercurial/util.py @ 1609:c50bddfbc812

eliminate backtrace when piping output on windows. this fixes issue 54.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Mon, 02 Jan 2006 15:25:33 -0800
parents a329e0fda2ae
children 84e9b3484ff6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
1 """
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
2 util.py - Mercurial utility functions and platform specfic implementations
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
3
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
4 Copyright 2005 K. Thananchayan <thananck@yahoo.com>
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
5
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
6 This software may be used and distributed according to the terms
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
7 of the GNU General Public License, incorporated herein by reference.
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
8
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
9 This contains helper routines that are independent of the SCM core and hide
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
10 platform-specific details from the core.
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
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
1400
cf9a1233738a i18n first part: make '_' available for files who need it
Benoit Boissinot <benoit.boissinot@ens-lyon.org
parents: 1399
diff changeset
14 from i18n import gettext as _
724
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
15 from demandload import *
1609
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
16 demandload(globals(), "cStringIO errno popen2 re shutil sys tempfile")
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
17 demandload(globals(), "threading time")
1258
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
18
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
19 def pipefilter(s, cmd):
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
20 '''filter string S through command CMD, returning its output'''
1258
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
21 (pout, pin) = popen2.popen2(cmd, -1, 'b')
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
22 def writer():
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
23 pin.write(s)
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
24 pin.close()
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
25
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
26 # we should use select instead on UNIX, but this will work on most
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
27 # systems, including Windows
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
28 w = threading.Thread(target=writer)
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
29 w.start()
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
30 f = pout.read()
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
31 pout.close()
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
32 w.join()
1945754e466b Add file encoding/decoding support
mpm@selenic.com
parents: 1241
diff changeset
33 return f
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
34
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
35 def tempfilter(s, cmd):
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
36 '''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
37 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
38 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
39 the temporary files generated.'''
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
40 inname, outname = None, None
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
41 try:
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
42 infd, inname = tempfile.mkstemp(prefix='hgfin')
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
43 fp = os.fdopen(infd, 'wb')
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
44 fp.write(s)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
45 fp.close()
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
46 outfd, outname = tempfile.mkstemp(prefix='hgfout')
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
47 os.close(outfd)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
48 cmd = cmd.replace('INFILE', inname)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
49 cmd = cmd.replace('OUTFILE', outname)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
50 code = os.system(cmd)
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
51 if code: raise Abort(_("command '%s' failed: %s") %
1293
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
52 (cmd, explain_exit(code)))
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
53 return open(outname, 'rb').read()
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
54 finally:
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
55 try:
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
56 if inname: os.unlink(inname)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
57 except: pass
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
58 try:
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
59 if outname: os.unlink(outname)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
60 except: pass
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
61
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
62 filtertable = {
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
63 'tempfile:': tempfilter,
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
64 'pipe:': pipefilter,
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
65 }
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
66
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
67 def filter(s, cmd):
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
68 "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
69 for name, fn in filtertable.iteritems():
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
70 if cmd.startswith(name):
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
71 return fn(s, cmd[len(name):].lstrip())
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
72 return pipefilter(s, cmd)
a6ffcebd3315 Enhance the file filtering capabilities.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1292
diff changeset
73
1285
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
74 def patch(strip, patchname, ui):
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
75 """apply the patch <patchname> to the working directory.
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
76 a list of patched files is returned"""
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
77 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
78 files = {}
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
79 for line in fp:
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
80 line = line.rstrip()
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
81 ui.status("%s\n" % line)
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
82 if line.startswith('patching file '):
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
83 pf = parse_patch_output(line)
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
84 files.setdefault(pf, 1)
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
85 code = fp.close()
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
86 if code:
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
87 raise Abort(_("patch command failed: %s") % explain_exit(code)[0])
1285
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
88 return files.keys()
1308
2073e5a71008 Cleanup of tabs and trailing spaces.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1285
diff changeset
89
1015
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 917
diff changeset
90 def binary(s):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
91 """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
92 if s and '\0' in s[:4096]:
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 917
diff changeset
93 return True
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 917
diff changeset
94 return False
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 917
diff changeset
95
556
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
96 def unique(g):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
97 """return the uniq elements of iterable g"""
556
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
98 seen = {}
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
99 for f in g:
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
100 if f not in seen:
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
101 seen[f] = 1
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
102 yield f
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
103
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
104 class Abort(Exception):
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
105 """Raised if a command needs to print an error and exit."""
508
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
106
724
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
107 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
108 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
109
1563
cc2a2e12f4ad export patkind() from util
Robin Farine <robin.farine@terminus.org>
parents: 1546
diff changeset
110 def patkind(name, dflt_pat='glob'):
cc2a2e12f4ad export patkind() from util
Robin Farine <robin.farine@terminus.org>
parents: 1546
diff changeset
111 """Split a string into an optional pattern kind prefix and the
cc2a2e12f4ad export patkind() from util
Robin Farine <robin.farine@terminus.org>
parents: 1546
diff changeset
112 actual pattern."""
cc2a2e12f4ad export patkind() from util
Robin Farine <robin.farine@terminus.org>
parents: 1546
diff changeset
113 for prefix in 're', 'glob', 'path', 'relglob', 'relpath', 'relre':
cc2a2e12f4ad export patkind() from util
Robin Farine <robin.farine@terminus.org>
parents: 1546
diff changeset
114 if name.startswith(prefix + ':'): return name.split(':', 1)
cc2a2e12f4ad export patkind() from util
Robin Farine <robin.farine@terminus.org>
parents: 1546
diff changeset
115 return dflt_pat, name
cc2a2e12f4ad export patkind() from util
Robin Farine <robin.farine@terminus.org>
parents: 1546
diff changeset
116
1062
6d5a62a549fa pep-0008 cleanup
benoit.boissinot@ens-lyon.fr
parents: 1031
diff changeset
117 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
118 "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
119 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
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 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
122 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
123 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
124 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
125 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
126 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
127 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
128 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
129 res += '.*'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
130 else:
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
131 res += '[^/]*'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
132 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
133 res += '.'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
134 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
135 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
136 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
137 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
138 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
139 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
140 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
141 res += '\\['
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
142 else:
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
143 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
144 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
145 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
146 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
147 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
148 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
149 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
150 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
151 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
152 res += '(?:'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
153 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
154 res += ')'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
155 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
156 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
157 res += '|'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
158 else:
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
159 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
160 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
161
812
b65af904d6d7 Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents: 782
diff changeset
162 _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
163
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
164 def pathto(n1, n2):
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
165 '''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
166 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
167 if not n1: return localpath(n2)
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
168 a, b = n1.split('/'), n2.split('/')
1541
bf4e7ef08741 fixed some stuff pychecker shows, marked unclear/wrong stuff with XXX
twaldmann@thinkmo.de
parents: 1528
diff changeset
169 a.reverse()
bf4e7ef08741 fixed some stuff pychecker shows, marked unclear/wrong stuff with XXX
twaldmann@thinkmo.de
parents: 1528
diff changeset
170 b.reverse()
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
171 while a and b and a[-1] == b[-1]:
1541
bf4e7ef08741 fixed some stuff pychecker shows, marked unclear/wrong stuff with XXX
twaldmann@thinkmo.de
parents: 1528
diff changeset
172 a.pop()
bf4e7ef08741 fixed some stuff pychecker shows, marked unclear/wrong stuff with XXX
twaldmann@thinkmo.de
parents: 1528
diff changeset
173 b.pop()
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
174 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
175 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
176
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
177 def canonpath(root, cwd, myname):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
178 """return the canonical path of myname, given cwd and root"""
1566
8befbb4e30b2 Handle hg under /
Arun Sharma <arun@sharma-home.net>
parents: 1563
diff changeset
179 if root == os.sep:
8befbb4e30b2 Handle hg under /
Arun Sharma <arun@sharma-home.net>
parents: 1563
diff changeset
180 rootsep = os.sep
8befbb4e30b2 Handle hg under /
Arun Sharma <arun@sharma-home.net>
parents: 1563
diff changeset
181 else:
8befbb4e30b2 Handle hg under /
Arun Sharma <arun@sharma-home.net>
parents: 1563
diff changeset
182 rootsep = root + os.sep
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
183 name = myname
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
184 if not name.startswith(os.sep):
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
185 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
186 name = os.path.normpath(name)
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
187 if name.startswith(rootsep):
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
188 return pconvert(name[len(rootsep):])
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
189 elif name == root:
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
190 return ''
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
191 else:
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
192 raise Abort('%s not under root' % myname)
897
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
193
1270
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
194 def matcher(canonroot, cwd='', names=['.'], inc=[], exc=[], head=''):
1413
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
195 return _matcher(canonroot, cwd, names, inc, exc, head, 'glob')
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
196
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
197 def cmdmatcher(canonroot, cwd='', names=['.'], inc=[], exc=[], head=''):
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
198 if os.name == 'nt':
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
199 dflt_pat = 'glob'
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
200 else:
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
201 dflt_pat = 'relpath'
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
202 return _matcher(canonroot, cwd, names, inc, exc, head, dflt_pat)
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
203
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
204 def _matcher(canonroot, cwd, names, inc, exc, head, dflt_pat):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
205 """build a function to match a set of file patterns
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
206
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
207 arguments:
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
208 canonroot - the canonical root of the tree you're matching against
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
209 cwd - the current working directory, if relevant
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
210 names - patterns to find
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
211 inc - patterns to include
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
212 exc - patterns to exclude
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
213 head - a regex to prepend to patterns to control whether a match is rooted
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
214
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
215 a pattern is one of:
1270
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
216 'glob:<rooted glob>'
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
217 're:<rooted regexp>'
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
218 'path:<rooted path>'
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
219 'relglob:<relative glob>'
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
220 'relpath:<relative path>'
1270
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
221 'relre:<relative regexp>'
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
222 '<rooted path or regexp>'
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
223
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
224 returns:
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
225 a 3-tuple containing
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
226 - list of explicit non-pattern names passed in
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
227 - a bool match(filename) function
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
228 - a bool indicating if any patterns were passed in
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
229
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
230 todo:
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
231 make head regex a rooted bool
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
232 """
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
233
1413
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
234 def contains_glob(name):
812
b65af904d6d7 Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents: 782
diff changeset
235 for c in name:
1413
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
236 if c in _globchars: return True
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
237 return False
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
238
888
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
239 def regex(kind, name, tail):
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
240 '''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
241 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
242 return name
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
243 elif kind == 'path':
888
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
244 return '^' + re.escape(name) + '(?:/|$)'
1270
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
245 elif kind == 'relglob':
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
246 return head + globre(name, '(?:|.*/)', tail)
888
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
247 elif kind == 'relpath':
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
248 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
249 elif kind == 'relre':
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
250 if name.startswith('^'):
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
251 return name
fc3b41570082 Switch to new syntax for .hgignore files.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1258
diff changeset
252 return '.*' + name
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
253 return head + globre(name, '', tail)
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
254
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
255 def matchfn(pats, tail):
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
256 """build a matching function from a set of patterns"""
1454
f4250806dbeb further fix traceback on invalid .hgignore patterns
Benoit Boissinot <mercurial-bugs@selenic.com>
parents: 1446
diff changeset
257 if not pats:
f4250806dbeb further fix traceback on invalid .hgignore patterns
Benoit Boissinot <mercurial-bugs@selenic.com>
parents: 1446
diff changeset
258 return
1446
4babaa52badf abort on invalid pattern in matcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1420
diff changeset
259 matches = []
4babaa52badf abort on invalid pattern in matcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1420
diff changeset
260 for k, p in pats:
4babaa52badf abort on invalid pattern in matcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1420
diff changeset
261 try:
4babaa52badf abort on invalid pattern in matcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1420
diff changeset
262 pat = '(?:%s)' % regex(k, p, tail)
4babaa52badf abort on invalid pattern in matcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1420
diff changeset
263 matches.append(re.compile(pat).match)
1541
bf4e7ef08741 fixed some stuff pychecker shows, marked unclear/wrong stuff with XXX
twaldmann@thinkmo.de
parents: 1528
diff changeset
264 except re.error:
1446
4babaa52badf abort on invalid pattern in matcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1420
diff changeset
265 raise Abort("invalid pattern: %s:%s" % (k, p))
4babaa52badf abort on invalid pattern in matcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1420
diff changeset
266
4babaa52badf abort on invalid pattern in matcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1420
diff changeset
267 def buildfn(text):
4babaa52badf abort on invalid pattern in matcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1420
diff changeset
268 for m in matches:
4babaa52badf abort on invalid pattern in matcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1420
diff changeset
269 r = m(text)
4babaa52badf abort on invalid pattern in matcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1420
diff changeset
270 if r:
4babaa52badf abort on invalid pattern in matcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1420
diff changeset
271 return r
4babaa52badf abort on invalid pattern in matcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1420
diff changeset
272
4babaa52badf abort on invalid pattern in matcher
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1420
diff changeset
273 return buildfn
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
274
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
275 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
276 '''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
277 root = []
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
278 for p in pat.split(os.sep):
1413
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
279 if contains_glob(p): break
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
280 root.append(p)
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
281 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
282
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
283 pats = []
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
284 files = []
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
285 roots = []
1413
1c64c628d15f Do not use 'glob' expansion by default on OS != 'nt'
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1402
diff changeset
286 for kind, name in [patkind(p, dflt_pat) for p in names]:
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
287 if kind in ('glob', 'relpath'):
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
288 name = canonpath(canonroot, cwd, name)
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
289 if name == '':
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
290 kind, name = 'glob', '**'
888
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
291 if kind in ('glob', 'path', 're'):
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
292 pats.append((kind, name))
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
293 if kind == 'glob':
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
294 root = globprefix(name)
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
295 if root: roots.append(root)
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
296 elif kind == 'relpath':
888
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
297 files.append((kind, name))
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
298 roots.append(name)
897
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
299
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
300 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
301 filematch = matchfn(files, '(?:/|$)') or always
897
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
302 incmatch = always
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
303 if inc:
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
304 incmatch = matchfn(map(patkind, inc), '(?:/|$)')
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
305 excmatch = lambda fn: False
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
306 if exc:
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
307 excmatch = matchfn(map(patkind, exc), '(?:/|$)')
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
308
1031
503aaf19a040 Rewrite log command. New version is faster and more featureful.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1015
diff changeset
309 return (roots,
503aaf19a040 Rewrite log command. New version is faster and more featureful.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1015
diff changeset
310 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
311 (fn.endswith('/') or
503aaf19a040 Rewrite log command. New version is faster and more featureful.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1015
diff changeset
312 (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
313 (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
314 (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
315 (inc or exc or (pats and pats != [('glob', '**')])) and True)
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
316
521
0fb8ade0f756 [PATCH] Fix use of util.CommandError
mpm@selenic.com
parents: 515
diff changeset
317 def system(cmd, errprefix=None):
508
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
318 """execute a shell command that must succeed"""
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
319 rc = os.system(cmd)
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
320 if rc:
521
0fb8ade0f756 [PATCH] Fix use of util.CommandError
mpm@selenic.com
parents: 515
diff changeset
321 errmsg = "%s %s" % (os.path.basename(cmd.split(None, 1)[0]),
0fb8ade0f756 [PATCH] Fix use of util.CommandError
mpm@selenic.com
parents: 515
diff changeset
322 explain_exit(rc)[0])
0fb8ade0f756 [PATCH] Fix use of util.CommandError
mpm@selenic.com
parents: 515
diff changeset
323 if errprefix:
0fb8ade0f756 [PATCH] Fix use of util.CommandError
mpm@selenic.com
parents: 515
diff changeset
324 errmsg = "%s: %s" % (errprefix, errmsg)
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
325 raise Abort(errmsg)
508
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
326
421
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
327 def rename(src, dst):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
328 """forcibly rename a file"""
421
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
329 try:
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
330 os.rename(src, dst)
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
331 except:
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
332 os.unlink(dst)
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
333 os.rename(src, dst)
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
334
1415
c6e6ca96a033 refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1413
diff changeset
335 def unlink(f):
c6e6ca96a033 refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1413
diff changeset
336 """unlink and remove the directory if it is empty"""
c6e6ca96a033 refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1413
diff changeset
337 os.unlink(f)
c6e6ca96a033 refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1413
diff changeset
338 # try removing directories that might now be empty
c6e6ca96a033 refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1413
diff changeset
339 try: os.removedirs(os.path.dirname(f))
c6e6ca96a033 refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1413
diff changeset
340 except: pass
c6e6ca96a033 refactor some unlink/remove code and make sure we prune empty dir
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1413
diff changeset
341
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
342 def copyfiles(src, dst, hardlink=None):
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
343 """Copy a directory tree using hardlinks if possible"""
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
344
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
345 if hardlink is None:
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
346 hardlink = (os.stat(src).st_dev ==
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
347 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
348
1207
a7b8812973d9 Rewrite copytree as copyfiles
mpm@selenic.com
parents: 1200
diff changeset
349 if os.path.isdir(src):
a7b8812973d9 Rewrite copytree as copyfiles
mpm@selenic.com
parents: 1200
diff changeset
350 os.mkdir(dst)
a7b8812973d9 Rewrite copytree as copyfiles
mpm@selenic.com
parents: 1200
diff changeset
351 for name in os.listdir(src):
a7b8812973d9 Rewrite copytree as copyfiles
mpm@selenic.com
parents: 1200
diff changeset
352 srcname = os.path.join(src, name)
a7b8812973d9 Rewrite copytree as copyfiles
mpm@selenic.com
parents: 1200
diff changeset
353 dstname = os.path.join(dst, name)
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
354 copyfiles(srcname, dstname, hardlink)
1207
a7b8812973d9 Rewrite copytree as copyfiles
mpm@selenic.com
parents: 1200
diff changeset
355 else:
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
356 if hardlink:
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
357 try:
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
358 os_link(src, dst)
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
359 except:
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
360 hardlink = False
1591
5a3229cf1492 do not copy atime and mtime in util.copyfiles
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1585
diff changeset
361 shutil.copy(src, dst)
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
362 else:
1591
5a3229cf1492 do not copy atime and mtime in util.copyfiles
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1585
diff changeset
363 shutil.copy(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
364
1090
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
365 def opener(base):
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
366 """
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
367 return a function that opens files relative to base
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
368
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
369 this function is used to hide the details of COW semantics and
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
370 remote file access from higher level code.
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
371 """
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
372 p = base
1528
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
373
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
374 def mktempcopy(name):
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
375 d, fn = os.path.split(name)
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
376 fd, temp = tempfile.mkstemp(prefix=fn, dir=d)
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
377 fp = os.fdopen(fd, "wb")
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
378 try:
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
379 fp.write(file(name, "rb").read())
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
380 except:
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
381 try: os.unlink(temp)
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
382 except: pass
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
383 raise
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
384 fp.close()
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
385 st = os.lstat(name)
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
386 os.chmod(temp, st.st_mode)
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
387 return temp
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
388
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
389 class atomicfile(file):
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
390 """the file will only be copied on close"""
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
391 def __init__(self, name, mode, atomic=False):
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
392 self.__name = name
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
393 self.temp = mktempcopy(name)
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
394 file.__init__(self, self.temp, mode)
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
395 def close(self):
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
396 if not self.closed:
1546
487e256ad545 close file before renaming it (since it doesn't work the other way on windows)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1541
diff changeset
397 file.close(self)
1528
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
398 rename(self.temp, self.__name)
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
399 def __del__(self):
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
400 self.close()
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
401
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
402 def o(path, mode="r", text=False, atomic=False):
1090
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
403 f = os.path.join(p, path)
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
404
1329
8f06817bf266 Allow files to be opened in text mode, even on Windows.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1321
diff changeset
405 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
406 mode += "b" # for that other OS
1090
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
407
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
408 if mode[0] != "r":
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
409 try:
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
410 nlink = nlinks(f)
1090
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
411 except OSError:
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
412 d = os.path.dirname(f)
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
413 if not os.path.isdir(d):
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
414 os.makedirs(d)
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
415 else:
1528
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
416 if atomic:
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
417 return atomicfile(f, mode)
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
418 if nlink > 1:
1528
c9f33196805b add an atomic argument to util.opener
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1521
diff changeset
419 rename(mktempcopy(f), f)
1090
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
420 return file(f, mode)
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
421
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
422 return o
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
423
704
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
424 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
425 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
426 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
427 os.close(ld)
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
428
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
429 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
430 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
431
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
432 def nlinks(pathname):
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
433 """Return number of hardlinks for the given file."""
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
434 return os.stat(pathname).st_nlink
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
435
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
436 if hasattr(os, 'link'):
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
437 os_link = os.link
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
438 else:
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
439 def os_link(src, dst):
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
440 raise OSError(0, _("Hardlinks not supported"))
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
441
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
442 # Platform specific variants
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
443 if os.name == 'nt':
1420
b32b3509c7ab Avoid insertion/deletion of CRs on stdio during hg serve
olivier.maquelin@intel.com
parents: 1415
diff changeset
444 demandload(globals(), "msvcrt")
461
9ae0034f2772 [PATCH] /dev/null for other OS
mpm@selenic.com
parents: 441
diff changeset
445 nulldev = 'NUL:'
1609
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
446
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
447 class winstdout:
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
448 '''stdout on windows misbehaves if sent through a pipe'''
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
449
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
450 def __init__(self, fp):
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
451 self.fp = fp
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
452
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
453 def __getattr__(self, key):
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
454 return getattr(self.fp, key)
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
455
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
456 def close(self):
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
457 try:
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
458 self.fp.close()
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
459 except: pass
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
460
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
461 def write(self, s):
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
462 try:
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
463 return self.fp.write(s)
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
464 except IOError, inst:
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
465 if inst.errno != 0: raise
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
466 self.close()
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
467 raise IOError(errno.EPIPE, 'Broken pipe')
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
468
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
469 sys.stdout = winstdout(sys.stdout)
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
470
1399
9a70776e355e Try to use ini-file in the same directory as the exe as the default on NT.
Zbynek Winkler <zwin@users.sourceforge.net>
parents: 1391
diff changeset
471 try:
9a70776e355e Try to use ini-file in the same directory as the exe as the default on NT.
Zbynek Winkler <zwin@users.sourceforge.net>
parents: 1391
diff changeset
472 import win32api, win32process
9a70776e355e Try to use ini-file in the same directory as the exe as the default on NT.
Zbynek Winkler <zwin@users.sourceforge.net>
parents: 1391
diff changeset
473 filename = win32process.GetModuleFileNameEx(win32api.GetCurrentProcess(), 0)
9a70776e355e Try to use ini-file in the same directory as the exe as the default on NT.
Zbynek Winkler <zwin@users.sourceforge.net>
parents: 1391
diff changeset
474 systemrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
1609
c50bddfbc812 eliminate backtrace when piping output on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1594
diff changeset
475
1399
9a70776e355e Try to use ini-file in the same directory as the exe as the default on NT.
Zbynek Winkler <zwin@users.sourceforge.net>
parents: 1391
diff changeset
476 except ImportError:
9a70776e355e Try to use ini-file in the same directory as the exe as the default on NT.
Zbynek Winkler <zwin@users.sourceforge.net>
parents: 1391
diff changeset
477 systemrc = r'c:\mercurial\mercurial.ini'
9a70776e355e Try to use ini-file in the same directory as the exe as the default on NT.
Zbynek Winkler <zwin@users.sourceforge.net>
parents: 1391
diff changeset
478 pass
461
9ae0034f2772 [PATCH] /dev/null for other OS
mpm@selenic.com
parents: 441
diff changeset
479
1399
9a70776e355e Try to use ini-file in the same directory as the exe as the default on NT.
Zbynek Winkler <zwin@users.sourceforge.net>
parents: 1391
diff changeset
480 rcpath = (systemrc,
1292
141951276ba1 Use platform-appropriate rc file names.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1285
diff changeset
481 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
482
1285
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
483 def parse_patch_output(output_line):
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
484 """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
485 pf = output_line[14:]
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
486 if pf[0] == '`':
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
487 pf = pf[1:-1] # Remove the quotes
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
488 return pf
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
489
1241
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
490 try: # ActivePython can create hard links using win32file module
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
491 import win32file
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
492
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
493 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
494 win32file.CreateHardLink(dst, src)
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
495
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
496 def nlinks(pathname):
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
497 """Return number of hardlinks for the given file."""
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
498 try:
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
499 fh = win32file.CreateFile(pathname,
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
500 win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
501 None, win32file.OPEN_EXISTING, 0, None)
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
502 res = win32file.GetFileInformationByHandle(fh)
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
503 fh.Close()
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
504 return res[7]
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
505 except:
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
506 return os.stat(pathname).st_nlink
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
507
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
508 except ImportError:
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
509 pass
3b4f05ff3130 Add support for cloning with hardlinks on windows.
Stephen Darnell
parents: 1207
diff changeset
510
441
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
511 def is_exec(f, last):
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
512 return last
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
513
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
514 def set_exec(f, mode):
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
515 pass
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 508
diff changeset
516
1420
b32b3509c7ab Avoid insertion/deletion of CRs on stdio during hg serve
olivier.maquelin@intel.com
parents: 1415
diff changeset
517 def set_binary(fd):
b32b3509c7ab Avoid insertion/deletion of CRs on stdio during hg serve
olivier.maquelin@intel.com
parents: 1415
diff changeset
518 msvcrt.setmode(fd.fileno(), os.O_BINARY)
b32b3509c7ab Avoid insertion/deletion of CRs on stdio during hg serve
olivier.maquelin@intel.com
parents: 1415
diff changeset
519
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
520 def pconvert(path):
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
521 return path.replace("\\", "/")
422
10c43444a38e [PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents: 421
diff changeset
522
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
523 def localpath(path):
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
524 return path.replace('/', '\\')
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
525
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
526 def normpath(path):
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
527 return pconvert(os.path.normpath(path))
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
528
704
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
529 makelock = _makelock_file
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
530 readlock = _readlock_file
461
9ae0034f2772 [PATCH] /dev/null for other OS
mpm@selenic.com
parents: 441
diff changeset
531
782
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
532 def explain_exit(code):
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
533 return _("exited with status %d") % code, code
782
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
534
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
535 else:
461
9ae0034f2772 [PATCH] /dev/null for other OS
mpm@selenic.com
parents: 441
diff changeset
536 nulldev = '/dev/null'
9ae0034f2772 [PATCH] /dev/null for other OS
mpm@selenic.com
parents: 441
diff changeset
537
1583
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
538 def rcfiles(path):
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
539 rcs = [os.path.join(path, 'hgrc')]
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
540 rcdir = os.path.join(path, 'hgrc.d')
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
541 try:
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
542 rcs.extend([os.path.join(rcdir, f) for f in os.listdir(rcdir)
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
543 if f.endswith(".rc")])
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
544 except OSError, inst: pass
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
545 return rcs
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
546 rcpath = rcfiles(os.path.dirname(sys.argv[0]) + '/../etc/mercurial')
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
547 rcpath.extend(rcfiles('/etc/mercurial'))
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
548 rcpath.append(os.path.expanduser('~/.hgrc'))
32a4e6802864 make mercurial look in more places for config files.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1482
diff changeset
549 rcpath = [os.path.normpath(f) for f in rcpath]
1292
141951276ba1 Use platform-appropriate rc file names.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1285
diff changeset
550
1285
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
551 def parse_patch_output(output_line):
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
552 """parses the output produced by patch and returns the file name"""
1593
6bb3463b124b if a filename contains spaces, patch adds quote around it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1585
diff changeset
553 pf = output_line[14:]
6bb3463b124b if a filename contains spaces, patch adds quote around it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1585
diff changeset
554 if pf.startswith("'") and pf.endswith("'") and pf.find(" ") >= 0:
6bb3463b124b if a filename contains spaces, patch adds quote around it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1585
diff changeset
555 pf = pf[1:-1] # Remove the quotes
6bb3463b124b if a filename contains spaces, patch adds quote around it
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1585
diff changeset
556 return pf
1285
1546c2aa6b30 Make 'hg import' platform independent.
Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
parents: 1270
diff changeset
557
441
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
558 def is_exec(f, last):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
559 """check whether a file is executable"""
441
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
560 return (os.stat(f).st_mode & 0100 != 0)
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
561
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
562 def set_exec(f, mode):
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
563 s = os.stat(f).st_mode
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
564 if (s & 0100 != 0) == mode:
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
565 return
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
566 if mode:
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
567 # Turn on +x for every +r bit when making a file executable
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
568 # and obey umask.
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
569 umask = os.umask(0)
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
570 os.umask(umask)
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
571 os.chmod(f, s | (s & 0444) >> 2 & ~umask)
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
572 else:
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
573 os.chmod(f, s & 0666)
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
574
1420
b32b3509c7ab Avoid insertion/deletion of CRs on stdio during hg serve
olivier.maquelin@intel.com
parents: 1415
diff changeset
575 def set_binary(fd):
b32b3509c7ab Avoid insertion/deletion of CRs on stdio during hg serve
olivier.maquelin@intel.com
parents: 1415
diff changeset
576 pass
b32b3509c7ab Avoid insertion/deletion of CRs on stdio during hg serve
olivier.maquelin@intel.com
parents: 1415
diff changeset
577
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
578 def pconvert(path):
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
579 return path
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
580
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
581 def localpath(path):
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
582 return path
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
583
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
584 normpath = os.path.normpath
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
585
422
10c43444a38e [PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents: 421
diff changeset
586 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
587 try:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
588 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
589 except OSError, why:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
590 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
591 raise
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
592 else:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
593 _makelock_file(info, pathname)
422
10c43444a38e [PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents: 421
diff changeset
594
10c43444a38e [PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents: 421
diff changeset
595 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
596 try:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
597 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
598 except OSError, why:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
599 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
600 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
601 else:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
602 raise
782
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
603
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
604 def explain_exit(code):
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
605 """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
606 if os.WIFEXITED(code):
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
607 val = os.WEXITSTATUS(code)
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
608 return _("exited with status %d") % val, val
782
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
609 elif os.WIFSIGNALED(code):
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
610 val = os.WTERMSIG(code)
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
611 return _("killed by signal %d") % val, val
782
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
612 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
613 val = os.WSTOPSIG(code)
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
614 return _("stopped by signal %d") % val, val
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
615 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
616
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
617 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
618 """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
619 iterator over chunks of arbitrary size."""
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
620
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
621 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
622 """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
623 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
624 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
625 self.buf = ''
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
626 self.targetsize = int(targetsize)
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
627 if self.targetsize <= 0:
1402
9d2c2e6b32b5 i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1400
diff changeset
628 raise ValueError(_("targetsize must be greater than 0, was %d") %
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
629 targetsize)
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
630 self.iterempty = False
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
631
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
632 def fillbuf(self):
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
633 """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
634 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
635 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
636 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
637 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
638 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
639 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
640 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
641
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
642 def read(self, l):
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
643 """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
644 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
645 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
646 # 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
647 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
648 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
649 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
650 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
651 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
652 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
653 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
654 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
655 break
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
656 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
657 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
658 self.buf = collector.getvalue()
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
659 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
660 return s
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
661
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
662 def filechunkiter(f, size = 65536):
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
663 """Create a generator that produces all the data in the file size
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
664 (default 65536) bytes at a time. Chunks may be less than size
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
665 bytes if the chunk is the last chunk in the file, or the file is a
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
666 socket or some other type of file that sometimes reads less data
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
667 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
668 s = f.read(size)
1377
854775b27d1a Fixed a bug in my changes to httprepo.py
Eric Hopper <hopper@omnifarious.org>
parents: 1343
diff changeset
669 while len(s) > 0:
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
670 yield s
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
671 s = f.read(size)
1320
5f277e73778f Fix up representation of dates in hgweb.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1312
diff changeset
672
1321
b47f96a178a3 Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1320
diff changeset
673 def makedate():
1482
4d38b85e60aa fix handling of daylight saving time
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1479
diff changeset
674 lt = time.localtime()
4d38b85e60aa fix handling of daylight saving time
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1479
diff changeset
675 if lt[8] == 1 and time.daylight:
4d38b85e60aa fix handling of daylight saving time
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1479
diff changeset
676 tz = time.altzone
4d38b85e60aa fix handling of daylight saving time
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1479
diff changeset
677 else:
4d38b85e60aa fix handling of daylight saving time
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1479
diff changeset
678 tz = time.timezone
4d38b85e60aa fix handling of daylight saving time
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1479
diff changeset
679 return time.mktime(lt), tz
1329
8f06817bf266 Allow files to be opened in text mode, even on Windows.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1321
diff changeset
680
1321
b47f96a178a3 Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1320
diff changeset
681 def datestr(date=None, format='%c'):
b47f96a178a3 Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1320
diff changeset
682 """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
683 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
684 number of seconds away from UTC."""
b47f96a178a3 Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1320
diff changeset
685 t, tz = date or makedate()
1320
5f277e73778f Fix up representation of dates in hgweb.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1312
diff changeset
686 return ("%s %+03d%02d" %
5f277e73778f Fix up representation of dates in hgweb.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1312
diff changeset
687 (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
688 -tz / 3600,
5f277e73778f Fix up representation of dates in hgweb.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1312
diff changeset
689 ((-tz % 3600) / 60)))