comparison mercurial/wireproto.py @ 21646:ce25f465e572

getbundle: declare type of parameters In addition to listing the expected options for ``getbundle``, we also list their types and handle the encoding/decoding automatically. This should make it easier for extensions to transmit additional information to getbundle.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Thu, 22 May 2014 09:53:52 -0700
parents 9bafe09285f2
children 3aae044408aa
comparison
equal deleted inserted replaced
21645:aed14bb165f3 21646:ce25f465e572
188 .replace(':=', '=') 188 .replace(':=', '=')
189 .replace(':;', ';') 189 .replace(':;', ';')
190 .replace(':,', ',') 190 .replace(':,', ',')
191 .replace('::', ':')) 191 .replace('::', ':'))
192 192
193 # mapping of options accepted by getbundle and their types
194 #
195 # Meant to be extended by extensions. It is extensions responsibility to ensure
196 # such options are properly processed in exchange.getbundle.
197 #
198 # supported types are:
199 #
200 # :nodes: list of binary nodes
201 # :csv: list of comma-separated values
202 # :plain: string with no transformation needed.
203 gboptsmap = {'heads': 'nodes',
204 'common': 'nodes',
205 'bundlecaps': 'csv'}
206
193 # client side 207 # client side
194 208
195 class wirepeer(peer.peerrepository): 209 class wirepeer(peer.peerrepository):
196 210
197 def batch(self): 211 def batch(self):
323 heads = encodelist(heads) 337 heads = encodelist(heads)
324 f = self._callcompressable("changegroupsubset", 338 f = self._callcompressable("changegroupsubset",
325 bases=bases, heads=heads) 339 bases=bases, heads=heads)
326 return changegroupmod.unbundle10(f, 'UN') 340 return changegroupmod.unbundle10(f, 'UN')
327 341
328 def getbundle(self, source, heads=None, common=None, bundlecaps=None, 342 def getbundle(self, source, **kwargs):
329 **kwargs):
330 self.requirecap('getbundle', _('look up remote changes')) 343 self.requirecap('getbundle', _('look up remote changes'))
331 opts = {} 344 opts = {}
332 if heads is not None: 345 for key, value in kwargs.iteritems():
333 opts['heads'] = encodelist(heads) 346 if value is None:
334 if common is not None: 347 continue
335 opts['common'] = encodelist(common) 348 keytype = gboptsmap.get(key)
336 if bundlecaps is not None: 349 if keytype is None:
337 opts['bundlecaps'] = ','.join(bundlecaps) 350 assert False, 'unexpected'
338 opts.update(kwargs) 351 elif keytype == 'nodes':
352 value = encodelist(value)
353 elif keytype == 'csv':
354 value = ','.join(value)
355 elif keytype != 'plain':
356 raise KeyError('unknown getbundle option type %s'
357 % keytype)
358 opts[key] = value
339 f = self._callcompressable("getbundle", **opts) 359 f = self._callcompressable("getbundle", **opts)
360 bundlecaps = kwargs.get('bundlecaps')
340 if bundlecaps is not None and 'HG2X' in bundlecaps: 361 if bundlecaps is not None and 'HG2X' in bundlecaps:
341 return bundle2.unbundle20(self.ui, f) 362 return bundle2.unbundle20(self.ui, f)
342 else: 363 else:
343 return changegroupmod.unbundle10(f, 'UN') 364 return changegroupmod.unbundle10(f, 'UN')
344 365
625 # ensure such options are properly processed in exchange.getbundle. 646 # ensure such options are properly processed in exchange.getbundle.
626 gboptslist = ['heads', 'common', 'bundlecaps'] 647 gboptslist = ['heads', 'common', 'bundlecaps']
627 648
628 @wireprotocommand('getbundle', '*') 649 @wireprotocommand('getbundle', '*')
629 def getbundle(repo, proto, others): 650 def getbundle(repo, proto, others):
630 opts = options('getbundle', gboptslist, others) 651 opts = options('getbundle', gboptsmap.keys(), others)
631 for k, v in opts.iteritems(): 652 for k, v in opts.iteritems():
632 if k in ('heads', 'common'): 653 keytype = gboptsmap[k]
654 if keytype == 'nodes':
633 opts[k] = decodelist(v) 655 opts[k] = decodelist(v)
634 elif k == 'bundlecaps': 656 elif keytype == 'csv':
635 opts[k] = set(v.split(',')) 657 opts[k] = set(v.split(','))
658 elif keytype != 'plain':
659 raise KeyError('unknown getbundle option type %s'
660 % keytype)
636 cg = exchange.getbundle(repo, 'serve', **opts) 661 cg = exchange.getbundle(repo, 'serve', **opts)
637 return streamres(proto.groupchunks(cg)) 662 return streamres(proto.groupchunks(cg))
638 663
639 @wireprotocommand('heads') 664 @wireprotocommand('heads')
640 def heads(repo, proto): 665 def heads(repo, proto):