bundle2: first version of a bundle processing
authorPierre-Yves David <pierre-yves.david@fb.com>
Mon, 24 Mar 2014 12:25:33 -0700
changeset 20889 deed5edb72de
parent 20888 0b0d3800c248
child 20890 ec7fc110faee
bundle2: first version of a bundle processing We now have a function that interpret part content. This is a version early version of this function. It'll see major changes in scope and API in future development. As for previous I'm just focussing on getting minimal logic setup. Refining will happen with real world usage.
mercurial/bundle2.py
tests/test-bundle2.t
--- a/mercurial/bundle2.py	Mon Mar 24 11:27:00 2014 -0700
+++ b/mercurial/bundle2.py	Mon Mar 24 12:25:33 2014 -0700
@@ -148,6 +148,48 @@
     """
     return '>'+('BB'*nbparams)
 
+
+parthandlermapping = {}
+
+def processbundle(repo, stream):
+    """This function process a bundle, apply effect to/from a repo
+
+    Currently it:
+    - parse a stream into an unbundle20 object
+    - iterate over each parts then search and use the proper handling code to
+      process the part.
+
+    Parts are processes in order.
+
+    This is very early version of this function that will be strongly reworked
+    before final usage.
+
+    All unknown parts are currently ignored (Mandatory parts logic will comes
+    later).
+    """
+    ui = repo.ui
+    # Extraction of the unbundler object will most likely change. It may be
+    # done outside of this function, the unbundler would be passed as argument.
+    # in all case the unbundler will eventually be created by a
+    # `changegroup.readbundle` style function.
+    unbundler = unbundle20(ui, stream)
+    # todo:
+    # - replace this is a init function soon.
+    # - exception catching
+    unbundler.params
+    for part in unbundler:
+        parttype = part.type
+        # part key are matched lower case
+        key = parttype.lower()
+        try:
+            handler = parthandlermapping[key]
+            ui.debug('found an handler for part %r\n' % parttype)
+        except KeyError:
+            ui.debug('ignoring unknown advisory part %r\n' % key)
+            # todo: consume the part (once we use streamed parts)
+            continue
+        handler(repo, part)
+
 class bundle20(object):
     """represent an outgoing bundle2 container
 
--- a/tests/test-bundle2.t	Mon Mar 24 11:27:00 2014 -0700
+++ b/tests/test-bundle2.t	Mon Mar 24 12:25:33 2014 -0700
@@ -20,6 +20,14 @@
   > Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko."""
   > assert len(ELEPHANTSSONG) == 178 # future test say 178 bytes, trust it.
   > 
+  > def songhandler(repo, part):
+  >     """handle a "test:song" bundle2 part, printing the lyrics on stdin"""
+  >     repo.ui.write('The choir start singing:\n')
+  >     for line in part.data.split('\n'):
+  >         repo.ui.write('    %s\n' % line)
+  > 
+  > bundle2.parthandlermapping['test:song'] = songhandler
+  > 
   > @command('bundle2',
   >          [('', 'param', [], 'stream level parameter'),
   >           ('', 'parts', False, 'include some arbitrary parts to the bundle'),],
@@ -56,6 +64,11 @@
   >     for chunk in bundler.getchunks():
   >         file.write(chunk)
   > 
+  > @command('unbundle2', [], '')
+  > def cmdunbundle2(ui, repo):
+  >     """process a bundle2 stream from stdin on the current repo"""
+  >     bundle2.processbundle(repo, sys.stdin)
+  > 
   > @command('statbundle2', [], '')
   > def cmdstatbundle2(ui, repo):
   >     """print statistic on the bundle2 container read from stdin"""
@@ -327,3 +340,41 @@
       mandatory: 2
       advisory: 1
       payload: 2 bytes
+
+Test actual unbundling
+========================
+
+Process the bundle
+
+  $ hg unbundle2 --debug < ../parts.hg2
+  start processing of HG20 stream
+  reading bundle2 stream parameters
+  start extraction of bundle2 parts
+  part header size: 13
+  part type: "test:empty"
+  part parameters: 0
+  payload chunk size: 0
+  ignoring unknown advisory part 'test:empty'
+  part header size: 13
+  part type: "test:empty"
+  part parameters: 0
+  payload chunk size: 0
+  ignoring unknown advisory part 'test:empty'
+  part header size: 12
+  part type: "test:song"
+  part parameters: 0
+  payload chunk size: 178
+  payload chunk size: 0
+  found an handler for part 'test:song'
+  The choir start singing:
+      Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
+      Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
+      Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
+  part header size: 39
+  part type: "test:math"
+  part parameters: 3
+  payload chunk size: 2
+  payload chunk size: 0
+  ignoring unknown advisory part 'test:math'
+  part header size: 0
+  end of bundle2 stream