Make keyword against current Mercurial available as standalone extension
authorChristian Ebert <blacktrash@gmx.net>
Wed, 07 Nov 2007 13:40:58 +0100
changeset 290 b05795ad5632
parent 288 80a300088654
child 292 783c1310e20f
Make keyword against current Mercurial available as standalone extension
hgkw/keyword.py
tests/test-keyword
tests/test-keyword.out
--- a/hgkw/keyword.py	Tue Nov 06 13:20:39 2007 +0100
+++ b/hgkw/keyword.py	Wed Nov 07 13:40:58 2007 +0100
@@ -80,65 +80,10 @@
         Or, better, use bundle/unbundle to share changes.
 '''
 
-from mercurial import commands, cmdutil, context, fancyopts
+from mercurial import commands, cmdutil, context, dispatch
 from mercurial import filelog, localrepo, revlog, templater, util
-from mercurial.i18n import gettext as _
-import getopt, os.path, re, shutil, sys, tempfile, time
-
-# backwards compatibility hacks
-
-try:
-    # cmdutil.parse moves to dispatch._parse in 18a9fbb5cd78
-    # also avoid name conflict with other dispatch package(s)
-    from mercurial.dispatch import _parse
-except ImportError:
-    try:
-        # commands.parse moves to cmdutil.parse in 0c61124ad877
-        _parse = cmdutil.parse
-    except AttributeError:
-        _parse = commands.parse
-
-def _pathto(repo, f, cwd=None):
-    '''kwfiles behaves similar to status, using pathto since 78b6add1f966.'''
-    try:
-        return repo.pathto(f, cwd)
-    except AttributeError:
-        return f
-
-# commands.parse/cmdutil.parse returned nothing for
-# "hg diff --rev" before 88803a69b24a due to bug in fancyopts
-def _fancyopts(args, options, state):
-    '''Fixed fancyopts from 88803a69b24a.'''
-    long = []
-    short = ''
-    map = {}
-    dt = {}
-    for s, l, d, c in options:
-        pl = l.replace('-', '_')
-        map['-'+s] = map['--'+l] = pl
-        if isinstance(d, list):
-            state[pl] = d[:]
-        else:
-            state[pl] = d
-        dt[pl] = type(d)
-        if (d is not None and d is not True and d is not False and
-            not callable(d)):
-            if s: s += ':'
-            if l: l += '='
-        if s: short = short + s
-        if l: long.append(l)
-    opts, args = getopt.getopt(args, short, long)
-    for opt, arg in opts:
-        if dt[map[opt]] is type(fancyopts): state[map[opt]](state, map[opt], arg)
-        elif dt[map[opt]] is type(1): state[map[opt]] = int(arg)
-        elif dt[map[opt]] is type(''): state[map[opt]] = arg
-        elif dt[map[opt]] is type([]): state[map[opt]].append(arg)
-        elif dt[map[opt]] is type(None): state[map[opt]] = True
-        elif dt[map[opt]] is type(False): state[map[opt]] = True
-    return args
-
-fancyopts.fancyopts = _fancyopts
-
+from mercurial.i18n import _
+import re, shutil, sys, tempfile, time
 
 commands.optionalrepo += ' kwdemo'
 
@@ -179,35 +124,8 @@
         self.re_kw = re.compile(kwpat)
         if self.t:
             templater.common_filters['utcdate'] = utcdate
-            self.t = self._changeset_templater()
-
-    def _changeset_templater(self):
-        '''Backwards compatible cmdutil.changeset_templater.'''
-        # before 1e0b94cfba0e there was an extra "brinfo" argument
-        try:
-            return cmdutil.changeset_templater(self.ui, self.repo,
-                                               False, '', False)
-        except TypeError:
-            return cmdutil.changeset_templater(self.ui, self.repo,
-                                               False, None, '', False)
-
-    def _wwrite(self, f, data, man):
-        '''Makes repo.wwrite backwards compatible.'''
-        # 656e06eebda7 removed file descriptor argument
-        # 67982d3ee76c added flags argument
-        try:
-            self.repo.wwrite(f, data, man.flags(f))
-        except (AttributeError, TypeError):
-            self.repo.wwrite(f, data)
-
-    def _normal(self, files):
-        '''Backwards compatible repo.dirstate.normal/update.'''
-        # 6fd953d5faea introduced dirstate.normal()
-        try:
-            for f in files:
-                self.repo.dirstate.normal(f)
-        except AttributeError:
-            self.repo.dirstate.update(files, 'n')
+            self.t = cmdutil.changeset_templater(self.ui, self.repo,
+                                                 False, '', False)
 
     def kwsub(self, mobj):
         '''Substitutes keyword using corresponding template.'''
@@ -238,7 +156,8 @@
 
     def process(self, node, data):
         '''Returns a tuple: data, count.
-        Count is number of keywords/keyword substitutions.
+        Count is number of keywords/keyword substitutions, indicates
+        to caller whether to act on file containing data.
         Keywords in data are expanded, if templater was initialized.'''
         if util.binary(data):
             return data, None
@@ -259,15 +178,13 @@
         expand = self.t is not None
         action = ('shrinking', 'expanding')[expand]
         notify = (self.ui.note, self.ui.debug)[commit]
-        overwritten = []
         for f in candidates:
             fp = self.repo.file(f, kwexp=expand, kwmatch=True)
             data, kwfound = fp.kwctread(man[f])
             if kwfound:
                 notify(_('overwriting %s %s keywords\n') % (f, action))
-                self._wwrite(f, data, man)
-                overwritten.append(f)
-        self._normal(overwritten)
+                self.repo.wwrite(f, data, man.flags(f))
+                self.repo.dirstate.normal(f)
 
 class kwfilelog(filelog.filelog):
     '''
@@ -303,6 +220,8 @@
         return revlog.revlog.cmp(self, node, text)
 
 def _status(ui, repo, *pats, **opts):
+    '''Bails out if [keyword] configuration is not active.
+    Returns status of working directory.'''
     if hasattr(ui, 'kwfmatcher'):
         files, match, anypats = cmdutil.matchpats(repo, pats, opts)
         return repo.status(files=files, match=match, list_clean=True)
@@ -440,9 +359,7 @@
     else:
         files = modified + added + clean
     files.sort()
-    # use the full definition of repo._link for backwards compatibility
-    kwfiles = [f for f in files if ui.kwfmatcher(f)
-               and not os.path.islink(repo.wjoin(f))]
+    kwfiles = [f for f in files if ui.kwfmatcher(f) and not repo._link(f)]
     cwd = pats and repo.getcwd() or ''
     allf = opts['all']
     ignore = opts['ignore']
@@ -450,11 +367,11 @@
     if not ignore:
         format = ('%s\n', 'K %s\n')[flag]
         for k in kwfiles:
-            ui.write(format % _pathto(repo, k, cwd))
+            ui.write(format % repo.pathto(k, cwd))
     if allf or ignore:
         format = ('%s\n', 'I %s\n')[flag]
         for i in [f for f in files if f not in kwfiles]:
-            ui.write(format % _pathto(repo, i, cwd))
+            ui.write(format % repo.pathto(i, cwd))
 
 def shrink(ui, repo, *pats, **opts):
     '''revert expanded keywords in working directory
@@ -481,7 +398,8 @@
                     'grep', 'identify', 'incoming', 'init', 'outgoing', 'push',
                     'remove', 'rename', 'rollback', 'convert']
 
-    if not repo.local() or _parse(ui, sys.argv[1:])[0] in nokwcommands:
+    if (not repo.local() or
+        dispatch._parse(ui, sys.argv[1:])[0] in nokwcommands):
         return
 
     inc, exc = [], ['.hgtags']
@@ -504,39 +422,18 @@
                 return kwfilelog(self.sopener, f, kwt)
             return filelog.filelog(self.sopener, f)
 
-        def _commit(self, files, text, user, date, match, force, lock, wlock,
-                    force_editor, p1, p2, extra):
-            '''Private commit wrapper for backwards compatibility.'''
+        def commit(self, files=None, text='', user=None, date=None,
+                   match=util.always, force=False, force_editor=False,
+                   p1=None, p2=None, extra={}):
+            wlock = lock = None
             try:
-                return super(kwrepo, self).commit(files=files, text=text,
-                                                  user=user, date=date,
-                                                  match=match, force=force,
-                                                  lock=lock, wlock=wlock,
-                                                  force_editor=force_editor,
-                                                  p1=p1, p2=p2, extra=extra)
-            except TypeError:
-                return super(kwrepo, self).commit(files=files, text=text,
-                                                  user=user, date=date,
-                                                  match=match, force=force,
-                                                  force_editor=force_editor,
-                                                  p1=p1, p2=p2, extra=extra)
-
-        def commit(self, files=None, text='', user=None, date=None,
-                   match=util.always, force=False, lock=None, wlock=None,
-                   force_editor=False, p1=None, p2=None, extra={}):
-            # (w)lock arguments removed in 126f527b3ba3
-            # so they are None or what was passed to commit
-            # use private _(w)lock for deletion
-            _lock = lock
-            _wlock = wlock
-            del wlock, lock
-            try:
-                if not _wlock:
-                    _wlock = self.wlock()
-                if not _lock:
-                    _lock = self.lock()
-                node = self._commit(files, text, user, date, match, force,
-                                    _lock, _wlock, force_editor, p1, p2, extra)
+                wlock = self.wlock()
+                lock = self.lock()
+                node = super(kwrepo,
+                             self).commit(files=files, text=text, user=user,
+                                          date=date, match=match, force=force,
+                                          force_editor=force_editor,
+                                          p1=p1, p2=p2, extra=extra)
                 if node is not None:
                     cl = self.changelog.read(node)
                     mn = self.manifest.read(cl[0])
@@ -547,7 +444,7 @@
                         _overwrite(ui, self, candidates, node, mn, True, True)
                 return node
             finally:
-                del _wlock, _lock
+                del wlock, lock
 
     repo.__class__ = kwrepo
 
--- a/tests/test-keyword	Tue Nov 06 13:20:39 2007 +0100
+++ b/tests/test-keyword	Wed Nov 07 13:40:58 2007 +0100
@@ -9,9 +9,7 @@
 EOF
 
 echo % help
-# grep for backwards compatibility
-hg help keyword \
-| grep -E -v '^list of commands|hg -v help keyword|^$'
+hg help keyword
 
 echo % hg kwdemo
 hg --quiet kwdemo --default \
@@ -35,31 +33,33 @@
 echo 'do not process $Id:' >> a
 echo 'xxx $' >> a
 echo 'ignore $Id$' > b
+ln -s a sym
 echo % cat
-cat a b
+cat sym a b
 
 echo % default keyword expansion
 echo % commit
-hg --debug commit -A -mab -d '0 0' -u 'User Name <user@example.com>'
+hg --debug commit -A -mabsym -d '0 0' -u 'User Name <user@example.com>'
 echo % status
 hg status
 echo % identify
 hg --quiet identify
 echo % cat
-cat a b
+cat sym a b
 echo % hg cat
-hg cat a b
+hg cat sym a b
 
+echo
 echo % touch
 touch a b
 echo % status
 hg status
 
-rm a b
+rm sym a b
 echo % update
 hg update
 echo % cat
-cat a b
+cat sym a b
 
 echo % copy
 hg cp a c
@@ -101,10 +101,11 @@
 EOF
 
 echo % cat
-cat a b
+cat sym a b
 echo % hg cat
-hg cat a b
+hg cat sym a b
 
+echo
 echo '$Xinfo$' >> a
 cat <<EOF >> log
 firstline
@@ -112,8 +113,7 @@
 EOF
 
 echo % interrupted commit
-# redirection and grep for backwards compatibility
-HGEDITOR=false hg commit 2>&1 | grep -v 'edit failed:'
+HGEDITOR=false hg commit
 echo % status
 hg status
 
@@ -124,9 +124,10 @@
 hg status
 
 echo % cat
-cat a b
+cat sym a b
 echo % hg cat
-hg cat a b
+hg cat sym a b
+echo
 
 echo % remove
 hg remove a
@@ -151,8 +152,8 @@
 default = ../Test
 EOF
 echo % incoming
-# remove path to temp dir for backwards compatibility
-hg incoming | grep -v '^comparing with'
+# remove path to temp dir
+hg incoming | sed -e 's/^\(comparing with \).*\(test-keyword.*\)/\1\2/'
 
 cd ../Test
 echo % kwexpand/kwshrink on selected files
@@ -181,12 +182,13 @@
 cp a u
 hg --verbose kwshrink
 echo % cat
-cat a b
+cat sym a b
 echo % hg cat
-hg cat a b
-
+hg cat sym a b
+echo
 rm $HGRCPATH
 echo % cat
-cat a b
+cat sym a b
 echo % hg cat
-hg cat a b
+hg cat sym a b
+echo
--- a/tests/test-keyword.out	Tue Nov 06 13:20:39 2007 +0100
+++ b/tests/test-keyword.out	Wed Nov 07 13:40:58 2007 +0100
@@ -1,39 +1,57 @@
 % help
 keyword extension - keyword expansion in local repositories
+
 This extension expands RCS/CVS-like or self-customized $Keywords$
 in tracked text files selected by your configuration.
+
 Keywords are only expanded in local repositories and not stored in
 the change history. The mechanism can be regarded as a convenience
 for the current user or for archive distribution.
+
 Configuration is done in the [keyword] and [keywordmaps] sections
 of hgrc files.
+
 Example:
+
     [keyword]
     # expand keywords in every python file except those matching "x*"
     **.py =
     x*    = ignore
+
 Note: the more specific you are in your filename patterns
       the less you lose speed in huge repos.
+
 For [keywordmaps] template mapping and expansion demonstration and
 control run "hg kwdemo".
+
 An additional date template filter {date|utcdate} is provided.
+
 The default template mappings (view with "hg kwdemo -d") can be replaced
 with customized keywords and templates.
 Again, run "hg kwdemo" to control the results of your config changes.
+
 Before changing/disabling active keywords, run "hg kwshrink" to avoid
 the risk of inadvertedly storing expanded keywords in the change history.
+
 To force expansion after enabling it, or a configuration change, run
 "hg kwexpand".
+
 Expansions spanning more than one line and incremental expansions,
 like CVS' $Log$, are not supported. A keyword template map
 "Log = {desc}" expands to the first line of the changeset description.
+
 Caveat: "hg import" fails if the patch context contains an active
         keyword. In that case run "hg kwshrink", and then reimport.
         Or, better, use bundle/unbundle to share changes.
+
+list of commands:
+
  kwdemo     print [keywordmaps] configuration and an expansion example
  kwexpand   expand keywords in working directory
  kwfiles    print files currently configured for keyword expansion
  kwshrink   revert expanded keywords in working directory
+
+use "hg -v help keyword" to show aliases and global options
 % hg kwdemo
 [extensions]
 hgext.keyword = 
@@ -74,33 +92,45 @@
 expand $Id$
 do not process $Id:
 xxx $
+expand $Id$
+do not process $Id:
+xxx $
 ignore $Id$
 % default keyword expansion
 % commit
 adding a
 adding b
+adding sym
 a
 b
+sym
 overwriting a expanding keywords
 % status
 % identify
-7f0665a496fd
+f782df5f9602
 % cat
-expand $Id: a,v 7f0665a496fd 1970/01/01 00:00:00 user $
+expand $Id: a,v f782df5f9602 1970/01/01 00:00:00 user $
+do not process $Id:
+xxx $
+expand $Id: a,v f782df5f9602 1970/01/01 00:00:00 user $
 do not process $Id:
 xxx $
 ignore $Id$
 % hg cat
-expand $Id: a,v 7f0665a496fd 1970/01/01 00:00:00 user $
+expand $Id: a,v f782df5f9602 1970/01/01 00:00:00 user $
 do not process $Id:
 xxx $
 ignore $Id$
+a
 % touch
 % status
 % update
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 % cat
-expand $Id: a,v 7f0665a496fd 1970/01/01 00:00:00 user $
+expand $Id: a,v f782df5f9602 1970/01/01 00:00:00 user $
+do not process $Id:
+xxx $
+expand $Id: a,v f782df5f9602 1970/01/01 00:00:00 user $
 do not process $Id:
 xxx $
 ignore $Id$
@@ -113,10 +143,10 @@
  c: copy a:0045e12f6c5791aac80ca6cbfd97709a88307292
 overwriting c expanding keywords
 % cat a c
-expand $Id: a,v 7f0665a496fd 1970/01/01 00:00:00 user $
+expand $Id: a,v f782df5f9602 1970/01/01 00:00:00 user $
 do not process $Id:
 xxx $
-expand $Id: c,v 6a127771f5db 1970/01/01 00:00:01 user $
+expand $Id: c,v 0ba462c0f077 1970/01/01 00:00:01 user $
 do not process $Id:
 xxx $
 % touch copied c after 1 second
@@ -125,10 +155,10 @@
 a
 c
 % diff --rev
-diff -r 7f0665a496fd c
+diff -r f782df5f9602 c
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
 @@ -0,0 +1,3 @@
-+expand $Id: c,v 6a127771f5db 1970/01/01 00:00:01 user $
++expand $Id: c,v 0ba462c0f077 1970/01/01 00:00:01 user $
 +do not process $Id:
 +xxx $
 % rollback
@@ -149,18 +179,23 @@
 Xinfo = {author}: {desc}
 $Xinfo: test: hg keyword config and expansion example $
 % cat
-expand $Id: a,v 7f0665a496fd 1970/01/01 00:00:00 user $
+expand $Id: a,v f782df5f9602 1970/01/01 00:00:00 user $
+do not process $Id:
+xxx $
+expand $Id: a,v f782df5f9602 1970/01/01 00:00:00 user $
 do not process $Id:
 xxx $
 ignore $Id$
 % hg cat
-expand $Id: a 7f0665a496fd Thu, 01 Jan 1970 00:00:00 +0000 user $
+expand $Id: a f782df5f9602 Thu, 01 Jan 1970 00:00:00 +0000 user $
 do not process $Id:
 xxx $
 ignore $Id$
+a
 % interrupted commit
 transaction abort!
 rollback completed
+abort: edit failed: false exited with status 1
 % status
 M a
 ? log
@@ -169,17 +204,22 @@
 overwriting a expanding keywords
 % status
 % cat
-expand $Id: a 576a35651b0a Thu, 01 Jan 1970 00:00:02 +0000 user $
+expand $Id: a 0729690beff6 Thu, 01 Jan 1970 00:00:02 +0000 user $
+do not process $Id:
+xxx $
+$Xinfo: User Name <user@example.com>: firstline $
+expand $Id: a 0729690beff6 Thu, 01 Jan 1970 00:00:02 +0000 user $
 do not process $Id:
 xxx $
 $Xinfo: User Name <user@example.com>: firstline $
 ignore $Id$
 % hg cat
-expand $Id: a 576a35651b0a Thu, 01 Jan 1970 00:00:02 +0000 user $
+expand $Id: a 0729690beff6 Thu, 01 Jan 1970 00:00:02 +0000 user $
 do not process $Id:
 xxx $
 $Xinfo: User Name <user@example.com>: firstline $
 ignore $Id$
+a
 % remove
 % status
 % rollback
@@ -188,7 +228,7 @@
 R a
 % revert a
 % cat a
-expand $Id: a 576a35651b0a Thu, 01 Jan 1970 00:00:02 +0000 user $
+expand $Id: a 0729690beff6 Thu, 01 Jan 1970 00:00:02 +0000 user $
 do not process $Id:
 xxx $
 $Xinfo: User Name <user@example.com>: firstline $
@@ -197,11 +237,12 @@
 adding changesets
 adding manifests
 adding file changes
-added 1 changesets with 2 changes to 2 files
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+added 1 changesets with 3 changes to 3 files
+3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 % incoming
+comparing with test-keyword/Test-a/../Test
 searching for changes
-changeset:   1:576a35651b0a
+changeset:   1:0729690beff6
 tag:         tip
 user:        User Name <user@example.com>
 date:        Thu Jan 01 00:00:02 1970 +0000
@@ -217,7 +258,7 @@
  x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
 overwriting x/a expanding keywords
 % cat a
-expand $Id: x/a 2d19a72f00da Thu, 01 Jan 1970 00:00:03 +0000 user $
+expand $Id: x/a f27c134d2d9b Thu, 01 Jan 1970 00:00:03 +0000 user $
 do not process $Id:
 xxx $
 $Xinfo: User Name <user@example.com>: xa $
@@ -239,18 +280,27 @@
 do not process $Id:
 xxx $
 $Xinfo$
+expand $Id$
+do not process $Id:
+xxx $
+$Xinfo$
 ignore $Id$
 % hg cat
-expand $Id: a 576a35651b0a Thu, 01 Jan 1970 00:00:02 +0000 user $
+expand $Id: a 0729690beff6 Thu, 01 Jan 1970 00:00:02 +0000 user $
 do not process $Id:
 xxx $
 $Xinfo: User Name <user@example.com>: firstline $
 ignore $Id$
+a
 % cat
 expand $Id$
 do not process $Id:
 xxx $
 $Xinfo$
+expand $Id$
+do not process $Id:
+xxx $
+$Xinfo$
 ignore $Id$
 % hg cat
 expand $Id$
@@ -258,3 +308,4 @@
 xxx $
 $Xinfo$
 ignore $Id$
+a