hgkw/keyword.py
changeset 355 b3caec747375
parent 354 8e3364294d0c
child 357 7b165e66b81b
equal deleted inserted replaced
354:8e3364294d0c 355:b3caec747375
    78 Expansions spanning more than one line and incremental expansions,
    78 Expansions spanning more than one line and incremental expansions,
    79 like CVS' $Log$, are not supported. A keyword template map
    79 like CVS' $Log$, are not supported. A keyword template map
    80 "Log = {desc}" expands to the first line of the changeset description.
    80 "Log = {desc}" expands to the first line of the changeset description.
    81 '''
    81 '''
    82 
    82 
    83 from mercurial import commands, cmdutil, context, localrepo
    83 from mercurial import commands, cmdutil, context, filelog, localrepo
    84 from mercurial import patch, revlog, templater, util
    84 from mercurial import patch, revlog, templater, util
    85 from mercurial.node import *
    85 from mercurial.node import *
    86 from mercurial.i18n import _
    86 from mercurial.i18n import _
    87 import re, shutil, tempfile, time
    87 import re, shutil, tempfile, time
    88 
    88 
   135                 self.ctx = self.repo.changectx()
   135                 self.ctx = self.repo.changectx()
   136             fnode = self.ctx.filenode(path)
   136             fnode = self.ctx.filenode(path)
   137             fl = self.repo.file(path)
   137             fl = self.repo.file(path)
   138             c = context.filectx(self.repo, path, fileid=fnode, filelog=fl)
   138             c = context.filectx(self.repo, path, fileid=fnode, filelog=fl)
   139             node = c.node()
   139             node = c.node()
       
   140         elif subfunc == self.re_kw.sub:
       
   141             # hg kwcat using kwfilelog.read
       
   142             c = context.filectx(self.repo, path, fileid=node)
       
   143             node = c.node()
   140 
   144 
   141         def kwsub(mobj):
   145         def kwsub(mobj):
   142             '''Substitutes keyword using corresponding template.'''
   146             '''Substitutes keyword using corresponding template.'''
   143             kw = mobj.group(1)
   147             kw = mobj.group(1)
   144             self.ct.use_template(self.templates[kw])
   148             self.ct.use_template(self.templates[kw])
   146             self.ct.show(changenode=node, root=self.repo.root, file=path)
   150             self.ct.show(changenode=node, root=self.repo.root, file=path)
   147             return '$%s: %s $' % (kw, templater.firstline(self.ui.popbuffer()))
   151             return '$%s: %s $' % (kw, templater.firstline(self.ui.popbuffer()))
   148 
   152 
   149         return subfunc(kwsub, data)
   153         return subfunc(kwsub, data)
   150 
   154 
   151     def expand(self, path, data):
   155     def expand(self, path, data, node):
   152         '''Returns data with keywords expanded.'''
   156         '''Returns data with keywords expanded.'''
   153         if util.binary(data):
   157         if util.binary(data):
   154             return data
   158             return data
   155         return self.substitute(path, data, None, self.re_kw.sub)
   159         return self.substitute(path, data, node, self.re_kw.sub)
   156 
   160 
   157     def process(self, path, data, expand, ctx, node):
   161     def process(self, path, data, expand, ctx, node):
   158         '''Returns a tuple: data, count.
   162         '''Returns a tuple: data, count.
   159         Count is number of keywords/keyword substitutions,
   163         Count is number of keywords/keyword substitutions,
   160         telling caller whether to act on file containing data.'''
   164         telling caller whether to act on file containing data.'''
   168     def shrink(self, data):
   172     def shrink(self, data):
   169         '''Returns text with all keyword substitutions removed.'''
   173         '''Returns text with all keyword substitutions removed.'''
   170         if util.binary(data):
   174         if util.binary(data):
   171             return data
   175             return data
   172         return self.re_kw.sub(r'$\1$', data)
   176         return self.re_kw.sub(r'$\1$', data)
       
   177 
       
   178 class kwfilelog(filelog.filelog):
       
   179     '''
       
   180     Subclass of filelog to hook into its read method for kwcat.
       
   181     '''
       
   182     def __init__(self, opener, path, kwt):
       
   183         super(kwfilelog, self).__init__(opener, path)
       
   184         self._kwt = kwt
       
   185         self._path = path
       
   186 
       
   187     def read(self, node):
       
   188         '''Expands keywords when reading filelog.'''
       
   189         data = super(kwfilelog, self).read(node)
       
   190         return self._kwt.expand(self._path, data, node)
   173 
   191 
   174 # store original patch.patchfile.__init__
   192 # store original patch.patchfile.__init__
   175 _patchfile_init = patch.patchfile.__init__
   193 _patchfile_init = patch.patchfile.__init__
   176 
   194 
   177 
   195 
   222         lock = repo.lock()
   240         lock = repo.lock()
   223         _overwrite(ui, repo, expand=expand, files=clean)
   241         _overwrite(ui, repo, expand=expand, files=clean)
   224     finally:
   242     finally:
   225         del wlock, lock
   243         del wlock, lock
   226 
   244 
       
   245 def cat(ui, repo, file1, *pats, **opts):
       
   246     '''output the current or given revision of files expanding keywords
       
   247 
       
   248     Print the specified files as they were at the given revision.
       
   249     If no revision is given, the parent of the working directory is used,
       
   250     or tip if no revision is checked out.
       
   251 
       
   252     Output may be to a file, in which case the name of the file is
       
   253     given using a format string.  The formatting rules are the same as
       
   254     for the export command, with the following additions:
       
   255 
       
   256     %s   basename of file being printed
       
   257     %d   dirname of file being printed, or '.' if in repo root
       
   258     %p   root-relative path name of file being printed
       
   259     '''
       
   260     try:
       
   261         repo.file = repo._kwfile
       
   262     except AttributeError:
       
   263         pass
       
   264     commands.cat(ui, repo, file1, *pats, **opts)
   227 
   265 
   228 def demo(ui, repo, *args, **opts):
   266 def demo(ui, repo, *args, **opts):
   229     '''print [keywordmaps] configuration and an expansion example
   267     '''print [keywordmaps] configuration and an expansion example
   230 
   268 
   231     Show current, custom, or default keyword template maps
   269     Show current, custom, or default keyword template maps
   362             exc.append(pat)
   400             exc.append(pat)
   363     if not inc:
   401     if not inc:
   364         return
   402         return
   365 
   403 
   366     class kwrepo(repo.__class__):
   404     class kwrepo(repo.__class__):
       
   405         def _kwfile(self, f):
       
   406             '''Returns filelog expanding keywords on read (for kwcat).'''
       
   407             if f[0] == '/':
       
   408                 f = f[1:]
       
   409             if self._kwt.matcher(f):
       
   410                 return kwfilelog(self.sopener, f, self._kwt)
       
   411             return filelog.filelog(self.sopener, f)
       
   412 
   367         def _wreadkwct(self, filename, expand, ctx, node):
   413         def _wreadkwct(self, filename, expand, ctx, node):
   368             '''Reads filename and returns tuple of data with keywords
   414             '''Reads filename and returns tuple of data with keywords
   369             expanded/shrunk and count of keywords (for _overwrite).'''
   415             expanded/shrunk and count of keywords (for _overwrite).'''
   370             data = super(kwrepo, self).wread(filename)
   416             data = super(kwrepo, self).wread(filename)
   371             return self._kwt.process(filename, data, expand, ctx, node)
   417             return self._kwt.process(filename, data, expand, ctx, node)
   376                 return self._kwt.shrink(data)
   422                 return self._kwt.shrink(data)
   377             return data
   423             return data
   378 
   424 
   379         def wwrite(self, filename, data, flags, overwrite=False):
   425         def wwrite(self, filename, data, flags, overwrite=False):
   380             if not overwrite and self._kwt.matcher(filename):
   426             if not overwrite and self._kwt.matcher(filename):
   381                 data = self._kwt.expand(filename, data)
   427                 data = self._kwt.expand(filename, data, None)
   382             super(kwrepo, self).wwrite(filename, data, flags)
   428             super(kwrepo, self).wwrite(filename, data, flags)
   383 
   429 
   384         def wwritedata(self, filename, data):
   430         def wwritedata(self, filename, data):
   385             if self._kwt.matcher(filename):
   431             if self._kwt.matcher(filename):
   386                 data = self._kwt.expand(filename, data)
   432                 data = self._kwt.expand(filename, data, None)
   387             return super(kwrepo, self).wwritedata(filename, data)
   433             return super(kwrepo, self).wwritedata(filename, data)
   388 
   434 
   389         def commit(self, files=None, text='', user=None, date=None,
   435         def commit(self, files=None, text='', user=None, date=None,
   390                    match=util.always, force=False, force_editor=False,
   436                    match=util.always, force=False, force_editor=False,
   391                    p1=None, p2=None, extra={}):
   437                    p1=None, p2=None, extra={}):
   443     repo.__class__ = kwrepo
   489     repo.__class__ = kwrepo
   444     patch.patchfile.__init__ = kwpatchfile_init
   490     patch.patchfile.__init__ = kwpatchfile_init
   445 
   491 
   446 
   492 
   447 cmdtable = {
   493 cmdtable = {
       
   494     'kwcat':
       
   495         (cat, commands.table['cat'][1],
       
   496          _('hg kwcat [OPTION]... FILE...')),
   448     'kwdemo':
   497     'kwdemo':
   449         (demo,
   498         (demo,
   450          [('d', 'default', None, _('show default keyword template maps')),
   499          [('d', 'default', None, _('show default keyword template maps')),
   451           ('f', 'rcfile', [], _('read maps from rcfile'))],
   500           ('f', 'rcfile', [], _('read maps from rcfile'))],
   452          _('hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]...')),
   501          _('hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]...')),