mercurial/wireproto.py
author Gregory Szorc <gregory.szorc@gmail.com>
Wed, 09 Aug 2017 22:52:05 -0700
changeset 33765 e2fc2122029c
parent 33764 297d1b70685c
child 33766 4c706037adef
permissions -rw-r--r--
wireproto: remove support for local results in @batchable (API) @peer.batchable decorated generator functions have two forms: yield value, None and yield args, future yield value These forms have been present since the decorator was introduced. There are currently no in-repo consumers of the first form. So this commit removes support for it. Note that remoteiterbatcher.submit() asserts the 2nd form. And b6e71f8af5b8 removed the last user of remotebatcher, forcing everyone to remoteiterbatcher. So anything relying on this in the wild would have been broken since b6e71f8af5b8. .. api:: @peer.batchable can no longer emit local values Differential Revision: https://phab.mercurial-scm.org/D318
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# wireproto.py - generic wire protocol support functions
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2005-2010 Matt Mackall <mpm@selenic.com>
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
     8
from __future__ import absolute_import
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
     9
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29216
diff changeset
    10
import hashlib
28438
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
    11
import itertools
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    12
import os
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    13
import tempfile
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    14
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    15
from .i18n import _
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    16
from .node import (
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    17
    bin,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    18
    hex,
32260
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
    19
    nullid,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    20
)
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    21
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    22
from . import (
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    23
    bundle2,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    24
    changegroup as changegroupmod,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    25
    encoding,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    26
    error,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    27
    exchange,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    28
    peer,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    29
    pushkey as pushkeymod,
30924
48dea083f66d py3: convert the mode argument of os.fdopen to unicodes (1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30914
diff changeset
    30
    pycompat,
26443
d947086d8973 streamclone: move code out of exchange.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25993
diff changeset
    31
    streamclone,
25993
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    32
    util,
0851678be71b wireproto: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25913
diff changeset
    33
)
20903
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    34
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
    35
urlerr = util.urlerr
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
    36
urlreq = util.urlreq
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
    37
30909
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
    38
bundle2requiredmain = _('incompatible Mercurial client; bundle2 required')
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
    39
bundle2requiredhint = _('see https://www.mercurial-scm.org/wiki/'
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
    40
                        'IncompatibleClient')
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
    41
bundle2required = '%s\n(%s)\n' % (bundle2requiredmain, bundle2requiredhint)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
    42
20903
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    43
class abstractserverproto(object):
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    44
    """abstract class that summarizes the protocol API
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    45
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    46
    Used as reference and documentation.
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    47
    """
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    48
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    49
    def getargs(self, args):
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    50
        """return the value for arguments in <args>
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    51
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    52
        returns a list of values (same order as <args>)"""
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    53
        raise NotImplementedError()
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    54
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    55
    def getfile(self, fp):
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    56
        """write the whole content of a file into a file like object
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    57
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    58
        The file is in the form::
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    59
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    60
            (<chunk-size>\n<chunk>)+0\n
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    61
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    62
        chunk size is the ascii version of the int.
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    63
        """
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    64
        raise NotImplementedError()
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    65
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    66
    def redirect(self):
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    67
        """may setup interception for stdout and stderr
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    68
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    69
        See also the `restore` method."""
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    70
        raise NotImplementedError()
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    71
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    72
    # If the `redirect` function does install interception, the `restore`
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    73
    # function MUST be defined. If interception is not used, this function
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    74
    # MUST NOT be defined.
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    75
    #
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    76
    # left commented here on purpose
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    77
    #
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    78
    #def restore(self):
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    79
    #    """reinstall previous stdout and stderr and return intercepted stdout
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    80
    #    """
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    81
    #    raise NotImplementedError()
8d477543882b wireproto: introduce an abstractserverproto class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20902
diff changeset
    82
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 25711
diff changeset
    83
class remotebatch(peer.batcher):
14621
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
    84
    '''batches the queued calls; uses as few roundtrips as possible'''
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
    85
    def __init__(self, remote):
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16535
diff changeset
    86
        '''remote must support _submitbatch(encbatch) and
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16535
diff changeset
    87
        _submitone(op, encargs)'''
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 25711
diff changeset
    88
        peer.batcher.__init__(self)
14621
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
    89
        self.remote = remote
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
    90
    def submit(self):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
    91
        req, rsp = [], []
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
    92
        for name, args, opts, resref in self.calls:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
    93
            mtd = getattr(self.remote, name)
14970
592e45b7d43e wireproto: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14623
diff changeset
    94
            batchablefn = getattr(mtd, 'batchable', None)
592e45b7d43e wireproto: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14623
diff changeset
    95
            if batchablefn is not None:
592e45b7d43e wireproto: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14623
diff changeset
    96
                batchable = batchablefn(mtd.im_self, *args, **opts)
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 29151
diff changeset
    97
                encargsorres, encresref = next(batchable)
33765
e2fc2122029c wireproto: remove support for local results in @batchable (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33764
diff changeset
    98
                assert encresref
e2fc2122029c wireproto: remove support for local results in @batchable (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33764
diff changeset
    99
                req.append((name, encargsorres,))
e2fc2122029c wireproto: remove support for local results in @batchable (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33764
diff changeset
   100
                rsp.append((batchable, encresref, resref,))
14621
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   101
            else:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   102
                if req:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   103
                    self._submitreq(req, rsp)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   104
                    req, rsp = [], []
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   105
                resref.set(mtd(*args, **opts))
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   106
        if req:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   107
            self._submitreq(req, rsp)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   108
    def _submitreq(self, req, rsp):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   109
        encresults = self.remote._submitbatch(req)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   110
        for encres, r in zip(encresults, rsp):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   111
            batchable, encresref, resref = r
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   112
            encresref.set(encres)
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 29151
diff changeset
   113
            resref.set(next(batchable))
14621
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   114
28436
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   115
class remoteiterbatcher(peer.iterbatcher):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   116
    def __init__(self, remote):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   117
        super(remoteiterbatcher, self).__init__()
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   118
        self._remote = remote
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   119
28438
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   120
    def __getattr__(self, name):
33764
297d1b70685c wireproto: properly implement batchable checking
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33499
diff changeset
   121
        # Validate this method is batchable, since submit() only supports
297d1b70685c wireproto: properly implement batchable checking
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33499
diff changeset
   122
        # batchable methods.
297d1b70685c wireproto: properly implement batchable checking
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33499
diff changeset
   123
        fn = getattr(self._remote, name)
297d1b70685c wireproto: properly implement batchable checking
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33499
diff changeset
   124
        if not getattr(fn, 'batchable', None):
297d1b70685c wireproto: properly implement batchable checking
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33499
diff changeset
   125
            raise error.ProgrammingError('Attempted to batch a non-batchable '
297d1b70685c wireproto: properly implement batchable checking
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33499
diff changeset
   126
                                         'call to %r' % name)
297d1b70685c wireproto: properly implement batchable checking
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33499
diff changeset
   127
28438
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   128
        return super(remoteiterbatcher, self).__getattr__(name)
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   129
28436
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   130
    def submit(self):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   131
        """Break the batch request into many patch calls and pipeline them.
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   132
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   133
        This is mostly valuable over http where request sizes can be
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   134
        limited, but can be used in other places as well.
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   135
        """
28438
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   136
        req, rsp = [], []
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   137
        for name, args, opts, resref in self.calls:
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   138
            mtd = getattr(self._remote, name)
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   139
            batchable = mtd.batchable(mtd.im_self, *args, **opts)
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 29151
diff changeset
   140
            encargsorres, encresref = next(batchable)
28438
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   141
            assert encresref
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   142
            req.append((name, encargsorres))
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   143
            rsp.append((batchable, encresref))
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   144
        if req:
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   145
            self._resultiter = self._remote._submitbatch(req)
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   146
        self._rsp = rsp
28436
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   147
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   148
    def results(self):
28438
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   149
        for (batchable, encresref), encres in itertools.izip(
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   150
                self._rsp, self._resultiter):
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   151
            encresref.set(encres)
29216
ead25aa27a43 py3: convert to next() function
timeless <timeless@mozdev.org>
parents: 29151
diff changeset
   152
            yield next(batchable)
28436
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   153
25912
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 25711
diff changeset
   154
# Forward a couple of names from peer to make wireproto interactions
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 25711
diff changeset
   155
# slightly more sensible.
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 25711
diff changeset
   156
batchable = peer.batchable
cbbdd085c991 batching: migrate basic noop batching into peer.peer
Augie Fackler <augie@google.com>
parents: 25711
diff changeset
   157
future = peer.future
14621
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
   158
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   159
# list of nodes encoding / decoding
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   160
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   161
def decodelist(l, sep=' '):
13722
f4a85acef50c wireproto: fix decodelist to properly return empty list
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13721
diff changeset
   162
    if l:
f4a85acef50c wireproto: fix decodelist to properly return empty list
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13721
diff changeset
   163
        return map(bin, l.split(sep))
f4a85acef50c wireproto: fix decodelist to properly return empty list
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13721
diff changeset
   164
    return []
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   165
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   166
def encodelist(l, sep=' '):
23848
c5456b64eb07 discovery: run discovery on filtered repository
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23591
diff changeset
   167
    try:
c5456b64eb07 discovery: run discovery on filtered repository
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23591
diff changeset
   168
        return sep.join(map(hex, l))
c5456b64eb07 discovery: run discovery on filtered repository
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23591
diff changeset
   169
    except TypeError:
c5456b64eb07 discovery: run discovery on filtered repository
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23591
diff changeset
   170
        raise
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   171
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   172
# batched call argument encoding
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   173
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   174
def escapearg(plain):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   175
    return (plain
25708
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   176
            .replace(':', ':c')
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   177
            .replace(',', ':o')
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   178
            .replace(';', ':s')
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   179
            .replace('=', ':e'))
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   180
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   181
def unescapearg(escaped):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   182
    return (escaped
25708
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   183
            .replace(':e', '=')
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   184
            .replace(':s', ';')
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   185
            .replace(':o', ',')
d3d32643c060 wireproto: correctly escape batched args and responses (issue4739)
Augie Fackler <augie@google.com>
parents: 25691
diff changeset
   186
            .replace(':c', ':'))
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   187
29733
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   188
def encodebatchcmds(req):
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   189
    """Return a ``cmds`` argument value for the ``batch`` command."""
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   190
    cmds = []
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   191
    for op, argsdict in req:
29734
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
   192
        # Old servers didn't properly unescape argument names. So prevent
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
   193
        # the sending of argument names that may not be decoded properly by
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
   194
        # servers.
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
   195
        assert all(escapearg(k) == k for k in argsdict)
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
   196
29733
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   197
        args = ','.join('%s=%s' % (escapearg(k), escapearg(v))
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   198
                        for k, v in argsdict.iteritems())
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   199
        cmds.append('%s %s' % (op, args))
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   200
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   201
    return ';'.join(cmds)
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   202
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   203
# mapping of options accepted by getbundle and their types
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   204
#
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   205
# Meant to be extended by extensions. It is extensions responsibility to ensure
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   206
# such options are properly processed in exchange.getbundle.
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   207
#
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   208
# supported types are:
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   209
#
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   210
# :nodes: list of binary nodes
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   211
# :csv:   list of comma-separated values
25403
30ab130af221 wireprotocol: distinguish list and set in getbundle argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25339
diff changeset
   212
# :scsv:  list of comma-separated values return as set
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   213
# :plain: string with no transformation needed.
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   214
gboptsmap = {'heads':  'nodes',
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   215
             'common': 'nodes',
22353
47e3420ae889 getbundle: add `obsmarkers` argument to getbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22351
diff changeset
   216
             'obsmarkers': 'boolean',
25403
30ab130af221 wireprotocol: distinguish list and set in getbundle argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25339
diff changeset
   217
             'bundlecaps': 'scsv',
21989
bdb6d97f0a04 getbundle: add a ``cg`` boolean argument to control changegroup inclusion
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21988
diff changeset
   218
             'listkeys': 'csv',
26690
704818fb170d exchange: advertise if a clone bundle was attempted
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26686
diff changeset
   219
             'cg': 'boolean',
704818fb170d exchange: advertise if a clone bundle was attempted
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26686
diff changeset
   220
             'cbattempted': 'boolean'}
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   221
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   222
# client side
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   223
17192
1ac628cd7113 peer: introduce real peer classes
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 16683
diff changeset
   224
class wirepeer(peer.peerrepository):
27243
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   225
    """Client-side interface for communicating with a peer repository.
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   226
27243
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   227
    Methods commonly call wire protocol commands of the same name.
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   228
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   229
    See also httppeer.py and sshpeer.py for protocol-specific
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   230
    implementations of this interface.
3abee2ba27af wireproto: add docstring for wirepeer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26911
diff changeset
   231
    """
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   232
    def batch(self):
25913
fa14ba7b9667 wireproto: make wirepeer look-before-you-leap on batching
Augie Fackler <augie@google.com>
parents: 25912
diff changeset
   233
        if self.capable('batch'):
fa14ba7b9667 wireproto: make wirepeer look-before-you-leap on batching
Augie Fackler <augie@google.com>
parents: 25912
diff changeset
   234
            return remotebatch(self)
fa14ba7b9667 wireproto: make wirepeer look-before-you-leap on batching
Augie Fackler <augie@google.com>
parents: 25912
diff changeset
   235
        else:
fa14ba7b9667 wireproto: make wirepeer look-before-you-leap on batching
Augie Fackler <augie@google.com>
parents: 25912
diff changeset
   236
            return peer.localbatch(self)
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   237
    def _submitbatch(self, req):
28438
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   238
        """run batch request <req> on the server
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   239
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   240
        Returns an iterator of the raw responses from the server.
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   241
        """
29733
bb04f96df51c wireproto: consolidate code for obtaining "cmds" argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29706
diff changeset
   242
        rsp = self._callstream("batch", cmds=encodebatchcmds(req))
29151
7996c3acc33b wireproto: optimize handling of large batch responses
Augie Fackler <augie@google.com>
parents: 28883
diff changeset
   243
        chunk = rsp.read(1024)
7996c3acc33b wireproto: optimize handling of large batch responses
Augie Fackler <augie@google.com>
parents: 28883
diff changeset
   244
        work = [chunk]
28438
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   245
        while chunk:
29151
7996c3acc33b wireproto: optimize handling of large batch responses
Augie Fackler <augie@google.com>
parents: 28883
diff changeset
   246
            while ';' not in chunk and chunk:
7996c3acc33b wireproto: optimize handling of large batch responses
Augie Fackler <augie@google.com>
parents: 28883
diff changeset
   247
                chunk = rsp.read(1024)
7996c3acc33b wireproto: optimize handling of large batch responses
Augie Fackler <augie@google.com>
parents: 28883
diff changeset
   248
                work.append(chunk)
7996c3acc33b wireproto: optimize handling of large batch responses
Augie Fackler <augie@google.com>
parents: 28883
diff changeset
   249
            merged = ''.join(work)
7996c3acc33b wireproto: optimize handling of large batch responses
Augie Fackler <augie@google.com>
parents: 28883
diff changeset
   250
            while ';' in merged:
7996c3acc33b wireproto: optimize handling of large batch responses
Augie Fackler <augie@google.com>
parents: 28883
diff changeset
   251
                one, merged = merged.split(';', 1)
28438
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   252
                yield unescapearg(one)
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   253
            chunk = rsp.read(1024)
29151
7996c3acc33b wireproto: optimize handling of large batch responses
Augie Fackler <augie@google.com>
parents: 28883
diff changeset
   254
            work = [merged, chunk]
7996c3acc33b wireproto: optimize handling of large batch responses
Augie Fackler <augie@google.com>
parents: 28883
diff changeset
   255
        yield unescapearg(''.join(work))
28438
48fd02dac1d4 wireproto: make iterbatcher behave streamily over http(s)
Augie Fackler <augie@google.com>
parents: 28436
diff changeset
   256
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   257
    def _submitone(self, op, args):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   258
        return self._call(op, **args)
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   259
28436
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   260
    def iterbatch(self):
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   261
        return remoteiterbatcher(self)
8d38eab2777a peer: add an iterbatcher interface
Augie Fackler <augie@google.com>
parents: 28435
diff changeset
   262
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   263
    @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   264
    def lookup(self, key):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   265
        self.requirecap('lookup', _('look up remote revision'))
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   266
        f = future()
20671
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   267
        yield {'key': encoding.fromlocal(key)}, f
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   268
        d = f.value
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   269
        success, data = d[:-1].split(" ", 1)
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   270
        if int(success):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   271
            yield bin(data)
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   272
        self._abort(error.RepoError(data))
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   273
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   274
    @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   275
    def heads(self):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   276
        f = future()
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   277
        yield {}, f
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   278
        d = f.value
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   279
        try:
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   280
            yield decodelist(d[:-1])
13726
378522bdc059 wireproto: avoid naked excepts
Matt Mackall <mpm@selenic.com>
parents: 13723
diff changeset
   281
        except ValueError:
11879
4e804302d30c fix undefined variables, spotted by pylint
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11627
diff changeset
   282
            self._abort(error.ResponseError(_("unexpected response:"), d))
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   283
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   284
    @batchable
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   285
    def known(self, nodes):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   286
        f = future()
20671
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   287
        yield {'nodes': encodelist(nodes)}, f
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   288
        d = f.value
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   289
        try:
22201
269688a398c4 cleanup: fix some list comprehension redefinitions of existing vars
Mads Kiilerich <madski@unity3d.com>
parents: 21989
diff changeset
   290
            yield [bool(int(b)) for b in d]
13726
378522bdc059 wireproto: avoid naked excepts
Matt Mackall <mpm@selenic.com>
parents: 13723
diff changeset
   291
        except ValueError:
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   292
            self._abort(error.ResponseError(_("unexpected response:"), d))
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   293
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   294
    @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   295
    def branchmap(self):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   296
        f = future()
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   297
        yield {}, f
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   298
        d = f.value
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   299
        try:
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   300
            branchmap = {}
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   301
            for branchpart in d.splitlines():
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   302
                branchname, branchheads = branchpart.split(' ', 1)
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
   303
                branchname = encoding.tolocal(urlreq.unquote(branchname))
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   304
                branchheads = decodelist(branchheads)
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   305
                branchmap[branchname] = branchheads
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   306
            yield branchmap
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   307
        except TypeError:
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   308
            self._abort(error.ResponseError(_("unexpected response:"), d))
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   309
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   310
    def branches(self, nodes):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   311
        n = encodelist(nodes)
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   312
        d = self._call("branches", nodes=n)
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   313
        try:
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   314
            br = [tuple(decodelist(b)) for b in d.splitlines()]
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   315
            return br
13726
378522bdc059 wireproto: avoid naked excepts
Matt Mackall <mpm@selenic.com>
parents: 13723
diff changeset
   316
        except ValueError:
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   317
            self._abort(error.ResponseError(_("unexpected response:"), d))
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   318
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   319
    def between(self, pairs):
11587
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
   320
        batch = 8 # avoid giant requests
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
   321
        r = []
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
   322
        for i in xrange(0, len(pairs), batch):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   323
            n = " ".join([encodelist(p, '-') for p in pairs[i:i + batch]])
11587
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
   324
            d = self._call("between", pairs=n)
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
   325
            try:
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   326
                r.extend(l and decodelist(l) or [] for l in d.splitlines())
13726
378522bdc059 wireproto: avoid naked excepts
Matt Mackall <mpm@selenic.com>
parents: 13723
diff changeset
   327
            except ValueError:
11587
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
   328
                self._abort(error.ResponseError(_("unexpected response:"), d))
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
   329
        return r
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   330
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   331
    @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   332
    def pushkey(self, namespace, key, old, new):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   333
        if not self.capable('pushkey'):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   334
            yield False, None
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   335
        f = future()
17293
d3f84ccc5495 pushkey: add more verbose debug output regarding pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17205
diff changeset
   336
        self.ui.debug('preparing pushkey for "%s:%s"\n' % (namespace, key))
20671
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   337
        yield {'namespace': encoding.fromlocal(namespace),
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   338
               'key': encoding.fromlocal(key),
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   339
               'old': encoding.fromlocal(old),
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   340
               'new': encoding.fromlocal(new)}, f
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   341
        d = f.value
15652
ca6accdad79c wireproto: handle other server output in pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15585
diff changeset
   342
        d, output = d.split('\n', 1)
13450
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   343
        try:
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   344
            d = bool(int(d))
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   345
        except ValueError:
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   346
            raise error.ResponseError(
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
   347
                _('push failed (unexpected response):'), d)
15652
ca6accdad79c wireproto: handle other server output in pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15585
diff changeset
   348
        for l in output.splitlines(True):
ca6accdad79c wireproto: handle other server output in pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15585
diff changeset
   349
            self.ui.status(_('remote: '), l)
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   350
        yield d
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   351
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   352
    @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   353
    def listkeys(self, namespace):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   354
        if not self.capable('pushkey'):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   355
            yield {}, None
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   356
        f = future()
17293
d3f84ccc5495 pushkey: add more verbose debug output regarding pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17205
diff changeset
   357
        self.ui.debug('preparing listkeys for "%s"\n' % namespace)
20671
5442cab57b09 wireproto: remove todict() and use {} literals instead
Augie Fackler <raf@durin42.com>
parents: 19201
diff changeset
   358
        yield {'namespace': encoding.fromlocal(namespace)}, f
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
   359
        d = f.value
25339
c50655b9c856 listkey: display the size of the listkey payload in a debug message
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25240
diff changeset
   360
        self.ui.debug('received listkey for "%s": %i bytes\n'
c50655b9c856 listkey: display the size of the listkey payload in a debug message
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25240
diff changeset
   361
                      % (namespace, len(d)))
21653
4188cae727ce wireproto: use pushkey.decodekey
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21651
diff changeset
   362
        yield pushkeymod.decodekeys(d)
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   363
11588
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
   364
    def stream_out(self):
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
   365
        return self._callstream('stream_out')
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
   366
11591
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
   367
    def changegroup(self, nodes, kind):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   368
        n = encodelist(nodes)
20905
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   369
        f = self._callcompressable("changegroup", roots=n)
22390
e2806b8613ca changegroup: rename bundle-related functions and classes
Sune Foldager <cryo@cyanite.org>
parents: 22353
diff changeset
   370
        return changegroupmod.cg1unpacker(f, 'UN')
11591
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
   371
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
   372
    def changegroupsubset(self, bases, heads, kind):
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
   373
        self.requirecap('changegroupsubset', _('look up remote changes'))
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   374
        bases = encodelist(bases)
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   375
        heads = encodelist(heads)
20905
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   376
        f = self._callcompressable("changegroupsubset",
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   377
                                   bases=bases, heads=heads)
22390
e2806b8613ca changegroup: rename bundle-related functions and classes
Sune Foldager <cryo@cyanite.org>
parents: 22353
diff changeset
   378
        return changegroupmod.cg1unpacker(f, 'UN')
11591
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
   379
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   380
    def getbundle(self, source, **kwargs):
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   381
        self.requirecap('getbundle', _('look up remote changes'))
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   382
        opts = {}
25128
631766d1f57a getbundle: sort bundlecaps before exchanging then over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24797
diff changeset
   383
        bundlecaps = kwargs.get('bundlecaps')
631766d1f57a getbundle: sort bundlecaps before exchanging then over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24797
diff changeset
   384
        if bundlecaps is not None:
631766d1f57a getbundle: sort bundlecaps before exchanging then over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24797
diff changeset
   385
            kwargs['bundlecaps'] = sorted(bundlecaps)
631766d1f57a getbundle: sort bundlecaps before exchanging then over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24797
diff changeset
   386
        else:
631766d1f57a getbundle: sort bundlecaps before exchanging then over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24797
diff changeset
   387
            bundlecaps = () # kwargs could have it to None
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   388
        for key, value in kwargs.iteritems():
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   389
            if value is None:
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   390
                continue
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   391
            keytype = gboptsmap.get(key)
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   392
            if keytype is None:
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   393
                assert False, 'unexpected'
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   394
            elif keytype == 'nodes':
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   395
                value = encodelist(value)
25403
30ab130af221 wireprotocol: distinguish list and set in getbundle argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25339
diff changeset
   396
            elif keytype in ('csv', 'scsv'):
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   397
                value = ','.join(value)
21988
12cd3827b860 wireproto: add a ``boolean`` type for getbundle parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21728
diff changeset
   398
            elif keytype == 'boolean':
22351
7e6dd496d327 wireprotocol: fix 'boolean' handling
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22342
diff changeset
   399
                value = '%i' % bool(value)
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   400
            elif keytype != 'plain':
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   401
                raise KeyError('unknown getbundle option type %s'
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   402
                               % keytype)
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   403
            opts[key] = value
20905
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   404
        f = self._callcompressable("getbundle", **opts)
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 25128
diff changeset
   405
        if any((cap.startswith('HG2') for cap in bundlecaps)):
24641
60fecc5b14a4 unbundle20: retrieve unbundler instances through a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23878
diff changeset
   406
            return bundle2.getunbundler(self.ui, f)
21069
0a9cae236738 bundle2: allow bundle2 for pulling over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21064
diff changeset
   407
        else:
22390
e2806b8613ca changegroup: rename bundle-related functions and classes
Sune Foldager <cryo@cyanite.org>
parents: 22353
diff changeset
   408
            return changegroupmod.cg1unpacker(f, 'UN')
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   409
29706
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   410
    def unbundle(self, cg, heads, url):
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   411
        '''Send cg (a readable file-like object representing the
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   412
        changegroup to push, typically a chunkbuffer object) to the
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   413
        remote server as a bundle.
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   414
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   415
        When pushing a bundle10 stream, return an integer indicating the
32880
4c2a46f89f08 wireproto: update reference to deleted addchangegroup()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32744
diff changeset
   416
        result of the push (see changegroup.apply()).
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   417
29706
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   418
        When pushing a bundle20 stream, return a bundle20 stream.
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   419
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   420
        `url` is the url the client thinks it's pushing to, which is
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   421
        visible to hooks.
7f6130c7ffe1 wirepeer: rename confusing `source` parameter
Augie Fackler <augie@google.com>
parents: 29590
diff changeset
   422
        '''
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   423
14419
ede7cea1550f wireproto: do not hash when heads == ['force']
Martin Geisler <mg@aragost.com>
parents: 14093
diff changeset
   424
        if heads != ['force'] and self.capable('unbundlehash'):
13942
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
   425
            heads = encodelist(['hashed',
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29216
diff changeset
   426
                                hashlib.sha1(''.join(sorted(heads))).digest()])
13942
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
   427
        else:
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
   428
            heads = encodelist(heads)
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
   429
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   430
        if util.safehasattr(cg, 'deltaheader'):
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   431
            # this a bundle10, do the old style call sequence
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   432
            ret, output = self._callpush("unbundle", cg, heads=heads)
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   433
            if ret == "":
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   434
                raise error.ResponseError(
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   435
                    _('push failed:'), output)
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   436
            try:
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   437
                ret = int(ret)
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   438
            except ValueError:
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   439
                raise error.ResponseError(
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   440
                    _('push failed (unexpected response):'), ret)
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   441
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   442
            for l in output.splitlines(True):
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   443
                self.ui.status(_('remote: '), l)
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   444
        else:
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   445
            # bundle2 push. Send a stream, fetch a stream.
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   446
            stream = self._calltwowaystream('unbundle', cg, heads=heads)
24641
60fecc5b14a4 unbundle20: retrieve unbundler instances through a factory function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23878
diff changeset
   447
            ret = bundle2.getunbundler(self.ui, stream)
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   448
        return ret
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   449
14048
58e58406ed19 wireproto: add test for new optional arg missing on server
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13942
diff changeset
   450
    def debugwireargs(self, one, two, three=None, four=None, five=None):
13720
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   451
        # don't pass optional arguments left at their default value
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   452
        opts = {}
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   453
        if three is not None:
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   454
            opts['three'] = three
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   455
        if four is not None:
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   456
            opts['four'] = four
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   457
        return self._call('debugwireargs', one=one, two=two, **opts)
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   458
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   459
    def _call(self, cmd, **args):
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   460
        """execute <cmd> on the server
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   461
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   462
        The command is expected to return a simple string.
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   463
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   464
        returns the server reply as a string."""
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   465
        raise NotImplementedError()
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   466
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   467
    def _callstream(self, cmd, **args):
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   468
        """execute <cmd> on the server
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   469
28435
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   470
        The command is expected to return a stream. Note that if the
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   471
        command doesn't return a stream, _callstream behaves
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   472
        differently for ssh and http peers.
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   473
28435
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   474
        returns the server reply as a file like object.
176736afa886 wireproto: document quirk of _callstream between http and ssh
Augie Fackler <augie@google.com>
parents: 27633
diff changeset
   475
        """
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   476
        raise NotImplementedError()
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   477
20905
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   478
    def _callcompressable(self, cmd, **args):
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   479
        """execute <cmd> on the server
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   480
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   481
        The command is expected to return a stream.
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   482
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20969
diff changeset
   483
        The stream may have been compressed in some implementations. This
20905
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   484
        function takes care of the decompression. This is the only difference
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   485
        with _callstream.
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   486
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   487
        returns the server reply as a file like object.
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   488
        """
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   489
        raise NotImplementedError()
167047ba3cfa wireproto: drop the _decompress method in favor a new call type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20904
diff changeset
   490
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   491
    def _callpush(self, cmd, fp, **args):
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   492
        """execute a <cmd> on server
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   493
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   494
        The command is expected to be related to a push. Push has a special
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   495
        return method.
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   496
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   497
        returns the server reply as a (ret, output) tuple. ret is either
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   498
        empty (error) or a stringified int.
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   499
        """
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   500
        raise NotImplementedError()
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   501
21072
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   502
    def _calltwowaystream(self, cmd, fp, **args):
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   503
        """execute <cmd> on server
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   504
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   505
        The command will send a stream to the server and get a stream in reply.
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   506
        """
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   507
        raise NotImplementedError()
0879352d67d8 wireproto: add a _calltwowaystream method on wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21069
diff changeset
   508
20904
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   509
    def _abort(self, exception):
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   510
        """clearly abort the wire protocol connection and raise the exception
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   511
        """
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   512
        raise NotImplementedError()
3dbe6bcd7f62 wireproto: document protocol specific function of wirepeer
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20903
diff changeset
   513
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   514
# server side
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
   515
20902
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   516
# wire protocol command can either return a string or one of these classes.
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
   517
class streamres(object):
20902
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   518
    """wireproto reply: binary stream
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   519
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   520
    The call was successful and the result is a stream.
30466
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   521
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   522
    Accepts either a generator or an object with a ``read(size)`` method.
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   523
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   524
    ``v1compressible`` indicates whether this data can be compressed to
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   525
    "version 1" clients (technically: HTTP peers using
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   526
    application/mercurial-0.1 media type). This flag should NOT be used on
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   527
    new commands because new clients should support a more modern compression
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   528
    mechanism.
20902
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   529
    """
30466
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   530
    def __init__(self, gen=None, reader=None, v1compressible=False):
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
   531
        self.gen = gen
30466
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   532
        self.reader = reader
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   533
        self.v1compressible = v1compressible
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
   534
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
   535
class pushres(object):
20902
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   536
    """wireproto reply: success with simple integer return
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   537
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   538
    The call was successful and returned an integer contained in `self.res`.
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   539
    """
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
   540
    def __init__(self, res):
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
   541
        self.res = res
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
   542
12703
40bb5853fc4b wireproto: introduce pusherr() to deal with "unsynced changes" error
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12702
diff changeset
   543
class pusherr(object):
20902
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   544
    """wireproto reply: failure
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   545
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   546
    The call failed. The `self.res` attribute contains the error message.
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   547
    """
12703
40bb5853fc4b wireproto: introduce pusherr() to deal with "unsynced changes" error
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12702
diff changeset
   548
    def __init__(self, res):
40bb5853fc4b wireproto: introduce pusherr() to deal with "unsynced changes" error
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12702
diff changeset
   549
        self.res = res
40bb5853fc4b wireproto: introduce pusherr() to deal with "unsynced changes" error
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12702
diff changeset
   550
15017
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
   551
class ooberror(object):
20902
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   552
    """wireproto reply: failure of a batch of operation
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   553
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   554
    Something failed during a batch call. The error message is stored in
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   555
    `self.message`.
1e4fda2f5cf1 wireproto: document possible return type
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20775
diff changeset
   556
    """
15017
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
   557
    def __init__(self, message):
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
   558
        self.message = message
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
   559
29590
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   560
def getdispatchrepo(repo, proto, command):
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   561
    """Obtain the repo used for processing wire protocol commands.
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   562
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   563
    The intent of this function is to serve as a monkeypatch point for
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   564
    extensions that need commands to operate on different repo views under
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   565
    specialized circumstances.
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   566
    """
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   567
    return repo.filtered('served')
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   568
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   569
def dispatch(repo, proto, command):
29590
84c1a5942f1d wireproto: extract repo filtering to standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29341
diff changeset
   570
    repo = getdispatchrepo(repo, proto, command)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   571
    func, spec = commands[command]
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   572
    args = proto.getargs(spec)
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
   573
    return func(repo, proto, *args)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   574
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   575
def options(cmd, keys, others):
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   576
    opts = {}
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   577
    for k in keys:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   578
        if k in others:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   579
            opts[k] = others[k]
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   580
            del others[k]
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   581
    if others:
30473
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30466
diff changeset
   582
        util.stderr.write("warning: %s ignored unexpected arguments %s\n"
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30466
diff changeset
   583
                          % (cmd, ",".join(others)))
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   584
    return opts
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   585
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   586
def bundle1allowed(repo, action):
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   587
    """Whether a bundle1 operation is allowed from the server.
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   588
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   589
    Priority is:
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   590
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   591
    1. server.bundle1gd.<action> (if generaldelta active)
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   592
    2. server.bundle1.<action>
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   593
    3. server.bundle1gd (if generaldelta active)
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   594
    4. server.bundle1
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   595
    """
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   596
    ui = repo.ui
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   597
    gd = 'generaldelta' in repo.requirements
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   598
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   599
    if gd:
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   600
        v = ui.configbool('server', 'bundle1gd.%s' % action, None)
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   601
        if v is not None:
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   602
            return v
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   603
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   604
    v = ui.configbool('server', 'bundle1.%s' % action, None)
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   605
    if v is not None:
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   606
        return v
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   607
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   608
    if gd:
33220
40861b2254a5 configitems: register the 'server.bundle1gd' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33219
diff changeset
   609
        v = ui.configbool('server', 'bundle1gd')
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   610
        if v is not None:
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   611
            return v
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   612
33219
ffb1d0f541f5 configitems: register the 'server.bundle1' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32880
diff changeset
   613
    return ui.configbool('server', 'bundle1')
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   614
30762
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   615
def supportedcompengines(ui, proto, role):
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   616
    """Obtain the list of supported compression engines for a request."""
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   617
    assert role in (util.CLIENTROLE, util.SERVERROLE)
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   618
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   619
    compengines = util.compengines.supportedwireengines(role)
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   620
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   621
    # Allow config to override default list and ordering.
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   622
    if role == util.SERVERROLE:
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   623
        configengines = ui.configlist('server', 'compressionengines')
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   624
        config = 'server.compressionengines'
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   625
    else:
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   626
        # This is currently implemented mainly to facilitate testing. In most
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   627
        # cases, the server should be in charge of choosing a compression engine
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   628
        # because a server has the most to lose from a sub-optimal choice. (e.g.
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   629
        # CPU DoS due to an expensive engine or a network DoS due to poor
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   630
        # compression ratio).
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   631
        configengines = ui.configlist('experimental',
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   632
                                      'clientcompressionengines')
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   633
        config = 'experimental.clientcompressionengines'
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   634
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   635
    # No explicit config. Filter out the ones that aren't supposed to be
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   636
    # advertised and return default ordering.
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   637
    if not configengines:
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   638
        attr = 'serverpriority' if role == util.SERVERROLE else 'clientpriority'
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   639
        return [e for e in compengines
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   640
                if getattr(e.wireprotosupport(), attr) > 0]
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   641
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   642
    # If compression engines are listed in the config, assume there is a good
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   643
    # reason for it (like server operators wanting to achieve specific
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   644
    # performance characteristics). So fail fast if the config references
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   645
    # unusable compression engines.
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   646
    validnames = set(e.name() for e in compengines)
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   647
    invalidnames = set(e for e in configengines if e not in validnames)
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   648
    if invalidnames:
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   649
        raise error.Abort(_('invalid compression engine defined in %s: %s') %
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   650
                          (config, ', '.join(sorted(invalidnames))))
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   651
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   652
    compengines = [e for e in compengines if e.name() in configengines]
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   653
    compengines = sorted(compengines,
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   654
                         key=lambda e: configengines.index(e.name()))
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   655
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   656
    if not compengines:
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   657
        raise error.Abort(_('%s config option does not specify any known '
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   658
                            'compression engines') % config,
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   659
                          hint=_('usable compression engines: %s') %
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   660
                          ', '.sorted(validnames))
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   661
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   662
    return compengines
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   663
20906
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   664
# list of commands
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   665
commands = {}
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   666
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   667
def wireprotocommand(name, args=''):
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20969
diff changeset
   668
    """decorator for wire protocol command"""
20906
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   669
    def register(func):
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   670
        commands[name] = (func, args)
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   671
        return func
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   672
    return register
7a634b34fc91 wireproto: add decorator for wire protocol command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20905
diff changeset
   673
20907
aedec880e095 wireproto: use decorator for the batch command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20906
diff changeset
   674
@wireprotocommand('batch', 'cmds *')
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   675
def batch(repo, proto, cmds, others):
18382
f3b21beb9802 filtering: rename filters to their antonyms
Kevin Bullock <kbullock@ringworld.org>
parents: 18381
diff changeset
   676
    repo = repo.filtered("served")
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   677
    res = []
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   678
    for pair in cmds.split(';'):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   679
        op, args = pair.split(' ', 1)
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   680
        vals = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   681
        for a in args.split(','):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   682
            if a:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   683
                n, v = a.split('=')
29734
62e2e048d068 wireproto: unescape argument names in batch command (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 29733
diff changeset
   684
                vals[unescapearg(n)] = unescapearg(v)
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   685
        func, spec = commands[op]
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   686
        if spec:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   687
            keys = spec.split()
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   688
            data = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   689
            for k in keys:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   690
                if k == '*':
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   691
                    star = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   692
                    for key in vals.keys():
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   693
                        if key not in keys:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   694
                            star[key] = vals[key]
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   695
                    data['*'] = star
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   696
                else:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   697
                    data[k] = vals[k]
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   698
            result = func(repo, proto, *[data[k] for k in keys])
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   699
        else:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   700
            result = func(repo, proto)
15017
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
   701
        if isinstance(result, ooberror):
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
   702
            return result
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   703
        res.append(escapearg(result))
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   704
    return ';'.join(res)
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
   705
20908
ae4bf69c8068 wireproto: use decorator for the between command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20907
diff changeset
   706
@wireprotocommand('between', 'pairs')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   707
def between(repo, proto, pairs):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   708
    pairs = [decodelist(p, '-') for p in pairs.split(" ")]
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   709
    r = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   710
    for b in repo.between(pairs):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   711
        r.append(encodelist(b) + "\n")
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   712
    return "".join(r)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   713
20909
c8b9cbf55840 wireproto: use decorator for the branchmap command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20908
diff changeset
   714
@wireprotocommand('branchmap')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   715
def branchmap(repo, proto):
18281
898c575833c9 clfilter: drop extra filtering in wireprotocol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18280
diff changeset
   716
    branchmap = repo.branchmap()
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   717
    heads = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   718
    for branch, nodes in branchmap.iteritems():
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
   719
        branchname = urlreq.quote(encoding.fromlocal(branch))
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   720
        branchnodes = encodelist(nodes)
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   721
        heads.append('%s %s' % (branchname, branchnodes))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   722
    return '\n'.join(heads)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   723
20910
acbfce12fafd wireproto: use decorator for the branches command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20909
diff changeset
   724
@wireprotocommand('branches', 'nodes')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   725
def branches(repo, proto, nodes):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   726
    nodes = decodelist(nodes)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   727
    r = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   728
    for b in repo.branches(nodes):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   729
        r.append(encodelist(b) + "\n")
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   730
    return "".join(r)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   731
26857
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   732
@wireprotocommand('clonebundles', '')
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   733
def clonebundles(repo, proto):
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   734
    """Server command for returning info for available bundles to seed clones.
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   735
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   736
    Clients will parse this response and determine what bundle to fetch.
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   737
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   738
    Extensions may wrap this command to filter or dynamically emit data
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   739
    depending on the request. e.g. you could advertise URLs for the closest
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   740
    data center given the client's IP address.
e5a1df51bb25 wireproto: move clonebundles command from extension (issue4931)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26690
diff changeset
   741
    """
31146
16d8bec0177d clonebundle: use 'repo.vfs' instead of 'repo.opener'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31073
diff changeset
   742
    return repo.vfs.tryread('clonebundles.manifest')
20774
cdc3ac896997 wireproto: extract capabilities list in outside the wireproto function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20671
diff changeset
   743
cdc3ac896997 wireproto: extract capabilities list in outside the wireproto function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20671
diff changeset
   744
wireprotocaps = ['lookup', 'changegroupsubset', 'branchmap', 'pushkey',
cdc3ac896997 wireproto: extract capabilities list in outside the wireproto function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20671
diff changeset
   745
                 'known', 'getbundle', 'unbundlehash', 'batch']
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   746
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   747
def _capabilities(repo, proto):
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   748
    """return a list of capabilities for a repo
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   749
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   750
    This function exists to allow extensions to easily wrap capabilities
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   751
    computation
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   752
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   753
    - returns a lists: easy to alter
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   754
    - change done here will be propagated to both `capabilities` and `hello`
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20969
diff changeset
   755
      command without any other action needed.
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   756
    """
20774
cdc3ac896997 wireproto: extract capabilities list in outside the wireproto function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20671
diff changeset
   757
    # copy to prevent modification of the global list
cdc3ac896997 wireproto: extract capabilities list in outside the wireproto function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20671
diff changeset
   758
    caps = list(wireprotocaps)
32744
33b7283a3828 streamclone: consider secret changesets (BC) (issue5589)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32291
diff changeset
   759
    if streamclone.allowservergeneration(repo):
33225
90a1b62bdc91 configitems: register the 'server.preferuncompressed' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33224
diff changeset
   760
        if repo.ui.configbool('server', 'preferuncompressed'):
16361
6097ede2be4d protocol: Add the stream-preferred capability
Benoit Allard <benoit@aeteurope.nl>
parents: 15925
diff changeset
   761
            caps.append('stream-preferred')
12296
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   762
        requiredformats = repo.requirements & repo.supportedformats
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   763
        # if our local revlogs are just revlogv1, add 'stream' cap
32291
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 32260
diff changeset
   764
        if not requiredformats - {'revlogv1'}:
12296
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   765
            caps.append('stream')
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   766
        # otherwise, add 'streamreqs' detailing our local revlog format
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
   767
        else:
26911
d7e5e4da8394 stream: sort stream capability before serialisation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26857
diff changeset
   768
            caps.append('streamreqs=%s' % ','.join(sorted(requiredformats)))
33499
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 33225
diff changeset
   769
    if repo.ui.configbool('experimental', 'bundle2-advertise'):
22342
262c5cc126c1 bundle2: introduce a `getrepocaps` to retrieve the bundle2 caps of a repo
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22341
diff changeset
   770
        capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
28883
032c4c2f802a pycompat: switch to util.urlreq/util.urlerr for py3 compat
timeless <timeless@mozdev.org>
parents: 28666
diff changeset
   771
        caps.append('bundle2=' + urlreq.quote(capsblob))
28666
ae53ecc47414 bundle: move writebundle() from changegroup.py to bundle2.py (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 28530
diff changeset
   772
    caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority))
30563
e118233172fe wireproto: only advertise HTTP-specific capabilities to HTTP peers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30473
diff changeset
   773
e118233172fe wireproto: only advertise HTTP-specific capabilities to HTTP peers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30473
diff changeset
   774
    if proto.name == 'http':
e118233172fe wireproto: only advertise HTTP-specific capabilities to HTTP peers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30473
diff changeset
   775
        caps.append('httpheader=%d' %
33224
ab9121fda8d2 configitems: register the 'server.maxhttpheaderlen' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33223
diff changeset
   776
                    repo.ui.configint('server', 'maxhttpheaderlen'))
33499
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 33225
diff changeset
   777
        if repo.ui.configbool('experimental', 'httppostargs'):
30563
e118233172fe wireproto: only advertise HTTP-specific capabilities to HTTP peers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30473
diff changeset
   778
            caps.append('httppostargs')
e118233172fe wireproto: only advertise HTTP-specific capabilities to HTTP peers (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30473
diff changeset
   779
30762
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   780
        # FUTURE advertise 0.2rx once support is implemented
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   781
        # FUTURE advertise minrx and mintx after consulting config option
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   782
        caps.append('httpmediatype=0.1rx,0.1tx,0.2tx')
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   783
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   784
        compengines = supportedcompengines(repo.ui, proto, util.SERVERROLE)
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   785
        if compengines:
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   786
            comptypes = ','.join(urlreq.quote(e.wireprotosupport().name)
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   787
                                 for e in compengines)
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   788
            caps.append('compression=%s' % comptypes)
35b516f800e0 wireproto: advertise supported media types and compression formats
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30563
diff changeset
   789
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   790
    return caps
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   791
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20969
diff changeset
   792
# If you are writing an extension and consider wrapping this function. Wrap
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   793
# `_capabilities` instead.
20911
1bb8ed6c000c wireproto: use decorator for the capabilities command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20910
diff changeset
   794
@wireprotocommand('capabilities')
20775
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   795
def capabilities(repo, proto):
982f13bef503 wireproto: move wireproto capabilities computation in a subfunction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20774
diff changeset
   796
    return ' '.join(_capabilities(repo, proto))
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   797
20912
96ecb77f971d wireproto: use decorator for the changegroup command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20911
diff changeset
   798
@wireprotocommand('changegroup', 'roots')
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   799
def changegroup(repo, proto, roots):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   800
    nodes = decodelist(roots)
20931
de60ca3a390e localrepo: move the changegroup method in changegroup module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20930
diff changeset
   801
    cg = changegroupmod.changegroup(repo, nodes, 'serve')
30466
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   802
    return streamres(reader=cg, v1compressible=True)
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   803
20913
fc7219ec08bb wireproto: use decorator for the changegroupsubset command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20912
diff changeset
   804
@wireprotocommand('changegroupsubset', 'bases heads')
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   805
def changegroupsubset(repo, proto, bases, heads):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   806
    bases = decodelist(bases)
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   807
    heads = decodelist(heads)
20927
24a443948627 localrepo: move the changegroupsubset method in changegroup module
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20923
diff changeset
   808
    cg = changegroupmod.changegroupsubset(repo, bases, heads, 'serve')
30466
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   809
    return streamres(reader=cg, v1compressible=True)
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
   810
20914
d81b518a1862 wireproto: use decorator for the debugwireargs command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20913
diff changeset
   811
@wireprotocommand('debugwireargs', 'one two *')
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   812
def debugwireargs(repo, proto, one, two, others):
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   813
    # only accept optional args from the known set
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   814
    opts = options('debugwireargs', ['three', 'four'], others)
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
   815
    return repo.debugwireargs(one, two, **opts)
13720
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
   816
20915
6aae815f3e0d wireproto: use decorator for the getbundle command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20914
diff changeset
   817
@wireprotocommand('getbundle', '*')
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   818
def getbundle(repo, proto, others):
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   819
    opts = options('getbundle', gboptsmap.keys(), others)
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   820
    for k, v in opts.iteritems():
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   821
        keytype = gboptsmap[k]
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   822
        if keytype == 'nodes':
19201
309c439cdbaa bundle-ng: add bundlecaps argument to getbundle() command
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 19176
diff changeset
   823
            opts[k] = decodelist(v)
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   824
        elif keytype == 'csv':
25403
30ab130af221 wireprotocol: distinguish list and set in getbundle argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25339
diff changeset
   825
            opts[k] = list(v.split(','))
30ab130af221 wireprotocol: distinguish list and set in getbundle argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25339
diff changeset
   826
        elif keytype == 'scsv':
19201
309c439cdbaa bundle-ng: add bundlecaps argument to getbundle() command
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 19176
diff changeset
   827
            opts[k] = set(v.split(','))
21988
12cd3827b860 wireproto: add a ``boolean`` type for getbundle parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21728
diff changeset
   828
        elif keytype == 'boolean':
26686
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   829
            # Client should serialize False as '0', which is a non-empty string
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   830
            # so it evaluates as a True bool.
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   831
            if v == '0':
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   832
                opts[k] = False
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   833
            else:
3e7f675628ad wireproto: properly parse false boolean args (BC)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
   834
                opts[k] = bool(v)
21646
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   835
        elif keytype != 'plain':
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   836
            raise KeyError('unknown getbundle option type %s'
ce25f465e572 getbundle: declare type of parameters
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21631
diff changeset
   837
                           % keytype)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   838
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   839
    if not bundle1allowed(repo, 'pull'):
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   840
        if not exchange.bundle2requested(opts.get('bundlecaps')):
30912
3d4afc2fdcd7 bundle1: fix bundle1-denied reporting for pull over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30910
diff changeset
   841
            if proto.name == 'http':
3d4afc2fdcd7 bundle1: fix bundle1-denied reporting for pull over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30910
diff changeset
   842
                return ooberror(bundle2required)
3d4afc2fdcd7 bundle1: fix bundle1-denied reporting for pull over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30910
diff changeset
   843
            raise error.Abort(bundle2requiredmain,
3d4afc2fdcd7 bundle1: fix bundle1-denied reporting for pull over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30910
diff changeset
   844
                              hint=bundle2requiredhint)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   845
30914
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   846
    try:
33223
d227451ee280 configitems: register the 'server.disablefullbundle' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33220
diff changeset
   847
        if repo.ui.configbool('server', 'disablefullbundle'):
32260
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   848
            # Check to see if this is a full clone.
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   849
            clheads = set(repo.changelog.heads())
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   850
            heads = set(opts.get('heads', set()))
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   851
            common = set(opts.get('common', set()))
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   852
            common.discard(nullid)
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   853
            if not common and clheads == heads:
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   854
                raise error.Abort(
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   855
                    _('server has pull-based clones disabled'),
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   856
                    hint=_('remove --pull if specified or upgrade Mercurial'))
d0d9a4fca59b clone: add a server-side option to disable full getbundles (pull-based clones)
Siddharth Agarwal <sid0@fb.com>
parents: 31451
diff changeset
   857
30914
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   858
        chunks = exchange.getbundlechunks(repo, 'serve', **opts)
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   859
    except error.Abort as exc:
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   860
        # cleanly forward Abort error to the client
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   861
        if not exchange.bundle2requested(opts.get('bundlecaps')):
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   862
            if proto.name == 'http':
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   863
                return ooberror(str(exc) + '\n')
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   864
            raise # cannot do better for bundle1 + ssh
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   865
        # bundle2 request expect a bundle2 reply
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   866
        bundler = bundle2.bundle20(repo.ui)
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   867
        manargs = [('message', str(exc))]
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   868
        advargs = []
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   869
        if exc.hint is not None:
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   870
            advargs.append(('hint', exc.hint))
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   871
        bundler.addpart(bundle2.bundlepart('error:abort',
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   872
                                           manargs, advargs))
f3807a135e43 wireproto: properly report server Abort during 'getbundle'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30912
diff changeset
   873
        return streamres(gen=bundler.getchunks(), v1compressible=True)
30466
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   874
    return streamres(gen=chunks, v1compressible=True)
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
   875
20916
31eacf182f80 wireproto: use decorator for the heads command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20915
diff changeset
   876
@wireprotocommand('heads')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   877
def heads(repo, proto):
18281
898c575833c9 clfilter: drop extra filtering in wireprotocol
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18280
diff changeset
   878
    h = repo.heads()
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   879
    return encodelist(h) + "\n"
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   880
20917
5ad151f8a3fa wireproto: use decorator for the hello command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20916
diff changeset
   881
@wireprotocommand('hello')
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   882
def hello(repo, proto):
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   883
    '''the hello command returns a set of lines describing various
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   884
    interesting things about the server, in an RFC822-like format.
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   885
    Currently the only one defined is "capabilities", which
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   886
    consists of a line in the form:
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   887
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   888
    capabilities: space separated list of tokens
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   889
    '''
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   890
    return "capabilities: %s\n" % (capabilities(repo, proto))
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
   891
20919
0bb1882c85b0 wireproto: use decorator for the listkeys command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20918
diff changeset
   892
@wireprotocommand('listkeys', 'namespace')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   893
def listkeys(repo, proto, namespace):
15217
42d0d4f63bf0 wireproto: do not call pushkey module directly (issue3041)
Andreas Freimuth <andreas.freimuth@united-bits.de>
parents: 15017
diff changeset
   894
    d = repo.listkeys(encoding.tolocal(namespace)).items()
21651
3aae044408aa wireproto: use pushkey.encodekey
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21646
diff changeset
   895
    return pushkeymod.encodekeys(d)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   896
20920
7fac25eddcea wireproto: use decorator for the lookup command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20919
diff changeset
   897
@wireprotocommand('lookup', 'key')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   898
def lookup(repo, proto, key):
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   899
    try:
15925
f9fc46698352 wireproto: refuse to lookup secret csets
Matt Mackall <mpm@selenic.com>
parents: 15713
diff changeset
   900
        k = encoding.tolocal(key)
f9fc46698352 wireproto: refuse to lookup secret csets
Matt Mackall <mpm@selenic.com>
parents: 15713
diff changeset
   901
        c = repo[k]
f9fc46698352 wireproto: refuse to lookup secret csets
Matt Mackall <mpm@selenic.com>
parents: 15713
diff changeset
   902
        r = c.hex()
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   903
        success = 1
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25493
diff changeset
   904
    except Exception as inst:
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   905
        r = str(inst)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   906
        success = 0
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   907
    return "%s %s\n" % (success, r)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   908
20918
0971939f51aa wireproto: use decorator for the known command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20917
diff changeset
   909
@wireprotocommand('known', 'nodes *')
14436
5adb52524779 wireproto: enable optional args for known() for future extensibility
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14419
diff changeset
   910
def known(repo, proto, nodes, others):
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   911
    return ''.join(b and "1" or "0" for b in repo.known(decodelist(nodes)))
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
   912
20921
70ed3174ce69 wireproto: use decorator for the pushkey command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20920
diff changeset
   913
@wireprotocommand('pushkey', 'namespace key old new')
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
   914
def pushkey(repo, proto, namespace, key, old, new):
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   915
    # compatibility with pre-1.8 clients which were accidentally
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   916
    # sending raw binary nodes rather than utf-8-encoded hex
31451
53865692a354 util: wrap s.encode('string_escape') call for future py3 compatibility
Yuya Nishihara <yuya@tcha.org>
parents: 31146
diff changeset
   917
    if len(new) == 20 and util.escapestr(new) != new:
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   918
        # looks like it could be a binary node
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   919
        try:
14064
e4bfb9c337f3 remove unused imports and variables
Alexander Solovyov <alexander@solovyov.net>
parents: 14048
diff changeset
   920
            new.decode('utf-8')
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   921
            new = encoding.tolocal(new) # but cleanly decodes as UTF-8
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   922
        except UnicodeDecodeError:
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   923
            pass # binary, leave unmodified
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   924
    else:
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   925
        new = encoding.tolocal(new) # normal path
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
   926
17793
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
   927
    if util.safehasattr(proto, 'restore'):
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
   928
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
   929
        proto.redirect()
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
   930
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
   931
        try:
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
   932
            r = repo.pushkey(encoding.tolocal(namespace), encoding.tolocal(key),
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
   933
                             encoding.tolocal(old), new) or False
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26469
diff changeset
   934
        except error.Abort:
17793
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
   935
            r = False
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
   936
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
   937
        output = proto.restore()
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
   938
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
   939
        return '%s\n%s' % (int(r), output)
8474be4412ca wireproto: fix pushkey hook failure and output on remote http repo
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 17603
diff changeset
   940
15217
42d0d4f63bf0 wireproto: do not call pushkey module directly (issue3041)
Andreas Freimuth <andreas.freimuth@united-bits.de>
parents: 15017
diff changeset
   941
    r = repo.pushkey(encoding.tolocal(namespace), encoding.tolocal(key),
42d0d4f63bf0 wireproto: do not call pushkey module directly (issue3041)
Andreas Freimuth <andreas.freimuth@united-bits.de>
parents: 15017
diff changeset
   942
                     encoding.tolocal(old), new)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   943
    return '%s\n' % int(r)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   944
20922
588e24f3eea3 wireproto: use decorator for the stream command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20921
diff changeset
   945
@wireprotocommand('stream_out')
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
   946
def stream(repo, proto):
11627
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
   947
    '''If the server supports streaming clone, it advertises the "stream"
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
   948
    capability with a value representing the version and flags of the repo
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
   949
    it is serving. Client checks to see if it understands the format.
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
   950
    '''
32744
33b7283a3828 streamclone: consider secret changesets (BC) (issue5589)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 32291
diff changeset
   951
    if not streamclone.allowservergeneration(repo):
11627
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
   952
        return '1\n'
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
   953
25235
41965bf23295 exchange: move code for generating a streaming clone into exchange
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25179
diff changeset
   954
    def getstream(it):
41965bf23295 exchange: move code for generating a streaming clone into exchange
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25179
diff changeset
   955
        yield '0\n'
41965bf23295 exchange: move code for generating a streaming clone into exchange
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25179
diff changeset
   956
        for chunk in it:
41965bf23295 exchange: move code for generating a streaming clone into exchange
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25179
diff changeset
   957
            yield chunk
17556
39c6e349dfff wireproto: don't audit local paths during stream_out
Bryan O'Sullivan <bryano@fb.com>
parents: 17424
diff changeset
   958
25235
41965bf23295 exchange: move code for generating a streaming clone into exchange
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25179
diff changeset
   959
    try:
41965bf23295 exchange: move code for generating a streaming clone into exchange
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25179
diff changeset
   960
        # LockError may be raised before the first result is yielded. Don't
41965bf23295 exchange: move code for generating a streaming clone into exchange
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25179
diff changeset
   961
        # emit output until we're sure we got the lock successfully.
26469
fb743268510e streamclone: move payload header generation into own function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26444
diff changeset
   962
        it = streamclone.generatev1wireproto(repo)
30466
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
   963
        return streamres(gen=getstream(it))
25235
41965bf23295 exchange: move code for generating a streaming clone into exchange
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25179
diff changeset
   964
    except error.LockError:
41965bf23295 exchange: move code for generating a streaming clone into exchange
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25179
diff changeset
   965
        return '2\n'
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
   966
20923
d771641b7051 wireproto: use decorator for the ubundle command
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20922
diff changeset
   967
@wireprotocommand('unbundle', 'heads')
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
   968
def unbundle(repo, proto, heads):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
   969
    their_heads = decodelist(heads)
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
   970
20967
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
   971
    try:
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
   972
        proto.redirect()
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
   973
20967
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
   974
        exchange.check_heads(repo, their_heads, 'preparing changes')
12702
f747c085b789 wireproto: redirect the output earlier
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12701
diff changeset
   975
20967
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
   976
        # write bundle data to temporary file because it can be big
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
   977
        fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
30924
48dea083f66d py3: convert the mode argument of os.fdopen to unicodes (1 of 2)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30914
diff changeset
   978
        fp = os.fdopen(fd, pycompat.sysstr('wb+'))
20967
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
   979
        r = 0
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
   980
        try:
20967
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
   981
            proto.getfile(fp)
20968
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
   982
            fp.seek(0)
21064
4d9d490d7bbe bundle2: add a ui argument to readbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21063
diff changeset
   983
            gen = exchange.readbundle(repo.ui, fp, None)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   984
            if (isinstance(gen, changegroupmod.cg1unpacker)
27633
37d7cf569cf3 wireproto: support disabling bundle1 only if repo is generaldelta
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27246
diff changeset
   985
                and not bundle1allowed(repo, 'push')):
30909
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
   986
                if proto.name == 'http':
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
   987
                    # need to special case http because stderr do not get to
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
   988
                    # the http client on failed push so we need to abuse some
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
   989
                    # other error type to make sure the message get to the
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
   990
                    # user.
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
   991
                    return ooberror(bundle2required)
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
   992
                raise error.Abort(bundle2requiredmain,
d554e624c5fe bundle1: fix bundle1-denied reporting for push over ssh
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30762
diff changeset
   993
                                  hint=bundle2requiredhint)
27246
b288fb2724bf wireproto: config options to disable bundle1
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27243
diff changeset
   994
20968
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
   995
            r = exchange.unbundle(repo, gen, their_heads, 'serve',
33d5fdd9bd99 unbundle: extract the core logic in another function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20967
diff changeset
   996
                                  proto._client())
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   997
            if util.safehasattr(r, 'addpart'):
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23009
diff changeset
   998
                # The return looks streamable, we are in the bundle2 case and
21075
438803e4bd97 bundle2: support for push over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21072
diff changeset
   999
                # should return a stream.
30466
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
  1000
                return streamres(gen=r.getchunks())
20967
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1001
            return pushres(r)
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1002
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
  1003
        finally:
20967
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1004
            fp.close()
984850270acb unbundle: extract checkheads in its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20933
diff changeset
  1005
            os.unlink(tempname)
24796
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1006
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26469
diff changeset
  1007
    except (error.BundleValueError, error.Abort, error.PushRaced) as exc:
24796
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1008
        # handle non-bundle2 case first
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1009
        if not getattr(exc, 'duringunbundle2', False):
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1010
            try:
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1011
                raise
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26469
diff changeset
  1012
            except error.Abort:
30473
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30466
diff changeset
  1013
                # The old code we moved used util.stderr directly.
24796
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1014
                # We did not change it to minimise code change.
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1015
                # This need to be moved to something proper.
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1016
                # Feel free to do it.
30473
39d13b8c101d py3: bulk replace sys.stdin/out/err by util's
Yuya Nishihara <yuya@tcha.org>
parents: 30466
diff changeset
  1017
                util.stderr.write("abort: %s\n" % exc)
30910
accaa04f951c bundle1: display server abort hint during unbundle
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30909
diff changeset
  1018
                if exc.hint is not None:
accaa04f951c bundle1: display server abort hint during unbundle
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30909
diff changeset
  1019
                    util.stderr.write("(%s)\n" % exc.hint)
24796
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1020
                return pushres(0)
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1021
            except error.PushRaced:
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1022
                return pusherr(str(exc))
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1023
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1024
        bundler = bundle2.bundle20(repo.ui)
24797
0c4d5e01b31f bundle2-wireproto: properly propagate the server output on error (issue4594)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24796
diff changeset
  1025
        for out in getattr(exc, '_bundle2salvagedoutput', ()):
0c4d5e01b31f bundle2-wireproto: properly propagate the server output on error (issue4594)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24796
diff changeset
  1026
            bundler.addpart(out)
24796
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1027
        try:
25493
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1028
            try:
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1029
                raise
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25493
diff changeset
  1030
            except error.PushkeyFailed as exc:
25493
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1031
                # check client caps
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1032
                remotecaps = getattr(exc, '_replycaps', None)
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1033
                if (remotecaps is not None
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1034
                        and 'pushkey' not in remotecaps.get('error', ())):
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1035
                    # no support remote side, fallback to Abort handler.
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1036
                    raise
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1037
                part = bundler.newpart('error:pushkey')
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1038
                part.addparam('in-reply-to', exc.partid)
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1039
                if exc.namespace is not None:
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1040
                    part.addparam('namespace', exc.namespace, mandatory=False)
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1041
                if exc.key is not None:
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1042
                    part.addparam('key', exc.key, mandatory=False)
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1043
                if exc.new is not None:
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1044
                    part.addparam('new', exc.new, mandatory=False)
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1045
                if exc.old is not None:
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1046
                    part.addparam('old', exc.old, mandatory=False)
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1047
                if exc.ret is not None:
d8e7b0781ad7 bundle2: convey PushkeyFailed error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25403
diff changeset
  1048
                    part.addparam('ret', exc.ret, mandatory=False)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25493
diff changeset
  1049
        except error.BundleValueError as exc:
24686
e0e28e910fa3 bundle2: rename format, parts and config to final names
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24649
diff changeset
  1050
            errpart = bundler.newpart('error:unsupportedcontent')
21627
3e8bcc90f07c bundle2: support None parttype in BundleValueError
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21622
diff changeset
  1051
            if exc.parttype is not None:
3e8bcc90f07c bundle2: support None parttype in BundleValueError
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21622
diff changeset
  1052
                errpart.addparam('parttype', exc.parttype)
21622
457492741007 bundle2: support transmission of params error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21620
diff changeset
  1053
            if exc.params:
457492741007 bundle2: support transmission of params error over the wire
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21620
diff changeset
  1054
                errpart.addparam('params', '\0'.join(exc.params))
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26469
diff changeset
  1055
        except error.Abort as exc:
24796
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1056
            manargs = [('message', str(exc))]
21177
952af771bc17 bundle2: gracefully handle abort during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21157
diff changeset
  1057
            advargs = []
24796
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1058
            if exc.hint is not None:
61ff209fc01d bundle2: refactor error bundle creation for the wireprotocol
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24696
diff changeset
  1059
                advargs.append(('hint', exc.hint))
24686
e0e28e910fa3 bundle2: rename format, parts and config to final names
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24649
diff changeset
  1060
            bundler.addpart(bundle2.bundlepart('error:abort',
21177
952af771bc17 bundle2: gracefully handle abort during unbundle
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21157
diff changeset
  1061
                                               manargs, advargs))
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25493
diff changeset
  1062
        except error.PushRaced as exc:
24686
e0e28e910fa3 bundle2: rename format, parts and config to final names
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24649
diff changeset
  1063
            bundler.newpart('error:pushraced', [('message', str(exc))])
30466
2add671bf55b wireproto: perform chunking and compression at protocol layer (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30206
diff changeset
  1064
        return streamres(gen=bundler.getchunks())