firefoxtree: support pulling firefoxtree labels from local peers (bug 1275663); r=smacleod draft
authorGregory Szorc <gps@mozilla.com>
Wed, 25 May 2016 21:50:46 -0700
changeset 8186 9cc83ed84f25d381bf827a4b553f377521b6fb2e
parent 8185 641e58a2330e4918163581054e342878d126a5bf
push id862
push userbmo:gps@mozilla.com
push dateThu, 26 May 2016 17:44:18 +0000
reviewerssmacleod
bugs1275663
firefoxtree: support pulling firefoxtree labels from local peers (bug 1275663); r=smacleod Today I learned that "local" peer repository instances in Mercurial have a separate code path from remote peer repos (namely httppeer and sshpeer) for retrieving capabilities and calling wire proto commands. localrepo.py has a "moderncaps" module level variable holding a set of capabilities. This is used by localpeer.__init__ to set the capabilities for localpeer instances. Fortunately, localrepository._restrictcapabilities is called during localpeer.__init__, giving us a hook point to adjust the capabilities set. If you look at the default implementation of that function, it adds a capability, so the "restrict" part of its name isn't very accurate. We implement our own _restrictcapabilities function that supplements the capabilities set if the repo is a Firefox repo. But that's not all. Calling commands on localpeers is different because there is no generic "call" API on localpeer instances. Instead, methods call functions directly. So, when calling the "firefoxtrees" wire protocol command, we detect local peers and make a direct function call. I wonder how many other extensions in version-control-tools won't work with localpeer instances because we haven't implemented this pattern before... MozReview-Commit-ID: FpCOLCzyuq1
hgext/firefoxtree/__init__.py
hgext/firefoxtree/tests/test-pull-tags-wireproto.t
--- a/hgext/firefoxtree/__init__.py
+++ b/hgext/firefoxtree/__init__.py
@@ -324,17 +324,23 @@ def wrappedpullobsolete(orig, pullop):
     repo = pullop.repo
     remote = pullop.remote
 
     if not isfirefoxrepo(repo):
         return res
 
     if remote.capable('firefoxtrees'):
         bmstore = bookmarks.bmstore(repo)
-        lines = remote._call('firefoxtrees').splitlines()
+        # remote.local() returns a localrepository or None. If local,
+        # just pass it into the wire protocol command/function to simulate
+        # the remote command call.
+        if remote.local():
+            lines = firefoxtrees(remote.local(), None).splitlines()
+        else:
+            lines = remote._call('firefoxtrees').splitlines()
         oldtags = {}
         for tag, node, tree, uri in get_firefoxtrees(repo):
             oldtags[tag] = node
         newtags = {}
         for line in lines:
             tag, node = line.split()
             newtags[tag] = node
 
@@ -561,16 +567,26 @@ def extsetup(ui):
         templatekw.dockeywords.update(keywords)
 
 
 def reposetup(ui, repo):
     if not repo.local():
         return
 
     class firefoxtreesrepo(repo.__class__):
+        # Wrap _restrictcapabilities so capabilities are exposed to local peers.
+        def _restrictcapabilities(self, caps):
+            caps = super(firefoxtreesrepo, self)._restrictcapabilities(caps)
+
+            if (isfirefoxrepo(self) and
+                    self.ui.configbool('firefoxtree', 'servetags', False)):
+                caps.add('firefoxtrees')
+
+            return caps
+
         @util.propertycache
         def firefoxtrees(self):
             trees = {}
 
             try:
                 with open(self._firefoxtreespath, 'rb') as fh:
                     data = fh.read()
             except IOError as e:
--- a/hgext/firefoxtree/tests/test-pull-tags-wireproto.t
+++ b/hgext/firefoxtree/tests/test-pull-tags-wireproto.t
@@ -91,16 +91,39 @@ Doing an incremental pull will print com
   updated firefox tree tag inbound (+2 commits)
   (run 'hg update' to get a working copy)
 
   $ cat .hg/firefoxtrees
   central 994ec05999daf04fb3c01a8cb0dea1458a7d4d3d
   fx-team a4521c3750458afd82406ac87977b3fdc2fdc62a
   inbound 388ff24b5456e83175491ae321bceb89aad2259f (no-eol)
 
+Local filesystem pull should retrieve tree tags
+
+  $ cd ..
+  $ hg init localpull
+  $ cd localpull
+  $ touch .hg/IS_FIREFOX_REPO
+  $ hg pull ../root/unified
+  pulling from ../root/unified
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 8 changesets with 8 changes to 2 files (+1 heads)
+  updated firefox tree tag central
+  updated firefox tree tag fx-team
+  updated firefox tree tag inbound
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+
+  $ cat .hg/firefoxtrees
+  central 994ec05999daf04fb3c01a8cb0dea1458a7d4d3d
+  fx-team a4521c3750458afd82406ac87977b3fdc2fdc62a
+  inbound 388ff24b5456e83175491ae321bceb89aad2259f (no-eol)
+
 Serve firefoxtree tags from bookmarks
 
   $ cd $TESTTMP/root/unified
   $ cat > .hg/hgrc << EOF
   > [firefoxtree]
   > servetags = true
   > servetagsfrombookmarks = true
   > EOF