Mercurial > hg
annotate mercurial/bundle2.py @ 21210:799c494189a9 stable
rebase: empty revset should be a gentle no-op with exit code 1, not an error
author | Mads Kiilerich <madski@unity3d.com> |
---|---|
date | Thu, 01 May 2014 16:47:50 +0200 |
parents | 9f3652e851f8 |
children | 1daad9dcdba2 |
rev | line source |
---|---|
20801
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
1 # bundle2.py - generic container format to transmit arbitrary data. |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
2 # |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
3 # Copyright 2013 Facebook, Inc. |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
4 # |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
7 """Handling of the new bundle2 format |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
8 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
9 The goal of bundle2 is to act as an atomically packet to transmit a set of |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
10 payloads in an application agnostic way. It consist in a sequence of "parts" |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
11 that will be handed to and processed by the application layer. |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
12 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
13 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
14 General format architecture |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
15 =========================== |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
16 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
17 The format is architectured as follow |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
18 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
19 - magic string |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
20 - stream level parameters |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
21 - payload parts (any number) |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
22 - end of stream marker. |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
23 |
20856
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
24 the Binary format |
20801
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
25 ============================ |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
26 |
21024
7731a2281cf0
spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents:
21020
diff
changeset
|
27 All numbers are unsigned and big-endian. |
20801
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
28 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
29 stream level parameters |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
30 ------------------------ |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
31 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
32 Binary format is as follow |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
33 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
34 :params size: (16 bits integer) |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
35 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
36 The total number of Bytes used by the parameters |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
37 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
38 :params value: arbitrary number of Bytes |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
39 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
40 A blob of `params size` containing the serialized version of all stream level |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
41 parameters. |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
42 |
21024
7731a2281cf0
spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents:
21020
diff
changeset
|
43 The blob contains a space separated list of parameters. Parameters with value |
20811
9785c3f8f598
bundle2: urlquote stream parameter name and value
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20810
diff
changeset
|
44 are stored in the form `<name>=<value>`. Both name and value are urlquoted. |
20804
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
45 |
20813
8c74b3ce5b70
bundle2: refuse empty parameter name
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20812
diff
changeset
|
46 Empty name are obviously forbidden. |
8c74b3ce5b70
bundle2: refuse empty parameter name
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20812
diff
changeset
|
47 |
20844
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
48 Name MUST start with a letter. If this first letter is lower case, the |
21024
7731a2281cf0
spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents:
21020
diff
changeset
|
49 parameter is advisory and can be safely ignored. However when the first |
20844
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
50 letter is capital, the parameter is mandatory and the bundling process MUST |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
51 stop if he is not able to proceed it. |
20814
8532f5e1b9df
bundle2: force the first char of parameter to be an letter.
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20813
diff
changeset
|
52 |
20808
4c9130c7a29f
bundle2: clarify stream parameter design in the documentation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20805
diff
changeset
|
53 Stream parameters use a simple textual format for two main reasons: |
20804
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
54 |
21024
7731a2281cf0
spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents:
21020
diff
changeset
|
55 - Stream level parameters should remain simple and we want to discourage any |
20808
4c9130c7a29f
bundle2: clarify stream parameter design in the documentation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20805
diff
changeset
|
56 crazy usage. |
21024
7731a2281cf0
spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents:
21020
diff
changeset
|
57 - Textual data allow easy human inspection of a bundle2 header in case of |
20808
4c9130c7a29f
bundle2: clarify stream parameter design in the documentation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20805
diff
changeset
|
58 troubles. |
4c9130c7a29f
bundle2: clarify stream parameter design in the documentation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20805
diff
changeset
|
59 |
4c9130c7a29f
bundle2: clarify stream parameter design in the documentation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20805
diff
changeset
|
60 Any Applicative level options MUST go into a bundle2 part instead. |
20801
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
61 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
62 Payload part |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
63 ------------------------ |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
64 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
65 Binary format is as follow |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
66 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
67 :header size: (16 bits inter) |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
68 |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
69 The total number of Bytes used by the part headers. When the header is empty |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
70 (size = 0) this is interpreted as the end of stream marker. |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
71 |
20856
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
72 :header: |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
73 |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
74 The header defines how to interpret the part. It contains two piece of |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
75 data: the part type, and the part parameters. |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
76 |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
77 The part type is used to route an application level handler, that can |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
78 interpret payload. |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
79 |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
80 Part parameters are passed to the application level handler. They are |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
81 meant to convey information that will help the application level object to |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
82 interpret the part payload. |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
83 |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
84 The binary format of the header is has follow |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
85 |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
86 :typesize: (one byte) |
20877
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
87 |
21024
7731a2281cf0
spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents:
21020
diff
changeset
|
88 :parttype: alphanumerical part name |
20877
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
89 |
20995
e995d104c87f
bundle2: add an integer id to part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20952
diff
changeset
|
90 :partid: A 32bits integer (unique in the bundle) that can be used to refer |
e995d104c87f
bundle2: add an integer id to part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20952
diff
changeset
|
91 to this part. |
e995d104c87f
bundle2: add an integer id to part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20952
diff
changeset
|
92 |
20877
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
93 :parameters: |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
94 |
21024
7731a2281cf0
spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents:
21020
diff
changeset
|
95 Part's parameter may have arbitrary content, the binary structure is:: |
20877
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
96 |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
97 <mandatory-count><advisory-count><param-sizes><param-data> |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
98 |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
99 :mandatory-count: 1 byte, number of mandatory parameters |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
100 |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
101 :advisory-count: 1 byte, number of advisory parameters |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
102 |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
103 :param-sizes: |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
104 |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
105 N couple of bytes, where N is the total number of parameters. Each |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
106 couple contains (<size-of-key>, <size-of-value) for one parameter. |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
107 |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
108 :param-data: |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
109 |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
110 A blob of bytes from which each parameter key and value can be |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
111 retrieved using the list of size couples stored in the previous |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
112 field. |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
113 |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
114 Mandatory parameters comes first, then the advisory ones. |
20856
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
115 |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
116 :payload: |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
117 |
20876
ddd56f3eb786
bundle2: support for bundling and unbundling payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20864
diff
changeset
|
118 payload is a series of `<chunksize><chunkdata>`. |
ddd56f3eb786
bundle2: support for bundling and unbundling payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20864
diff
changeset
|
119 |
ddd56f3eb786
bundle2: support for bundling and unbundling payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20864
diff
changeset
|
120 `chunksize` is a 32 bits integer, `chunkdata` are plain bytes (as much as |
ddd56f3eb786
bundle2: support for bundling and unbundling payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20864
diff
changeset
|
121 `chunksize` says)` The payload part is concluded by a zero size chunk. |
ddd56f3eb786
bundle2: support for bundling and unbundling payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20864
diff
changeset
|
122 |
ddd56f3eb786
bundle2: support for bundling and unbundling payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20864
diff
changeset
|
123 The current implementation always produces either zero or one chunk. |
21024
7731a2281cf0
spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents:
21020
diff
changeset
|
124 This is an implementation limitation that will ultimately be lifted. |
20891
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
125 |
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
126 Bundle processing |
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
127 ============================ |
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
128 |
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
129 Each part is processed in order using a "part handler". Handler are registered |
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
130 for a certain part type. |
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
131 |
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
132 The matching of a part to its handler is case insensitive. The case of the |
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
133 part type is used to know if a part is mandatory or advisory. If the Part type |
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
134 contains any uppercase char it is considered mandatory. When no handler is |
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
135 known for a Mandatory part, the process is aborted and an exception is raised. |
20892
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
136 If the part is advisory and no handler is known, the part is ignored. When the |
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
137 process is aborted, the full bundle is still read from the stream to keep the |
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
138 channel usable. But none of the part read from an abort are processed. In the |
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
139 future, dropping the stream may become an option for channel we do not care to |
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
140 preserve. |
20801
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
141 """ |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
142 |
20802
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
143 import util |
20804
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
144 import struct |
20811
9785c3f8f598
bundle2: urlquote stream parameter name and value
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20810
diff
changeset
|
145 import urllib |
20814
8532f5e1b9df
bundle2: force the first char of parameter to be an letter.
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20813
diff
changeset
|
146 import string |
20804
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
147 |
21184
28d76afa1568
bundle2: fix raising errors during heads checking
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21183
diff
changeset
|
148 import changegroup, error |
20803
88db3e615319
bundle2: make sure the unbundler refuse non bundle2 stream
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20802
diff
changeset
|
149 from i18n import _ |
20802
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
150 |
20804
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
151 _pack = struct.pack |
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
152 _unpack = struct.unpack |
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
153 |
21144
7a20fe8dc080
bundle2: use HG2X in the header
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21139
diff
changeset
|
154 _magicstring = 'HG2X' |
20801
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
155 |
20804
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
156 _fstreamparamsize = '>H' |
20856
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
157 _fpartheadersize = '>H' |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
158 _fparttypesize = '>B' |
20995
e995d104c87f
bundle2: add an integer id to part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20952
diff
changeset
|
159 _fpartid = '>I' |
20876
ddd56f3eb786
bundle2: support for bundling and unbundling payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20864
diff
changeset
|
160 _fpayloadsize = '>I' |
20877
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
161 _fpartparamcount = '>BB' |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
162 |
21001
c93bb6a08fa1
bundle2: support chunk iterator as part data
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21000
diff
changeset
|
163 preferedchunksize = 4096 |
c93bb6a08fa1
bundle2: support chunk iterator as part data
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21000
diff
changeset
|
164 |
20877
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
165 def _makefpartparamsizes(nbparams): |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
166 """return a struct format to read part parameter sizes |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
167 |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
168 The number parameters is variable so we need to build that format |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
169 dynamically. |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
170 """ |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
171 return '>'+('BB'*nbparams) |
20804
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
172 |
21179
372f4772f7a0
bundle2: use a more specific UnknownPartError when no handler is found
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21177
diff
changeset
|
173 class UnknownPartError(KeyError): |
372f4772f7a0
bundle2: use a more specific UnknownPartError when no handler is found
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21177
diff
changeset
|
174 """error raised when no handler is found for a Mandatory part""" |
372f4772f7a0
bundle2: use a more specific UnknownPartError when no handler is found
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21177
diff
changeset
|
175 pass |
372f4772f7a0
bundle2: use a more specific UnknownPartError when no handler is found
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21177
diff
changeset
|
176 |
20890
ec7fc110faee
bundle2: introduce a `parthandler` decorator
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20889
diff
changeset
|
177 parthandlermapping = {} |
20889
deed5edb72de
bundle2: first version of a bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20887
diff
changeset
|
178 |
20890
ec7fc110faee
bundle2: introduce a `parthandler` decorator
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20889
diff
changeset
|
179 def parthandler(parttype): |
ec7fc110faee
bundle2: introduce a `parthandler` decorator
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20889
diff
changeset
|
180 """decorator that register a function as a bundle2 part handler |
ec7fc110faee
bundle2: introduce a `parthandler` decorator
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20889
diff
changeset
|
181 |
ec7fc110faee
bundle2: introduce a `parthandler` decorator
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20889
diff
changeset
|
182 eg:: |
ec7fc110faee
bundle2: introduce a `parthandler` decorator
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20889
diff
changeset
|
183 |
ec7fc110faee
bundle2: introduce a `parthandler` decorator
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20889
diff
changeset
|
184 @parthandler('myparttype') |
ec7fc110faee
bundle2: introduce a `parthandler` decorator
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20889
diff
changeset
|
185 def myparttypehandler(...): |
ec7fc110faee
bundle2: introduce a `parthandler` decorator
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20889
diff
changeset
|
186 '''process a part of type "my part".''' |
ec7fc110faee
bundle2: introduce a `parthandler` decorator
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20889
diff
changeset
|
187 ... |
ec7fc110faee
bundle2: introduce a `parthandler` decorator
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20889
diff
changeset
|
188 """ |
ec7fc110faee
bundle2: introduce a `parthandler` decorator
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20889
diff
changeset
|
189 def _decorator(func): |
20891
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
190 lparttype = parttype.lower() # enforce lower case matching. |
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
191 assert lparttype not in parthandlermapping |
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
192 parthandlermapping[lparttype] = func |
20890
ec7fc110faee
bundle2: introduce a `parthandler` decorator
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20889
diff
changeset
|
193 return func |
ec7fc110faee
bundle2: introduce a `parthandler` decorator
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20889
diff
changeset
|
194 return _decorator |
20889
deed5edb72de
bundle2: first version of a bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20887
diff
changeset
|
195 |
20949
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
196 class unbundlerecords(object): |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
197 """keep record of what happens during and unbundle |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
198 |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
199 New records are added using `records.add('cat', obj)`. Where 'cat' is a |
21024
7731a2281cf0
spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents:
21020
diff
changeset
|
200 category of record and obj is an arbitrary object. |
20949
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
201 |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
202 `records['cat']` will return all entries of this category 'cat'. |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
203 |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
204 Iterating on the object itself will yield `('category', obj)` tuples |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
205 for all entries. |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
206 |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
207 All iterations happens in chronological order. |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
208 """ |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
209 |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
210 def __init__(self): |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
211 self._categories = {} |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
212 self._sequences = [] |
20996
ed3c5e18a047
bundle2: add reply awareness to unbundlerecords
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20995
diff
changeset
|
213 self._replies = {} |
20949
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
214 |
20996
ed3c5e18a047
bundle2: add reply awareness to unbundlerecords
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20995
diff
changeset
|
215 def add(self, category, entry, inreplyto=None): |
20949
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
216 """add a new record of a given category. |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
217 |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
218 The entry can then be retrieved in the list returned by |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
219 self['category'].""" |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
220 self._categories.setdefault(category, []).append(entry) |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
221 self._sequences.append((category, entry)) |
20996
ed3c5e18a047
bundle2: add reply awareness to unbundlerecords
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20995
diff
changeset
|
222 if inreplyto is not None: |
ed3c5e18a047
bundle2: add reply awareness to unbundlerecords
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20995
diff
changeset
|
223 self.getreplies(inreplyto).add(category, entry) |
ed3c5e18a047
bundle2: add reply awareness to unbundlerecords
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20995
diff
changeset
|
224 |
ed3c5e18a047
bundle2: add reply awareness to unbundlerecords
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20995
diff
changeset
|
225 def getreplies(self, partid): |
ed3c5e18a047
bundle2: add reply awareness to unbundlerecords
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20995
diff
changeset
|
226 """get the subrecords that replies to a specific part""" |
ed3c5e18a047
bundle2: add reply awareness to unbundlerecords
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20995
diff
changeset
|
227 return self._replies.setdefault(partid, unbundlerecords()) |
20949
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
228 |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
229 def __getitem__(self, cat): |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
230 return tuple(self._categories.get(cat, ())) |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
231 |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
232 def __iter__(self): |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
233 return iter(self._sequences) |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
234 |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
235 def __len__(self): |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
236 return len(self._sequences) |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
237 |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
238 def __nonzero__(self): |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
239 return bool(self._sequences) |
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
240 |
20948
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
241 class bundleoperation(object): |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
242 """an object that represents a single bundling process |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
243 |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
244 Its purpose is to carry unbundle-related objects and states. |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
245 |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
246 A new object should be created at the beginning of each bundle processing. |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
247 The object is to be returned by the processing function. |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
248 |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
249 The object has very little content now it will ultimately contain: |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
250 * an access to the repo the bundle is applied to, |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
251 * a ui object, |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
252 * a way to retrieve a transaction to add changes to the repo, |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
253 * a way to record the result of processing each part, |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
254 * a way to construct a bundle response when applicable. |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
255 """ |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
256 |
20952
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
257 def __init__(self, repo, transactiongetter): |
20948
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
258 self.repo = repo |
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
259 self.ui = repo.ui |
20949
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
260 self.records = unbundlerecords() |
20952
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
261 self.gettransaction = transactiongetter |
20997
d7df4b7378ae
bundle2: produce a bundle2 reply
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20996
diff
changeset
|
262 self.reply = None |
20948
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
263 |
20952
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
264 class TransactionUnavailable(RuntimeError): |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
265 pass |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
266 |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
267 def _notransaction(): |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
268 """default method to get a transaction while processing a bundle |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
269 |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
270 Raise an exception to highlight the fact that no transaction was expected |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
271 to be created""" |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
272 raise TransactionUnavailable() |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
273 |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
274 def processbundle(repo, unbundler, transactiongetter=_notransaction): |
20889
deed5edb72de
bundle2: first version of a bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20887
diff
changeset
|
275 """This function process a bundle, apply effect to/from a repo |
deed5edb72de
bundle2: first version of a bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20887
diff
changeset
|
276 |
20947
c33d7bf53812
bundle2: feed a unbundle20 to the `processbundle` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20892
diff
changeset
|
277 It iterates over each part then searches for and uses the proper handling |
c33d7bf53812
bundle2: feed a unbundle20 to the `processbundle` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20892
diff
changeset
|
278 code to process the part. Parts are processed in order. |
20889
deed5edb72de
bundle2: first version of a bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20887
diff
changeset
|
279 |
deed5edb72de
bundle2: first version of a bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20887
diff
changeset
|
280 This is very early version of this function that will be strongly reworked |
deed5edb72de
bundle2: first version of a bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20887
diff
changeset
|
281 before final usage. |
deed5edb72de
bundle2: first version of a bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20887
diff
changeset
|
282 |
20891
1c6cd23fc221
bundle2: add some distinction between mandatory and advisory part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20890
diff
changeset
|
283 Unknown Mandatory part will abort the process. |
20889
deed5edb72de
bundle2: first version of a bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20887
diff
changeset
|
284 """ |
20952
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
285 op = bundleoperation(repo, transactiongetter) |
20889
deed5edb72de
bundle2: first version of a bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20887
diff
changeset
|
286 # todo: |
deed5edb72de
bundle2: first version of a bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20887
diff
changeset
|
287 # - replace this is a init function soon. |
deed5edb72de
bundle2: first version of a bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20887
diff
changeset
|
288 # - exception catching |
deed5edb72de
bundle2: first version of a bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20887
diff
changeset
|
289 unbundler.params |
21129
07bcbf326c8d
bundle2: use an official iterparts method to unbundle parts
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21066
diff
changeset
|
290 iterparts = unbundler.iterparts() |
21019
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
291 part = None |
20892
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
292 try: |
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
293 for part in iterparts: |
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
294 parttype = part.type |
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
295 # part key are matched lower case |
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
296 key = parttype.lower() |
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
297 try: |
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
298 handler = parthandlermapping[key] |
20948
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
299 op.ui.debug('found a handler for part %r\n' % parttype) |
20892
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
300 except KeyError: |
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
301 if key != parttype: # mandatory parts |
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
302 # todo: |
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
303 # - use a more precise exception |
21179
372f4772f7a0
bundle2: use a more specific UnknownPartError when no handler is found
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21177
diff
changeset
|
304 raise UnknownPartError(key) |
20948
329cd74b52bd
bundle2: introduce a bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20947
diff
changeset
|
305 op.ui.debug('ignoring unknown advisory part %r\n' % key) |
21019
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
306 # consuming the part |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
307 part.read() |
20892
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
308 continue |
21004
27ab4b8d2503
bundle2: comment to clarify why the handler call is where it is
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21001
diff
changeset
|
309 |
27ab4b8d2503
bundle2: comment to clarify why the handler call is where it is
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21001
diff
changeset
|
310 # handler is called outside the above try block so that we don't |
27ab4b8d2503
bundle2: comment to clarify why the handler call is where it is
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21001
diff
changeset
|
311 # risk catching KeyErrors from anything other than the |
27ab4b8d2503
bundle2: comment to clarify why the handler call is where it is
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21001
diff
changeset
|
312 # parthandlermapping lookup (any KeyError raised by handler() |
27ab4b8d2503
bundle2: comment to clarify why the handler call is where it is
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21001
diff
changeset
|
313 # itself represents a defect of a different variety). |
21131
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
314 output = None |
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
315 if op.reply is not None: |
21133
bef4a2adc532
bundle2: include stderr when capturing handlers output
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21131
diff
changeset
|
316 op.ui.pushbuffer(error=True) |
21131
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
317 output = '' |
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
318 try: |
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
319 handler(op, part) |
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
320 finally: |
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
321 if output is not None: |
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
322 output = op.ui.popbuffer() |
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
323 if output: |
21146
4676135ac555
bundle2: move all parts into a `bx2` namespace
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21144
diff
changeset
|
324 outpart = bundlepart('b2x:output', |
21131
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
325 advisoryparams=[('in-reply-to', |
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
326 str(part.id))], |
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
327 data=output) |
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
328 op.reply.addpart(outpart) |
21019
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
329 part.read() |
21176
70fcb0a71445
bundle2: decorate exception raised during bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21146
diff
changeset
|
330 except Exception, exc: |
21019
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
331 if part is not None: |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
332 # consume the bundle content |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
333 part.read() |
20892
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
334 for part in iterparts: |
21019
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
335 # consume the bundle content |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
336 part.read() |
21176
70fcb0a71445
bundle2: decorate exception raised during bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21146
diff
changeset
|
337 # Small hack to let caller code distinguish exceptions from bundle2 |
70fcb0a71445
bundle2: decorate exception raised during bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21146
diff
changeset
|
338 # processing fron the ones from bundle1 processing. This is mostly |
70fcb0a71445
bundle2: decorate exception raised during bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21146
diff
changeset
|
339 # needed to handle different return codes to unbundle according to the |
70fcb0a71445
bundle2: decorate exception raised during bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21146
diff
changeset
|
340 # type of bundle. We should probably clean up or drop this return code |
70fcb0a71445
bundle2: decorate exception raised during bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21146
diff
changeset
|
341 # craziness in a future version. |
70fcb0a71445
bundle2: decorate exception raised during bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21146
diff
changeset
|
342 exc.duringunbundle2 = True |
20892
6fe95448596d
bundle2: read the whole bundle from stream on abort
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20891
diff
changeset
|
343 raise |
20949
571f2903ff1e
bundle2: record processing results in the bundleoperation object
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20948
diff
changeset
|
344 return op |
20889
deed5edb72de
bundle2: first version of a bundle processing
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20887
diff
changeset
|
345 |
21138
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
346 def decodecaps(blob): |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
347 """decode a bundle2 caps bytes blob into a dictionnary |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
348 |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
349 The blob is a list of capabilities (one per line) |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
350 Capabilities may have values using a line of the form:: |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
351 |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
352 capability=value1,value2,value3 |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
353 |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
354 The values are always a list.""" |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
355 caps = {} |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
356 for line in blob.splitlines(): |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
357 if not line: |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
358 continue |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
359 if '=' not in line: |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
360 key, vals = line, () |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
361 else: |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
362 key, vals = line.split('=', 1) |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
363 vals = vals.split(',') |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
364 key = urllib.unquote(key) |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
365 vals = [urllib.unquote(v) for v in vals] |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
366 caps[key] = vals |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
367 return caps |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
368 |
21139
2b8c82f7f11d
bundle2: capabilities encoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21138
diff
changeset
|
369 def encodecaps(caps): |
2b8c82f7f11d
bundle2: capabilities encoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21138
diff
changeset
|
370 """encode a bundle2 caps dictionary into a bytes blob""" |
2b8c82f7f11d
bundle2: capabilities encoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21138
diff
changeset
|
371 chunks = [] |
2b8c82f7f11d
bundle2: capabilities encoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21138
diff
changeset
|
372 for ca in sorted(caps): |
2b8c82f7f11d
bundle2: capabilities encoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21138
diff
changeset
|
373 vals = caps[ca] |
2b8c82f7f11d
bundle2: capabilities encoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21138
diff
changeset
|
374 ca = urllib.quote(ca) |
2b8c82f7f11d
bundle2: capabilities encoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21138
diff
changeset
|
375 vals = [urllib.quote(v) for v in vals] |
2b8c82f7f11d
bundle2: capabilities encoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21138
diff
changeset
|
376 if vals: |
2b8c82f7f11d
bundle2: capabilities encoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21138
diff
changeset
|
377 ca = "%s=%s" % (ca, ','.join(vals)) |
2b8c82f7f11d
bundle2: capabilities encoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21138
diff
changeset
|
378 chunks.append(ca) |
2b8c82f7f11d
bundle2: capabilities encoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21138
diff
changeset
|
379 return '\n'.join(chunks) |
2b8c82f7f11d
bundle2: capabilities encoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21138
diff
changeset
|
380 |
20801
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
381 class bundle20(object): |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
382 """represent an outgoing bundle2 container |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
383 |
20856
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
384 Use the `addparam` method to add stream level parameter. and `addpart` to |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
385 populate it. Then call `getchunks` to retrieve all the binary chunks of |
21024
7731a2281cf0
spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents:
21020
diff
changeset
|
386 data that compose the bundle2 container.""" |
20801
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
387 |
21134
2f8c4fa237f5
bundle2: adds a capabilities attribute on bundler20
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21133
diff
changeset
|
388 def __init__(self, ui, capabilities=()): |
20842
938718d72624
bundle2: print debug information during bundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20814
diff
changeset
|
389 self.ui = ui |
20801
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
390 self._params = [] |
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
391 self._parts = [] |
21136
b6fd496e5c72
bundle2: support for capabilities with values
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21135
diff
changeset
|
392 self.capabilities = dict(capabilities) |
20801
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
393 |
20804
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
394 def addparam(self, name, value=None): |
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
395 """add a stream level parameter""" |
20813
8c74b3ce5b70
bundle2: refuse empty parameter name
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20812
diff
changeset
|
396 if not name: |
8c74b3ce5b70
bundle2: refuse empty parameter name
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20812
diff
changeset
|
397 raise ValueError('empty parameter name') |
20814
8532f5e1b9df
bundle2: force the first char of parameter to be an letter.
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20813
diff
changeset
|
398 if name[0] not in string.letters: |
8532f5e1b9df
bundle2: force the first char of parameter to be an letter.
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20813
diff
changeset
|
399 raise ValueError('non letter first character: %r' % name) |
20804
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
400 self._params.append((name, value)) |
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
401 |
20856
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
402 def addpart(self, part): |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
403 """add a new part to the bundle2 container |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
404 |
21024
7731a2281cf0
spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents:
21020
diff
changeset
|
405 Parts contains the actual applicative payload.""" |
20995
e995d104c87f
bundle2: add an integer id to part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20952
diff
changeset
|
406 assert part.id is None |
e995d104c87f
bundle2: add an integer id to part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20952
diff
changeset
|
407 part.id = len(self._parts) # very cheap counter |
20856
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
408 self._parts.append(part) |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
409 |
20801
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
410 def getchunks(self): |
20842
938718d72624
bundle2: print debug information during bundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20814
diff
changeset
|
411 self.ui.debug('start emission of %s stream\n' % _magicstring) |
20801
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
412 yield _magicstring |
20804
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
413 param = self._paramchunk() |
20842
938718d72624
bundle2: print debug information during bundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20814
diff
changeset
|
414 self.ui.debug('bundle parameter: %s\n' % param) |
20804
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
415 yield _pack(_fstreamparamsize, len(param)) |
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
416 if param: |
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
417 yield param |
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
418 |
20856
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
419 self.ui.debug('start of parts\n') |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
420 for part in self._parts: |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
421 self.ui.debug('bundle part: "%s"\n' % part.type) |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
422 for chunk in part.getchunks(): |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
423 yield chunk |
20842
938718d72624
bundle2: print debug information during bundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20814
diff
changeset
|
424 self.ui.debug('end of bundle\n') |
20801
9c5183cb9bca
bundle2: very first version of a bundle2 bundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
diff
changeset
|
425 yield '\0\0' |
20802
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
426 |
20804
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
427 def _paramchunk(self): |
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
428 """return a encoded version of all stream parameters""" |
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
429 blocks = [] |
20809
b93bb639451a
bundle2: support for bundling parameter value
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20808
diff
changeset
|
430 for par, value in self._params: |
20811
9785c3f8f598
bundle2: urlquote stream parameter name and value
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20810
diff
changeset
|
431 par = urllib.quote(par) |
20809
b93bb639451a
bundle2: support for bundling parameter value
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20808
diff
changeset
|
432 if value is not None: |
20811
9785c3f8f598
bundle2: urlquote stream parameter name and value
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20810
diff
changeset
|
433 value = urllib.quote(value) |
20809
b93bb639451a
bundle2: support for bundling parameter value
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20808
diff
changeset
|
434 par = '%s=%s' % (par, value) |
b93bb639451a
bundle2: support for bundling parameter value
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20808
diff
changeset
|
435 blocks.append(par) |
20804
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
436 return ' '.join(blocks) |
db9d3991d2c6
bundle2: support bundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20803
diff
changeset
|
437 |
21013
a813caca89b3
bundle2: extract stream/unpack logic in an unpackermixin
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21005
diff
changeset
|
438 class unpackermixin(object): |
a813caca89b3
bundle2: extract stream/unpack logic in an unpackermixin
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21005
diff
changeset
|
439 """A mixin to extract bytes and struct data from a stream""" |
20802
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
440 |
21013
a813caca89b3
bundle2: extract stream/unpack logic in an unpackermixin
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21005
diff
changeset
|
441 def __init__(self, fp): |
20802
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
442 self._fp = fp |
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
443 |
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
444 def _unpack(self, format): |
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
445 """unpack this struct format from the stream""" |
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
446 data = self._readexact(struct.calcsize(format)) |
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
447 return _unpack(format, data) |
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
448 |
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
449 def _readexact(self, size): |
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
450 """read exactly <size> bytes from the stream""" |
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
451 return changegroup.readexactly(self._fp, size) |
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
452 |
21013
a813caca89b3
bundle2: extract stream/unpack logic in an unpackermixin
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21005
diff
changeset
|
453 |
a813caca89b3
bundle2: extract stream/unpack logic in an unpackermixin
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21005
diff
changeset
|
454 class unbundle20(unpackermixin): |
a813caca89b3
bundle2: extract stream/unpack logic in an unpackermixin
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21005
diff
changeset
|
455 """interpret a bundle2 stream |
a813caca89b3
bundle2: extract stream/unpack logic in an unpackermixin
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21005
diff
changeset
|
456 |
21129
07bcbf326c8d
bundle2: use an official iterparts method to unbundle parts
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21066
diff
changeset
|
457 This class is fed with a binary stream and yields parts through its |
07bcbf326c8d
bundle2: use an official iterparts method to unbundle parts
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21066
diff
changeset
|
458 `iterparts` methods.""" |
21013
a813caca89b3
bundle2: extract stream/unpack logic in an unpackermixin
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21005
diff
changeset
|
459 |
21066
5ecfe76d0d96
bundle2: make header reading optional
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21062
diff
changeset
|
460 def __init__(self, ui, fp, header=None): |
5ecfe76d0d96
bundle2: make header reading optional
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21062
diff
changeset
|
461 """If header is specified, we do not read it out of the stream.""" |
21013
a813caca89b3
bundle2: extract stream/unpack logic in an unpackermixin
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21005
diff
changeset
|
462 self.ui = ui |
a813caca89b3
bundle2: extract stream/unpack logic in an unpackermixin
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21005
diff
changeset
|
463 super(unbundle20, self).__init__(fp) |
21066
5ecfe76d0d96
bundle2: make header reading optional
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21062
diff
changeset
|
464 if header is None: |
5ecfe76d0d96
bundle2: make header reading optional
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21062
diff
changeset
|
465 header = self._readexact(4) |
5ecfe76d0d96
bundle2: make header reading optional
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21062
diff
changeset
|
466 magic, version = header[0:2], header[2:4] |
5ecfe76d0d96
bundle2: make header reading optional
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21062
diff
changeset
|
467 if magic != 'HG': |
5ecfe76d0d96
bundle2: make header reading optional
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21062
diff
changeset
|
468 raise util.Abort(_('not a Mercurial bundle')) |
21144
7a20fe8dc080
bundle2: use HG2X in the header
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21139
diff
changeset
|
469 if version != '2X': |
21066
5ecfe76d0d96
bundle2: make header reading optional
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21062
diff
changeset
|
470 raise util.Abort(_('unknown bundle version %s') % version) |
21013
a813caca89b3
bundle2: extract stream/unpack logic in an unpackermixin
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21005
diff
changeset
|
471 self.ui.debug('start processing of %s stream\n' % header) |
a813caca89b3
bundle2: extract stream/unpack logic in an unpackermixin
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21005
diff
changeset
|
472 |
20802
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
473 @util.propertycache |
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
474 def params(self): |
21024
7731a2281cf0
spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents:
21020
diff
changeset
|
475 """dictionary of stream level parameters""" |
20843
0641b41b0b49
bundle2: print debug information during unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20842
diff
changeset
|
476 self.ui.debug('reading bundle2 stream parameters\n') |
20805
c5aaeca0cfbf
bundle2: support for unbundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20804
diff
changeset
|
477 params = {} |
c5aaeca0cfbf
bundle2: support for unbundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20804
diff
changeset
|
478 paramssize = self._unpack(_fstreamparamsize)[0] |
c5aaeca0cfbf
bundle2: support for unbundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20804
diff
changeset
|
479 if paramssize: |
c5aaeca0cfbf
bundle2: support for unbundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20804
diff
changeset
|
480 for p in self._readexact(paramssize).split(' '): |
20810
47293877b54c
bundle2: support for unbundling parameter value
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20809
diff
changeset
|
481 p = p.split('=', 1) |
20812
e2f908773754
bundle2: urlunquote stream parameter name and value during unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20811
diff
changeset
|
482 p = [urllib.unquote(i) for i in p] |
20810
47293877b54c
bundle2: support for unbundling parameter value
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20809
diff
changeset
|
483 if len(p) < 2: |
47293877b54c
bundle2: support for unbundling parameter value
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20809
diff
changeset
|
484 p.append(None) |
20844
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
485 self._processparam(*p) |
20810
47293877b54c
bundle2: support for unbundling parameter value
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20809
diff
changeset
|
486 params[p[0]] = p[1] |
20805
c5aaeca0cfbf
bundle2: support for unbundling simple parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20804
diff
changeset
|
487 return params |
20802
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
488 |
20844
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
489 def _processparam(self, name, value): |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
490 """process a parameter, applying its effect if needed |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
491 |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
492 Parameter starting with a lower case letter are advisory and will be |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
493 ignored when unknown. Those starting with an upper case letter are |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
494 mandatory and will this function will raise a KeyError when unknown. |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
495 |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
496 Note: no option are currently supported. Any input will be either |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
497 ignored or failing. |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
498 """ |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
499 if not name: |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
500 raise ValueError('empty parameter name') |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
501 if name[0] not in string.letters: |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
502 raise ValueError('non letter first character: %r' % name) |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
503 # Some logic will be later added here to try to process the option for |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
504 # a dict of known parameter. |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
505 if name[0].islower(): |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
506 self.ui.debug("ignoring unknown parameter %r\n" % name) |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
507 else: |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
508 raise KeyError(name) |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
509 |
2631204d7305
bundle2: implement the mandatory/advisory logic for parameter
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20843
diff
changeset
|
510 |
21129
07bcbf326c8d
bundle2: use an official iterparts method to unbundle parts
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21066
diff
changeset
|
511 def iterparts(self): |
20802
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
512 """yield all parts contained in the stream""" |
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
513 # make sure param have been loaded |
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
514 self.params |
20843
0641b41b0b49
bundle2: print debug information during unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20842
diff
changeset
|
515 self.ui.debug('start extraction of bundle2 parts\n') |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
516 headerblock = self._readpartheader() |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
517 while headerblock is not None: |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
518 part = unbundlepart(self.ui, headerblock, self._fp) |
20802
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
519 yield part |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
520 headerblock = self._readpartheader() |
20843
0641b41b0b49
bundle2: print debug information during unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20842
diff
changeset
|
521 self.ui.debug('end of bundle2 stream\n') |
20802
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
522 |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
523 def _readpartheader(self): |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
524 """reads a part header size and return the bytes blob |
20864
9a75d2559cff
bundle2: support unbundling empty part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20856
diff
changeset
|
525 |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
526 returns None if empty""" |
20864
9a75d2559cff
bundle2: support unbundling empty part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20856
diff
changeset
|
527 headersize = self._unpack(_fpartheadersize)[0] |
9a75d2559cff
bundle2: support unbundling empty part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20856
diff
changeset
|
528 self.ui.debug('part header size: %i\n' % headersize) |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
529 if headersize: |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
530 return self._readexact(headersize) |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
531 return None |
20864
9a75d2559cff
bundle2: support unbundling empty part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20856
diff
changeset
|
532 |
20802
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
533 |
21005
3d38ebb586fe
bundle2: rename part to bundlepart
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21004
diff
changeset
|
534 class bundlepart(object): |
20856
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
535 """A bundle2 part contains application level payload |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
536 |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
537 The part `type` is used to route the part to the application level |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
538 handler. |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
539 """ |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
540 |
20877
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
541 def __init__(self, parttype, mandatoryparams=(), advisoryparams=(), |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
542 data=''): |
20995
e995d104c87f
bundle2: add an integer id to part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20952
diff
changeset
|
543 self.id = None |
20856
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
544 self.type = parttype |
20864
9a75d2559cff
bundle2: support unbundling empty part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20856
diff
changeset
|
545 self.data = data |
20877
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
546 self.mandatoryparams = mandatoryparams |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
547 self.advisoryparams = advisoryparams |
20856
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
548 |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
549 def getchunks(self): |
20877
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
550 #### header |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
551 ## parttype |
20856
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
552 header = [_pack(_fparttypesize, len(self.type)), |
20995
e995d104c87f
bundle2: add an integer id to part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20952
diff
changeset
|
553 self.type, _pack(_fpartid, self.id), |
20856
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
554 ] |
20877
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
555 ## parameters |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
556 # count |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
557 manpar = self.mandatoryparams |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
558 advpar = self.advisoryparams |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
559 header.append(_pack(_fpartparamcount, len(manpar), len(advpar))) |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
560 # size |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
561 parsizes = [] |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
562 for key, value in manpar: |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
563 parsizes.append(len(key)) |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
564 parsizes.append(len(value)) |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
565 for key, value in advpar: |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
566 parsizes.append(len(key)) |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
567 parsizes.append(len(value)) |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
568 paramsizes = _pack(_makefpartparamsizes(len(parsizes) / 2), *parsizes) |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
569 header.append(paramsizes) |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
570 # key, value |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
571 for key, value in manpar: |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
572 header.append(key) |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
573 header.append(value) |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
574 for key, value in advpar: |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
575 header.append(key) |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
576 header.append(value) |
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
577 ## finalize header |
20856
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
578 headerchunk = ''.join(header) |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
579 yield _pack(_fpartheadersize, len(headerchunk)) |
8a6a86c9a5b5
bundle2: support bundling of empty part (with a type)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20844
diff
changeset
|
580 yield headerchunk |
20877
9e9e3a4e9261
bundle2: part params
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20876
diff
changeset
|
581 ## payload |
21000
4cae06ae1562
bundle2: extract a _payloadchunks method for part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20998
diff
changeset
|
582 for chunk in self._payloadchunks(): |
4cae06ae1562
bundle2: extract a _payloadchunks method for part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20998
diff
changeset
|
583 yield _pack(_fpayloadsize, len(chunk)) |
4cae06ae1562
bundle2: extract a _payloadchunks method for part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20998
diff
changeset
|
584 yield chunk |
4cae06ae1562
bundle2: extract a _payloadchunks method for part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20998
diff
changeset
|
585 # end of payload |
4cae06ae1562
bundle2: extract a _payloadchunks method for part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20998
diff
changeset
|
586 yield _pack(_fpayloadsize, 0) |
4cae06ae1562
bundle2: extract a _payloadchunks method for part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20998
diff
changeset
|
587 |
4cae06ae1562
bundle2: extract a _payloadchunks method for part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20998
diff
changeset
|
588 def _payloadchunks(self): |
4cae06ae1562
bundle2: extract a _payloadchunks method for part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20998
diff
changeset
|
589 """yield chunks of a the part payload |
4cae06ae1562
bundle2: extract a _payloadchunks method for part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20998
diff
changeset
|
590 |
4cae06ae1562
bundle2: extract a _payloadchunks method for part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20998
diff
changeset
|
591 Exists to handle the different methods to provide data to a part.""" |
20876
ddd56f3eb786
bundle2: support for bundling and unbundling payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20864
diff
changeset
|
592 # we only support fixed size data now. |
ddd56f3eb786
bundle2: support for bundling and unbundling payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20864
diff
changeset
|
593 # This will be improved in the future. |
21001
c93bb6a08fa1
bundle2: support chunk iterator as part data
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21000
diff
changeset
|
594 if util.safehasattr(self.data, 'next'): |
c93bb6a08fa1
bundle2: support chunk iterator as part data
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21000
diff
changeset
|
595 buff = util.chunkbuffer(self.data) |
c93bb6a08fa1
bundle2: support chunk iterator as part data
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21000
diff
changeset
|
596 chunk = buff.read(preferedchunksize) |
c93bb6a08fa1
bundle2: support chunk iterator as part data
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21000
diff
changeset
|
597 while chunk: |
c93bb6a08fa1
bundle2: support chunk iterator as part data
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21000
diff
changeset
|
598 yield chunk |
c93bb6a08fa1
bundle2: support chunk iterator as part data
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21000
diff
changeset
|
599 chunk = buff.read(preferedchunksize) |
c93bb6a08fa1
bundle2: support chunk iterator as part data
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21000
diff
changeset
|
600 elif len(self.data): |
20876
ddd56f3eb786
bundle2: support for bundling and unbundling payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20864
diff
changeset
|
601 yield self.data |
20802
520df53ad26a
bundle2: a very first version of bundle2 unbundler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20801
diff
changeset
|
602 |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
603 class unbundlepart(unpackermixin): |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
604 """a bundle part read from a bundle""" |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
605 |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
606 def __init__(self, ui, header, fp): |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
607 super(unbundlepart, self).__init__(fp) |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
608 self.ui = ui |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
609 # unbundle state attr |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
610 self._headerdata = header |
21015
14dd49260246
bundle2: move the fromheader closure into the class itself
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21014
diff
changeset
|
611 self._headeroffset = 0 |
21019
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
612 self._initialized = False |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
613 self.consumed = False |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
614 # part data |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
615 self.id = None |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
616 self.type = None |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
617 self.mandatoryparams = None |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
618 self.advisoryparams = None |
21019
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
619 self._payloadstream = None |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
620 self._readheader() |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
621 |
21015
14dd49260246
bundle2: move the fromheader closure into the class itself
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21014
diff
changeset
|
622 def _fromheader(self, size): |
14dd49260246
bundle2: move the fromheader closure into the class itself
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21014
diff
changeset
|
623 """return the next <size> byte from the header""" |
14dd49260246
bundle2: move the fromheader closure into the class itself
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21014
diff
changeset
|
624 offset = self._headeroffset |
14dd49260246
bundle2: move the fromheader closure into the class itself
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21014
diff
changeset
|
625 data = self._headerdata[offset:(offset + size)] |
21019
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
626 self._headeroffset = offset + size |
21015
14dd49260246
bundle2: move the fromheader closure into the class itself
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21014
diff
changeset
|
627 return data |
14dd49260246
bundle2: move the fromheader closure into the class itself
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21014
diff
changeset
|
628 |
21016
b477afb1c81e
bundle2: move unpackheader closure into the class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21015
diff
changeset
|
629 def _unpackheader(self, format): |
b477afb1c81e
bundle2: move unpackheader closure into the class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21015
diff
changeset
|
630 """read given format from header |
b477afb1c81e
bundle2: move unpackheader closure into the class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21015
diff
changeset
|
631 |
b477afb1c81e
bundle2: move unpackheader closure into the class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21015
diff
changeset
|
632 This automatically compute the size of the format to read.""" |
b477afb1c81e
bundle2: move unpackheader closure into the class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21015
diff
changeset
|
633 data = self._fromheader(struct.calcsize(format)) |
b477afb1c81e
bundle2: move unpackheader closure into the class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21015
diff
changeset
|
634 return _unpack(format, data) |
b477afb1c81e
bundle2: move unpackheader closure into the class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21015
diff
changeset
|
635 |
21019
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
636 def _readheader(self): |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
637 """read the header and setup the object""" |
21016
b477afb1c81e
bundle2: move unpackheader closure into the class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21015
diff
changeset
|
638 typesize = self._unpackheader(_fparttypesize)[0] |
21015
14dd49260246
bundle2: move the fromheader closure into the class itself
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21014
diff
changeset
|
639 self.type = self._fromheader(typesize) |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
640 self.ui.debug('part type: "%s"\n' % self.type) |
21016
b477afb1c81e
bundle2: move unpackheader closure into the class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21015
diff
changeset
|
641 self.id = self._unpackheader(_fpartid)[0] |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
642 self.ui.debug('part id: "%s"\n' % self.id) |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
643 ## reading parameters |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
644 # param count |
21016
b477afb1c81e
bundle2: move unpackheader closure into the class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21015
diff
changeset
|
645 mancount, advcount = self._unpackheader(_fpartparamcount) |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
646 self.ui.debug('part parameters: %i\n' % (mancount + advcount)) |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
647 # param size |
21016
b477afb1c81e
bundle2: move unpackheader closure into the class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21015
diff
changeset
|
648 fparamsizes = _makefpartparamsizes(mancount + advcount) |
b477afb1c81e
bundle2: move unpackheader closure into the class
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21015
diff
changeset
|
649 paramsizes = self._unpackheader(fparamsizes) |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
650 # make it a list of couple again |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
651 paramsizes = zip(paramsizes[::2], paramsizes[1::2]) |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
652 # split mandatory from advisory |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
653 mansizes = paramsizes[:mancount] |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
654 advsizes = paramsizes[mancount:] |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
655 # retrive param value |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
656 manparams = [] |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
657 for key, value in mansizes: |
21015
14dd49260246
bundle2: move the fromheader closure into the class itself
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21014
diff
changeset
|
658 manparams.append((self._fromheader(key), self._fromheader(value))) |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
659 advparams = [] |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
660 for key, value in advsizes: |
21015
14dd49260246
bundle2: move the fromheader closure into the class itself
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21014
diff
changeset
|
661 advparams.append((self._fromheader(key), self._fromheader(value))) |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
662 self.mandatoryparams = manparams |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
663 self.advisoryparams = advparams |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
664 ## part payload |
21019
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
665 def payloadchunks(): |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
666 payloadsize = self._unpack(_fpayloadsize)[0] |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
667 self.ui.debug('payload chunk size: %i\n' % payloadsize) |
21019
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
668 while payloadsize: |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
669 yield self._readexact(payloadsize) |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
670 payloadsize = self._unpack(_fpayloadsize)[0] |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
671 self.ui.debug('payload chunk size: %i\n' % payloadsize) |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
672 self._payloadstream = util.chunkbuffer(payloadchunks()) |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
673 # we read the data, tell it |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
674 self._initialized = True |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
675 |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
676 def read(self, size=None): |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
677 """read payload data""" |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
678 if not self._initialized: |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
679 self._readheader() |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
680 if size is None: |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
681 data = self._payloadstream.read() |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
682 else: |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
683 data = self._payloadstream.read(size) |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
684 if size is None or len(data) < size: |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
685 self.consumed = True |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
686 return data |
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
687 |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
688 |
21146
4676135ac555
bundle2: move all parts into a `bx2` namespace
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21144
diff
changeset
|
689 @parthandler('b2x:changegroup') |
20998
93a3c5b58635
bundle2: use reply part to return result of addchangegroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20997
diff
changeset
|
690 def handlechangegroup(op, inpart): |
20950
c7ceae0faf69
bundle2: first crude version of bundling changeset with bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20949
diff
changeset
|
691 """apply a changegroup part on the repo |
c7ceae0faf69
bundle2: first crude version of bundling changeset with bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20949
diff
changeset
|
692 |
c7ceae0faf69
bundle2: first crude version of bundling changeset with bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20949
diff
changeset
|
693 This is a very early implementation that will massive rework before being |
c7ceae0faf69
bundle2: first crude version of bundling changeset with bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20949
diff
changeset
|
694 inflicted to any end-user. |
c7ceae0faf69
bundle2: first crude version of bundling changeset with bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20949
diff
changeset
|
695 """ |
20952
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
696 # Make sure we trigger a transaction creation |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
697 # |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
698 # The addchangegroup function will get a transaction object by itself, but |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
699 # we need to make sure we trigger the creation of a transaction object used |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
700 # for the whole processing scope. |
b24ee5076b94
bundle2: make it possible have a global transaction for the unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20950
diff
changeset
|
701 op.gettransaction() |
21062
e7c0a65a5c9c
bundle2: use headerless HG10UN stream in changegroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21060
diff
changeset
|
702 cg = changegroup.unbundle10(inpart, 'UN') |
20950
c7ceae0faf69
bundle2: first crude version of bundling changeset with bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20949
diff
changeset
|
703 ret = changegroup.addchangegroup(op.repo, cg, 'bundle2', 'bundle2') |
c7ceae0faf69
bundle2: first crude version of bundling changeset with bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20949
diff
changeset
|
704 op.records.add('changegroup', {'return': ret}) |
20998
93a3c5b58635
bundle2: use reply part to return result of addchangegroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20997
diff
changeset
|
705 if op.reply is not None: |
93a3c5b58635
bundle2: use reply part to return result of addchangegroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20997
diff
changeset
|
706 # This is definitly not the final form of this |
93a3c5b58635
bundle2: use reply part to return result of addchangegroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20997
diff
changeset
|
707 # return. But one need to start somewhere. |
21146
4676135ac555
bundle2: move all parts into a `bx2` namespace
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21144
diff
changeset
|
708 part = bundlepart('b2x:reply:changegroup', (), |
21014
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
709 [('in-reply-to', str(inpart.id)), |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
710 ('return', '%i' % ret)]) |
a6246bba7b9e
bundle2: add an unbundle part responsible from unbundling part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21013
diff
changeset
|
711 op.reply.addpart(part) |
21019
3dc09f831a2e
bundle2: lazy unbundle of part payload
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21016
diff
changeset
|
712 assert not inpart.read() |
20950
c7ceae0faf69
bundle2: first crude version of bundling changeset with bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20949
diff
changeset
|
713 |
21146
4676135ac555
bundle2: move all parts into a `bx2` namespace
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21144
diff
changeset
|
714 @parthandler('b2x:reply:changegroup') |
20998
93a3c5b58635
bundle2: use reply part to return result of addchangegroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20997
diff
changeset
|
715 def handlechangegroup(op, inpart): |
93a3c5b58635
bundle2: use reply part to return result of addchangegroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20997
diff
changeset
|
716 p = dict(inpart.advisoryparams) |
93a3c5b58635
bundle2: use reply part to return result of addchangegroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20997
diff
changeset
|
717 ret = int(p['return']) |
93a3c5b58635
bundle2: use reply part to return result of addchangegroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20997
diff
changeset
|
718 op.records.add('changegroup', {'return': ret}, int(p['in-reply-to'])) |
20950
c7ceae0faf69
bundle2: first crude version of bundling changeset with bundle2
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20949
diff
changeset
|
719 |
21146
4676135ac555
bundle2: move all parts into a `bx2` namespace
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21144
diff
changeset
|
720 @parthandler('b2x:check:heads') |
21060
0bea9db7543b
bundle2: add a "check:heads" handler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21024
diff
changeset
|
721 def handlechangegroup(op, inpart): |
0bea9db7543b
bundle2: add a "check:heads" handler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21024
diff
changeset
|
722 """check that head of the repo did not change |
0bea9db7543b
bundle2: add a "check:heads" handler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21024
diff
changeset
|
723 |
0bea9db7543b
bundle2: add a "check:heads" handler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21024
diff
changeset
|
724 This is used to detect a push race when using unbundle. |
0bea9db7543b
bundle2: add a "check:heads" handler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21024
diff
changeset
|
725 This replaces the "heads" argument of unbundle.""" |
0bea9db7543b
bundle2: add a "check:heads" handler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21024
diff
changeset
|
726 h = inpart.read(20) |
0bea9db7543b
bundle2: add a "check:heads" handler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21024
diff
changeset
|
727 heads = [] |
0bea9db7543b
bundle2: add a "check:heads" handler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21024
diff
changeset
|
728 while len(h) == 20: |
0bea9db7543b
bundle2: add a "check:heads" handler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21024
diff
changeset
|
729 heads.append(h) |
0bea9db7543b
bundle2: add a "check:heads" handler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21024
diff
changeset
|
730 h = inpart.read(20) |
0bea9db7543b
bundle2: add a "check:heads" handler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21024
diff
changeset
|
731 assert not h |
0bea9db7543b
bundle2: add a "check:heads" handler
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21024
diff
changeset
|
732 if heads != op.repo.heads(): |
21185
5b3717e1a3ea
bundle2: add an error message to push race error
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21184
diff
changeset
|
733 raise error.PushRaced('repository changed while pushing - ' |
5b3717e1a3ea
bundle2: add an error message to push race error
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21184
diff
changeset
|
734 'please try again') |
21130
1ff06386217f
bundle2: introduce `replycaps` part for on-demand reply
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21129
diff
changeset
|
735 |
21146
4676135ac555
bundle2: move all parts into a `bx2` namespace
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21144
diff
changeset
|
736 @parthandler('b2x:output') |
21131
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
737 def handleoutput(op, inpart): |
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
738 """forward output captured on the server to the client""" |
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
739 for line in inpart.read().splitlines(): |
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
740 op.ui.write(('remote: %s\n' % line)) |
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
741 |
21146
4676135ac555
bundle2: move all parts into a `bx2` namespace
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21144
diff
changeset
|
742 @parthandler('b2x:replycaps') |
21130
1ff06386217f
bundle2: introduce `replycaps` part for on-demand reply
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21129
diff
changeset
|
743 def handlereplycaps(op, inpart): |
1ff06386217f
bundle2: introduce `replycaps` part for on-demand reply
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21129
diff
changeset
|
744 """Notify that a reply bundle should be created |
1ff06386217f
bundle2: introduce `replycaps` part for on-demand reply
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21129
diff
changeset
|
745 |
21138
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
746 The payload contains the capabilities information for the reply""" |
f469879d27ec
bundle2: extract capabilities decoding
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21137
diff
changeset
|
747 caps = decodecaps(inpart.read()) |
21130
1ff06386217f
bundle2: introduce `replycaps` part for on-demand reply
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21129
diff
changeset
|
748 if op.reply is None: |
21135
98fbf3adfd83
bundle2: add capabilities support in `replycaps` part
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21134
diff
changeset
|
749 op.reply = bundle20(op.ui, caps) |
21131
b7435117d951
bundle2: capture remote stdout while unbundling
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21130
diff
changeset
|
750 |
21177
952af771bc17
bundle2: gracefully handle abort during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21176
diff
changeset
|
751 @parthandler('b2x:error:abort') |
952af771bc17
bundle2: gracefully handle abort during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21176
diff
changeset
|
752 def handlereplycaps(op, inpart): |
952af771bc17
bundle2: gracefully handle abort during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21176
diff
changeset
|
753 """Used to transmit abort error over the wire""" |
952af771bc17
bundle2: gracefully handle abort during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21176
diff
changeset
|
754 manargs = dict(inpart.mandatoryparams) |
952af771bc17
bundle2: gracefully handle abort during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21176
diff
changeset
|
755 advargs = dict(inpart.advisoryparams) |
952af771bc17
bundle2: gracefully handle abort during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21176
diff
changeset
|
756 raise util.Abort(manargs['message'], hint=advargs.get('hint')) |
21183
4345274adc4b
bundle2: gracefully handle UnknownPartError during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21179
diff
changeset
|
757 |
4345274adc4b
bundle2: gracefully handle UnknownPartError during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21179
diff
changeset
|
758 @parthandler('b2x:error:unknownpart') |
4345274adc4b
bundle2: gracefully handle UnknownPartError during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21179
diff
changeset
|
759 def handlereplycaps(op, inpart): |
4345274adc4b
bundle2: gracefully handle UnknownPartError during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21179
diff
changeset
|
760 """Used to transmit unknown part error over the wire""" |
4345274adc4b
bundle2: gracefully handle UnknownPartError during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21179
diff
changeset
|
761 manargs = dict(inpart.mandatoryparams) |
4345274adc4b
bundle2: gracefully handle UnknownPartError during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21179
diff
changeset
|
762 raise UnknownPartError(manargs['parttype']) |
21186
9f3652e851f8
bundle2: gracefully handle PushRaced error during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21185
diff
changeset
|
763 |
9f3652e851f8
bundle2: gracefully handle PushRaced error during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21185
diff
changeset
|
764 @parthandler('b2x:error:pushraced') |
9f3652e851f8
bundle2: gracefully handle PushRaced error during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21185
diff
changeset
|
765 def handlereplycaps(op, inpart): |
9f3652e851f8
bundle2: gracefully handle PushRaced error during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21185
diff
changeset
|
766 """Used to transmit push race error over the wire""" |
9f3652e851f8
bundle2: gracefully handle PushRaced error during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21185
diff
changeset
|
767 manargs = dict(inpart.mandatoryparams) |
9f3652e851f8
bundle2: gracefully handle PushRaced error during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21185
diff
changeset
|
768 raise error.ResponseError(_('push failed:'), manargs['message']) |