##// END OF EJS Templates
wireproto: define and expose types of wire command arguments...
Gregory Szorc -
r37553:69e46c18 default
parent child Browse files
Show More
@@ -1712,7 +1712,12 b' commands'
1712 are:
1712 are:
1713
1713
1714 args
1714 args
1715 An array of argument names accepted by this command.
1715 A map of argument names and their expected types.
1716
1717 Types are defined as a representative value for the expected type.
1718 e.g. an argument expecting a boolean type will have its value
1719 set to true. An integer type will have its value set to 42. The
1720 actual values are arbitrary and may not have meaning.
1716 permissions
1721 permissions
1717 An array of permissions required to execute this command.
1722 An array of permissions required to execute this command.
1718
1723
@@ -713,8 +713,11 b" def wireprotocommand(name, args='', tran"
713
713
714 ``name`` is the name of the wire protocol command being provided.
714 ``name`` is the name of the wire protocol command being provided.
715
715
716 ``args`` is a space-delimited list of named arguments that the command
716 ``args`` defines the named arguments accepted by the command. It is
717 accepts. ``*`` is a special value that says to accept all arguments.
717 ideally a dict mapping argument names to their types. For backwards
718 compatibility, it can be a space-delimited list of argument names. For
719 version 1 transports, ``*`` denotes a special value that says to accept
720 all named arguments.
718
721
719 ``transportpolicy`` is a POLICY_* constant denoting which transports
722 ``transportpolicy`` is a POLICY_* constant denoting which transports
720 this wire protocol command should be exposed to. By default, commands
723 this wire protocol command should be exposed to. By default, commands
@@ -752,6 +755,17 b" def wireprotocommand(name, args='', tran"
752 'got %s; expected "push" or "pull"' %
755 'got %s; expected "push" or "pull"' %
753 permission)
756 permission)
754
757
758 if 1 in transportversions and not isinstance(args, bytes):
759 raise error.ProgrammingError('arguments for version 1 commands must '
760 'be declared as bytes')
761
762 if isinstance(args, bytes):
763 dictargs = {arg: b'legacy' for arg in args.split()}
764 elif isinstance(args, dict):
765 dictargs = args
766 else:
767 raise ValueError('args must be bytes or a dict')
768
755 def register(func):
769 def register(func):
756 if 1 in transportversions:
770 if 1 in transportversions:
757 if name in commands:
771 if name in commands:
@@ -764,7 +778,8 b" def wireprotocommand(name, args='', tran"
764 if name in commandsv2:
778 if name in commandsv2:
765 raise error.ProgrammingError('%s command already registered '
779 raise error.ProgrammingError('%s command already registered '
766 'for version 2' % name)
780 'for version 2' % name)
767 commandsv2[name] = commandentry(func, args=args,
781
782 commandsv2[name] = commandentry(func, args=dictargs,
768 transports=transports,
783 transports=transports,
769 permission=permission)
784 permission=permission)
770
785
@@ -1304,7 +1319,7 b' def _capabilitiesv2(repo, proto):'
1304
1319
1305 for command, entry in commandsv2.items():
1320 for command, entry in commandsv2.items():
1306 caps['commands'][command] = {
1321 caps['commands'][command] = {
1307 'args': sorted(entry.args.split()) if entry.args else [],
1322 'args': entry.args,
1308 'permissions': [entry.permission],
1323 'permissions': [entry.permission],
1309 }
1324 }
1310
1325
@@ -1325,7 +1340,11 b' def capabilitiesv2(repo, proto):'
1325
1340
1326 return wireprototypes.cborresponse(caps)
1341 return wireprototypes.cborresponse(caps)
1327
1342
1328 @wireprotocommand('heads', args='publiconly', permission='pull',
1343 @wireprotocommand('heads',
1344 args={
1345 'publiconly': False,
1346 },
1347 permission='pull',
1329 transportpolicy=POLICY_V2_ONLY)
1348 transportpolicy=POLICY_V2_ONLY)
1330 def headsv2(repo, proto, publiconly=False):
1349 def headsv2(repo, proto, publiconly=False):
1331 if publiconly:
1350 if publiconly:
@@ -1333,14 +1352,22 b' def headsv2(repo, proto, publiconly=Fals'
1333
1352
1334 return wireprototypes.cborresponse(repo.heads())
1353 return wireprototypes.cborresponse(repo.heads())
1335
1354
1336 @wireprotocommand('known', 'nodes', permission='pull',
1355 @wireprotocommand('known',
1356 args={
1357 'nodes': [b'deadbeef'],
1358 },
1359 permission='pull',
1337 transportpolicy=POLICY_V2_ONLY)
1360 transportpolicy=POLICY_V2_ONLY)
1338 def knownv2(repo, proto, nodes=None):
1361 def knownv2(repo, proto, nodes=None):
1339 nodes = nodes or []
1362 nodes = nodes or []
1340 result = b''.join(b'1' if n else b'0' for n in repo.known(nodes))
1363 result = b''.join(b'1' if n else b'0' for n in repo.known(nodes))
1341 return wireprototypes.cborresponse(result)
1364 return wireprototypes.cborresponse(result)
1342
1365
1343 @wireprotocommand('listkeys', 'namespace', permission='pull',
1366 @wireprotocommand('listkeys',
1367 args={
1368 'namespace': b'ns',
1369 },
1370 permission='pull',
1344 transportpolicy=POLICY_V2_ONLY)
1371 transportpolicy=POLICY_V2_ONLY)
1345 def listkeysv2(repo, proto, namespace=None):
1372 def listkeysv2(repo, proto, namespace=None):
1346 keys = repo.listkeys(encoding.tolocal(namespace))
1373 keys = repo.listkeys(encoding.tolocal(namespace))
@@ -606,10 +606,11 b' class httpv2protocolhandler(object):'
606
606
607 def getargs(self, args):
607 def getargs(self, args):
608 data = {}
608 data = {}
609 for k in args.split():
609 for k, typ in args.items():
610 if k == '*':
610 if k == '*':
611 raise NotImplementedError('do not support * args')
611 raise NotImplementedError('do not support * args')
612 elif k in self._args:
612 elif k in self._args:
613 # TODO consider validating value types.
613 data[k] = self._args[k]
614 data[k] = self._args[k]
614
615
615 return data
616 return data
@@ -30,11 +30,11 b' capabilities request returns an array of'
30 s> \r\n
30 s> \r\n
31 s> *\r\n (glob)
31 s> *\r\n (glob)
32 s> *\x00\x01\x00\x02\x01F (glob)
32 s> *\x00\x01\x00\x02\x01F (glob)
33 s> \xa2Hcommands\xaaEheads\xa2Dargs\x81JpubliconlyKpermissions\x81DpullEknown\xa2Dargs\x81EnodesKpermissions\x81DpullFlookup\xa2Dargs\x81CkeyKpermissions\x81DpullGpushkey\xa2Dargs\x84CkeyInamespaceCnewColdKpermissions\x81DpushHlistkeys\xa2Dargs\x81InamespaceKpermissions\x81DpullHunbundle\xa2Dargs\x81EheadsKpermissions\x81DpushIbranchmap\xa2Dargs\x80Kpermissions\x81DpullIgetbundle\xa2Dargs\x81A*Kpermissions\x81DpullLcapabilities\xa2Dargs\x80Kpermissions\x81DpullLclonebundles\xa2Dargs\x80Kpermissions\x81DpullKcompression\x82\xa1DnameDzstd\xa1DnameDzlib
33 s> \xa2Hcommands\xaaEheads\xa2Dargs\xa1Jpubliconly\xf4Kpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\x81HdeadbeefKpermissions\x81DpullFlookup\xa2Dargs\xa1CkeyFlegacyKpermissions\x81DpullGpushkey\xa2Dargs\xa4CkeyFlegacyCnewFlegacyColdFlegacyInamespaceFlegacyKpermissions\x81DpushHlistkeys\xa2Dargs\xa1InamespaceBnsKpermissions\x81DpullHunbundle\xa2Dargs\xa1EheadsFlegacyKpermissions\x81DpushIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullIgetbundle\xa2Dargs\xa1A*FlegacyKpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullLclonebundles\xa2Dargs\xa0Kpermissions\x81DpullKcompression\x82\xa1DnameDzstd\xa1DnameDzlib
34 s> \r\n
34 s> \r\n
35 received frame(size=*; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) (glob)
35 received frame(size=*; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) (glob)
36 s> 0\r\n
36 s> 0\r\n
37 s> \r\n
37 s> \r\n
38 response: [{b'commands': {b'branchmap': {b'args': [], b'permissions': [b'pull']}, b'capabilities': {b'args': [], b'permissions': [b'pull']}, b'clonebundles': {b'args': [], b'permissions': [b'pull']}, b'getbundle': {b'args': [b'*'], b'permissions': [b'pull']}, b'heads': {b'args': [b'publiconly'], b'permissions': [b'pull']}, b'known': {b'args': [b'nodes'], b'permissions': [b'pull']}, b'listkeys': {b'args': [b'namespace'], b'permissions': [b'pull']}, b'lookup': {b'args': [b'key'], b'permissions': [b'pull']}, b'pushkey': {b'args': [b'key', b'namespace', b'new', b'old'], b'permissions': [b'push']}, b'unbundle': {b'args': [b'heads'], b'permissions': [b'push']}}, b'compression': [{b'name': b'zstd'}, {b'name': b'zlib'}]}]
38 response: [{b'commands': {b'branchmap': {b'args': {}, b'permissions': [b'pull']}, b'capabilities': {b'args': {}, b'permissions': [b'pull']}, b'clonebundles': {b'args': {}, b'permissions': [b'pull']}, b'getbundle': {b'args': {b'*': b'legacy'}, b'permissions': [b'pull']}, b'heads': {b'args': {b'publiconly': False}, b'permissions': [b'pull']}, b'known': {b'args': {b'nodes': [b'deadbeef']}, b'permissions': [b'pull']}, b'listkeys': {b'args': {b'namespace': b'ns'}, b'permissions': [b'pull']}, b'lookup': {b'args': {b'key': b'legacy'}, b'permissions': [b'pull']}, b'pushkey': {b'args': {b'key': b'legacy', b'namespace': b'legacy', b'new': b'legacy', b'old': b'legacy'}, b'permissions': [b'push']}, b'unbundle': {b'args': {b'heads': b'legacy'}, b'permissions': [b'push']}}, b'compression': [{b'name': b'zstd'}, {b'name': b'zlib'}]}]
39
39
40 $ cat error.log
40 $ cat error.log
General Comments 0
You need to be logged in to leave comments. Login now