comparison mercurial/bundle2.py @ 20891:1c6cd23fc221

bundle2: add some distinction between mandatory and advisory part Mandatory part cannot be ignored when unknown. We raise a simple KeyError exception when this happen. This is very early version of this logic, see inline comment for future improvement lead.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Mon, 24 Mar 2014 13:02:02 -0700
parents ec7fc110faee
children 6fe95448596d
comparison
equal deleted inserted replaced
20890:ec7fc110faee 20891:1c6cd23fc221
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