changeset 20804:db9d3991d2c6

bundle2: support bundling simple parameter This changeset add bundling capacity for simple parameters, not value or any special case are handled.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Wed, 19 Mar 2014 14:52:03 -0700
parents 88db3e615319
children c5aaeca0cfbf
files mercurial/bundle2.py tests/test-bundle2.t
diffstat 2 files changed, 77 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/bundle2.py	Tue Mar 18 16:35:34 2014 -0700
+++ b/mercurial/bundle2.py	Wed Mar 19 14:52:03 2014 -0700
@@ -21,7 +21,7 @@
  - payload parts (any number)
  - end of stream marker.
 
-The current implementation is limited to empty bundle.
+The current implementation accept some stream level option but no part.
 
 Details on the Binary format
 ============================
@@ -37,14 +37,18 @@
 
   The total number of Bytes used by the parameters
 
-  Currently force to 0.
-
 :params value: arbitrary number of Bytes
 
   A blob of `params size` containing the serialized version of all stream level
   parameters.
 
-  Currently always empty.
+  The blob contains a space separated list of parameters.
+
+  Parameter value are not supported yet.
+
+  Special character in param name are not supported yet.
+
+
 
 
 Payload part
@@ -61,32 +65,57 @@
 """
 
 import util
+import struct
+
 import changegroup
 from i18n import _
 
+_pack = struct.pack
+_unpack = struct.unpack
+
 _magicstring = 'HG20'
 
+_fstreamparamsize = '>H'
+
 class bundle20(object):
     """represent an outgoing bundle2 container
 
-    People will eventually be able to add param and parts to this object and
-    generated a stream from it."""
+    Use the `addparam` method to add stream level parameter. Then call
+    `getchunks` to retrieve all the binary chunks of datathat compose the
+    bundle2 container.
+
+    This object does not support payload part yet."""
 
     def __init__(self):
         self._params = []
         self._parts = []
 
+    def addparam(self, name, value=None):
+        """add a stream level parameter"""
+        self._params.append((name, value))
+
     def getchunks(self):
         yield _magicstring
-        # no support for any param yet
-        # to be obviously fixed soon.
-        assert not self._params
-        yield '\0\0'
+        param = self._paramchunk()
+        yield _pack(_fstreamparamsize, len(param))
+        if param:
+            yield param
+
         # no support for parts
         # to be obviously fixed soon.
         assert not self._parts
         yield '\0\0'
 
+    def _paramchunk(self):
+        """return a encoded version of all stream parameters"""
+        blocks = []
+        for key, value in self._params:
+            # XXX no support for value yet
+            assert value is None
+            # XXX no escaping yet
+            blocks.append(key)
+        return ' '.join(blocks)
+
 class unbundle20(object):
     """interpret a bundle2 stream
 
--- a/tests/test-bundle2.t	Tue Mar 18 16:35:34 2014 -0700
+++ b/tests/test-bundle2.t	Wed Mar 19 14:52:03 2014 -0700
@@ -14,11 +14,15 @@
   > cmdtable = {}
   > command = cmdutil.command(cmdtable)
   > 
-  > @command('bundle2', [], '')
-  > def cmdbundle2(ui, repo):
+  > @command('bundle2',
+  >          [('', 'param', [], 'stream level parameter'),],
+  >          '')
+  > def cmdbundle2(ui, repo, **opts):
   >     """write a bundle2 container on standard ouput"""
-  >     bundle = bundle2.bundle20()
-  >     for chunk in bundle.getchunks():
+  >     bundler = bundle2.bundle20()
+  >     for p in opts['param']:
+  >         bundler.addparam(p)
+  >     for chunk in bundler.getchunks():
   >         ui.write(chunk)
   > 
   > @command('unbundle2', [], '')
@@ -42,12 +46,19 @@
   $ hg add a
   $ hg commit -m 'a'
 
-Test simple generation of empty bundle
+
+Empty bundle
+=================
+
+- no option
+- no parts
+
+Test bundling
 
   $ hg bundle2
   HG20\x00\x00\x00\x00 (no-eol) (esc)
 
-Test parsing of an empty bundle
+Test unbundling
 
   $ hg bundle2 | hg unbundle2
   options count: 0
@@ -60,3 +71,24 @@
   $ hg unbundle2 < ../bundle.hg
   abort: unknown bundle version 10
   [255]
+
+Test parameters
+=================
+
+- some options
+- no parts
+
+advisory parameters, no value
+-------------------------------
+
+Simplest possible parameters form
+
+Test generation
+
+  $ hg bundle2 --param 'caution'
+  HG20\x00\x07caution\x00\x00 (no-eol) (esc)
+
+Test generation multiple option
+
+  $ hg bundle2 --param 'caution' --param 'meal'
+  HG20\x00\x0ccaution meal\x00\x00 (no-eol) (esc)