--- a/hgkw/keyword.py Sat Dec 01 13:15:13 2007 +0100
+++ b/hgkw/keyword.py Sat Dec 01 20:31:13 2007 +0100
@@ -92,6 +92,8 @@
'''Returns hgdate in cvs-like UTC format.'''
return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0]))
+_kwtemplater = None
+
class kwtemplater(object):
'''
Sets up keyword templates, corresponding keyword regex, and
@@ -107,12 +109,12 @@
'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}',
}
- def __init__(self, ui, repo, expand, path='', node=None):
+ def __init__(self, ui, repo, inc, exc):
self.ui = ui
self.repo = repo
- self.ct = expand or None
- self.path = path
- self.node = node
+ self.match = util.matcher(repo.root, inc=inc, exc=exc)[1]
+ self.node = None
+ self.path = ''
kwmaps = self.ui.configitems('keywordmaps')
if kwmaps: # override default templates
@@ -122,10 +124,10 @@
escaped = map(re.escape, self.templates.keys())
kwpat = r'\$(%s)(: [^$\n\r]*? )??\$' % '|'.join(escaped)
self.re_kw = re.compile(kwpat)
- if self.ct:
- templater.common_filters['utcdate'] = utcdate
- self.ct = cmdutil.changeset_templater(self.ui, self.repo,
- False, '', False)
+
+ templater.common_filters['utcdate'] = utcdate
+ self.ct = cmdutil.changeset_templater(self.ui, self.repo,
+ False, '', False)
def substitute(self, node, data, subfunc):
'''Obtains node if missing, and calls given substitution function.'''
@@ -150,14 +152,14 @@
return data
return self.substitute(node, data, self.re_kw.sub)
- def process(self, node, data):
+ def process(self, node, data, expand):
'''Returns a tuple: data, count.
Count is number of keywords/keyword substitutions, indicates
to caller whether to act on file containing data.
Keywords in data are expanded, if templater was initialized.'''
if util.binary(data):
return data, None
- if self.ct:
+ if expand:
return self.substitute(node, data, self.re_kw.subn)
return data, self.re_kw.search(data)
@@ -167,21 +169,6 @@
return text
return self.re_kw.sub(r'$\1$', text)
- def overwrite(self, candidates, man, commit):
- '''Overwrites files in working directory if keywords are detected.
- Keywords are expanded if keyword templater is initialized,
- otherwise their substitution is removed.'''
- expand = self.ct is not None
- action = ('shrinking', 'expanding')[expand]
- notify = (self.ui.note, self.ui.debug)[commit]
- for f in candidates:
- fp = self.repo.file(f, kwexp=expand, kwmatch=True)
- data, kwfound = fp.kwctread(man[f])
- if kwfound:
- notify(_('overwriting %s %s keywords\n') % (f, action))
- self.repo.wwrite(f, data, man.flags(f))
- self.repo.dirstate.normal(f)
-
class kwfilelog(filelog.filelog):
'''
Subclass of filelog to hook into its read, add, cmp methods.
@@ -191,11 +178,11 @@
super(kwfilelog, self).__init__(opener, path)
self.kwtemplater = kwtemplater
- def kwctread(self, node):
+ def kwctread(self, node, expand):
'''Reads expanding and counting keywords
(only called from kwtemplater.overwrite).'''
data = super(kwfilelog, self).read(node)
- return self.kwtemplater.process(node, data)
+ return self.kwtemplater.process(node, data, expand)
def read(self, node):
'''Expands keywords when reading filelog.'''
@@ -215,28 +202,42 @@
return t2 != text
return revlog.revlog.cmp(self, node, text)
-def _status(ui, repo, *pats, **opts):
+def _status(ui, repo, kwtemplater, *pats, **opts):
'''Bails out if [keyword] configuration is not active.
Returns status of working directory.'''
- if hasattr(ui, 'kwfmatcher'):
+ if kwtemplater:
files, match, anypats = cmdutil.matchpats(repo, pats, opts)
return repo.status(files=files, match=match, list_clean=True)
if ui.configitems('keyword'):
raise util.Abort(_('[keyword] patterns cannot match'))
raise util.Abort(_('no [keyword] patterns configured'))
-def _iskwfile(ui, man, f):
- return not man.linkf(f) and ui.kwfmatcher(f)
-
-def _overwrite(ui, repo, files, node, man, expand, commit):
- '''Passes given files to kwtemplater for overwriting.'''
- files.sort()
- kwt = kwtemplater(ui, repo, expand, node=node)
- kwt.overwrite(files, man, commit)
+def _overwrite(ui, repo, kwtemplater, node=None, expand=True, files=None):
+ '''Overwrites selected files expanding/shrinking keywords.'''
+ ctx = repo.changectx(node)
+ mf = ctx.manifest()
+ if files is None:
+ notify = ui.debug # commit
+ files = [f for f in ctx.files() if mf.has_key(f)]
+ else:
+ notify = ui.note # kwexpand/kwshrink
+ candidates = [f for f in files if not mf.linkf(f) and kwtemplater.match(f)]
+ if candidates:
+ candidates.sort()
+ action = expand and 'expanding' or 'shrinking'
+ kwtemplater.node = node or ctx.node()
+ for f in candidates:
+ fp = repo.file(f, kwmatch=True)
+ data, kwfound = fp.kwctread(mf[f], expand)
+ if kwfound:
+ notify(_('overwriting %s %s keywords\n') % (f, action))
+ repo.wwrite(f, data, mf.flags(f))
+ repo.dirstate.normal(f)
def _kwfwrite(ui, repo, expand, *pats, **opts):
'''Selects files and passes them to _overwrite.'''
- status = _status(ui, repo, *pats, **opts)
+ global _kwtemplater
+ status = _status(ui, repo, _kwtemplater, *pats, **opts)
modified, added, removed, deleted, unknown, ignored, clean = status
if modified or added or removed or deleted:
raise util.Abort(_('outstanding uncommitted changes in given files'))
@@ -244,12 +245,7 @@
try:
wlock = repo.wlock()
lock = repo.lock()
- ctx = repo.changectx()
- man = ctx.manifest()
- candidates = [f for f in clean if _iskwfile(ui, man, f)]
- if candidates:
- # 7th argument sets commit to False
- _overwrite(ui, repo, candidates, ctx.node(), man, expand, False)
+ _overwrite(ui, repo, _kwtemplater, expand=expand, files=clean)
finally:
del wlock, lock
@@ -352,14 +348,15 @@
keyword expansion.
That is, files matched by [keyword] config patterns but not symlinks.
'''
- status = _status(ui, repo, *pats, **opts)
+ global _kwtemplater
+ status = _status(ui, repo, _kwtemplater, *pats, **opts)
modified, added, removed, deleted, unknown, ignored, clean = status
if opts['untracked']:
files = modified + added + unknown + clean
else:
files = modified + added + clean
files.sort()
- kwfiles = [f for f in files if ui.kwfmatcher(f) and not repo._link(f)]
+ kwfiles = [f for f in files if _kwtemplater.match(f) and not repo._link(f)]
cwd = pats and repo.getcwd() or ''
allf = opts['all']
ignore = opts['ignore']
@@ -421,15 +418,16 @@
if not inc:
return
- ui.kwfmatcher = util.matcher(repo.root, inc=inc, exc=exc)[1]
+ global _kwtemplater
+ _kwtemplater = kwtemplater(ui, repo, inc, exc)
class kwrepo(repo.__class__):
- def file(self, f, kwexp=True, kwmatch=False):
+ def file(self, f, kwmatch=False):
if f[0] == '/':
f = f[1:]
- if kwmatch or ui.kwfmatcher(f):
- kwt = kwtemplater(ui, self, kwexp, path=f)
- return kwfilelog(self.sopener, f, kwt)
+ if kwmatch or _kwtemplater.match(f):
+ _kwtemplater.path = f
+ return kwfilelog(self.sopener, f, _kwtemplater)
return filelog.filelog(self.sopener, f)
def commit(self, files=None, text='', user=None, date=None,
@@ -468,13 +466,7 @@
for name, cmd in commithooks:
ui.setconfig('hooks', name, cmd)
if node is not None:
- cl = self.changelog.read(node)
- mn = self.manifest.read(cl[0])
- candidates = [f for f in cl[3] if mn.has_key(f)
- and _iskwfile(ui, mn, f)]
- if candidates:
- # 6th, 7th arguments set expansion, commit to True
- _overwrite(ui, self, candidates, node, mn, True, True)
+ _overwrite(ui, self, _kwtemplater, node=node)
repo.hook('commit', node=node, parent1=_p1, parent2=_p2)
return node
finally: