# HG changeset patch # User Pierre-Yves David # Date 1395176450 25200 # Node ID 9c5183cb9bca46c95b0e8cd94e99cb168df0a057 # Parent 8253e55930a3e85ed54075d09fa17f059d1737f4 bundle2: very first version of a bundle2 bundler This changeset is the very first of a long series. It create a new bundle2 module and add a simple class that generate and empty bundle2 container. The module is documented with the current state of the implementation. For information about the final goal you may want to consult the mercurial wiki page: http://mercurial.selenic.com/wiki/BundleFormat2 The documentation of the module will be updated with later patches adding more and more feature to the format. This patches also introduce a test case. This test case build and use its own small extension that use the new bundle2 module. Since the new format is unable to do anything right now, we could not use real mercurial code to test it. Moreover, some advanced feature of the bundle2 spec will not be used by core mercurial at all. So we need to have them tested. diff -r 8253e55930a3 -r 9c5183cb9bca mercurial/bundle2.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial/bundle2.py Tue Mar 18 14:00:50 2014 -0700 @@ -0,0 +1,84 @@ +# bundle2.py - generic container format to transmit arbitrary data. +# +# Copyright 2013 Facebook, Inc. +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. +"""Handling of the new bundle2 format + +The goal of bundle2 is to act as an atomically packet to transmit a set of +payloads in an application agnostic way. It consist in a sequence of "parts" +that will be handed to and processed by the application layer. + + +General format architecture +=========================== + +The format is architectured as follow + + - magic string + - stream level parameters + - payload parts (any number) + - end of stream marker. + +The current implementation is limited to empty bundle. + +Details on the Binary format +============================ + +All numbers are unsigned and big endian. + +stream level parameters +------------------------ + +Binary format is as follow + +:params size: (16 bits integer) + + 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. + + +Payload part +------------------------ + +Binary format is as follow + +:header size: (16 bits inter) + + The total number of Bytes used by the part headers. When the header is empty + (size = 0) this is interpreted as the end of stream marker. + + Currently forced to 0 in the current state of the implementation +""" + +_magicstring = 'HG20' + +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.""" + + def __init__(self): + self._params = [] + self._parts = [] + + def getchunks(self): + yield _magicstring + # no support for any param yet + # to be obviously fixed soon. + assert not self._params + yield '\0\0' + # no support for parts + # to be obviously fixed soon. + assert not self._parts + yield '\0\0' diff -r 8253e55930a3 -r 9c5183cb9bca tests/test-bundle2.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-bundle2.t Tue Mar 18 14:00:50 2014 -0700 @@ -0,0 +1,36 @@ + +Create an extension to test bundle2 API + + $ cat > bundle2.py << EOF + > """A small extension to test bundle2 implementation + > + > Current bundle2 implementation is far too limited to be used in any core + > code. We still need to be able to test it while it grow up. + > """ + > + > from mercurial import cmdutil + > from mercurial import bundle2 + > cmdtable = {} + > command = cmdutil.command(cmdtable) + > + > @command('bundle2', [], '') + > def cmdbundle2(ui, repo): + > """write a bundle2 container on standard ouput""" + > bundle = bundle2.bundle20() + > for chunk in bundle.getchunks(): + > ui.write(chunk) + > EOF + $ cat >> $HGRCPATH << EOF + > [extensions] + > bundle2=$TESTTMP/bundle2.py + > EOF + +The extension requires a repo (currently unused) + + $ hg init main + $ cd main + +Test simple generation of empty bundle + + $ hg bundle2 + HG20\x00\x00\x00\x00 (no-eol) (esc)