[PATCH 2 of 2] bundle2: add a part to import external bundles
Mike Hommey
mh at glandium.org
Sat Oct 11 20:39:20 CDT 2014
On Sat, Oct 11, 2014 at 06:17:57PM -0700, Pierre-Yves David wrote:
> > capabilities = {'HG2X': (),
> > 'b2x:listkeys': (),
> > 'b2x:pushkey': (),
> > 'b2x:changegroup': (),
> >+ 'digests': tuple(digester.DIGESTS.keys()),
>
> You need to sort this otherwise this the order will be unstable. Also, this
> may be more appropriate for capabilities in general (and not just bundle2
> capabilities) but this area is a but fuzzy.
Why would order matter?
> > }
> >
> > def getrepocaps(repo):
> > """return the bundle2 capabilities for a given repo
> >
> > Exists to allow extensions (like evolution) to mutate the capabilities.
> > """
> > caps = capabilities.copy()
> >@@ -826,16 +889,76 @@ def handlechangegroup(op, inpart):
> > if op.reply is not None:
> > # This is definitly not the final form of this
> > # return. But one need to start somewhere.
> > part = op.reply.newpart('b2x:reply:changegroup')
> > part.addparam('in-reply-to', str(inpart.id), mandatory=False)
> > part.addparam('return', '%i' % ret, mandatory=False)
> > assert not inpart.read()
> >
> >+ at parthandler('b2x:import-bundle')
> >+def handleimportbundle(op, inpart):
> >+ """apply a bundle on the repo, given an url and validation information
> >+
> >+ The part contains a bundle url, as well as hash digest(s) and size
> >+ information to validate the downloaded content.
> >+ The expected format for this part is:
> >+ <URL>
> >+ <SIZE in bytes>
> >+ <DIGEST-TYPE>: <DIGEST-VALUE>
>
> Part can have parameters. You should use such parameter instead of encoding
> the information into the part payload.
I'll have to check how that works.
> >+ ...
> >+ Multiple digest types are supported in the same part, in which case they
> >+ are all validated.
> >+ This currently only supports bundle10, but is intended to support bundle20
> >+ eventually.
> >+ """
>
> Lets play simple and call this b2x:remote-changegroup and support
> changegroup for now. We will need something wider in the future but this
> will have to be more complicated.
>
> >+ lines = inpart.read().splitlines()
> >+ try:
> >+ url = lines.pop(0)
> >+ except IndexError:
> >+ raise util.Abort(_('import-bundle format error'))
> >+ parsed_url = urlparse.urlparse(url)
> >+ if parsed_url.scheme not in ('http', 'https'):
> >+ raise util.Abort(_('import-bundle only supports http/https urls'))
> >+
> >+ try:
> >+ size = int(lines.pop(0))
> >+ except (ValueError, IndexError):
> >+ raise util.Abort(_('import-bundle format error'))
> >+ digests = {}
> >+ for line in lines:
> >+ if ':' not in line:
> >+ raise util.Abort(_('import-bundle format error'))
> >+ k, v = line.split(':', 1)
> >+ digests[k.strip()] = v.strip()
>
> As pointed before, all this code can be replaced by something using
> parameter.
>
> >+ real_part = digestchecker(urllib2.urlopen(url), size, digests)
> >+
> >+ # Make sure we trigger a transaction creation
> >+ #
> >+ # The addchangegroup function will get a transaction object by itself, but
> >+ # we need to make sure we trigger the creation of a transaction object used
> >+ # for the whole processing scope.
> >+ op.gettransaction()
> >+ import exchange
> >+ cg = exchange.readbundle(op.repo.ui, real_part, None)
>
> If we focus on changegroup only, we can use the changegroup module directly.
> Avoiding dancing around circular import issue.
... except the code to handle the various HG10* headers and setting up
the corresponding decompression is in exchange.readbundle.
Mike
More information about the Mercurial-devel
mailing list