hgkw/keyword.py
branch0.9.2compat
changeset 387 ecb2935f9bb8
parent 380 0ed26effe190
child 388 05fbd226cb5c
equal deleted inserted replaced
380:0ed26effe190 387:ecb2935f9bb8
    87 
    87 
    88 from mercurial import commands, cmdutil, context, fancyopts
    88 from mercurial import commands, cmdutil, context, fancyopts
    89 from mercurial import filelog, localrepo, revlog, templater, util
    89 from mercurial import filelog, localrepo, revlog, templater, util
    90 from mercurial.node import *
    90 from mercurial.node import *
    91 from mercurial.i18n import gettext as _
    91 from mercurial.i18n import gettext as _
    92 import getopt, os.path, re, shutil, sys, tempfile, time
    92 import getopt, os.path, re, shutil, tempfile, time
    93 
    93 
    94 commands.optionalrepo += ' kwdemo'
    94 commands.optionalrepo += ' kwdemo'
    95 
    95 
    96 # hg commands that do not act on keywords
    96 # hg commands that do not act on keywords
    97 nokwcommands = ('add addremove bundle copy export grep identify incoming init'
    97 nokwcommands = ('add addremove bundle copy export grep identify incoming init'
    98                 ' log outgoing push remove rename rollback tip convert')
    98                 ' log outgoing push remove rename rollback tip convert email')
    99 
    99 
   100 # hg commands that trigger expansion only when writing to working dir,
   100 # hg commands that trigger expansion only when writing to working dir,
   101 # not when reading filelog, and unexpand when reading from working dir
   101 # not when reading filelog, and unexpand when reading from working dir
   102 restricted = 'diff1 record qfold qimport qnew qpush qrefresh qrecord'
   102 restricted = 'diff1 record qfold qimport qnew qpush qrefresh qrecord'
   103 
   103 
   104 def utcdate(date):
   104 def utcdate(date):
   105     '''Returns hgdate in cvs-like UTC format.'''
   105     '''Returns hgdate in cvs-like UTC format.'''
   106     return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0]))
   106     return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0]))
   107 
   107 
   108 
   108 
   109 _kwtemplater = None
   109 _kwtemplater, _cmd, _cmdoptions = None, None, None
   110 
   110 
   111 # backwards compatibility hacks
   111 # backwards compatibility hacks
       
   112 
       
   113 try:
       
   114     # cmdutil.parse moves to dispatch._parse in 18a9fbb5cd78
       
   115     from mercurial import dispatch
       
   116     _dispatch_parse = dispatch._parse
       
   117 except ImportError:
       
   118     try:
       
   119         # commands.parse moves to cmdutil.parse in 0c61124ad877
       
   120         _dispatch_parse = cmdutil.parse
       
   121     except AttributeError:
       
   122         _dispatch_parse = commands.parse
       
   123 
       
   124 def _kwdispatch_parse(ui, args):
       
   125     '''Monkeypatch dispatch._parse to obtain
       
   126     current command and command options (global _cmd, _cmdoptions).'''
       
   127     global _cmd, _cmdoptions
       
   128     _cmd, func, args, options, _cmdoptions = _dispatch_parse(ui, args)
       
   129     return _cmd, func, args, options, _cmdoptions
       
   130 
       
   131 try:
       
   132     setattr(dispatch, '_parse', _kwdispatch_parse)
       
   133 except (NameError, ImportError):
       
   134     # 0.9.4 needs ImportError
       
   135     if hasattr(cmdutil, 'parse'):
       
   136         cmdutil.parse = _kwdispatch_parse
       
   137     else:
       
   138         commands.parse = _kwdispatch_parse
   112 
   139 
   113 try:
   140 try:
   114     # avoid spurious rejects if patchfile is available
   141     # avoid spurious rejects if patchfile is available
   115     from mercurial.patch import patchfile
   142     from mercurial.patch import patchfile
   116     _patchfile_init = patchfile.__init__
   143     _patchfile_init = patchfile.__init__
   132     template_filters = templatefilters.filters
   159     template_filters = templatefilters.filters
   133     template_firstline = templatefilters.firstline
   160     template_firstline = templatefilters.firstline
   134 except ImportError:
   161 except ImportError:
   135     template_filters = templater.common_filters
   162     template_filters = templater.common_filters
   136     template_firstline = templater.firstline
   163     template_firstline = templater.firstline
   137 
       
   138 try:
       
   139     # cmdutil.parse moves to dispatch._parse in 18a9fbb5cd78
       
   140     # also avoid name conflict with other dispatch package(s)
       
   141     from mercurial.dispatch import _parse
       
   142 except ImportError:
       
   143     try:
       
   144         # commands.parse moves to cmdutil.parse in 0c61124ad877
       
   145         _parse = cmdutil.parse
       
   146     except AttributeError:
       
   147         _parse = commands.parse
       
   148 
   164 
   149 def _wwrite(repo, f, data, mf):
   165 def _wwrite(repo, f, data, mf):
   150     '''Makes repo.wwrite backwards compatible.'''
   166     '''Makes repo.wwrite backwards compatible.'''
   151     # 656e06eebda7 removed file descriptor argument
   167     # 656e06eebda7 removed file descriptor argument
   152     # 67982d3ee76c added flags argument
   168     # 67982d3ee76c added flags argument
   243         'Source': '{root}/{file},v',
   259         'Source': '{root}/{file},v',
   244         'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}',
   260         'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}',
   245         'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}',
   261         'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}',
   246     }
   262     }
   247 
   263 
   248     def __init__(self, ui, repo, inc, exc, restricted):
   264     def __init__(self, ui, repo, inc, exc, restrict):
   249         self.ui = ui
   265         self.ui = ui
   250         self.repo = repo
   266         self.repo = repo
   251         self.matcher = util.matcher(repo.root, inc=inc, exc=exc)[1]
   267         self.matcher = util.matcher(repo.root, inc=inc, exc=exc)[1]
   252         self.restricted = restricted
   268         self.restrict = restrict
   253         self.commitnode = None
   269         self.commitnode = None
   254         self.path = ''
   270         self.path = ''
   255 
   271 
   256         kwmaps = self.ui.configitems('keywordmaps')
   272         kwmaps = self.ui.configitems('keywordmaps')
   257         if kwmaps: # override default templates
   273         if kwmaps: # override default templates
   294 
   310 
   295         return subfunc(kwsub, data)
   311         return subfunc(kwsub, data)
   296 
   312 
   297     def expand(self, node, data):
   313     def expand(self, node, data):
   298         '''Returns data with keywords expanded.'''
   314         '''Returns data with keywords expanded.'''
   299         if self.restricted or util.binary(data):
   315         if self.restrict or util.binary(data):
   300             return data
   316             return data
   301         return self.substitute(node, data, self.re_kw.sub)
   317         return self.substitute(node, data, self.re_kw.sub)
   302 
   318 
   303     def process(self, node, data, expand):
   319     def process(self, node, data, expand):
   304         '''Returns a tuple: data, count.
   320         '''Returns a tuple: data, count.
   534     Wraps commit to overwrite configured files with updated
   550     Wraps commit to overwrite configured files with updated
   535     keyword substitutions.
   551     keyword substitutions.
   536     This is done for local repos only, and only if there are
   552     This is done for local repos only, and only if there are
   537     files configured at all for keyword substitution.'''
   553     files configured at all for keyword substitution.'''
   538 
   554 
   539     if not repo.local():
   555     global _kwtemplater
   540         return
   556     hgcmd, hgcmdopts = _cmd, _cmdoptions
   541 
   557 
   542     hgcmd, func, args, opts, cmdopts = _parse(ui, sys.argv[1:])
   558     try:
   543     if hgcmd in nokwcommands.split():
   559         if (not repo.local() or hgcmd in nokwcommands.split() 
   544         return
   560             or '.hg' in repo.root.split('/')
   545 
   561             or repo._url.startswith('bundle:')):
   546     if hgcmd == 'diff':
       
   547         # only expand if comparing against working dir
       
   548         node1, node2 = cmdutil.revpair(repo, cmdopts.get('rev'))
       
   549         if node2 is not None:
       
   550             return
   562             return
   551         # shrink if rev is not current node
   563     except AttributeError:
   552         if node1 is not None and node1 != repo.changectx().node():
   564         pass
   553             hgcmd = 'diff1'
   565 
   554 
   566     inc, exc = [], ['.hg*']
   555     inc, exc = [], ['.hgtags']
       
   556     for pat, opt in ui.configitems('keyword'):
   567     for pat, opt in ui.configitems('keyword'):
   557         if opt != 'ignore':
   568         if opt != 'ignore':
   558             inc.append(pat)
   569             inc.append(pat)
   559         else:
   570         else:
   560             exc.append(pat)
   571             exc.append(pat)
   561     if not inc:
   572     if not inc:
   562         return
   573         return
   563 
   574 
   564     global _kwtemplater
   575     if hgcmd == 'diff':
   565     _restricted = hgcmd in restricted.split()
   576         # only expand if comparing against working dir
   566     _kwtemplater = kwtemplater(ui, repo, inc, exc, _restricted)
   577         node1, node2 = cmdutil.revpair(repo, hgcmdopts.get('rev'))
       
   578         if node2 is not None:
       
   579             return
       
   580         # shrink if rev is not current node
       
   581         if node1 is not None and node1 != repo.changectx().node():
       
   582             hgcmd = 'diff1'
       
   583 
       
   584     restrict = hgcmd in restricted.split()
       
   585     _kwtemplater = kwtemplater(ui, repo, inc, exc, restrict)
   567 
   586 
   568     class kwrepo(repo.__class__):
   587     class kwrepo(repo.__class__):
   569         def file(self, f, kwmatch=False):
   588         def file(self, f, kwmatch=False):
   570             if f[0] == '/':
   589             if f[0] == '/':
   571                 f = f[1:]
   590                 f = f[1:]
   573                 return kwfilelog(self.sopener, f)
   592                 return kwfilelog(self.sopener, f)
   574             return filelog.filelog(self.sopener, f)
   593             return filelog.filelog(self.sopener, f)
   575 
   594 
   576         def wread(self, filename):
   595         def wread(self, filename):
   577             data = super(kwrepo, self).wread(filename)
   596             data = super(kwrepo, self).wread(filename)
   578             if _restricted and _kwtemplater.matcher(filename):
   597             if restrict and _kwtemplater.matcher(filename):
   579                 return _kwtemplater.shrink(data)
   598                 return _kwtemplater.shrink(data)
   580             return data
   599             return data
   581 
   600 
   582         def _commit(self, files, text, user, date, match, force, lock, wlock,
   601         def _commit(self, files, text, user, date, match, force, lock, wlock,
   583                     force_editor, p1, p2, extra, empty_ok):
   602                     force_editor, p1, p2, extra, empty_ok):