@@ -146,10 +146,52 @@ def _makefpartparamsizes(nbparams):
The number parameters is variable so we need to build that format
dynamically.
"""
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
Use the `addparam` method to add stream level parameter. and `addpart` to
populate it. Then call `getchunks` to retrieve all the binary chunks of
@@ -18,10 +18,18 @@ Create an extension to test bundle2 API
> ELEPHANTSSONG = """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."""
> 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'),],
> '[OUTPUTFILE]')
> def cmdbundle2(ui, repo, path=None, **opts):
@@ -54,10 +62,15 @@ Create an extension to test bundle2 API
> file = open(path, 'w')
>
> 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"""
> unbundler = bundle2.unbundle20(ui, sys.stdin)
> try:
@@ -325,5 +338,43 @@ Test part
payload: 178 bytes
:test:math:
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