diff -r bc5cd6cf69bc -r c1b7b1d052de hgkw/keyword.py --- 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)