Commit Graph

96 Commits

Author SHA1 Message Date
Pierre-Yves David
f7baff1111 bundle2: add `pushkey` support
After ``listkeys`` we can now include ``pushkey`` request in a bundle2. The part
uses a very simple scheme closest as possible to the current wireproto command
for ``pushkey``. We may eventually decide for a more sophisticated part format
before the protocol becomes final.
2014-05-27 16:32:50 -07:00
Pierre-Yves David
c4d12e35a5 bundle: introduce a listkey handler
This makes it possible to handle listkeys-related data stored in a bundle2.
There are no producers yet.
2014-05-27 15:42:03 -07:00
Pierre-Yves David
c2721b6512 bundle2: introduce a bundle2caps function
The process of decoding remote bundle2caps blob into a dictionary is cumbersome.
We move it into a small helper function. This will clarify code that reads
bundle2 capabilities of peers and helps using it in new places.
2014-05-24 16:20:09 -07:00
Pierre-Yves David
e60d3c1093 bundle2: raise BundleValueError error for stream level unsupported params
This ensures both consistency and smooth propagation over the wire.
2014-05-28 15:37:47 -07:00
Pierre-Yves David
ee9ac67c31 bundle2: support None parttype in BundleValueError
This will be used for errors at the stream level.
2014-05-28 16:46:58 -07:00
Pierre-Yves David
29c25aabd5 bundle2: ignore advisory part with unknown parameters
Advisory parts are advisory. If a handler exists but does not support the
proper parameters, we can safely ignore it.

Test has been updated to include this case.
2014-05-27 12:16:45 -07:00
Pierre-Yves David
da0446d1b9 bundle2: enforce all parameters in a part to be handled
Once we picked a handler, we check that all mandatory parameter keys are
properly supported. If not we raise an exception.

We added a test for this case.

The code now fails for any part with unknown mandatory parameters. We will
ignore such errors for advisory parts in a later changeset.
2014-05-27 12:01:00 -07:00
Pierre-Yves David
5b7edfc76e bundle2: declare supported parameters for all handlers
We now update all existing handlers with the supported parameters information.
2014-05-28 11:40:07 -07:00
Pierre-Yves David
3e4ee45f47 bundle2: make it possible to declare params handled by a part handler
If we are to enforce the mandatory aspect of parameter, we need a way to
discover what a handler supports. The best option we end up with is this a simple
declaration of known parameters at registration time.

We simply plug the list of parameters on the function object because Python lets
us do that and there is no benefit for a more complicated way.

One of the handlers is updated for example and testing.
2014-05-27 11:49:48 -07:00
Pierre-Yves David
1b80836a48 bundle2: support transmission of params error over the wire
We picked a null character to split each parameter during the transfer. This is
fragile if the same character is used in parameter name. However other
codes will already behave in a strange way in that case, so we are not
introducing any regression. A better format may be picked for the final
version of the protocol.
2014-05-28 15:57:23 -07:00
Pierre-Yves David
72ac6a7248 bundle2: introduce a parttype attribute to BundleValueError
We will use the Exception for more that just unknown part type.
2014-05-28 15:51:19 -07:00
Pierre-Yves David
b5c6c1b880 bundle2: rename b2x:error:unknownpart to b2x:error:unsupportedcontent
This is a backward compatibility breakage per se. But bundle2 was explicitly
flagged as experimental, and this is one an error path anyway. So the worse
possible outcome from this change is to still have a crash but with a different
message.
2014-05-27 10:32:07 -07:00
Pierre-Yves David
d9f1652a77 bundle2: move exception classes into the error module
Exceptions should have known their place.
2014-05-28 15:31:05 -07:00
Pierre-Yves David
08bcb101f2 bundle2: rename UnknownPartError to BundleValueError
We are going to raise exceptions for a wider range of cases: unsupported
mandatory stream and part parameters.  We rename the exception with a wider
name.
2014-05-28 14:22:24 -07:00
Pierre-Yves David
096f428e53 bundle2: expose mandatory params in a mandatorykeys attribute
We expose all keys that MUST be processed in ``part.mandatorykeys``. This makes
it much easier to access the information. Enforcement of the mandatory
parameters is coming in later changesets.
2014-05-23 20:23:54 -07:00
Pierre-Yves David
467e401b10 bundle2: use the new `part.params` dictionary
We use the new ``part.params`` dictionary to access the value of parameters instead of
creating one from the part's attributes.
2014-05-26 18:45:43 -07:00
Pierre-Yves David
75a728d5f5 bundle2: introduce a `params` dictionary on unbundled parts
This exposes all parameters the part received into a ``part.params`` dictionary.
This should be much easier to use.

This dictionary itself does not expose the mandatory or advisory aspect of
parameters, but no current users of bundle2 actually enforce any of this logic.
Coming changesets will improve this aspect.
2014-05-23 17:26:57 -07:00
Pierre-Yves David
ecdd6aaf9e bundle2: make sure unbundled part param are read-only
My old uncle Robert once trusted an API user. We never saw him again.
2014-05-23 17:17:39 -07:00
Pierre-Yves David
ee0bc34f9d bundle2: introduce an `_initparams` method
The handling of parameters will become much more sophisticated in the coming
changesets. So we extract the logic in a function to not pollute the generic
logic.
2014-05-28 10:04:02 -07:00
Pierre-Yves David
17c8c5b1eb bundle2: forbid duplicate parameter keys
No rules were specified about parameter key uniqueness. We document that keys
should be unique and document it. This opens the way to a more friendly (read
dictionary like) way to access value of parameters in the code.
2014-05-22 12:52:09 -07:00
Pierre-Yves David
7023ca67e5 bundle2: update part creators to `addparam` when relevant
In some cases, the use of ``addparam`` makes code much clearer.
2014-05-23 16:46:30 -07:00
Pierre-Yves David
76215be0d0 bundle2: introduce a `addparam` method on part
We make it easier to add new parameters after the part creation. As for the
``data`` attribute we make sure the part generation has not begun yet.
2014-05-22 11:38:40 -07:00
Pierre-Yves David
3c42f04f04 bundle2: the ability to set `data` attribute of the part is now official
We make it safe to set the data attribute after part creation. It is an allowed
operation as long as the part has not started to be generated.
2014-05-22 11:21:26 -07:00
Pierre-Yves David
2ece793be7 bundle2: introduce a ReadOnlyPartError exception
As we will introduce functions to alter already created parts, we need a proper
exception to raise when code tries to alter a part that cannot be altered anymore.
2014-05-24 16:08:05 -07:00
Pierre-Yves David
4248dc3512 bundle2: warn about error during initialization in `newpart` docstring
As we are moving toward being able to alter a part after its creation, we need
to make the implication of the part being already part of the bundle2 clear.
2014-05-23 16:20:30 -07:00
Pierre-Yves David
3b20774c58 bundle2: track life cycle of parts
We introduce a ``_generated`` attribute on parts. Coming changesets will
make it easier to update a part's contents after its creation. We need a way to track
if the part is still open to modification or if it is currently being generated
and should not be touched anymore.

As a bonus, we can now detect and crash if someone manages to write bogus code
to get a part generated twice.
2014-05-22 11:14:02 -07:00
Pierre-Yves David
121338752e bundle2: update all `addpart callers to newpart`
The new method is what we want in all current cases.
2014-05-23 15:59:19 -07:00
Pierre-Yves David
a618942ce3 bundle2: have `newpart` automatically add the part to the bundle
The created part is automatically added to the bundle as this is most certainly
the intent of the user code.
2014-05-23 15:54:18 -07:00
Pierre-Yves David
637e050d21 bundle2: add a `newpart method to bundle20`
Creating new parts is the most common operation people do when exposed to a
bundler. We create a dedicated method on the bundler object for it. This will
simplify the code and also avoid having to import the ``mercurial.bundle2``
module in multiple places.

One part creators have been updated for testing purpose.
2014-05-23 15:45:46 -07:00
Pierre-Yves David
6480c98ec3 bundle2: small doc update on the bundler
The `bundle20` class contains methods to help define the content and methods
to generate the actual stream. We add small doc headers to help distinguish
between the two.
2014-05-22 10:48:37 -07:00
Pierre-Yves David
b4b66836e8 bundle2: gracefully handle PushRaced error during unbundle
Same drill again. We catch the PushRaced error, check if it cames from
a bundle2 processing, if so we turn it into a bundle2 with a part
transporting error information to be reraised client side.
2014-04-21 17:51:58 -07:00
Pierre-Yves David
eb0866dfad bundle2: add an error message to push race error
Errors with no explanations makes my uncle Bob sad.
2014-04-21 20:04:54 -07:00
Pierre-Yves David
716843e5d3 bundle2: fix raising errors during heads checking
If the heads on the server differ from the ones reported seen by the client at
bundle time, we raise a PushRaced exception. However, the part raising the
exception was broken.

To fix it, we move the PushRaced class in the error module so it can be
accessible everywhere without an import cycle.

A test is also added to prevent regression.
2014-04-21 18:59:09 -07:00
Pierre-Yves David
f5bff0c11f bundle2: gracefully handle UnknownPartError during unbundle
Same as for Abort error, we catch the error, encode it into a bundle2 reply
(expected by the client) and stream this reply. The client processing of the
error will raise the exception again.
2014-04-21 16:02:03 -07:00
Pierre-Yves David
8265035568 bundle2: use a more specific UnknownPartError when no handler is found
KeyError is very generic, we need something more specific for proper error
handling.
2014-04-21 19:42:40 -07:00
Pierre-Yves David
3085949133 bundle2: gracefully handle abort during unbundle
Clients expect a bundle2 reply to their bundle2 submission. So we
catch the Abort error and turn it into a bundle2 containing a part
transporting the exception data. The unbundling of this reply will
raise the error again.
2014-04-21 15:48:52 -07:00
Pierre-Yves David
3385347d38 bundle2: decorate exception raised during bundle processing
This is a small hack to help us do some graceful error handling in bundle2
without major refactoring. See embedded comment for details.
2014-04-22 11:22:41 -07:00
Pierre-Yves David
fd614e4d04 bundle2: move all parts into a bx2 namespace
All currently core parts are moved to a `bx2` namespace (for "bundle 2
experimental"). This should avoid conflicts between the final stable
format and the one about to be released.
2014-04-17 15:45:12 -04:00
Pierre-Yves David
7e653a9c0f bundle2: use HG2X in the header
The current implementation of bundle2 is still very experimental and the 3.0
freeze is yesterday. The current bundle2 format has never been field-tested, so
we rename the header to HG2X. This leaves the HG20 header available for real
usage as a stable format in Mercurial 3.1.

We won't guarantee that future mercurial versions will keep supporting this
`HG2X` format.
2014-04-17 15:27:54 -04:00
Pierre-Yves David
9bb9dc1703 bundle2: capabilities encoding 2014-04-17 01:44:53 -04:00
Pierre-Yves David
211041404c bundle2: extract capabilities decoding
We'll need to reuse this in more places (at least pull and push).
2014-04-17 01:09:05 -04:00
Pierre-Yves David
f2ead829c7 bundle2: protect capabilities name and values with url quoting
This lift limitations of the text based encoding.
2014-04-17 01:03:33 -04:00
Pierre-Yves David
f48478a77f bundle2: support for capabilities with values
The capabilities attributes of `bundle20` is now a dictionary and the reply caps
can encode capabilities with values.
2014-04-17 11:44:49 -04:00
Pierre-Yves David
b4784becd2 bundle2: add capabilities support in replycaps part
This part now contains a list of supported capabilities.
2014-04-17 11:32:30 -04:00
Pierre-Yves David
e273dad6f6 bundle2: adds a capabilities attribute on bundler20
This attribute conveys the capabilities supported by the destination of the
bundle. It is used to decide which parts to include in the bundle.

This is currently a set but will probably be turned into a dictionary to allow
capabilities with values.
2014-04-16 23:55:59 -04:00
Pierre-Yves David
1c2cd8594e bundle2: include stderr when capturing handlers output
We do not discriminate between stdout and stderr yet. But this will do for now.
2014-04-16 23:18:27 -04:00
Pierre-Yves David
53ffee95a2 bundle2: capture remote stdout while unbundling
When a reply is built, the bundle processing will capture the output of each
handler and sends it to the client in a dedicated part.

As a side effect, this add a "remote: " prefix to destination output on local
push. This is considered okay for now as:

1. bundle2 is still experimental,
2. Matt said he could be okay to change output for bundle2,
3. This keeps the implementation simple.

This changeset does it for stdout only. stderr will be done in a future changeset.
2014-04-16 14:22:24 -04:00
Pierre-Yves David
f7d4dc294b bundle2: introduce replycaps part for on-demand reply
The bundle2 processing does not create a bundle2 reply by default anymore.  It
is only done if the client requests it with a `replycaps` part. This part is
called `replycaps` as it will eventually contain data about which bundle2
capabilities are supported by the client.

We have to add a flag to the test command to control whether a reply is
generated or not.
2014-04-16 14:09:35 -04:00
Pierre-Yves David
88fa4f238f bundle2: use an official iterparts method to unbundle parts
Explicit is better than implicit.
2014-04-16 18:41:48 -04:00
Pierre-Yves David
4ba3ed7539 bundle2: make header reading optional
The `readbundle` function will consume the 4 first bytes to dispatch between
various unbundler. We introduce a way to inform `unbundle20` that the header
has been read and it can be trusted.
2014-04-15 13:54:54 -04:00