hgkw/keyword.py
branchself_initializing_hook
changeset 92 3c7c187e4001
parent 90 2e930f842242
child 93 9f70f953dd3b
equal deleted inserted replaced
91:04c899130750 92:3c7c187e4001
    34 '''
    34 '''
    35 
    35 
    36 from mercurial import context, util
    36 from mercurial import context, util
    37 import os.path, re, sys, time
    37 import os.path, re, sys, time
    38 
    38 
    39 
       
    40 re_kw = re.compile(
    39 re_kw = re.compile(
    41         r'\$(Id|Header|Author|Date|Revision|RCSFile|Source)[^$]*?\$')
    40         r'\$(Id|Header|Author|Date|Revision|RCSFile|Source)[^$]*?\$')
    42 
    41 
    43 
    42 def kwexpand(mobj, kwfctx):
    44 def kwexpand(matchobj, repo, path, changeid=None, fileid=None, filelog=None):
       
    45     '''Called by kwfilelog.read and pretxnkw.
    43     '''Called by kwfilelog.read and pretxnkw.
    46     Sets supported keywords as local variables and evaluates them to
    44     Expands keywords according to file context.'''
    47     their expansion if matchobj is equal to string representation.'''
    45     return '$%s: %s $' % (mobj.group(1), kwfctx.expand(mobj.group(1)))
    48     c = context.filectx(repo, path,
       
    49             changeid=changeid, fileid=fileid, filelog=filelog)
       
    50     def Revision():
       
    51         return str(c.changectx())
       
    52     def Author():
       
    53         return util.shortuser(c.user())
       
    54     def Date():
       
    55         return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(c.date()[0]))
       
    56     def RCSFile():
       
    57         return os.path.basename(path)+',v'
       
    58     def Source():
       
    59         return repo.wjoin(path)+',v'
       
    60     def Header():
       
    61         return ' '.join([Source(), Revision(), Date(), Author()])
       
    62     def Id():
       
    63         return ' '.join([RCSFile(), Revision(), Date(), Author()])
       
    64     return '$%s: %s $' % (matchobj.group(1), eval('%s()' % matchobj.group(1)))
       
    65 
    46 
    66 def kwfmatches(ui, repo, files):
    47 def kwfmatches(ui, repo, files):
    67     '''Selects candidates for keyword substitution
    48     '''Selects candidates for keyword substitution
    68     configured in keyword section in hgrc.'''
    49     configured in keyword section in hgrc.'''
    69     files = [f for f in files if not f.startswith('.hg')]
    50     files = [f for f in files if not f.startswith('.hg')]
    76         for mf in kwfmatchers:
    57         for mf in kwfmatchers:
    77             if mf(f):
    58             if mf(f):
    78                 candidates.append(f)
    59                 candidates.append(f)
    79                 break
    60                 break
    80     return candidates
    61     return candidates
       
    62 
       
    63 def utc(hgdate):
       
    64     '''Returns hgdate in cvs-like UTC format.'''
       
    65     return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(hgdate[0]))
       
    66 
       
    67 
       
    68 class kwfilectx(context.filectx):
       
    69     '''
       
    70     Provides keyword expansion functions based on file context.
       
    71     '''
       
    72     def __init__(self, repo, path, changeid=None, fileid=None, filelog=None):
       
    73         context.filectx.__init__(self, repo, path, changeid, fileid, filelog)
       
    74     def Revision(self):
       
    75         return str(self.changectx())
       
    76     def Author(self):
       
    77         return util.shortuser(self.user())
       
    78     def Date(self):
       
    79         return utc(self.date())
       
    80     def RCSFile(self):
       
    81         return os.path.basename(self._path)+',v'
       
    82     def Source(self):
       
    83         return self._repo.wjoin(self._path)+',v'
       
    84     def Header(self):
       
    85         return ' '.join(
       
    86                 [self.Source(), self.Revision(), self.Date(), self.Author()])
       
    87     def Id(self):
       
    88         return ' '.join(
       
    89                 [self.RCSFile(), self.Revision(), self.Date(), self.Author()])
       
    90     def expand(self, kw):
       
    91         '''Called from kwexpand, evaluates keyword.'''
       
    92         return eval('self.%s()' % kw)
    81 
    93 
    82 
    94 
    83 def reposetup(ui, repo):
    95 def reposetup(ui, repo):
    84     from mercurial import filelog, revlog
    96     from mercurial import filelog, revlog
    85 
    97 
   110 
   122 
   111         def read(self, node):
   123         def read(self, node):
   112             '''Substitutes keywords when reading filelog.'''
   124             '''Substitutes keywords when reading filelog.'''
   113             data = super(kwfilelog, self).read(node)
   125             data = super(kwfilelog, self).read(node)
   114             if self.iskwcandidate(data):
   126             if self.iskwcandidate(data):
   115                 return re_kw.sub(lambda m:
   127                 kwfctx = kwfilectx(self._repo, self._path,
   116                         kwexpand(m, self._repo, self._path,
   128                             fileid=node, filelog=self)
   117                             fileid=node, filelog=self), data)
   129                 return re_kw.sub(lambda m: kwexpand(m, kwfctx), data)
   118             return data
   130             return data
   119 
   131 
   120         def add(self, text, meta, tr, link, p1=None, p2=None):
   132         def add(self, text, meta, tr, link, p1=None, p2=None):
   121             '''Removes keyword substitutions when adding to filelog.'''
   133             '''Removes keyword substitutions when adding to filelog.'''
   122             if self.iskwcandidate(text):
   134             if self.iskwcandidate(text):
   168     modified, added = repo.status(files=files, match=match)[:2]
   180     modified, added = repo.status(files=files, match=match)[:2]
   169 
   181 
   170     for f in kwfmatches(ui, repo, modified+added):
   182     for f in kwfmatches(ui, repo, modified+added):
   171         data = repo.wfile(f).read()
   183         data = repo.wfile(f).read()
   172         if not util.binary(data):
   184         if not util.binary(data):
   173             data, kwct = re_kw.subn(lambda m:
   185             kwfctx = kwfilectx(repo, f, changeid=args['node'])
   174                     kwexpand(m, repo, f, changeid=args['node']), data)
   186             data, kwct = re_kw.subn(lambda m: kwexpand(m, kwfctx), data)
   175             if kwct:
   187             if kwct:
   176                 ui.debug(_('overwriting %s expanding keywords\n' % f))
   188                 ui.debug(_('overwriting %s expanding keywords\n' % f))
   177                 repo.wfile(f, 'w').write(data)
   189                 repo.wfile(f, 'w').write(data)