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