pushkey: add hooks for pushkey/listkeys
authorBrodie Rao <brodie@bitheap.org>
Sun, 01 May 2011 11:12:36 +0200
changeset 14102 7f45b1911893
parent 14101 0c5228836fcd
child 14103 a36e8c99d51c
pushkey: add hooks for pushkey/listkeys
doc/hgrc.5.txt
mercurial/localrepo.py
tests/test-hook.t
--- a/doc/hgrc.5.txt	Sat Apr 30 12:02:09 2011 -0500
+++ b/doc/hgrc.5.txt	Sun May 01 11:12:36 2011 +0200
@@ -634,6 +634,10 @@
   Run before starting a local commit. Exit status 0 allows the
   commit to proceed. Non-zero status will cause the commit to fail.
   Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
+``prelistkeys``
+  Run before listing pushkeys (like bookmarks) in the
+  repository. Non-zero status will cause failure. The key namespace is
+  in ``$HG_NAMESPACE``.
 ``preoutgoing``
   Run before collecting changes to send from the local repository to
   another. Non-zero status will cause failure. This lets you prevent
@@ -643,6 +647,12 @@
   ``$HG_SOURCE``. If "serve", operation is happening on behalf of remote
   SSH or HTTP repository. If "push", "pull" or "bundle", operation
   is happening on behalf of repository on same system.
+``prepushkey``
+  Run before a pushkey (like a bookmark) is added to the
+  repository. Non-zero status will cause the key to be rejected. The
+  key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
+  the old value (if any) is in ``$HG_OLD``, and the new value is in
+  ``$HG_NEW``.
 ``pretag``
   Run before creating a tag. Exit status 0 allows the tag to be
   created. Non-zero status will cause the tag to fail. ID of
@@ -669,6 +679,15 @@
   the update to proceed. Non-zero status will prevent the update.
   Changeset ID of first new parent is in ``$HG_PARENT1``. If merge, ID
   of second new parent is in ``$HG_PARENT2``.
+``listkeys``
+  Run after listing pushkeys (like bookmarks) in the repository. The
+  key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
+  dictionary containing the keys and values.
+``pushkey``
+  Run after a pushkey (like a bookmark) is added to the
+  repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
+  ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
+  value is in ``$HG_NEW``.
 ``tag``
   Run after a tag is created. ID of tagged changeset is in ``$HG_NODE``.
   Name of tag is in ``$HG_TAG``. Tag is local if ``$HG_LOCAL=1``, in
--- a/mercurial/localrepo.py	Sat Apr 30 12:02:09 2011 -0500
+++ b/mercurial/localrepo.py	Sun May 01 11:12:36 2011 +0200
@@ -1918,10 +1918,18 @@
         return self.pull(remote, heads)
 
     def pushkey(self, namespace, key, old, new):
-        return pushkey.push(self, namespace, key, old, new)
+        self.hook('prepushkey', throw=True, namespace=namespace, key=key,
+                  old=old, new=new)
+        ret = pushkey.push(self, namespace, key, old, new)
+        self.hook('pushkey', namespace=namespace, key=key, old=old, new=new,
+                  ret=ret)
+        return ret
 
     def listkeys(self, namespace):
-        return pushkey.list(self, namespace)
+        self.hook('prelistkeys', throw=True, namespace=namespace)
+        values = pushkey.list(self, namespace)
+        self.hook('listkeys', namespace=namespace, values=values)
+        return values
 
     def debugwireargs(self, one, two, three=None, four=None, five=None):
         '''used to test argument passing over the wire'''
--- a/tests/test-hook.t	Sat Apr 30 12:02:09 2011 -0500
+++ b/tests/test-hook.t	Sun May 01 11:12:36 2011 +0200
@@ -168,6 +168,61 @@
   update hook: HG_ERROR=0 HG_PARENT1=539e4b31b6dc 
   2 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
+pushkey hook
+
+  $ echo 'pushkey = python "$TESTDIR"/printenv.py pushkey' >> .hg/hgrc
+  $ cd ../b
+  $ hg bookmark -r null foo
+  $ hg push -B foo ../a
+  pushing to ../a
+  searching for changes
+  no changes found
+  exporting bookmark foo
+  pushkey hook: HG_KEY=foo HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_RET=1 
+  $ cd ../a
+
+listkeys hook
+
+  $ echo 'listkeys = python "$TESTDIR"/printenv.py listkeys' >> .hg/hgrc
+  $ hg bookmark -r null bar
+  $ cd ../b
+  $ hg pull -B bar ../a
+  pulling from ../a
+  listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} 
+  searching for changes
+  listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} 
+  importing bookmark bar
+  $ cd ../a
+
+test that prepushkey can prevent incoming keys
+
+  $ echo 'prepushkey = python "$TESTDIR"/printenv.py prepushkey.forbid 1' >> .hg/hgrc
+  $ cd ../b
+  $ hg bookmark -r null baz
+  $ hg push -B baz ../a
+  pushing to ../a
+  searching for changes
+  no changes found
+  listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} 
+  listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} 
+  exporting bookmark baz
+  prepushkey.forbid hook: HG_KEY=baz HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 
+  abort: prepushkey hook exited with status 1
+  [255]
+  $ cd ../a
+
+test that prelistkeys can prevent listing keys
+
+  $ echo 'prelistkeys = python "$TESTDIR"/printenv.py prelistkeys.forbid 1' >> .hg/hgrc
+  $ hg bookmark -r null quux
+  $ cd ../b
+  $ hg pull -B quux ../a
+  pulling from ../a
+  prelistkeys.forbid hook: HG_NAMESPACE=bookmarks 
+  abort: prelistkeys hook exited with status 1
+  [255]
+  $ cd ../a
+
 prechangegroup hook can prevent incoming changes
 
   $ cd ../b