hgkw/keyword.py
branchstable
changeset 403 9a93b5d66e65
parent 401 05d0c3e4efdc
child 404 45d3ea301c03
equal deleted inserted replaced
392:45a318c5ea20 403:9a93b5d66e65
    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, dispatch, filelog, revlog
    83 from mercurial import commands, cmdutil, context, dispatch, filelog, revlog
    84 from mercurial import patch, localrepo, templater, templatefilters, util
    84 from mercurial import patch, localrepo, templater, templatefilters, util
       
    85 from mercurial.hgweb import webcommands
    85 from mercurial.node import *
    86 from mercurial.node import *
    86 from mercurial.i18n import _
    87 from mercurial.i18n import _
    87 import re, shutil, tempfile, time, os
    88 import re, shutil, tempfile, time
    88 
    89 
    89 commands.optionalrepo += ' kwdemo'
    90 commands.optionalrepo += ' kwdemo'
    90 
    91 
    91 # hg commands that do not act on keywords
    92 # hg commands that do not act on keywords
    92 nokwcommands = ('add addremove bundle copy export grep identify incoming init'
    93 nokwcommands = ('add addremove bundle copy export grep identify incoming init'
    93                 ' log outgoing push remove rename rollback tip convert email')
    94                 ' log outgoing push remove rename rollback tip'
       
    95                 ' convert email glog')
    94 
    96 
    95 # hg commands that trigger expansion only when writing to working dir,
    97 # hg commands that trigger expansion only when writing to working dir,
    96 # not when reading filelog, and unexpand when reading from working dir
    98 # not when reading filelog, and unexpand when reading from working dir
    97 restricted = 'diff1 record qfold qimport qnew qpush qrefresh qrecord'
    99 restricted = 'diff1 record qfold qimport qnew qpush qrefresh qrecord'
    98 
   100 
    99 def utcdate(date):
   101 def utcdate(date):
   100     '''Returns hgdate in cvs-like UTC format.'''
   102     '''Returns hgdate in cvs-like UTC format.'''
   101     return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0]))
   103     return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0]))
   102 
   104 
   103 
   105 
   104 _kwtemplater, _cmd, _cmdoptions = None, None, None
   106 _kwtemplater = _cmd = _cmdoptions = None
   105  
   107  
   106 # store originals of monkeypatches
   108 # store originals of monkeypatches
   107 _patchfile_init = patch.patchfile.__init__
   109 _patchfile_init = patch.patchfile.__init__
   108 _dispatch_parse = dispatch._parse
   110 _dispatch_parse = dispatch._parse
   109 
   111 
   114     if _kwtemplater.matcher(self.fname):
   116     if _kwtemplater.matcher(self.fname):
   115         # shrink keywords read from working dir
   117         # shrink keywords read from working dir
   116         kwshrunk = _kwtemplater.shrink(''.join(self.lines))
   118         kwshrunk = _kwtemplater.shrink(''.join(self.lines))
   117         self.lines = kwshrunk.splitlines(True)
   119         self.lines = kwshrunk.splitlines(True)
   118 
   120 
       
   121 def _kwweb_changeset(web, req, tmpl):
       
   122     '''Wraps webcommands.changeset turning off keyword expansion.'''
       
   123     _kwtemplater.matcher = util.never
       
   124     return web.changeset(tmpl, web.changectx(req))
       
   125 
       
   126 def _kwweb_filediff(web, req, tmpl):
       
   127     '''Wraps webcommands.filediff turning off keyword expansion.'''
       
   128     _kwtemplater.matcher = util.never
       
   129     return web.filediff(tmpl, web.filectx(req))
       
   130 
   119 def _kwdispatch_parse(ui, args):
   131 def _kwdispatch_parse(ui, args):
   120     '''Monkeypatch dispatch._parse to obtain
   132     '''Monkeypatch dispatch._parse to obtain
   121     current command and command options (global _cmd, _cmdoptions).'''
   133     current command and command options (global _cmd, _cmdoptions).'''
   122     global _cmd, _cmdoptions
   134     global _cmd, _cmdoptions
   123     _cmd, func, args, options, _cmdoptions = _dispatch_parse(ui, args)
   135     _cmd, func, args, options, _cmdoptions = _dispatch_parse(ui, args)
   124     return _cmd, func, args, options, _cmdoptions
   136     return _cmd, func, args, options, _cmdoptions
   125 
   137 
       
   138 # dispatch._parse is run before reposetup, so wrap it here
   126 dispatch._parse = _kwdispatch_parse
   139 dispatch._parse = _kwdispatch_parse
   127 
   140 
   128 
   141 
   129 class kwtemplater(object):
   142 class kwtemplater(object):
   130     '''
   143     '''
   139         'Source': '{root}/{file},v',
   152         'Source': '{root}/{file},v',
   140         'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}',
   153         'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}',
   141         'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}',
   154         'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}',
   142     }
   155     }
   143 
   156 
   144     def __init__(self, ui, repo, inc, exc, restrict):
   157     def __init__(self, ui, repo, inc, exc, hgcmd):
   145         self.ui = ui
   158         self.ui = ui
   146         self.repo = repo
   159         self.repo = repo
   147         self.matcher = util.matcher(repo.root, inc=inc, exc=exc)[1]
   160         self.matcher = util.matcher(repo.root, inc=inc, exc=exc)[1]
   148         self.restrict = restrict
   161         self.restrict = hgcmd in restricted.split()
   149         self.commitnode = None
   162         self.commitnode = None
   150         self.path = ''
   163         self.path = ''
   151 
   164 
   152         kwmaps = self.ui.configitems('keywordmaps')
   165         kwmaps = self.ui.configitems('keywordmaps')
   153         if kwmaps: # override default templates
   166         if kwmaps: # override default templates
   425     global _kwtemplater
   438     global _kwtemplater
   426     hgcmd, hgcmdopts = _cmd, _cmdoptions
   439     hgcmd, hgcmdopts = _cmd, _cmdoptions
   427 
   440 
   428     try:
   441     try:
   429         if (not repo.local() or hgcmd in nokwcommands.split() 
   442         if (not repo.local() or hgcmd in nokwcommands.split() 
   430             or '.hg' in repo.root.split(os.sep)
   443             or '.hg' in util.splitpath(repo.root)
   431             or repo._url.startswith('bundle:')):
   444             or repo._url.startswith('bundle:')):
   432             return
   445             return
   433     except AttributeError:
   446     except AttributeError:
   434         pass
   447         pass
   435 
   448 
   449             return
   462             return
   450         # shrink if rev is not current node
   463         # shrink if rev is not current node
   451         if node1 is not None and node1 != repo.changectx().node():
   464         if node1 is not None and node1 != repo.changectx().node():
   452             hgcmd = 'diff1'
   465             hgcmd = 'diff1'
   453 
   466 
   454     restrict = hgcmd in restricted.split()
   467     _kwtemplater = kwtemplater(ui, repo, inc, exc, hgcmd)
   455     _kwtemplater = kwtemplater(ui, repo, inc, exc, restrict)
       
   456 
   468 
   457     class kwrepo(repo.__class__):
   469     class kwrepo(repo.__class__):
   458         def file(self, f, kwmatch=False):
   470         def file(self, f, kwmatch=False):
   459             if f[0] == '/':
   471             if f[0] == '/':
   460                 f = f[1:]
   472                 f = f[1:]
   462                 return kwfilelog(self.sopener, f)
   474                 return kwfilelog(self.sopener, f)
   463             return filelog.filelog(self.sopener, f)
   475             return filelog.filelog(self.sopener, f)
   464 
   476 
   465         def wread(self, filename):
   477         def wread(self, filename):
   466             data = super(kwrepo, self).wread(filename)
   478             data = super(kwrepo, self).wread(filename)
   467             if restrict and _kwtemplater.matcher(filename):
   479             if _kwtemplater.restrict and _kwtemplater.matcher(filename):
   468                 return _kwtemplater.shrink(data)
   480                 return _kwtemplater.shrink(data)
   469             return data
   481             return data
   470 
   482 
   471         def commit(self, files=None, text='', user=None, date=None,
   483         def commit(self, files=None, text='', user=None, date=None,
   472                    match=util.always, force=False, force_editor=False,
   484                    match=util.always, force=False, force_editor=False,
   511             finally:
   523             finally:
   512                 del wlock, lock
   524                 del wlock, lock
   513 
   525 
   514     repo.__class__ = kwrepo
   526     repo.__class__ = kwrepo
   515     patch.patchfile.__init__ = _kwpatchfile_init
   527     patch.patchfile.__init__ = _kwpatchfile_init
       
   528     webcommands.changeset = webcommands.rev = _kwweb_changeset
       
   529     webcommands.filediff = webcommands.diff = _kwweb_filediff
   516 
   530 
   517 
   531 
   518 cmdtable = {
   532 cmdtable = {
   519     'kwdemo':
   533     'kwdemo':
   520         (demo,
   534         (demo,