diff -r b2cc6a8d4a18 -r b0b85b383f36 hgkw/keyword.py --- a/hgkw/keyword.py Thu Jan 18 00:06:11 2007 +0100 +++ b/hgkw/keyword.py Thu Jan 18 01:50:18 2007 +0100 @@ -57,7 +57,8 @@ # above line for backwards compatibility; can be changed to # from mercurial.i18n import _ # some day -from mercurial import cmdutil, templater, util +from mercurial import context, filelog, revlog +from mercurial import commands, cmdutil, templater, util from mercurial.node import * import os.path, re, sys, time @@ -75,22 +76,22 @@ '''Returns hgdate in cvs-like UTC format.''' return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0])) -def kwfmatches(ui, repo, files): - '''Selects candidates for keyword substitution - configured in keyword section in hgrc.''' +def getkwconfig(ui, repo): inc = [pat for pat, opt in ui.configitems('keyword') if opt != 'ignore'] if not inc: - ui.warn(_('keyword: no filename globs for expansion\n')) - return [] + ui.warn(_('keyword: no filename globs for substitution\n')) + return None, None exc = [pat for pat, opt in ui.configitems('keyword') if opt == 'ignore'] - kwfmatcher = util.matcher(repo.root, inc=inc, exc=['.hg*']+exc)[1] - return [f for f in files if kwfmatcher(f)] + return inc, exc class kwtemplater(object): ''' Sets up keyword templates, corresponding keyword regex, and provides keyword expansion function. + + If a repo is configured for keyword substitution, this class + will be set as an (appendix) attribute to the repo. ''' def __init__(self, ui, repo): self.ui = ui @@ -100,7 +101,6 @@ '|'.join(re.escape(k) for k in self.templates.keys())) templater.common_filters['utcdate'] = utcdate self.t = cmdutil.changeset_templater(ui, repo, False, '', False) - def expand(self, mobj, path, node): '''Expands keyword with corresponding template.''' @@ -109,16 +109,20 @@ self.t.use_template(template) self.ui.pushbuffer() self.t.show(changenode=node, root=self.repo.root, file=path) - expansion = templater.firstline(self.ui.popbuffer()) - return '$%s: %s $' % (kw, expansion) + kwsub = templater.firstline(self.ui.popbuffer()) + return '$%s: %s $' % (kw, kwsub) def reposetup(ui, repo): '''Sets up repo, and filelog especially, as kwrepo and kwfilelog for keyword substitution. This is done for local repos only.''' + if not repo.local(): + return - from mercurial import context, filelog, revlog - if not repo.local(): + inc, exc = getkwconfig(ui, repo) + if not inc: + # no files configured for keyword substitution: + # no need to burden repo with extra ballast return class kwrepo(repo.__class__): @@ -137,15 +141,15 @@ super(kwfilelog, self).__init__(opener, path, defversion) self._repo = repo self._path = path - # only init kwtemplater if needed - if not isinstance(repo, int) and kwfmatches(ui, repo, [path]): - self.kwt = kwtemplater(ui, repo) + # check at init if file configured for keyword substition + if not isinstance(repo, int) and repo.kwfmatcher(path): + self.kwsub = True else: - self.kwt = None + self.kwsub = False def iskwcandidate(self, data): '''Decides whether to act on keywords.''' - return self.kwt is not None and not util.binary(data) + return self.kwsub and not util.binary(data) def read(self, node): '''Substitutes keywords when reading filelog.''' @@ -153,25 +157,32 @@ if self.iskwcandidate(data): c = context.filectx(self._repo, self._path, fileid=node, filelog=self) - return self.kwt.re_kw.sub(lambda m: - self.kwt.expand(m, self._path, c.node()), data) + return self._repo.kwt.re_kw.sub(lambda m: + self._repo.kwt.expand(m, self._path, c.node()), data) return data def add(self, text, meta, tr, link, p1=None, p2=None): '''Removes keyword substitutions when adding to filelog.''' if self.iskwcandidate(text): - text = self.kwt.re_kw.sub(r'$\1$', text) + text = self._repo.kwt.re_kw.sub(r'$\1$', text) return super(kwfilelog, self).add(text, meta, tr, link, p1=p1, p2=p2) def cmp(self, node, text): '''Removes keyword substitutions for comparison.''' if self.iskwcandidate(text): - text = self.kwt.re_kw.sub(r'$\1$', text) + text = self._repo.kwt.re_kw.sub(r'$\1$', text) return super(kwfilelog, self).cmp(node, text) filelog.filelog = kwfilelog repo.__class__ = kwrepo + + # create filematching function once for repo + setattr(repo, 'kwfmatcher', + util.matcher(repo.root, inc=inc, exc=['.hg*']+exc)[1]) + # initialize kwtemplater once for repo + setattr(repo, 'kwt', kwtemplater(ui, repo)) + # make pretxncommit hook import kwmodule regardless of where it's located for k, v in sys.modules.iteritems(): if v is None: @@ -185,13 +196,13 @@ sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) mod = os.path.splitext(os.path.basename(__file__))[0] ui.setconfig('hooks', 'pretxncommit.keyword', 'python:%s.pretxnkw' % mod) - del mod + + del inc, exc, mod def pretxnkw(ui, repo, hooktype, **args): '''pretxncommit hook that collects candidates for keyword expansion on commit and expands keywords in working dir.''' - from mercurial import commands cmd, sysargs, globalopts, cmdopts = commands.parse(ui, sys.argv[1:])[1:] if repr(cmd).split()[1] in ('tag', 'import_'): @@ -199,16 +210,16 @@ files, match, anypats = cmdutil.matchpats(repo, sysargs, cmdopts) modified, added = repo.status(files=files, match=match)[:2] - candidates = kwfmatches(ui, repo, modified+added) + candidates = [f for f in modified+added if repo.kwfmatcher(f)] if not candidates: return - kwt = kwtemplater(ui, repo) node = bin(args['node']) for f in candidates: data = repo.wfile(f).read() if not util.binary(data): - data, kwct = kwt.re_kw.subn(lambda m: kwt.expand(m, f, node), data) + data, kwct = repo.kwt.re_kw.subn(lambda m: + repo.kwt.expand(m, f, node), data) if kwct: ui.debug(_('overwriting %s expanding keywords\n' % f)) repo.wfile(f, 'w').write(data)