diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py new file mode 100644 index 0000000000000000000000000000000000000000..9c5183cb9bca46c95b0e8cd94e99cb168df0a057_bWVyY3VyaWFsL2J1bmRsZTIucHk= --- /dev/null +++ b/mercurial/bundle2.py @@ -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 --git a/tests/test-bundle2.t b/tests/test-bundle2.t new file mode 100644 index 0000000000000000000000000000000000000000..9c5183cb9bca46c95b0e8cd94e99cb168df0a057_dGVzdHMvdGVzdC1idW5kbGUyLnQ= --- /dev/null +++ b/tests/test-bundle2.t @@ -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)