Implement kwshrink/kwexpand commands to deal with config, import issues kwmap-templates
authorChristian Ebert <blacktrash@gmx.net>
Tue, 17 Jul 2007 14:15:47 +0200
branchkwmap-templates
changeset 185 bc5cd6cf69bc
parent 184 30b3e6a09a9d
child 186 c1b7b1d052de
Implement kwshrink/kwexpand commands to deal with config, import issues
hgkw/keyword.py
--- a/hgkw/keyword.py	Tue Jul 17 09:45:36 2007 +0200
+++ b/hgkw/keyword.py	Tue Jul 17 14:15:47 2007 +0200
@@ -20,9 +20,6 @@
 # Keyword expansion is based on Mercurial's changeset template mappings.
 # The extension provides an additional UTC-date filter ({date|utcdate}).
 #
-# The user has the choice either to create his own keywords and their
-# expansions or to use the CVS-like default ones.
-#
 # Expansions spanning more than one line are truncated to their first line.
 # Incremental expansion (like CVS' $Log$) is not supported.
 #
@@ -37,18 +34,12 @@
 
 '''keyword expansion in local repositories
 
-This extension expands RCS/CVS-like or self-customized keywords in
-the text files selected by your configuration.
+This extension expands RCS/CVS-like or self-customized $Keywords$
+in the text files selected by your configuration.
 
 Keywords are only expanded in local repositories and not logged by
 Mercurial internally. The mechanism can be regarded as a convenience
-for the current user and may be turned off anytime.
-
-An additional date template filter {date|utcdate} is provided.
-
-Caveat: "hg import" might fail if the patches were exported from a
-repo with a different/no keyword setup, whereas "hg unbundle" is
-safe.
+for the current user or archive distribution.
 
 Configuration is done in the [keyword] and [keywordmaps] sections of
 hgrc files.
@@ -58,17 +49,35 @@
     hgext.keyword =
 
     [keyword]
-    # expand keywords in every python file,
-    # except those matching "x*"
+    # expand keywords in every python file except those matching "x*"
     **.py =
     x* = ignore
 
-For [keywordmaps] demonstration run "hg kwdemo".
+Note: the more specific you are in your [keyword] filename patterns
+      the less you lose speed in huge repos.
+
+For a [keywordmaps] template mapping and expansion demonstration
+run "hg kwdemo".
+
+An additional date template filter {date|utcdate} is provided.
+
+You can replace the default template mappings with customized keywords
+and templates of your choice.
+Again, run "hg kwdemo" to control the results of your config changes.
+
+When you change keyword configuration, especially the active keywords,
+and do not want to store expanded keywords in change history, run
+"hg kwshrink", and then change configuration.
+
+Caveat: "hg import" fails if the patch context contains an active
+        keyword. In that case run "hg kwshrink", reimport, and then
+        "hg kwexpand".
+        Or, better, use bundle/unbundle to share changes.
 '''
 
+from mercurial import commands, cmdutil, context, fancyopts
+from mercurial import filelog, localrepo, templater, util, hg
 from mercurial.i18n import gettext as _
-from mercurial import commands, fancyopts, templater, util
-from mercurial import cmdutil, context, filelog, localrepo
 # findcmd might be in cmdutil or commands
 # depending on mercurial version
 if hasattr(cmdutil, 'findcmd'):
@@ -77,6 +86,8 @@
     findcmd = commands.findcmd
 import os, re, shutil, sys, tempfile, time
 
+commands.optionalrepo += ' kwdemo'
+
 deftemplates = {
     'Revision': '{node|short}',
     'Author': '{author|user}',
@@ -170,18 +181,27 @@
             return text
         return self.re_kw.sub(r'$\1$', text)
 
-    def overwrite(self, candidates, mn):
+    def overwrite(self, candidates, manifest, expand=True, commit=True):
         '''Overwrites candidates in working dir expanding keywords.'''
+        if expand:
+            sub = self.kwsub
+            action = 'expanding'
+        else:
+            sub = r'$\1$'
+            action = 'shrinking'
+        if not commit:
+            notify = self.ui.note
+        else:
+            notify = self.ui.debug
         files = []
-        m = self.repo.manifest.read(mn)
         for f in candidates:
             data = self.repo.wread(f)
             if not util.binary(data):
                 self.path = f
-                data, kwct = self.re_kw.subn(self.kwsub, data)
+                data, kwct = self.re_kw.subn(sub, data)
                 if kwct:
-                    self.ui.debug(_('overwriting %s expanding keywords\n') % f)
-                    self.repo.wwrite(f, data, m.flags(f))
+                    notify(_('overwriting %s %s keywords\n') % (f, action))
+                    self.repo.wwrite(f, data, manifest.flags(f))
                     files.append(f)
         if files:
             self.repo.dirstate.update(files, 'n')
@@ -213,9 +233,57 @@
             return t2 != text
         return super(kwfilelog, self).cmp(node, text)
 
+def overwrite(ui, repo, files=None, expand=False):
+    '''Expands/shrinks keywords in working directory.'''
+    wlock = repo.wlock()
+    try:
+        ctx = repo.changectx()
+        if not ctx:
+            raise hg.RepoError(_('no changeset found'))
+        for changed in repo.status()[:4]:
+            if changed:
+                raise util.Abort(_('local changes detected'))
+        kwfmatcher = keywordmatcher(ui, repo)
+        if kwfmatcher is None:
+            ui.warn(_('no files configured for keyword expansion\n'))
+            return
+        m = ctx.manifest()
+        if files:
+            files = [f for f in files if f in m.keys()]
+        else:
+            files = m.keys()
+        files = [f for f in files if kwfmatcher(f) and not os.path.islink(f)]
+        if not files:
+            ui.warn(_('given files not tracked or '
+                      'not configured for expansion\n'))
+            return
+        kwt = kwtemplater(ui, repo, node=ctx.node())
+        kwt.overwrite(files, m, expand=expand, commit=False)
+    finally:
+        wlock.release()
+
+
+def shrink(ui, repo, *args):
+    '''revert expanded keywords in working directory
+
+    run before:
+               disabling keyword expansion
+               changing keyword expansion configuration
+    or if you experience problems with "hg import"
+    '''
+    overwrite(ui, repo, args, expand=False)
+
+def expand(ui, repo, *args):
+    '''expand keywords in working directory
+
+    run after (re)enabling keyword expansion
+    '''
+    overwrite(ui, repo, args, expand=True)
 
 def demo(ui, repo, **opts):
     '''print [keywordmaps] configuration and an expansion example
+
+    Show current or default keyword template maps and their expansion
     '''
     msg = 'hg keyword config and expansion example'
     fn = 'demo.txt'
@@ -308,8 +376,9 @@
                               and f not in removed
                               and not os.path.islink(self.wjoin(f))]
                 if candidates:
+                    m = self.manifest.read(cl[0])
                     kwt = kwtemplater(ui, self, node=node)
-                    kwt.overwrite(candidates, cl[0])
+                    kwt.overwrite(candidates, m)
                 return node
             finally:
                 if wrelease:
@@ -321,6 +390,8 @@
 cmdtable = {
     'kwdemo':
         (demo,
-         [('d', 'default', None, _('use default keyword maps'))],
+         [('d', 'default', None, _('show default keyword template maps'))],
          _('hg kwdemo [-d]')),
+    'kwshrink': (shrink, [], _('hg kwshrink [NAME] ...')),
+    'kwexpand': (expand, [], _('hg kwexpand [NAME] ...')),
 }