annotate mercurial/util.py @ 1205:4003ea658693

Write out hgrc properly. Previously, we simply appended to the hgrc file, which meant that it ended up containing multiple "paths" sections. Now, we only modify "paths.default".
author Bryan O'Sullivan <bos@serpentine.com>
date Sun, 04 Sep 2005 15:47:59 -0700
parents 333de1d53846
children a7b8812973d9
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
724
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
14 from demandload import *
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
15 demandload(globals(), "re cStringIO")
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
16
1015
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 917
diff changeset
17 def binary(s):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
18 """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
19 if s and '\0' in s[:4096]:
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 917
diff changeset
20 return True
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 917
diff changeset
21 return False
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 917
diff changeset
22
556
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
23 def unique(g):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
24 """return the uniq elements of iterable g"""
556
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
25 seen = {}
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
26 for f in g:
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
27 if f not in seen:
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
28 seen[f] = 1
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
29 yield f
f6c6fa15ff70 Move dirstate.uniq to util.unique
mpm@selenic.com
parents: 521
diff changeset
30
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
31 class Abort(Exception):
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
32 """Raised if a command needs to print an error and exit."""
508
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
33
724
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
34 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
35 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
36
1062
6d5a62a549fa pep-0008 cleanup
benoit.boissinot@ens-lyon.fr
parents: 1031
diff changeset
37 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
38 "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
39 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
40 res = ''
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
41 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
42 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
43 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
44 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
45 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
46 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
47 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
48 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
49 res += '.*'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
50 else:
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
51 res += '[^/]*'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
52 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
53 res += '.'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
54 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
55 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
56 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
57 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
58 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
59 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
60 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
61 res += '\\['
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
62 else:
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
63 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
64 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
65 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
66 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
67 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
68 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
69 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
70 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
71 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
72 res += '(?:'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
73 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
74 res += ')'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
75 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
76 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
77 res += '|'
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
78 else:
1c0c413cccdd Get add and locate to use new repo and dirstate walk code.
Bryan O'Sullivan <bos@serpentine.com>
parents: 705
diff changeset
79 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
80 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
81
812
b65af904d6d7 Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents: 782
diff changeset
82 _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
83
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
84 def pathto(n1, n2):
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
85 '''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
86 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
87 if not n1: return localpath(n2)
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
88 a, b = n1.split('/'), n2.split('/')
884
087771ebe2e6 Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents: 878
diff changeset
89 a.reverse(), b.reverse()
087771ebe2e6 Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents: 878
diff changeset
90 while a and b and a[-1] == b[-1]:
087771ebe2e6 Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents: 878
diff changeset
91 a.pop(), b.pop()
087771ebe2e6 Fix walk code for files that do not exist anywhere, and unhandled types.
Bryan O'Sullivan <bos@serpentine.com>
parents: 878
diff changeset
92 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
93 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
94
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
95 def canonpath(root, cwd, myname):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
96 """return the canonical path of myname, given cwd and root"""
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
97 rootsep = root + os.sep
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
98 name = myname
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
99 if not name.startswith(os.sep):
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
100 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
101 name = os.path.normpath(name)
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
102 if name.startswith(rootsep):
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
103 return pconvert(name[len(rootsep):])
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
104 elif name == root:
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
105 return ''
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
106 else:
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
107 raise Abort('%s not under root' % myname)
897
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
108
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
109 def matcher(canonroot, cwd, names, inc, exc, head=''):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
110 """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
111
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
112 arguments:
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
113 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
114 cwd - the current working directory, if relevant
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
115 names - patterns to find
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
116 inc - patterns to include
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
117 exc - patterns to exclude
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
118 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
119
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
120 a pattern is one of:
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
121 're:<regex>'
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
122 'glob:<shellglob>'
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
123 'path:<explicit path>'
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
124 'relpath:<relative path>'
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
125 '<relative path>'
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
126
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
127 returns:
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
128 a 3-tuple containing
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
129 - list of explicit non-pattern names passed in
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
130 - a bool match(filename) function
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
131 - a bool indicating if any patterns were passed in
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
132
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
133 todo:
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
134 make head regex a rooted bool
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
135 """
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
136
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
137 def patkind(name):
888
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
138 for prefix in 're:', 'glob:', 'path:', 'relpath:':
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
139 if name.startswith(prefix): return name.split(':', 1)
812
b65af904d6d7 Reduce the amount of stat traffic generated by a walk.
Bryan O'Sullivan <bos@serpentine.com>
parents: 782
diff changeset
140 for c in name:
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
141 if c in _globchars: return 'glob', name
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
142 return 'relpath', name
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
143
888
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
144 def regex(kind, name, tail):
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
145 '''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
146 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
147 return name
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
148 elif kind == 'path':
888
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
149 return '^' + re.escape(name) + '(?:/|$)'
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
150 elif kind == 'relpath':
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
151 return head + re.escape(name) + tail
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
152 return head + globre(name, '', tail)
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
153
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
154 def matchfn(pats, tail):
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
155 """build a matching function from a set of patterns"""
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
156 if pats:
888
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
157 pat = '(?:%s)' % '|'.join([regex(k, p, tail) for (k, p) in pats])
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
158 return re.compile(pat).match
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
159
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
160 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
161 '''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
162 root = []
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
163 for p in pat.split(os.sep):
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
164 if patkind(p)[0] == 'glob': break
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
165 root.append(p)
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
166 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
167
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
168 pats = []
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
169 files = []
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
170 roots = []
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
171 for kind, name in map(patkind, names):
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
172 if kind in ('glob', 'relpath'):
1081
8b7d63489db3 Change canonpath to not know about repo objects
mpm@selenic.com
parents: 1075
diff changeset
173 name = canonpath(canonroot, cwd, name)
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
174 if name == '':
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
175 kind, name = 'glob', '**'
888
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
176 if kind in ('glob', 'path', 're'):
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
177 pats.append((kind, name))
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
178 if kind == 'glob':
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
179 root = globprefix(name)
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
180 if root: roots.append(root)
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
181 elif kind == 'relpath':
888
e7a943e8c52b Fix up handling of regexp paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 886
diff changeset
182 files.append((kind, name))
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
183 roots.append(name)
897
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
184
820
89985a1b3427 Clean up walk and changes code to use normalised names properly.
Bryan O'Sullivan <bos@serpentine.com>
parents: 814
diff changeset
185 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
186 filematch = matchfn(files, '(?:/|$)') or always
897
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
187 incmatch = always
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
188 if inc:
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
189 incmatch = matchfn(map(patkind, inc), '(?:/|$)')
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
190 excmatch = lambda fn: False
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
191 if exc:
fe30f5434b51 Fix bug with empty inc and exc
mpm@selenic.com
parents: 896
diff changeset
192 excmatch = matchfn(map(patkind, exc), '(?:/|$)')
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
193
1031
503aaf19a040 Rewrite log command. New version is faster and more featureful.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1015
diff changeset
194 return (roots,
503aaf19a040 Rewrite log command. New version is faster and more featureful.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1015
diff changeset
195 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
196 (fn.endswith('/') or
503aaf19a040 Rewrite log command. New version is faster and more featureful.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1015
diff changeset
197 (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
198 (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
199 (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
200 (inc or exc or (pats and pats != [('glob', '**')])) and True)
742
092937de2ad7 Refactor matchpats and walk
mpm@selenic.com
parents: 740
diff changeset
201
521
0fb8ade0f756 [PATCH] Fix use of util.CommandError
mpm@selenic.com
parents: 515
diff changeset
202 def system(cmd, errprefix=None):
508
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
203 """execute a shell command that must succeed"""
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
204 rc = os.system(cmd)
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
205 if rc:
521
0fb8ade0f756 [PATCH] Fix use of util.CommandError
mpm@selenic.com
parents: 515
diff changeset
206 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
207 explain_exit(rc)[0])
0fb8ade0f756 [PATCH] Fix use of util.CommandError
mpm@selenic.com
parents: 515
diff changeset
208 if errprefix:
0fb8ade0f756 [PATCH] Fix use of util.CommandError
mpm@selenic.com
parents: 515
diff changeset
209 errmsg = "%s: %s" % (errprefix, errmsg)
870
a82eae840447 Teach walk code about absolute paths.
Bryan O'Sullivan <bos@serpentine.com>
parents: 869
diff changeset
210 raise Abort(errmsg)
508
42a660abaf75 [PATCH] Harden os.system
mpm@selenic.com
parents: 464
diff changeset
211
421
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
212 def rename(src, dst):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
213 """forcibly rename a file"""
421
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
214 try:
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
215 os.rename(src, dst)
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
216 except:
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
217 os.unlink(dst)
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
218 os.rename(src, dst)
43b8da7420a9 [PATCH] rename under the other OS
mpm@selenic.com
parents: 419
diff changeset
219
698
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
220 def copytree(src, dst, copyfile):
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
221 """Copy a directory tree, files are copied using 'copyfile'."""
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
222 names = os.listdir(src)
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
223 os.mkdir(dst)
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
224
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
225 for name in names:
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
226 srcname = os.path.join(src, name)
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
227 dstname = os.path.join(dst, name)
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
228 if os.path.isdir(srcname):
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
229 copytree(srcname, dstname, copyfile)
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
230 elif os.path.isfile(srcname):
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
231 copyfile(srcname, dstname)
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
232 else:
917
7f3f55903496 Fix hg clone race with writer
mpm@selenic.com
parents: 912
diff changeset
233 pass
698
df78d8ccac4c Use python function instead of external 'cp' command when cloning repos.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 667
diff changeset
234
1090
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
235 def opener(base):
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
236 """
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
237 return a function that opens files relative to base
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
238
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
239 this function is used to hide the details of COW semantics and
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
240 remote file access from higher level code.
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
241 """
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
242 p = base
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
243 def o(path, mode="r"):
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
244 f = os.path.join(p, path)
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
245
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
246 mode += "b" # for that other OS
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
247
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
248 if mode[0] != "r":
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
249 try:
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
250 s = os.stat(f)
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
251 except OSError:
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
252 d = os.path.dirname(f)
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
253 if not os.path.isdir(d):
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
254 os.makedirs(d)
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
255 else:
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
256 if s.st_nlink > 1:
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
257 file(f + ".tmp", "wb").write(file(f, "rb").read())
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
258 rename(f+".tmp", f)
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
259
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
260 return file(f, mode)
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
261
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
262 return o
1bca39b85615 Move opener to utils
mpm@selenic.com
parents: 1082
diff changeset
263
704
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
264 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
265 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
266 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
267 os.close(ld)
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
268
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
269 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
270 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
271
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
272 # Platform specific variants
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
273 if os.name == 'nt':
461
9ae0034f2772 [PATCH] /dev/null for other OS
mpm@selenic.com
parents: 441
diff changeset
274 nulldev = 'NUL:'
9ae0034f2772 [PATCH] /dev/null for other OS
mpm@selenic.com
parents: 441
diff changeset
275
441
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
276 def is_exec(f, last):
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
277 return last
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
278
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
279 def set_exec(f, mode):
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
280 pass
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 508
diff changeset
281
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
282 def pconvert(path):
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
283 return path.replace("\\", "/")
422
10c43444a38e [PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents: 421
diff changeset
284
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
285 def localpath(path):
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
286 return path.replace('/', '\\')
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
287
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
288 def normpath(path):
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
289 return pconvert(os.path.normpath(path))
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
290
704
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
291 makelock = _makelock_file
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
292 readlock = _readlock_file
461
9ae0034f2772 [PATCH] /dev/null for other OS
mpm@selenic.com
parents: 441
diff changeset
293
782
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
294 def explain_exit(code):
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
295 return "exited with status %d" % code, code
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
296
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
297 else:
461
9ae0034f2772 [PATCH] /dev/null for other OS
mpm@selenic.com
parents: 441
diff changeset
298 nulldev = '/dev/null'
9ae0034f2772 [PATCH] /dev/null for other OS
mpm@selenic.com
parents: 441
diff changeset
299
441
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
300 def is_exec(f, last):
1082
ce96e316278a Update util.py docstrings, fix walk test
mpm@selenic.com
parents: 1081
diff changeset
301 """check whether a file is executable"""
441
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
302 return (os.stat(f).st_mode & 0100 != 0)
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
303
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
304 def set_exec(f, mode):
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
305 s = os.stat(f).st_mode
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
306 if (s & 0100 != 0) == mode:
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
307 return
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
308 if mode:
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
309 # 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
310 # and obey umask.
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
311 umask = os.umask(0)
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
312 os.umask(umask)
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
313 os.chmod(f, s | (s & 0444) >> 2 & ~umask)
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
314 else:
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
315 os.chmod(f, s & 0666)
e8af362cfb01 Permission handling for the other OS
mpm@selenic.com
parents: 422
diff changeset
316
419
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
317 def pconvert(path):
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
318 return path
28511fc21073 [PATCH] file seperator handling for the other 'OS'
mpm@selenic.com
parents:
diff changeset
319
886
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
320 def localpath(path):
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
321 return path
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
322
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
323 normpath = os.path.normpath
509de8ab6f31 Fix walk path handling on Windows
Bryan O'Sullivan <bos@serpentine.com>
parents: 884
diff changeset
324
422
10c43444a38e [PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents: 421
diff changeset
325 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
326 try:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
327 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
328 except OSError, why:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
329 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
330 raise
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
331 else:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
332 _makelock_file(info, pathname)
422
10c43444a38e [PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents: 421
diff changeset
333
10c43444a38e [PATCH] Enables lock work under the other 'OS'
mpm@selenic.com
parents: 421
diff changeset
334 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
335 try:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
336 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
337 except OSError, why:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
338 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
339 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
340 else:
5ca319a641e1 Make makelock and readlock work on filesystems without symlink support.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 698
diff changeset
341 raise
782
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
342
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
343 def explain_exit(code):
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
344 """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
345 if os.WIFEXITED(code):
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
346 val = os.WEXITSTATUS(code)
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
347 return "exited with status %d" % val, val
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
348 elif os.WIFSIGNALED(code):
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
349 val = os.WTERMSIG(code)
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
350 return "killed by signal %d" % val, val
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
351 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
352 val = os.WSTOPSIG(code)
782
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
353 return "stopped by signal %d" % val, val
cdb9e95b2fab Provided platform dependent implementations for explain_exit
thananck@yahoo.com
parents: 742
diff changeset
354 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
355
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
356 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
357 """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
358 iterator over chunks of arbitrary size."""
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
359
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
360 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
361 """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
362 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
363 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
364 self.buf = ''
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
365 self.targetsize = int(targetsize)
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
366 if self.targetsize <= 0:
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
367 raise ValueError("targetsize must be greater than 0, was %d" %
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
368 targetsize)
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
369 self.iterempty = False
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
370
1199
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
371 def fillbuf(self):
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
372 """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
373 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
374 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
375 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
376 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
377 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
378 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
379 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
380
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
381 def read(self, l):
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
382 """Read L bytes of data from the iterator of chunks of data.
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
383 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
384 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
385 # 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
386 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
387 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
388 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
389 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
390 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
391 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
392 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
393 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
394 break
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
395 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
396 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
397 self.buf = collector.getvalue()
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
398 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
399 return s
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
400
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
401 def filechunkiter(f, size = 65536):
1200
333de1d53846 Minor cleanups.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1199
diff changeset
402 """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
403 (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
404 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
405 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
406 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
407 s = f.read(size)
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
408 while len(s) >= 0:
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
409 yield s
78ceaf83f28f Created a class in util called chunkbuffer that buffers reads from an
Eric Hopper <hopper@omnifarious.org>
parents: 1169
diff changeset
410 s = f.read(size)