hgkw/keyword.py
branch0.9.2compat
changeset 575 fdb3a5bf2c5c
parent 574 9353633b1611
child 581 43bed08dda00
equal deleted inserted replaced
574:9353633b1611 575:fdb3a5bf2c5c
     1 # keyword.py - $Keyword$ expansion for Mercurial
     1 # keyword.py - $Keyword$ expansion for Mercurial
     2 #
     2 #
     3 # Copyright 2007, 2008 Christian Ebert <blacktrash@gmx.net>
     3 # Copyright 2007, 2008 Christian Ebert <blacktrash@gmx.net>
     4 #
     4 #
     5 # This software may be used and distributed according to the terms
     5 # This software may be used and distributed according to the terms of the
     6 # of the GNU General Public License, incorporated herein by reference.
     6 # GNU General Public License version 2, incorporated herein by reference.
     7 #
     7 #
     8 # $Id$
     8 # $Id$
     9 #
     9 #
    10 # Keyword expansion hack against the grain of a DSCM
    10 # Keyword expansion hack against the grain of a DSCM
    11 #
    11 #
    12 # There are many good reasons why this is not needed in a distributed
    12 # There are many good reasons why this is not needed in a distributed
    13 # SCM, still it may be useful in very small projects based on single
    13 # SCM, still it may be useful in very small projects based on single
    14 # files (like LaTeX packages), that are mostly addressed to an audience
    14 # files (like LaTeX packages), that are mostly addressed to an
    15 # not running a version control system.
    15 # audience not running a version control system.
    16 #
    16 #
    17 # For in-depth discussion refer to
    17 # For in-depth discussion refer to
    18 # <http://www.selenic.com/mercurial/wiki/index.cgi/KeywordPlan>.
    18 # <http://www.selenic.com/mercurial/wiki/index.cgi/KeywordPlan>.
    19 #
    19 #
    20 # Keyword expansion is based on Mercurial's changeset template mappings.
    20 # Keyword expansion is based on Mercurial's changeset template mappings.
    34 #
    34 #
    35 # Run "hg help keyword" and "hg kwdemo" to get info on configuration.
    35 # Run "hg help keyword" and "hg kwdemo" to get info on configuration.
    36 
    36 
    37 '''keyword expansion in local repositories
    37 '''keyword expansion in local repositories
    38 
    38 
    39 This extension expands RCS/CVS-like or self-customized $Keywords$
    39 This extension expands RCS/CVS-like or self-customized $Keywords$ in
    40 in tracked text files selected by your configuration.
    40 tracked text files selected by your configuration.
    41 
    41 
    42 Keywords are only expanded in local repositories and not stored in
    42 Keywords are only expanded in local repositories and not stored in the
    43 the change history. The mechanism can be regarded as a convenience
    43 change history. The mechanism can be regarded as a convenience for the
    44 for the current user or for archive distribution.
    44 current user or for archive distribution.
    45 
    45 
    46 Configuration is done in the [keyword] and [keywordmaps] sections
    46 Configuration is done in the [keyword] and [keywordmaps] sections of
    47 of hgrc files.
    47 hgrc files.
    48 
    48 
    49 Example:
    49 Example:
    50 
    50 
    51     [keyword]
    51     [keyword]
    52     # expand keywords in every python file except those matching "x*"
    52     # expand keywords in every python file except those matching "x*"
    53     **.py =
    53     **.py =
    54     x*    = ignore
    54     x*    = ignore
    55 
    55 
    56 Note: the more specific you are in your filename patterns
    56 Note: the more specific you are in your filename patterns
    57       the less you lose speed in huge repos.
    57       the less you lose speed in huge repositories.
    58 
    58 
    59 For [keywordmaps] template mapping and expansion demonstration and
    59 For [keywordmaps] template mapping and expansion demonstration and
    60 control run "hg kwdemo".
    60 control run "hg kwdemo".
    61 
    61 
    62 An additional date template filter {date|utcdate} is provided.
    62 An additional date template filter {date|utcdate} is provided.
    63 
    63 
    64 The default template mappings (view with "hg kwdemo -d") can be replaced
    64 The default template mappings (view with "hg kwdemo -d") can be
    65 with customized keywords and templates.
    65 replaced with customized keywords and templates. Again, run "hg
    66 Again, run "hg kwdemo" to control the results of your config changes.
    66 kwdemo" to control the results of your config changes.
    67 
    67 
    68 Before changing/disabling active keywords, run "hg kwshrink" to avoid
    68 Before changing/disabling active keywords, run "hg kwshrink" to avoid
    69 the risk of inadvertedly storing expanded keywords in the change history.
    69 the risk of inadvertently storing expanded keywords in the change
       
    70 history.
    70 
    71 
    71 To force expansion after enabling it, or a configuration change, run
    72 To force expansion after enabling it, or a configuration change, run
    72 "hg kwexpand".
    73 "hg kwexpand".
    73 
    74 
    74 Also, when committing with the record extension or using mq's qrecord, be aware
    75 Also, when committing with the record extension or using mq's qrecord,
    75 that keywords cannot be updated. Again, run "hg kwexpand" on the files in
    76 be aware that keywords cannot be updated. Again, run "hg kwexpand" on
    76 question to update keyword expansions after all changes have been checked in.
    77 the files in question to update keyword expansions after all changes
       
    78 have been checked in.
    77 
    79 
    78 Expansions spanning more than one line and incremental expansions,
    80 Expansions spanning more than one line and incremental expansions,
    79 like CVS' $Log$, are not supported. A keyword template map
    81 like CVS' $Log$, are not supported. A keyword template map
    80 "Log = {desc}" expands to the first line of the changeset description.
    82 "Log = {desc}" expands to the first line of the changeset description.
    81 
    83 
   444 
   446 
   445 
   447 
   446 def demo(ui, repo, *args, **opts):
   448 def demo(ui, repo, *args, **opts):
   447     '''print [keywordmaps] configuration and an expansion example
   449     '''print [keywordmaps] configuration and an expansion example
   448 
   450 
   449     Show current, custom, or default keyword template maps
   451     Show current, custom, or default keyword template maps and their
   450     and their expansions.
   452     expansions.
   451 
   453 
   452     Extend current configuration by specifying maps as arguments
   454     Extend current configuration by specifying maps as arguments and
   453     and optionally by reading from an additional hgrc file.
   455     optionally by reading from an additional hgrc file.
   454 
   456 
   455     Override current keyword template maps with "default" option.
   457     Override current keyword template maps with "default" option.
   456     '''
   458     '''
   457     def demostatus(stat):
   459     def demostatus(stat):
   458         ui.status(_('\n\t%s\n') % stat)
   460         ui.status(_('\n\t%s\n') % stat)
   465     msg = 'hg keyword config and expansion example'
   467     msg = 'hg keyword config and expansion example'
   466     kwstatus = 'current'
   468     kwstatus = 'current'
   467     fn = 'demo.txt'
   469     fn = 'demo.txt'
   468     branchname = 'demobranch'
   470     branchname = 'demobranch'
   469     tmpdir = tempfile.mkdtemp('', 'kwdemo.')
   471     tmpdir = tempfile.mkdtemp('', 'kwdemo.')
   470     ui.note(_('creating temporary repo at %s\n') % tmpdir)
   472     ui.note(_('creating temporary repository at %s\n') % tmpdir)
   471     repo = localrepo.localrepository(ui, tmpdir, True)
   473     repo = localrepo.localrepository(ui, tmpdir, True)
   472     ui.setconfig('keyword', fn, '')
   474     ui.setconfig('keyword', fn, '')
   473     if args or opts.get('rcfile'):
   475     if args or opts.get('rcfile'):
   474         kwstatus = 'custom'
   476         kwstatus = 'custom'
   475     if opts.get('rcfile'):
   477     if opts.get('rcfile'):
   518     ui.note('hg -R "%s" ci -m "%s"\n' % (tmpdir, msg))
   520     ui.note('hg -R "%s" ci -m "%s"\n' % (tmpdir, msg))
   519     repo.commit(text=msg)
   521     repo.commit(text=msg)
   520     fmt = ui.verbose and ' in %s' % path or ''
   522     fmt = ui.verbose and ' in %s' % path or ''
   521     demostatus('%s keywords expanded%s' % (kwstatus, fmt))
   523     demostatus('%s keywords expanded%s' % (kwstatus, fmt))
   522     ui.write(repo.wread(fn))
   524     ui.write(repo.wread(fn))
   523     ui.debug(_('\nremoving temporary repo %s\n') % tmpdir)
   525     ui.debug(_('\nremoving temporary repository %s\n') % tmpdir)
   524     shutil.rmtree(tmpdir, ignore_errors=True)
   526     shutil.rmtree(tmpdir, ignore_errors=True)
   525 
   527 
   526 def expand(ui, repo, *pats, **opts):
   528 def expand(ui, repo, *pats, **opts):
   527     '''expand keywords in the working directory
   529     '''expand keywords in the working directory
   528 
   530 
   534     _kwfwrite(ui, repo, True, *pats, **opts)
   536     _kwfwrite(ui, repo, True, *pats, **opts)
   535 
   537 
   536 def files(ui, repo, *pats, **opts):
   538 def files(ui, repo, *pats, **opts):
   537     '''print files currently configured for keyword expansion
   539     '''print files currently configured for keyword expansion
   538 
   540 
   539     Crosscheck which files in working directory are potential targets for
   541     Crosscheck which files in working directory are potential targets
   540     keyword expansion.
   542     for keyword expansion. That is, files matched by [keyword] config
   541     That is, files matched by [keyword] config patterns but not symlinks.
   543     patterns but not symlinks.
   542     '''
   544     '''
   543     kwt = kwtools['templater']
   545     kwt = kwtools['templater']
   544     status = _status(ui, repo, kwt, opts.get('untracked'), *pats, **opts)
   546     status = _status(ui, repo, kwt, opts.get('untracked'), *pats, **opts)
   545     modified, added, removed, deleted, unknown, ignored, clean = status
   547     modified, added, removed, deleted, unknown, ignored, clean = status
   546     try:
   548     try:
   574             ui.write(fmt % _pathto(repo, f, cwd))
   576             ui.write(fmt % _pathto(repo, f, cwd))
   575 
   577 
   576 def shrink(ui, repo, *pats, **opts):
   578 def shrink(ui, repo, *pats, **opts):
   577     '''revert expanded keywords in the working directory
   579     '''revert expanded keywords in the working directory
   578 
   580 
   579     Run before changing/disabling active keywords
   581     Run before changing/disabling active keywords or if you experience
   580     or if you experience problems with "hg import" or "hg merge".
   582     problems with "hg import" or "hg merge".
   581 
   583 
   582     kwshrink refuses to run if given files contain local changes.
   584     kwshrink refuses to run if given files contain local changes.
   583     '''
   585     '''
   584     # 3rd argument sets expansion to False
   586     # 3rd argument sets expansion to False
   585     _kwfwrite(ui, repo, False, *pats, **opts)
   587     _kwfwrite(ui, repo, False, *pats, **opts)
   589     '''Sets up repo as kwrepo for keyword substitution.
   591     '''Sets up repo as kwrepo for keyword substitution.
   590     Overrides file method to return kwfilelog instead of filelog
   592     Overrides file method to return kwfilelog instead of filelog
   591     if file matches user configuration.
   593     if file matches user configuration.
   592     Wraps commit to overwrite configured files with updated
   594     Wraps commit to overwrite configured files with updated
   593     keyword substitutions.
   595     keyword substitutions.
   594     This is done for local repos only, and only if there are
   596     Monkeypatches patch and webcommands.'''
   595     files configured at all for keyword substitution.'''
       
   596 
   597 
   597     try:
   598     try:
   598         if (not repo.local() or kwtools['hgcmd'] in nokwcommands.split()
   599         if (not repo.local() or kwtools['hgcmd'] in nokwcommands.split()
   599             or '.hg' in repo.root.split(os.sep)
   600             or '.hg' in repo.root.split(os.sep)
   600             or repo._url.startswith('bundle:')):
   601             or repo._url.startswith('bundle:')):