##// END OF EJS Templates
store: simplify class hierarchy
store: simplify class hierarchy

File last commit:

r6898:69aeaaaf default
r6898:69aeaaaf default
Show More
store.py
125 lines | 3.9 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
verify: check repo.store
r6892 from i18n import _
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()
Adrian Buehlmann
introduce store classes...
r6840 def _dirwalk(path, recurse):
'''yields (filename, size)'''
for e, kind, st in osutil.listdir(path, stat=True):
pe = os.path.join(path, e)
if kind == stat.S_IFDIR:
if recurse:
for x in _dirwalk(pe, True):
yield x
elif kind == stat.S_IFREG:
yield pe, st.st_size
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)
def _revlogfiles(self, relpath='', recurse=False):
'''yields (filename, size)'''
if relpath:
path = os.path.join(self.path, relpath)
else:
path = self.path
Adrian Buehlmann
store.py: accept empty repos...
r6890 if not os.path.isdir(path):
return
Adrian Buehlmann
introduce store classes...
r6840 striplen = len(self.path) + len(os.sep)
filetypes = ('.d', '.i')
for f, size in _dirwalk(path, recurse):
if (len(f) > 2) and f[-2:] in filetypes:
yield util.pconvert(f[striplen:]), size
Adrian Buehlmann
verify: check repo.store
r6892 def datafiles(self, reporterror=None):
Adrian Buehlmann
introduce store classes...
r6840 for x in self._revlogfiles('data', True):
yield x
def walk(self):
'''yields (direncoded filename, size)'''
# 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
meta = util.sort(self._revlogfiles())
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)
Adrian Buehlmann
verify: check repo.store
r6892 def datafiles(self, reporterror=None):
Adrian Buehlmann
introduce store classes...
r6840 for f, size in self._revlogfiles('data', True):
Adrian Buehlmann
verify: check repo.store
r6892 try:
yield decodefilename(f), size
except KeyError:
if not reporterror:
raise
reporterror(_("cannot decode filename '%s'") % f)
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)