##// END OF EJS Templates
store: change handling of decoding errors
store: change handling of decoding errors

File last commit:

r6900:def492d1 default
r6900:def492d1 default
Show More
store.py
116 lines | 3.6 KiB | text/x-python | PythonLexer
Adrian Buehlmann
move filename encoding functions from util.py to new store.py
r6839 # store.py - repository store handling for Mercurial
#
# Copyright 2008 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
Adrian Buehlmann
introduce store classes...
r6840 import os, stat, osutil, util
Adrian Buehlmann
move filename encoding functions from util.py to new store.py
r6839 def _buildencodefun():
e = '_'
win_reserved = [ord(x) for x in '\\:*?"<>|']
cmap = dict([ (chr(x), chr(x)) for x in xrange(127) ])
for x in (range(32) + range(126, 256) + win_reserved):
cmap[chr(x)] = "~%02x" % x
for x in range(ord("A"), ord("Z")+1) + [ord(e)]:
cmap[chr(x)] = e + chr(x).lower()
dmap = {}
for k, v in cmap.iteritems():
dmap[v] = k
def decode(s):
i = 0
while i < len(s):
for l in xrange(1, 4):
try:
yield dmap[s[i:i+l]]
i += l
break
except KeyError:
pass
else:
raise KeyError
return (lambda s: "".join([cmap[c] for c in s]),
lambda s: "".join(list(decode(s))))
encodefilename, decodefilename = _buildencodefun()
Matt Mackall
store: simplify class hierarchy
r6898 def _calcmode(path):
try:
# files in .hg/ will be created using this mode
mode = os.stat(path).st_mode
# avoid some useless chmods
if (0777 & ~util._umask) == (0777 & mode):
mode = None
except OSError:
mode = None
return mode
class basicstore:
Adrian Buehlmann
introduce store classes...
r6840 '''base class for local repository stores'''
Matt Mackall
store: simplify class hierarchy
r6898 def __init__(self, path, opener):
Adrian Buehlmann
introduce store classes...
r6840 self.path = path
Matt Mackall
store: simplify class hierarchy
r6898 self.createmode = _calcmode(path)
self.opener = opener(self.path)
self.opener.createmode = self.createmode
Adrian Buehlmann
introduce store classes...
r6840
def join(self, f):
return os.path.join(self.path, f)
Matt Mackall
store: simplify walking...
r6899 def _walk(self, relpath, recurse):
Matt Mackall
store: change handling of decoding errors
r6900 '''yields (unencoded, encoded, size)'''
Matt Mackall
store: simplify walking...
r6899 path = os.path.join(self.path, relpath)
Adrian Buehlmann
introduce store classes...
r6840 striplen = len(self.path) + len(os.sep)
Matt Mackall
store: simplify walking...
r6899 prefix = path[striplen:]
l = []
if os.path.isdir(path):
visit = [path]
while visit:
p = visit.pop()
for f, kind, st in osutil.listdir(p, stat=True):
fp = os.path.join(p, f)
if kind == stat.S_IFREG and f[-2:] in ('.d', '.i'):
Matt Mackall
store: change handling of decoding errors
r6900 n = util.pconvert(fp[striplen:])
l.append((n, n, st.st_size))
Matt Mackall
store: simplify walking...
r6899 elif kind == stat.S_IFDIR and recurse:
visit.append(fp)
return util.sort(l)
Adrian Buehlmann
introduce store classes...
r6840
Matt Mackall
store: change handling of decoding errors
r6900 def datafiles(self):
Matt Mackall
store: simplify walking...
r6899 return self._walk('data', True)
Adrian Buehlmann
introduce store classes...
r6840
def walk(self):
Matt Mackall
store: change handling of decoding errors
r6900 '''yields (unencoded, encoded, size)'''
Adrian Buehlmann
introduce store classes...
r6840 # yield data files first
Adrian Buehlmann
verify: check repo.store
r6892 for x in self.datafiles():
Adrian Buehlmann
introduce store classes...
r6840 yield x
# yield manifest before changelog
Matt Mackall
store: simplify walking...
r6899 meta = self._walk('', False)
Adrian Buehlmann
introduce store classes...
r6840 meta.reverse()
for x in meta:
yield x
Matt Mackall
store: simplify class hierarchy
r6898 class encodedstore(basicstore):
Matt Mackall
store: take opener as an argument
r6896 def __init__(self, path, opener):
Matt Mackall
store: simplify class hierarchy
r6898 self.path = os.path.join(path, 'store')
self.createmode = _calcmode(self.path)
Adrian Buehlmann
introduce store classes...
r6840 self.encodefn = encodefilename
Matt Mackall
store: take opener as an argument
r6896 op = opener(self.path)
Adrian Buehlmann
introduce store classes...
r6840 op.createmode = self.createmode
self.opener = lambda f, *args, **kw: op(self.encodefn(f), *args, **kw)
Matt Mackall
store: change handling of decoding errors
r6900 def datafiles(self):
for a, b, size in self._walk('data', True):
Adrian Buehlmann
verify: check repo.store
r6892 try:
Matt Mackall
store: change handling of decoding errors
r6900 a = decodefilename(a)
Adrian Buehlmann
verify: check repo.store
r6892 except KeyError:
Matt Mackall
store: change handling of decoding errors
r6900 a = None
yield a, b, size
Adrian Buehlmann
introduce store classes...
r6840
def join(self, f):
return os.path.join(self.path, self.encodefn(f))
Matt Mackall
store: take opener as an argument
r6896 def store(requirements, path, opener):
Matt Mackall
store: simplify class hierarchy
r6898 if 'store' in requirements:
Matt Mackall
store: take opener as an argument
r6896 return encodedstore(path, opener)
Matt Mackall
store: simplify class hierarchy
r6898 return basicstore(path, opener)