diff --git a/mercurial/wireprotov2peer.py b/mercurial/wireprotov2peer.py --- a/mercurial/wireprotov2peer.py +++ b/mercurial/wireprotov2peer.py @@ -12,6 +12,7 @@ cbor, ) from . import ( + encoding, error, util, wireprotoframing, @@ -127,7 +128,13 @@ response.cbor = True if meta['eos']: - self._futures[frame.requestid].set_result(response) + # If the command has a decoder, resolve the future to the + # decoded value. Otherwise resolve to the rich response object. + decoder = COMMAND_DECODERS.get(response.command) + + result = decoder(response) if decoder else response + + self._futures[frame.requestid].set_result(result) del self._requests[frame.requestid] del self._futures[frame.requestid] @@ -135,3 +142,38 @@ else: raise error.ProgrammingError( 'unhandled action from clientreactor: %s' % action) + +def decodebranchmap(resp): + # Response should be a single CBOR map of branch name to array of nodes. + bm = next(resp.cborobjects()) + + return {encoding.tolocal(k): v for k, v in bm.items()} + +def decodeheads(resp): + # Array of node bytestrings. + return next(resp.cborobjects()) + +def decodeknown(resp): + # Bytestring where each byte is a 0 or 1. + raw = next(resp.cborobjects()) + + return [True if c == '1' else False for c in raw] + +def decodelistkeys(resp): + # Map with bytestring keys and values. + return next(resp.cborobjects()) + +def decodelookup(resp): + return next(resp.cborobjects()) + +def decodepushkey(resp): + return next(resp.cborobjects()) + +COMMAND_DECODERS = { + 'branchmap': decodebranchmap, + 'heads': decodeheads, + 'known': decodeknown, + 'listkeys': decodelistkeys, + 'lookup': decodelookup, + 'pushkey': decodepushkey, +} diff --git a/tests/test-wireproto-command-branchmap.t b/tests/test-wireproto-command-branchmap.t --- a/tests/test-wireproto-command-branchmap.t +++ b/tests/test-wireproto-command-branchmap.t @@ -67,6 +67,6 @@ received frame(size=112; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) s> 0\r\n s> \r\n - response: [{b'branch1': [b'\xb5\xfa\xac\xdf\xd2c7h\xcb1R3l\xc0\x953\x81&f\x88'], b'branch2': [b'"Aa\xc7X\x9a\xa4\x8f\xa8:H\xfe\xff^\x95\xb5j\xe3\'\xfc'], b'default': [b'&\x80Z\xba\x1e`\n\x82\xe96a\x14\x9f#\x13\x86j"\x1a{', b'\xbe\x0e\xf7<\x17\xad\xe3\xfc\x89\xdcAp\x1e\xb9\xfc:\x91\xb5\x82\x82']}] + response: {b'branch1': [b'\xb5\xfa\xac\xdf\xd2c7h\xcb1R3l\xc0\x953\x81&f\x88'], b'branch2': [b'"Aa\xc7X\x9a\xa4\x8f\xa8:H\xfe\xff^\x95\xb5j\xe3\'\xfc'], b'default': [b'&\x80Z\xba\x1e`\n\x82\xe96a\x14\x9f#\x13\x86j"\x1a{', b'\xbe\x0e\xf7<\x17\xad\xe3\xfc\x89\xdcAp\x1e\xb9\xfc:\x91\xb5\x82\x82']} $ cat error.log diff --git a/tests/test-wireproto-command-heads.t b/tests/test-wireproto-command-heads.t --- a/tests/test-wireproto-command-heads.t +++ b/tests/test-wireproto-command-heads.t @@ -58,7 +58,7 @@ received frame(size=64; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) s> 0\r\n s> \r\n - response: [[b'\x1dok\x91\xd4J\xab\xa6\xd5\xe5\x80\xbc0\xa9\x94\x850\xdb\xe0\x0b', b'\xaeI.6\xb0\xc83\x9f\xfa\xf3(\xd0\x0b\x85\xb4R]\xe1\x16^', b')Dm-\xc5A\x9c_\x97Dz\x8b\xc0b\xe4\xcc2\x8b\xf2A']] + response: [b'\x1dok\x91\xd4J\xab\xa6\xd5\xe5\x80\xbc0\xa9\x94\x850\xdb\xe0\x0b', b'\xaeI.6\xb0\xc83\x9f\xfa\xf3(\xd0\x0b\x85\xb4R]\xe1\x16^', b')Dm-\xc5A\x9c_\x97Dz\x8b\xc0b\xe4\xcc2\x8b\xf2A'] Requesting just the public heads works @@ -91,6 +91,6 @@ received frame(size=22; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) s> 0\r\n s> \r\n - response: [[b'x\xd2\xdc\xa46\xb2\xf5\xb1\x88\xac&~)\xb8\x1e\x07&m8\xfc']] + response: [b'x\xd2\xdc\xa46\xb2\xf5\xb1\x88\xac&~)\xb8\x1e\x07&m8\xfc'] $ cat error.log diff --git a/tests/test-wireproto-command-known.t b/tests/test-wireproto-command-known.t --- a/tests/test-wireproto-command-known.t +++ b/tests/test-wireproto-command-known.t @@ -50,7 +50,7 @@ received frame(size=1; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) s> 0\r\n s> \r\n - response: [b''] + response: [] Single known node works @@ -83,7 +83,7 @@ received frame(size=2; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) s> 0\r\n s> \r\n - response: [b'1'] + response: [True] Multiple nodes works @@ -116,6 +116,6 @@ received frame(size=4; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) s> 0\r\n s> \r\n - response: [b'101'] + response: [True, False, True] $ cat error.log diff --git a/tests/test-wireproto-command-listkeys.t b/tests/test-wireproto-command-listkeys.t --- a/tests/test-wireproto-command-listkeys.t +++ b/tests/test-wireproto-command-listkeys.t @@ -54,7 +54,7 @@ received frame(size=32; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) s> 0\r\n s> \r\n - response: [{b'bookmarks': b'', b'namespaces': b'', b'phases': b''}] + response: {b'bookmarks': b'', b'namespaces': b'', b'phases': b''} Request for phases works @@ -87,7 +87,7 @@ received frame(size=61; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) s> 0\r\n s> \r\n - response: [{b'be0ef73c17ade3fc89dc41701eb9fc3a91b58282': b'1', b'publishing': b'True'}] + response: {b'be0ef73c17ade3fc89dc41701eb9fc3a91b58282': b'1', b'publishing': b'True'} Request for bookmarks works @@ -120,6 +120,6 @@ received frame(size=45; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) s> 0\r\n s> \r\n - response: [{b'@': b'26805aba1e600a82e93661149f2313866a221a7b'}] + response: {b'@': b'26805aba1e600a82e93661149f2313866a221a7b'} $ cat error.log diff --git a/tests/test-wireproto-command-lookup.t b/tests/test-wireproto-command-lookup.t --- a/tests/test-wireproto-command-lookup.t +++ b/tests/test-wireproto-command-lookup.t @@ -50,6 +50,6 @@ received frame(size=*; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) (glob) s> 0\r\n s> \r\n - response: [b'Bk\xad\xa5\xc6u\x98\xcae\x03mW\xd9\xe4\xb6K\x0c\x1c\xe7\xa0'] + response: b'Bk\xad\xa5\xc6u\x98\xcae\x03mW\xd9\xe4\xb6K\x0c\x1c\xe7\xa0' $ cat error.log diff --git a/tests/test-wireproto-command-pushkey.t b/tests/test-wireproto-command-pushkey.t --- a/tests/test-wireproto-command-pushkey.t +++ b/tests/test-wireproto-command-pushkey.t @@ -53,7 +53,7 @@ received frame(size=*; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) (glob) s> 0\r\n s> \r\n - response: [True] + response: True $ sendhttpv2peer << EOF > command listkeys @@ -84,6 +84,6 @@ received frame(size=45; request=1; stream=2; streamflags=stream-begin; type=bytes-response; flags=eos|cbor) s> 0\r\n s> \r\n - response: [{b'@': b'426bada5c67598ca65036d57d9e4b64b0c1ce7a0'}] + response: {b'@': b'426bada5c67598ca65036d57d9e4b64b0c1ce7a0'} $ cat error.log