hgkw/keyword.py
branchkwmap-templates
changeset 178 4a27c306c6a2
parent 177 261a6844145e
child 179 8ddd39a79dc7
equal deleted inserted replaced
177:261a6844145e 178:4a27c306c6a2
    42 
    42 
    43 Keywords are only expanded in local repositories and not logged by
    43 Keywords are only expanded in local repositories and not logged by
    44 Mercurial internally. The mechanism can be regarded as a convenience
    44 Mercurial internally. The mechanism can be regarded as a convenience
    45 for the current user and may be turned off anytime.
    45 for the current user and may be turned off anytime.
    46 
    46 
       
    47 An additional date template filter {date|utcdate} is provided.
       
    48 
    47 Caveat: "hg import" might fail if the patches were exported from a
    49 Caveat: "hg import" might fail if the patches were exported from a
    48 repo with a different/no keyword setup, whereas "hg unbundle" is
    50 repo with a different/no keyword setup, whereas "hg unbundle" is
    49 safe.
    51 safe.
    50 
    52 
    51 Configuration is done in the [keyword] and [keywordmaps] sections of
    53 Configuration is done in the [keyword] and [keywordmaps] sections of
    52 hgrc files.
    54 hgrc files.
    53 
    55 
    54 Example:
    56 Example:
    55      [keyword]
    57     [extensions]
    56      # filename patterns for expansion are configured in this section
    58     hgext.keyword =
    57      # files matching patterns with value 'ignore' are ignored
    59 
    58      **.py =          ## expand keywords in all python files
    60     [keyword]
    59      x* = ignore      ## but ignore files matching "x*"
    61     # expand keywords in every python file,
    60      ...
    62     # except those matching "x*"
    61      [keywordmaps]
    63     **.py =
    62      # custom hg template maps _replace_ the CVS-like default ones
    64     x* = ignore
    63      HGdate = {date|rfc822date}
    65 
    64      lastlog = {desc} ## same as {desc|firstline} in this context
    66 For [keywordmaps] demonstration run "hg kwdemo".
    65      checked in by = {author}
       
    66      ...
       
    67 
       
    68 If no [keywordmaps] are configured the extension falls back on the
       
    69 following defaults:
       
    70 
       
    71      Revision: changeset id
       
    72      Author: username
       
    73      Date: %Y/%m/%d %H:%M:%S      ## [UTC]
       
    74      RCSFile: basename,v
       
    75      Source: /path/to/basename,v
       
    76      Id: basename,v csetid %Y/%m/%d %H:%M:%S username
       
    77      Header: /path/to/basename,v csetid %Y/%m/%d %H:%M:%S username
       
    78 '''
    67 '''
    79 
    68 
    80 from mercurial.i18n import gettext as _
    69 from mercurial.i18n import gettext as _
    81 from mercurial import commands, fancyopts, templater, util
    70 from mercurial import commands, fancyopts, templater, util
    82 from mercurial import cmdutil, context, filelog
    71 from mercurial import cmdutil, context, filelog, localrepo
    83 # findcmd might be in cmdutil or commands
    72 # findcmd might be in cmdutil or commands
    84 # depending on mercurial version
    73 # depending on mercurial version
    85 if hasattr(cmdutil, 'findcmd'):
    74 if hasattr(cmdutil, 'findcmd'):
    86     findcmd = cmdutil.findcmd
    75     findcmd = cmdutil.findcmd
    87 else:
    76 else:
    88     findcmd = commands.findcmd
    77     findcmd = commands.findcmd
    89 import os, re, sys, time
    78 import os, re, shutil, sys, tempfile, time
    90 
    79 
    91 deftemplates = {
    80 deftemplates = {
    92         'Revision': '{node|short}',
    81     'Revision': '{node|short}',
    93         'Author': '{author|user}',
    82     'Author': '{author|user}',
    94         'Date': '{date|utcdate}',
    83     'Date': '{date|utcdate}',
    95         'RCSFile': '{file|basename},v',
    84     'RCSFile': '{file|basename},v',
    96         'Source': '{root}/{file},v',
    85     'Source': '{root}/{file},v',
    97         'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}',
    86     'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}',
    98         'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}',
    87     'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}',
    99         }
    88 }
   100 
    89 
   101 nokwcommands = ('add', 'addremove', 'bundle', 'clone', 'copy', 'export',
    90 nokwcommands = ('add', 'addremove', 'bundle', 'clone', 'copy', 'export',
   102                 'incoming', 'outgoing', 'push', 'remove', 'rename', 'rollback')
    91                 'incoming', 'outgoing', 'push', 'remove', 'rename', 'rollback')
   103 
    92 
   104 def utcdate(date):
    93 def utcdate(date):
   105     '''Returns hgdate in cvs-like UTC format.'''
    94     '''Returns hgdate in cvs-like UTC format.'''
   106     return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0]))
    95     return time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date[0]))
       
    96 
       
    97 def kwdemo(ui, repo, **opts):
       
    98     '''print [keywordmaps] configuration and an expansion example
       
    99     '''
       
   100     log = 'hg keyword config and expansion example'
       
   101     fn = 'demo.txt'
       
   102     ui.setconfig('keyword', fn, '')
       
   103     if opts['default']:
       
   104         kwstatus = 'default'
       
   105         kwmaps = deftemplates
       
   106         if ui.configitems('keywordmaps'):
       
   107             for k, v in kwmaps.items():
       
   108                 ui.setconfig('keywordmaps', k, v)
       
   109     else:
       
   110         kwstatus = 'current'
       
   111         kwmaps = dict(ui.configitems('keywordmaps')) or deftemplates
       
   112     tmpdir = tempfile.mkdtemp('', 'kwdemo.')
       
   113     if ui.verbose:
       
   114         ui.status(_('creating temporary repo at %s\n') % tmpdir)
       
   115     _repo = localrepo.localrepository(ui, path=tmpdir, create=True)
       
   116     reposetup(ui, _repo)
       
   117     ui.status(_('config with %s keyword maps:\n') % kwstatus)
       
   118     ui.write('[keyword]\n%s =\n[keywordmaps\n' % fn)
       
   119     for k, v in kwmaps.items():
       
   120         ui.write('%s = %s\n' % (k, v))
       
   121     path = _repo.wjoin(fn)
       
   122     keywords = '$' + '$\n$'.join(kwmaps.keys()) + '$\n'
       
   123     _repo.wfile(fn, 'w').write(keywords)
       
   124     _repo.add([fn])
       
   125     if ui.verbose:
       
   126         ui.status(_('\n%s keywords written to %s:\n') % (kwstatus, path))
       
   127         ui.write(keywords)
       
   128         ui.status(_("\nhg --repository '%s' commit\n") % tmpdir)
       
   129     _repo.commit(text=log)
       
   130     if ui.verbose:
       
   131         ui.status(_('\n%s keywords expanded in %s:\n') % (kwstatus, path))
       
   132     else:
       
   133         ui.status(_('\n%s keywords expanded:\n') % kwstatus)
       
   134     ui.write(_repo.wread(fn))
       
   135     ui.debug(_('\nremoving temporary repo\n'))
       
   136     shutil.rmtree(tmpdir)
   107 
   137 
   108 def getcmd(ui):
   138 def getcmd(ui):
   109     '''Returns current hg command.'''
   139     '''Returns current hg command.'''
   110     # commands.parse(ui, sys.argv[1:])[0] breaks "hg diff -r"
   140     # commands.parse(ui, sys.argv[1:])[0] breaks "hg diff -r"
   111     try:
   141     try:
   284             finally:
   314             finally:
   285                 if wrelease:
   315                 if wrelease:
   286                     wlock.release()
   316                     wlock.release()
   287 
   317 
   288     repo.__class__ = kwrepo
   318     repo.__class__ = kwrepo
       
   319 
       
   320 
       
   321 cmdtable = {
       
   322     'kwdemo':
       
   323         (kwdemo,
       
   324          [('d', 'default', None, _('use default keyword maps'))],
       
   325          _('hg kwdemo [-d]')),
       
   326 }