equal
deleted
inserted
replaced
117 `chunksize` is a 32 bits integer, `chunkdata` are plain bytes (as much as |
117 `chunksize` is a 32 bits integer, `chunkdata` are plain bytes (as much as |
118 `chunksize` says)` The payload part is concluded by a zero size chunk. |
118 `chunksize` says)` The payload part is concluded by a zero size chunk. |
119 |
119 |
120 The current implementation always produces either zero or one chunk. |
120 The current implementation always produces either zero or one chunk. |
121 This is an implementation limitation that will ultimatly be lifted. |
121 This is an implementation limitation that will ultimatly be lifted. |
|
122 |
|
123 Bundle processing |
|
124 ============================ |
|
125 |
|
126 Each part is processed in order using a "part handler". Handler are registered |
|
127 for a certain part type. |
|
128 |
|
129 The matching of a part to its handler is case insensitive. The case of the |
|
130 part type is used to know if a part is mandatory or advisory. If the Part type |
|
131 contains any uppercase char it is considered mandatory. When no handler is |
|
132 known for a Mandatory part, the process is aborted and an exception is raised. |
|
133 If the part is advisory and no handler is known, the part is ignored. |
|
134 |
122 """ |
135 """ |
123 |
136 |
124 import util |
137 import util |
125 import struct |
138 import struct |
126 import urllib |
139 import urllib |
159 def myparttypehandler(...): |
172 def myparttypehandler(...): |
160 '''process a part of type "my part".''' |
173 '''process a part of type "my part".''' |
161 ... |
174 ... |
162 """ |
175 """ |
163 def _decorator(func): |
176 def _decorator(func): |
164 assert parttype not in parthandlermapping |
177 lparttype = parttype.lower() # enforce lower case matching. |
165 parthandlermapping[parttype] = func |
178 assert lparttype not in parthandlermapping |
|
179 parthandlermapping[lparttype] = func |
166 return func |
180 return func |
167 return _decorator |
181 return _decorator |
168 |
182 |
169 def processbundle(repo, stream): |
183 def processbundle(repo, stream): |
170 """This function process a bundle, apply effect to/from a repo |
184 """This function process a bundle, apply effect to/from a repo |
177 Parts are processes in order. |
191 Parts are processes in order. |
178 |
192 |
179 This is very early version of this function that will be strongly reworked |
193 This is very early version of this function that will be strongly reworked |
180 before final usage. |
194 before final usage. |
181 |
195 |
182 All unknown parts are currently ignored (Mandatory parts logic will comes |
196 Unknown Mandatory part will abort the process. |
183 later). |
|
184 """ |
197 """ |
185 ui = repo.ui |
198 ui = repo.ui |
186 # Extraction of the unbundler object will most likely change. It may be |
199 # Extraction of the unbundler object will most likely change. It may be |
187 # done outside of this function, the unbundler would be passed as argument. |
200 # done outside of this function, the unbundler would be passed as argument. |
188 # in all case the unbundler will eventually be created by a |
201 # in all case the unbundler will eventually be created by a |
198 key = parttype.lower() |
211 key = parttype.lower() |
199 try: |
212 try: |
200 handler = parthandlermapping[key] |
213 handler = parthandlermapping[key] |
201 ui.debug('found an handler for part %r\n' % parttype) |
214 ui.debug('found an handler for part %r\n' % parttype) |
202 except KeyError: |
215 except KeyError: |
|
216 if key != parttype: # mandatory parts |
|
217 # todo: |
|
218 # - use a more precise exception |
|
219 # - consume the bundle2 stream anyway. |
|
220 raise |
203 ui.debug('ignoring unknown advisory part %r\n' % key) |
221 ui.debug('ignoring unknown advisory part %r\n' % key) |
204 # todo: consume the part (once we use streamed parts) |
222 # todo: consume the part (once we use streamed parts) |
205 continue |
223 continue |
206 handler(repo, part) |
224 handler(repo, part) |
207 |
225 |