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")])