hgkw/keyword.py
changeset 439 e658e469be45
parent 438 11ddc1ff268d
child 440 856fde439a0a
equal deleted inserted replaced
438:11ddc1ff268d 439:e658e469be45
   100 
   100 
   101 def utcdate(date):
   101 def utcdate(date):
   102     '''Returns hgdate in cvs-like UTC format.'''
   102     '''Returns hgdate in cvs-like UTC format.'''
   103     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]))
   104 
   104 
   105 
       
   106 # make keyword tools accessible
   105 # make keyword tools accessible
   107 kwtools = {'templater': None, 'hgcmd': '', 'inc': [], 'exc': ['.hg*']}
   106 kwtools = {'templater': None, 'hgcmd': '', 'inc': [], 'exc': ['.hg*']}
   108 
       
   109 # store originals of monkeypatches to be done at end of reposetup
       
   110 # that is, only if needed
       
   111 _patchfile_init = patch.patchfile.__init__
       
   112 _patch_diff = patch.diff
       
   113 _webcommands_changeset = webcommands.changeset
       
   114 _webcommands_filediff = webcommands.filediff
       
   115 
       
   116 def _kwpatchfile_init(self, ui, fname, missing=False):
       
   117     '''Monkeypatch/wrap patch.patchfile.__init__ to avoid
       
   118     rejects or conflicts due to expanded keywords in working dir.'''
       
   119     _patchfile_init(self, ui, fname, missing=missing)
       
   120     # shrink keywords read from working dir
       
   121     kwt = kwtools['templater']
       
   122     self.lines = kwt.shrinklines(self.fname, self.lines)
       
   123 
       
   124 def _kw_diff(repo, node1=None, node2=None, files=None, match=util.always,
       
   125              fp=None, changes=None, opts=None):
       
   126     '''Monkeypatch patch.diff to avoid expansion except when
       
   127     comparing against working dir.'''
       
   128     if node2 is not None:
       
   129         kwtools['templater'].matcher = util.never
       
   130     elif node1 is not None and node1 != repo.changectx().node():
       
   131         kwtools['templater'].restrict = True
       
   132     _patch_diff(repo, node1=node1, node2=node2, files=files, match=match,
       
   133                 fp=fp, changes=changes, opts=opts)
       
   134 
       
   135 def _kwweb_changeset(web, req, tmpl):
       
   136     '''Wraps webcommands.changeset turning off keyword expansion.'''
       
   137     kwtools['templater'].matcher = util.never
       
   138     return _webcommands_changeset(web, req, tmpl)
       
   139 
       
   140 def _kwweb_filediff(web, req, tmpl):
       
   141     '''Wraps webcommands.filediff turning off keyword expansion.'''
       
   142     kwtools['templater'].matcher = util.never
       
   143     return _webcommands_filediff(web, req, tmpl)
       
   144 
   107 
   145 
   108 
   146 class kwtemplater(object):
   109 class kwtemplater(object):
   147     '''
   110     '''
   148     Sets up keyword templates, corresponding keyword regex, and
   111     Sets up keyword templates, corresponding keyword regex, and
   265 class kwfilelog(filelog.filelog):
   228 class kwfilelog(filelog.filelog):
   266     '''
   229     '''
   267     Subclass of filelog to hook into its read, add, cmp methods.
   230     Subclass of filelog to hook into its read, add, cmp methods.
   268     Keywords are "stored" unexpanded, and processed on reading.
   231     Keywords are "stored" unexpanded, and processed on reading.
   269     '''
   232     '''
   270     def __init__(self, opener, path):
   233     def __init__(self, opener, kwt, path):
   271         super(kwfilelog, self).__init__(opener, path)
   234         super(kwfilelog, self).__init__(opener, path)
   272         self.kwt = kwtools['templater']
   235         self.kwt = kwt
   273         self.path = path
   236         self.path = path
   274 
   237 
   275     def read(self, node):
   238     def read(self, node):
   276         '''Expands keywords when reading filelog.'''
   239         '''Expands keywords when reading filelog.'''
   277         data = super(kwfilelog, self).read(node)
   240         data = super(kwfilelog, self).read(node)
   469     '''Sets up repo as kwrepo for keyword substitution.
   432     '''Sets up repo as kwrepo for keyword substitution.
   470     Overrides file method to return kwfilelog instead of filelog
   433     Overrides file method to return kwfilelog instead of filelog
   471     if file matches user configuration.
   434     if file matches user configuration.
   472     Wraps commit to overwrite configured files with updated
   435     Wraps commit to overwrite configured files with updated
   473     keyword substitutions.
   436     keyword substitutions.
   474     This is done for local repos only, and only if there are
   437     Monkeypatches patch and webcommands.'''
   475     files configured at all for keyword substitution.'''
       
   476 
   438 
   477     try:
   439     try:
   478         if (not repo.local() or not kwtools['inc']
   440         if (not repo.local() or not kwtools['inc']
   479             or kwtools['hgcmd'] in nokwcommands.split()
   441             or kwtools['hgcmd'] in nokwcommands.split()
   480             or '.hg' in util.splitpath(repo.root)
   442             or '.hg' in util.splitpath(repo.root)
   487 
   449 
   488     class kwrepo(repo.__class__):
   450     class kwrepo(repo.__class__):
   489         def file(self, f):
   451         def file(self, f):
   490             if f[0] == '/':
   452             if f[0] == '/':
   491                 f = f[1:]
   453                 f = f[1:]
   492             return kwfilelog(self.sopener, f)
   454             return kwfilelog(self.sopener, kwt, f)
   493 
   455 
   494         def wread(self, filename):
   456         def wread(self, filename):
   495             data = super(kwrepo, self).wread(filename)
   457             data = super(kwrepo, self).wread(filename)
   496             return kwt.wread(filename, data)
   458             return kwt.wread(filename, data)
   497 
   459 
   536                     repo.hook('commit', node=node, parent1=_p1, parent2=_p2)
   498                     repo.hook('commit', node=node, parent1=_p1, parent2=_p2)
   537                 return node
   499                 return node
   538             finally:
   500             finally:
   539                 del wlock, lock
   501                 del wlock, lock
   540 
   502 
       
   503     # monkeypatches
       
   504     def kwpatchfile_init(self, ui, fname, missing=False):
       
   505         '''Monkeypatch/wrap patch.patchfile.__init__ to avoid
       
   506         rejects or conflicts due to expanded keywords in working dir.'''
       
   507         patchfile_init(self, ui, fname, missing=missing)
       
   508         # shrink keywords read from working dir
       
   509         self.lines = kwt.shrinklines(self.fname, self.lines)
       
   510 
       
   511     def kw_diff(repo, node1=None, node2=None, files=None, match=util.always,
       
   512                 fp=None, changes=None, opts=None):
       
   513         '''Monkeypatch patch.diff to avoid expansion except when
       
   514         comparing against working dir.'''
       
   515         if node2 is not None:
       
   516             kwt.matcher = util.never
       
   517         elif node1 is not None and node1 != repo.changectx().node():
       
   518             kwt.restrict = True
       
   519         patch_diff(repo, node1=node1, node2=node2, files=files, match=match,
       
   520                    fp=fp, changes=changes, opts=opts)
       
   521 
       
   522     def kwweb_changeset(web, req, tmpl):
       
   523         '''Wraps webcommands.changeset turning off keyword expansion.'''
       
   524         kwt.matcher = util.never
       
   525         return webcommands_changeset(web, req, tmpl)
       
   526 
       
   527     def kwweb_filediff(web, req, tmpl):
       
   528         '''Wraps webcommands.filediff turning off keyword expansion.'''
       
   529         kwt.matcher = util.never
       
   530         return webcommands_filediff(web, req, tmpl)
       
   531 
   541     repo.__class__ = kwrepo
   532     repo.__class__ = kwrepo
   542     patch.patchfile.__init__ = _kwpatchfile_init
   533 
   543     patch.diff = _kw_diff
   534     patchfile_init = patch.patchfile.__init__
   544     webcommands.changeset = webcommands.rev = _kwweb_changeset
   535     patch_diff = patch.diff
   545     webcommands.filediff = webcommands.diff = _kwweb_filediff
   536     webcommands_changeset = webcommands.changeset
       
   537     webcommands_filediff = webcommands.filediff
       
   538 
       
   539     patch.patchfile.__init__ = kwpatchfile_init
       
   540     patch.diff = kw_diff
       
   541     webcommands.changeset = webcommands.rev = kwweb_changeset
       
   542     webcommands.filediff = webcommands.diff = kwweb_filediff
   546 
   543 
   547 
   544 
   548 cmdtable = {
   545 cmdtable = {
   549     'kwdemo':
   546     'kwdemo':
   550         (demo,
   547         (demo,