From patchwork Mon Aug 4 22:32:06 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [4,of,7] push: rework the bundle2partsgenerators logic From: Pierre-Yves David X-Patchwork-Id: 5252 Message-Id: To: mercurial-devel@selenic.com Cc: pierre-yves.david@ens-lyon.org Date: Mon, 04 Aug 2014 15:32:06 -0700 # HG changeset patch # User Pierre-Yves David # Date 1406772290 25200 # Wed Jul 30 19:04:50 2014 -0700 # Node ID ef23af55a08a21a479254a769dd0ccc94075be71 # Parent 757e2729b231c008ac4657d57f98a0eca6c4617b push: rework the bundle2partsgenerators logic Instead of a single list with function, we now have a list of name and a mapping of name to function. This aims at easing wrapping of step from extension. In the same move, declaration becomes decorator based (Syntax sugar, nom nom nom!) diff --git a/mercurial/exchange.py b/mercurial/exchange.py --- a/mercurial/exchange.py +++ b/mercurial/exchange.py @@ -241,10 +241,35 @@ def _pushcheckoutgoing(pushop): pushop.newbranch, bool(pushop.incoming), newbm) return True +# List of name of steps to perform for an outgoing bundle2, order matters. +b2partsgenorder = [] + +# Mapping between step name and function +# +# This exists to help extension to wrap step if necessary +b2partsgenmapping = {} + +def b2partsgenerator(stepname): + """decorator for function generating bundle2 part + + The function is added to the step -> function mapping and append to the + list of steps. Beware that decorated function will be added in order This + may matters. + + You can only use this decorator for new step, if you want to wrap a step + from an extension, attack the b2partsgenmapping dictionnary directly.""" + def dec(func): + assert stepname not in b2partsgenmapping + b2partsgenmapping[stepname] = func + b2partsgenorder.append(stepname) + return func + return dec + +@b2partsgenerator('changeset') def _pushb2ctx(pushop, bundler): """handle changegroup push through bundle2 addchangegroup result is stored in the ``pushop.ret`` attribute. """ @@ -267,12 +292,10 @@ def _pushb2ctx(pushop, bundler): cgreplies = op.records.getreplies(cgpart.id) assert len(cgreplies['changegroup']) == 1 pushop.ret = cgreplies['changegroup'][0]['return'] return handlereply -# list of function that may decide to add parts to an outgoing bundle2 -bundle2partsgenerators = [_pushb2ctx] def _pushbundle2(pushop): """push data to the remote using bundle2 The only currently supported type of data is changegroup but this will @@ -280,11 +303,12 @@ def _pushbundle2(pushop): bundler = bundle2.bundle20(pushop.ui, bundle2.bundle2caps(pushop.remote)) # create reply capability capsblob = bundle2.encodecaps(pushop.repo.bundle2caps) bundler.newpart('b2x:replycaps', data=capsblob) replyhandlers = [] - for partgen in bundle2partsgenerators: + for partgenname in b2partsgenorder: + partgen = b2partsgenmapping[partgenname] ret = partgen(pushop, bundler) if callable(ret): replyhandlers.append(ret) # do not push if nothing to push if bundler.nbparts <= 1: diff --git a/tests/test-bundle2.t b/tests/test-bundle2.t --- a/tests/test-bundle2.t +++ b/tests/test-bundle2.t @@ -962,11 +962,12 @@ Setting up > @bundle2.parthandler("test:abort") > def handleabort(op, part): > raise util.Abort('Abandon ship!', hint="don't panic") > > def uisetup(ui): - > exchange.bundle2partsgenerators.insert(0, _pushbundle2failpart) + > exchange.b2partsgenmapping['failpart'] = _pushbundle2failpart + > exchange.b2partsgenorder.insert(0, 'failpart') > > EOF $ cd main $ hg up tip