--- a/hgkw/keyword.py Tue Jul 17 14:15:47 2007 +0200
+++ b/hgkw/keyword.py Wed Jul 18 16:12:14 2007 +0200
@@ -136,27 +136,36 @@
Sets up keyword templates, corresponding keyword regex, and
provides keyword substitution functions.
'''
- def __init__(self, ui, repo, path='', node=None):
+ def __init__(self, ui, repo, path='', node=None, expand=True):
self.ui = ui
self.repo = repo
self.path = path
self.node = node
templates = dict(ui.configitems('keywordmaps'))
if templates:
- # parse templates here for less overhead in kwsub matchfunc
for k in templates.keys():
templates[k] = templater.parsestring(templates[k],
quoted=False)
self.templates = templates or deftemplates
escaped = [re.escape(k) for k in self.templates.keys()]
self.re_kw = re.compile(r'\$(%s)[^$]*?\$' % '|'.join(escaped))
- templater.common_filters['utcdate'] = utcdate
- try:
- self.t = cmdutil.changeset_templater(ui, repo, False, '', False)
- except TypeError:
- # depending on hg rev changeset_templater has extra "brinfo" arg
- self.t = cmdutil.changeset_templater(ui, repo,
- False, None, '', False)
+ if expand:
+ templater.common_filters['utcdate'] = utcdate
+ try:
+ self.t = cmdutil.changeset_templater(ui, repo,
+ False, '', False)
+ except TypeError:
+ # depending on hg rev changeset_templater has extra "brinfo" arg
+ self.t = cmdutil.changeset_templater(ui, repo,
+ False, None, '', False)
+ else:
+ self.t = None
+
+ def ctxnode(self, node):
+ '''Obtains missing node from file context.'''
+ if not self.node:
+ c = context.filectx(self.repo, self.path, fileid=node)
+ self.node = c.node()
def kwsub(self, mobj):
'''Substitutes keyword using corresponding template.'''
@@ -168,57 +177,66 @@
return '$%s: %s $' % (kw, keywordsub)
def expand(self, node, data):
- '''Returns data with expanded keywords.'''
+ '''Returns data with keywords expanded.'''
if util.binary(data):
return data
- c = context.filectx(self.repo, self.path, fileid=node)
- self.node = c.node()
+ self.ctxnode(node)
return self.re_kw.sub(self.kwsub, data)
+ def process(self, node, data):
+ '''Returns a tuple: data, count.
+ Count is number of keywords/keyword substitutions.
+ Keywords in data are expanded, if templater was initialized.'''
+ if util.binary(data):
+ return data, None
+ if self.t:
+ self.ctxnode(node)
+ return self.re_kw.subn(self.kwsub, data)
+ return data, self.re_kw.search(data)
+
def shrink(self, text):
'''Returns text with all keyword substitutions removed.'''
if util.binary(text):
return text
return self.re_kw.sub(r'$\1$', text)
- def overwrite(self, candidates, manifest, expand=True, commit=True):
- '''Overwrites candidates in working dir expanding keywords.'''
- if expand:
- sub = self.kwsub
- action = 'expanding'
- else:
- sub = r'$\1$'
- action = 'shrinking'
- if not commit:
- notify = self.ui.note
- else:
- notify = self.ui.debug
+ def overwrite(self, candidates, man, commit=True):
+ '''Overwrites files in working directory if keywords are detected.
+ Keywords are expanded if keyword templater is initialized,
+ otherwise their substitution is removed.'''
+ expand = self.t is not None
+ action = ('shrinking', 'expanding')[expand]
+ notify = (self.ui.note, self.ui.debug)[commit]
files = []
for f in candidates:
- data = self.repo.wread(f)
- if not util.binary(data):
- self.path = f
- data, kwct = self.re_kw.subn(sub, data)
- if kwct:
- notify(_('overwriting %s %s keywords\n') % (f, action))
- self.repo.wwrite(f, data, manifest.flags(f))
- files.append(f)
+ fp = self.repo.file(f, kwcnt=True, kwexp=expand)
+ data, cnt = fp.read(man[f])
+ if cnt:
+ notify(_('overwriting %s %s keywords\n') % (f, action))
+ self.repo.wwrite(f, data, man.flags(f))
+ files.append(f)
if files:
self.repo.dirstate.update(files, 'n')
class kwfilelog(filelog.filelog):
'''
Subclass of filelog to hook into its read, add, cmp methods.
- Keywords are "stored" unexpanded, and expanded on reading.
+ Keywords are "stored" unexpanded, and processed on reading.
'''
- def __init__(self, opener, path, kwtemplater):
+ def __init__(self, opener, path, kwtemplater, kwcnt):
super(kwfilelog, self).__init__(opener, path)
self.kwtemplater = kwtemplater
+ self.kwcnt = kwcnt
def read(self, node):
- '''Substitutes keywords when reading filelog.'''
+ '''Passes data through kwemplater methods for
+ either unconditional keyword expansion
+ or counting of keywords and substitution method
+ set by the calling overwrite function.'''
data = super(kwfilelog, self).read(node)
- return self.kwtemplater.expand(node, data)
+ if not self.kwcnt:
+ return self.kwtemplater.expand(node, data)
+ return self.kwtemplater.process(node, data)
def add(self, text, meta, tr, link, p1=None, p2=None):
'''Removes keyword substitutions when adding to filelog.'''
@@ -233,7 +251,7 @@
return t2 != text
return super(kwfilelog, self).cmp(node, text)
-def overwrite(ui, repo, files=None, expand=False):
+def overwrite(ui, repo, files=None, expand=True):
'''Expands/shrinks keywords in working directory.'''
wlock = repo.wlock()
try:
@@ -257,8 +275,8 @@
ui.warn(_('given files not tracked or '
'not configured for expansion\n'))
return
- kwt = kwtemplater(ui, repo, node=ctx.node())
- kwt.overwrite(files, m, expand=expand, commit=False)
+ kwt = kwtemplater(ui, repo, node=ctx.node(), expand=expand)
+ kwt.overwrite(files, m, commit=False)
finally:
wlock.release()
@@ -271,14 +289,14 @@
changing keyword expansion configuration
or if you experience problems with "hg import"
'''
- overwrite(ui, repo, args, expand=False)
+ overwrite(ui, repo, files=args, expand=False)
def expand(ui, repo, *args):
'''expand keywords in working directory
run after (re)enabling keyword expansion
'''
- overwrite(ui, repo, args, expand=True)
+ overwrite(ui, repo, files=args)
def demo(ui, repo, **opts):
'''print [keywordmaps] configuration and an expansion example
@@ -342,12 +360,12 @@
return
class kwrepo(repo.__class__):
- def file(self, f):
+ def file(self, f, kwcnt=False, kwexp=True):
if f[0] == '/':
f = f[1:]
if kwfmatcher(f):
- kwt = kwtemplater(ui, self, path=f)
- return kwfilelog(self.sopener, f, kwt)
+ kwt = kwtemplater(ui, self, path=f, expand=kwexp)
+ return kwfilelog(self.sopener, f, kwt, kwcnt)
else:
return filelog.filelog(self.sopener, f)