Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/util.py @ 1082:ce96e316278a
Update util.py docstrings, fix walk test
author | mpm@selenic.com |
---|---|
date | Sat, 27 Aug 2005 01:13:28 -0700 |
parents | 8b7d63489db3 |
children | 1bca39b85615 |
comparison
equal
deleted
inserted
replaced
1081:8b7d63489db3 | 1082:ce96e316278a |
---|---|
1 # util.py - utility functions and platform specfic implementations | 1 """ |
2 # | 2 util.py - Mercurial utility functions and platform specfic implementations |
3 # Copyright 2005 K. Thananchayan <thananck@yahoo.com> | 3 |
4 # | 4 Copyright 2005 K. Thananchayan <thananck@yahoo.com> |
5 # This software may be used and distributed according to the terms | 5 |
6 # of the GNU General Public License, incorporated herein by reference. | 6 This software may be used and distributed according to the terms |
7 of the GNU General Public License, incorporated herein by reference. | |
8 | |
9 This contains helper routines that are independent of the SCM core and hide | |
10 platform-specific details from the core. | |
11 """ | |
7 | 12 |
8 import os, errno | 13 import os, errno |
9 from demandload import * | 14 from demandload import * |
10 demandload(globals(), "re") | 15 demandload(globals(), "re") |
11 | 16 |
12 def binary(s): | 17 def binary(s): |
18 """return true if a string is binary data using diff's heuristic""" | |
13 if s and '\0' in s[:4096]: | 19 if s and '\0' in s[:4096]: |
14 return True | 20 return True |
15 return False | 21 return False |
16 | 22 |
17 def unique(g): | 23 def unique(g): |
24 """return the uniq elements of iterable g""" | |
18 seen = {} | 25 seen = {} |
19 for f in g: | 26 for f in g: |
20 if f not in seen: | 27 if f not in seen: |
21 seen[f] = 1 | 28 seen[f] = 1 |
22 yield f | 29 yield f |
84 a.pop(), b.pop() | 91 a.pop(), b.pop() |
85 b.reverse() | 92 b.reverse() |
86 return os.sep.join((['..'] * len(a)) + b) | 93 return os.sep.join((['..'] * len(a)) + b) |
87 | 94 |
88 def canonpath(root, cwd, myname): | 95 def canonpath(root, cwd, myname): |
96 """return the canonical path of myname, given cwd and root""" | |
89 rootsep = root + os.sep | 97 rootsep = root + os.sep |
90 name = myname | 98 name = myname |
91 if not name.startswith(os.sep): | 99 if not name.startswith(os.sep): |
92 name = os.path.join(root, cwd, name) | 100 name = os.path.join(root, cwd, name) |
93 name = os.path.normpath(name) | 101 name = os.path.normpath(name) |
97 return '' | 105 return '' |
98 else: | 106 else: |
99 raise Abort('%s not under root' % myname) | 107 raise Abort('%s not under root' % myname) |
100 | 108 |
101 def matcher(canonroot, cwd, names, inc, exc, head=''): | 109 def matcher(canonroot, cwd, names, inc, exc, head=''): |
110 """build a function to match a set of file patterns | |
111 | |
112 arguments: | |
113 canonroot - the canonical root of the tree you're matching against | |
114 cwd - the current working directory, if relevant | |
115 names - patterns to find | |
116 inc - patterns to include | |
117 exc - patterns to exclude | |
118 head - a regex to prepend to patterns to control whether a match is rooted | |
119 | |
120 a pattern is one of: | |
121 're:<regex>' | |
122 'glob:<shellglob>' | |
123 'path:<explicit path>' | |
124 'relpath:<relative path>' | |
125 '<relative path>' | |
126 | |
127 returns: | |
128 a 3-tuple containing | |
129 - list of explicit non-pattern names passed in | |
130 - a bool match(filename) function | |
131 - a bool indicating if any patterns were passed in | |
132 | |
133 todo: | |
134 make head regex a rooted bool | |
135 """ | |
136 | |
102 def patkind(name): | 137 def patkind(name): |
103 for prefix in 're:', 'glob:', 'path:', 'relpath:': | 138 for prefix in 're:', 'glob:', 'path:', 'relpath:': |
104 if name.startswith(prefix): return name.split(':', 1) | 139 if name.startswith(prefix): return name.split(':', 1) |
105 for c in name: | 140 for c in name: |
106 if c in _globchars: return 'glob', name | 141 if c in _globchars: return 'glob', name |
173 if errprefix: | 208 if errprefix: |
174 errmsg = "%s: %s" % (errprefix, errmsg) | 209 errmsg = "%s: %s" % (errprefix, errmsg) |
175 raise Abort(errmsg) | 210 raise Abort(errmsg) |
176 | 211 |
177 def rename(src, dst): | 212 def rename(src, dst): |
213 """forcibly rename a file""" | |
178 try: | 214 try: |
179 os.rename(src, dst) | 215 os.rename(src, dst) |
180 except: | 216 except: |
181 os.unlink(dst) | 217 os.unlink(dst) |
182 os.rename(src, dst) | 218 os.rename(src, dst) |
202 os.close(ld) | 238 os.close(ld) |
203 | 239 |
204 def _readlock_file(pathname): | 240 def _readlock_file(pathname): |
205 return file(pathname).read() | 241 return file(pathname).read() |
206 | 242 |
207 # Platfor specific varients | 243 # Platform specific variants |
208 if os.name == 'nt': | 244 if os.name == 'nt': |
209 nulldev = 'NUL:' | 245 nulldev = 'NUL:' |
210 | 246 |
211 def is_exec(f, last): | 247 def is_exec(f, last): |
212 return last | 248 return last |
231 | 267 |
232 else: | 268 else: |
233 nulldev = '/dev/null' | 269 nulldev = '/dev/null' |
234 | 270 |
235 def is_exec(f, last): | 271 def is_exec(f, last): |
272 """check whether a file is executable""" | |
236 return (os.stat(f).st_mode & 0100 != 0) | 273 return (os.stat(f).st_mode & 0100 != 0) |
237 | 274 |
238 def set_exec(f, mode): | 275 def set_exec(f, mode): |
239 s = os.stat(f).st_mode | 276 s = os.stat(f).st_mode |
240 if (s & 0100 != 0) == mode: | 277 if (s & 0100 != 0) == mode: |