changeset 919:92bd7b3678ea

Add a changegroup hook to update svn metadata
author Brad Hall <bhall@fb.com>
date Thu, 07 Jun 2012 16:29:05 -0700
parents 761a87134501
children 1be4ea4f3c0d
files hgsubversion/hooks/__init__.py hgsubversion/hooks/updatemeta.py setup.py tests/run.py tests/test_hooks.py
diffstat 5 files changed, 81 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/hgsubversion/hooks/updatemeta.py
@@ -0,0 +1,31 @@
+# Mercurial hook to update/rebuild svn metadata if there are svn changes in
+# the incoming changegroup.
+#
+# To install, add the following to your hgrc:
+# [hooks]
+# changegroup = python:hgsubversion.hooks.updatemeta.hook
+
+from mercurial import node
+
+import hgsubversion
+import hgsubversion.util
+import hgsubversion.svncommands
+
+def hook(ui, repo, **kwargs):
+    updatemeta = False
+    startrev = repo[node.bin(kwargs["node"])].rev()
+    # Check each rev until we find one that contains svn metadata
+    for rev in xrange(startrev, len(repo)):
+        svnrev = hgsubversion.util.getsvnrev(repo[rev])
+        if svnrev and svnrev.startswith("svn:"):
+            updatemeta = True
+            break
+
+    if updatemeta:
+        try:
+            hgsubversion.svncommands.updatemeta(ui, repo, args=[])
+            ui.status("Updated svn metadata\n")
+        except Exception, e:
+            ui.warn("Failed to update svn metadata: %s" % str(e))
+
+    return False
--- a/setup.py
+++ b/setup.py
@@ -118,7 +118,7 @@ setup(
     long_description=open(os.path.join(os.path.dirname(__file__),
                                          'README')).read(),
     keywords='mercurial',
-    packages=('hgsubversion', 'hgsubversion.svnwrap'),
+    packages=('hgsubversion', 'hgsubversion.hooks', 'hgsubversion.svnwrap'),
     package_data={ 'hgsubversion': ['help/subversion.rst'] },
     platforms='any',
     install_requires=requires,
--- a/tests/run.py
+++ b/tests/run.py
@@ -18,6 +18,7 @@ def tests():
     import test_fetch_renames
     import test_fetch_symlinks
     import test_fetch_truncated
+    import test_hooks
     import test_pull
     import test_push_command
     import test_push_renames
new file mode 100644
--- /dev/null
+++ b/tests/test_hooks.py
@@ -0,0 +1,48 @@
+import sys
+import test_util
+import unittest
+
+from mercurial import hg
+from mercurial import commands
+
+class TestHooks(test_util.TestBase):
+    def setUp(self):
+        super(TestHooks, self).setUp()
+
+    def _loadupdate(self, fixture_name, *args, **kwargs):
+        kwargs = kwargs.copy()
+        kwargs.update(stupid=False, noupdate=False)
+        repo, repo_path = self.load_and_fetch(fixture_name, *args, **kwargs)
+        return repo, repo_path
+
+    def test_updatemetahook(self):
+        repo, repo_path = self._loadupdate('single_rev.svndump')
+        state = repo.parents()
+        self.add_svn_rev(repo_path, {'trunk/alpha': 'Changed'})
+        commands.pull(self.repo.ui, self.repo)
+
+        # Clone to a new repository and add a hook
+        new_wc_path = "%s-2" % self.wc_path
+        commands.clone(self.repo.ui, self.wc_path, new_wc_path)
+        newrepo = hg.repository(test_util.testui(), new_wc_path)
+        newrepo.ui.setconfig('hooks', 'changegroup.meta',
+                'python:hgsubversion.hooks.updatemeta.hook')
+
+        # Commit a rev that should trigger svn meta update
+        self.add_svn_rev(repo_path, {'trunk/alpha': 'Changed Again'})
+        commands.pull(self.repo.ui, self.repo)
+
+        self.called = False
+        import hgsubversion.svncommands
+        oldupdatemeta = hgsubversion.svncommands.updatemeta
+        def _updatemeta(ui, repo, args=[]):
+            self.called = True
+        hgsubversion.svncommands.updatemeta = _updatemeta
+
+        # Pull and make sure our updatemeta function gets called
+        commands.pull(newrepo.ui, newrepo)
+        hgsubversion.svncommands.updatemeta = oldupdatemeta
+        self.assertTrue(self.called)
+
+def suite():
+    return unittest.findTestCases(sys.modules[__name__])