Patchwork [1,of,3] unbundle20: allow generic dispatch between unbundler

login
register
mail settings
Submitter Pierre-Yves David
Date April 7, 2015, 9:09 p.m.
Message ID <e176f57dbf891662f7e6.1428440980@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/8549/
State Accepted
Headers show

Comments

Pierre-Yves David - April 7, 2015, 9:09 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1428366191 25200
#      Mon Apr 06 17:23:11 2015 -0700
# Node ID e176f57dbf891662f7e63773d7f186772162ad80
# Parent  9007b498af9a642f16f316a117f112fb2b001d34
unbundle20: allow generic dispatch between unbundler

We now take full advantage of the 'getunbundler' function by using a
'{version -> unbundler-class}' mapping. This map currently contains a single
entry but will make it easy to support more versions from an extension/the
future.

At some point, this map will probably contains bundler-class information too,
in the same fashion the packer map do. However, this is not critically required
right now so it will happen by itself when needed.

The main target is to allow HG2Y support in an extension to ease transition of
companies using the experimental protocol in production (yeah...) But I've no
doubt this will be useful when playing with a future HG21.

Patch

diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -523,16 +523,17 @@  class unpackermixin(object):
 
 def getunbundler(ui, fp, header=None):
     """return a valid unbundler object for a given header"""
     if header is None:
         header = changegroup.readexactly(fp, 4)
-        magic, version = header[0:2], header[2:4]
-        if magic != 'HG':
-            raise util.Abort(_('not a Mercurial bundle'))
-        if version != '2Y':
-            raise util.Abort(_('unknown bundle version %s') % version)
-    unbundler = unbundle20(ui, fp)
+    magic, version = header[0:2], header[2:4]
+    if magic != 'HG':
+        raise util.Abort(_('not a Mercurial bundle'))
+    unbundlerclass = formatmap.get(version)
+    if unbundlerclass is None:
+        raise util.Abort(_('unknown bundle version %s') % version)
+    unbundler = unbundlerclass(ui, fp)
     ui.debug('start processing of %s stream\n' % header)
     return unbundler
 
 class unbundle20(unpackermixin):
     """interpret a bundle2 stream
@@ -613,10 +614,12 @@  class unbundle20(unpackermixin):
         return None
 
     def compressed(self):
         return False
 
+formatmap = {'2Y': unbundle20}
+
 class bundlepart(object):
     """A bundle2 part contains application level payload
 
     The part `type` is used to route the part to the application level
     handler.