Mercurial > hg
comparison mercurial/util.py @ 1584:b3e94785ab69
merge with crew
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Sun, 11 Dec 2005 15:38:42 -0800 |
parents | 32a4e6802864 8befbb4e30b2 |
children | d7c4b9bfcc94 |
comparison
equal
deleted
inserted
replaced
1583:32a4e6802864 | 1584:b3e94785ab69 |
---|---|
103 class Abort(Exception): | 103 class Abort(Exception): |
104 """Raised if a command needs to print an error and exit.""" | 104 """Raised if a command needs to print an error and exit.""" |
105 | 105 |
106 def always(fn): return True | 106 def always(fn): return True |
107 def never(fn): return False | 107 def never(fn): return False |
108 | |
109 def patkind(name, dflt_pat='glob'): | |
110 """Split a string into an optional pattern kind prefix and the | |
111 actual pattern.""" | |
112 for prefix in 're', 'glob', 'path', 'relglob', 'relpath', 'relre': | |
113 if name.startswith(prefix + ':'): return name.split(':', 1) | |
114 return dflt_pat, name | |
108 | 115 |
109 def globre(pat, head='^', tail='$'): | 116 def globre(pat, head='^', tail='$'): |
110 "convert a glob pattern into a regexp" | 117 "convert a glob pattern into a regexp" |
111 i, n = 0, len(pat) | 118 i, n = 0, len(pat) |
112 res = '' | 119 res = '' |
156 def pathto(n1, n2): | 163 def pathto(n1, n2): |
157 '''return the relative path from one place to another. | 164 '''return the relative path from one place to another. |
158 this returns a path in the form used by the local filesystem, not hg.''' | 165 this returns a path in the form used by the local filesystem, not hg.''' |
159 if not n1: return localpath(n2) | 166 if not n1: return localpath(n2) |
160 a, b = n1.split('/'), n2.split('/') | 167 a, b = n1.split('/'), n2.split('/') |
161 a.reverse(), b.reverse() | 168 a.reverse() |
169 b.reverse() | |
162 while a and b and a[-1] == b[-1]: | 170 while a and b and a[-1] == b[-1]: |
163 a.pop(), b.pop() | 171 a.pop() |
172 b.pop() | |
164 b.reverse() | 173 b.reverse() |
165 return os.sep.join((['..'] * len(a)) + b) | 174 return os.sep.join((['..'] * len(a)) + b) |
166 | 175 |
167 def canonpath(root, cwd, myname): | 176 def canonpath(root, cwd, myname): |
168 """return the canonical path of myname, given cwd and root""" | 177 """return the canonical path of myname, given cwd and root""" |
169 rootsep = root + os.sep | 178 if root == os.sep: |
179 rootsep = os.sep | |
180 else: | |
181 rootsep = root + os.sep | |
170 name = myname | 182 name = myname |
171 if not name.startswith(os.sep): | 183 if not name.startswith(os.sep): |
172 name = os.path.join(root, cwd, name) | 184 name = os.path.join(root, cwd, name) |
173 name = os.path.normpath(name) | 185 name = os.path.normpath(name) |
174 if name.startswith(rootsep): | 186 if name.startswith(rootsep): |
215 - a bool indicating if any patterns were passed in | 227 - a bool indicating if any patterns were passed in |
216 | 228 |
217 todo: | 229 todo: |
218 make head regex a rooted bool | 230 make head regex a rooted bool |
219 """ | 231 """ |
220 | |
221 def patkind(name, dflt_pat='glob'): | |
222 for prefix in 're', 'glob', 'path', 'relglob', 'relpath', 'relre': | |
223 if name.startswith(prefix + ':'): return name.split(':', 1) | |
224 return dflt_pat, name | |
225 | 232 |
226 def contains_glob(name): | 233 def contains_glob(name): |
227 for c in name: | 234 for c in name: |
228 if c in _globchars: return True | 235 if c in _globchars: return True |
229 return False | 236 return False |
251 matches = [] | 258 matches = [] |
252 for k, p in pats: | 259 for k, p in pats: |
253 try: | 260 try: |
254 pat = '(?:%s)' % regex(k, p, tail) | 261 pat = '(?:%s)' % regex(k, p, tail) |
255 matches.append(re.compile(pat).match) | 262 matches.append(re.compile(pat).match) |
256 except re.error, inst: | 263 except re.error: |
257 raise Abort("invalid pattern: %s:%s" % (k, p)) | 264 raise Abort("invalid pattern: %s:%s" % (k, p)) |
258 | 265 |
259 def buildfn(text): | 266 def buildfn(text): |
260 for m in matches: | 267 for m in matches: |
261 r = m(text) | 268 r = m(text) |
360 | 367 |
361 this function is used to hide the details of COW semantics and | 368 this function is used to hide the details of COW semantics and |
362 remote file access from higher level code. | 369 remote file access from higher level code. |
363 """ | 370 """ |
364 p = base | 371 p = base |
365 def o(path, mode="r", text=False): | 372 |
373 def mktempcopy(name): | |
374 d, fn = os.path.split(name) | |
375 fd, temp = tempfile.mkstemp(prefix=fn, dir=d) | |
376 fp = os.fdopen(fd, "wb") | |
377 try: | |
378 fp.write(file(name, "rb").read()) | |
379 except: | |
380 try: os.unlink(temp) | |
381 except: pass | |
382 raise | |
383 fp.close() | |
384 st = os.lstat(name) | |
385 os.chmod(temp, st.st_mode) | |
386 return temp | |
387 | |
388 class atomicfile(file): | |
389 """the file will only be copied on close""" | |
390 def __init__(self, name, mode, atomic=False): | |
391 self.__name = name | |
392 self.temp = mktempcopy(name) | |
393 file.__init__(self, self.temp, mode) | |
394 def close(self): | |
395 if not self.closed: | |
396 file.close(self) | |
397 rename(self.temp, self.__name) | |
398 def __del__(self): | |
399 self.close() | |
400 | |
401 def o(path, mode="r", text=False, atomic=False): | |
366 f = os.path.join(p, path) | 402 f = os.path.join(p, path) |
367 | 403 |
368 if not text: | 404 if not text: |
369 mode += "b" # for that other OS | 405 mode += "b" # for that other OS |
370 | 406 |
374 except OSError: | 410 except OSError: |
375 d = os.path.dirname(f) | 411 d = os.path.dirname(f) |
376 if not os.path.isdir(d): | 412 if not os.path.isdir(d): |
377 os.makedirs(d) | 413 os.makedirs(d) |
378 else: | 414 else: |
415 if atomic: | |
416 return atomicfile(f, mode) | |
379 if nlink > 1: | 417 if nlink > 1: |
380 d, fn = os.path.split(f) | 418 rename(mktempcopy(f), f) |
381 fd, temp = tempfile.mkstemp(prefix=fn, dir=d) | |
382 fp = os.fdopen(fd, "wb") | |
383 try: | |
384 fp.write(file(f, "rb").read()) | |
385 except: | |
386 try: os.unlink(temp) | |
387 except: pass | |
388 raise | |
389 fp.close() | |
390 rename(temp, f) | |
391 | |
392 return file(f, mode) | 419 return file(f, mode) |
393 | 420 |
394 return o | 421 return o |
395 | 422 |
396 def _makelock_file(info, pathname): | 423 def _makelock_file(info, pathname): |
482 | 509 |
483 else: | 510 else: |
484 nulldev = '/dev/null' | 511 nulldev = '/dev/null' |
485 | 512 |
486 def rcfiles(path): | 513 def rcfiles(path): |
514 print 'checking', path | |
487 rcs = [os.path.join(path, 'hgrc')] | 515 rcs = [os.path.join(path, 'hgrc')] |
488 rcdir = os.path.join(path, 'hgrc.d') | 516 rcdir = os.path.join(path, 'hgrc.d') |
489 try: | 517 try: |
490 rcs.extend([os.path.join(rcdir, f) for f in os.listdir(rcdir) | 518 rcs.extend([os.path.join(rcdir, f) for f in os.listdir(rcdir) |
491 if f.endswith(".rc")]) | 519 if f.endswith(".rc")]) |