--- a/mercurial/wireprotov2server.py Sat Oct 05 10:29:34 2019 -0400
+++ b/mercurial/wireprotov2server.py Sun Oct 06 09:45:02 2019 -0400
@@ -28,9 +28,7 @@
wireprotoframing,
wireprototypes,
)
-from .interfaces import (
- util as interfaceutil,
-)
+from .interfaces import util as interfaceutil
from .utils import (
cborutil,
stringutil,
@@ -47,6 +45,7 @@
# there is a change to how caching works, etc.
GLOBAL_CACHE_VERSION = 1
+
def handlehttpv2request(rctx, req, res, checkperm, urlparts):
from .hgweb import common as hgwebcommon
@@ -63,8 +62,9 @@
if len(urlparts) == 1:
res.status = b'404 Not Found'
res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(_('do not know how to process %s\n') %
- req.dispatchpath)
+ res.setbodybytes(
+ _('do not know how to process %s\n') % req.dispatchpath
+ )
return
permission, command = urlparts[0:2]
@@ -115,8 +115,10 @@
proto = httpv2protocolhandler(req, ui)
- if (not COMMANDS.commandavailable(command, proto)
- and command not in extracommands):
+ if (
+ not COMMANDS.commandavailable(command, proto)
+ and command not in extracommands
+ ):
res.status = b'404 Not Found'
res.headers[b'Content-Type'] = b'text/plain'
res.setbodybytes(_('invalid wire protocol command: %s') % command)
@@ -126,8 +128,10 @@
if req.headers.get(b'Accept') != FRAMINGTYPE:
res.status = b'406 Not Acceptable'
res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(_('client MUST specify Accept header with value: %s\n')
- % FRAMINGTYPE)
+ res.setbodybytes(
+ _('client MUST specify Accept header with value: %s\n')
+ % FRAMINGTYPE
+ )
return
if req.headers.get(b'Content-Type') != FRAMINGTYPE:
@@ -135,12 +139,15 @@
# TODO we should send a response with appropriate media type,
# since client does Accept it.
res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(_('client MUST send Content-Type header with '
- 'value: %s\n') % FRAMINGTYPE)
+ res.setbodybytes(
+ _('client MUST send Content-Type header with ' 'value: %s\n')
+ % FRAMINGTYPE
+ )
return
_processhttpv2request(ui, repo, req, res, permission, command, proto)
+
def _processhttpv2reflectrequest(ui, repo, req, res):
"""Reads unified frame protocol request and dumps out state to client.
@@ -171,9 +178,10 @@
states.append(b'received: <no frame>')
break
- states.append(b'received: %d %d %d %s' % (frame.typeid, frame.flags,
- frame.requestid,
- frame.payload))
+ states.append(
+ b'received: %d %d %d %s'
+ % (frame.typeid, frame.flags, frame.requestid, frame.payload)
+ )
action, meta = reactor.onframerecv(frame)
states.append(templatefilters.json((action, meta)))
@@ -186,6 +194,7 @@
res.headers[b'Content-Type'] = b'text/plain'
res.setbodybytes(b'\n'.join(states))
+
def _processhttpv2request(ui, repo, req, res, authedperm, reqcommand, proto):
"""Post-validation handler for HTTPv2 requests.
@@ -216,9 +225,18 @@
if not outstream:
outstream = reactor.makeoutputstream()
- sentoutput = _httpv2runcommand(ui, repo, req, res, authedperm,
- reqcommand, reactor, outstream,
- meta, issubsequent=seencommand)
+ sentoutput = _httpv2runcommand(
+ ui,
+ repo,
+ req,
+ res,
+ authedperm,
+ reqcommand,
+ reactor,
+ outstream,
+ meta,
+ issubsequent=seencommand,
+ )
if sentoutput:
return
@@ -233,7 +251,8 @@
return
else:
raise error.ProgrammingError(
- 'unhandled action from frame processor: %s' % action)
+ 'unhandled action from frame processor: %s' % action
+ )
action, meta = reactor.oninputeof()
if action == 'sendframes':
@@ -245,11 +264,23 @@
elif action == 'noop':
pass
else:
- raise error.ProgrammingError('unhandled action from frame processor: %s'
- % action)
+ raise error.ProgrammingError(
+ 'unhandled action from frame processor: %s' % action
+ )
+
-def _httpv2runcommand(ui, repo, req, res, authedperm, reqcommand, reactor,
- outstream, command, issubsequent):
+def _httpv2runcommand(
+ ui,
+ repo,
+ req,
+ res,
+ authedperm,
+ reqcommand,
+ reactor,
+ outstream,
+ command,
+ issubsequent,
+):
"""Dispatch a wire protocol command made from HTTPv2 requests.
The authenticated permission (``authedperm``) along with the original
@@ -277,8 +308,10 @@
# TODO proper error mechanism
res.status = b'200 OK'
res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(_('wire protocol command not available: %s') %
- command['command'])
+ res.setbodybytes(
+ _('wire protocol command not available: %s')
+ % command['command']
+ )
return True
# TODO don't use assert here, since it may be elided by -O.
@@ -290,8 +323,10 @@
# TODO proper error mechanism
res.status = b'403 Forbidden'
res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(_('insufficient permissions to execute '
- 'command: %s') % command['command'])
+ res.setbodybytes(
+ _('insufficient permissions to execute ' 'command: %s')
+ % command['command']
+ )
return True
# TODO should we also call checkperm() here? Maybe not if we're going
@@ -304,8 +339,9 @@
# TODO proper error mechanism
res.status = b'200 OK'
res.headers[b'Content-Type'] = b'text/plain'
- res.setbodybytes(_('multiple commands cannot be issued to this '
- 'URL'))
+ res.setbodybytes(
+ _('multiple commands cannot be issued to this ' 'URL')
+ )
return True
if reqcommand != command['command']:
@@ -322,17 +358,21 @@
objs = dispatch(repo, proto, command['command'], command['redirect'])
action, meta = reactor.oncommandresponsereadyobjects(
- outstream, command['requestid'], objs)
+ outstream, command['requestid'], objs
+ )
except error.WireprotoCommandError as e:
action, meta = reactor.oncommanderror(
- outstream, command['requestid'], e.message, e.messageargs)
+ outstream, command['requestid'], e.message, e.messageargs
+ )
except Exception as e:
action, meta = reactor.onservererror(
- outstream, command['requestid'],
- _('exception when invoking command: %s') %
- stringutil.forcebytestr(e))
+ outstream,
+ command['requestid'],
+ _('exception when invoking command: %s')
+ % stringutil.forcebytestr(e),
+ )
if action == 'sendframes':
res.setbodygen(meta['framegen'])
@@ -340,13 +380,16 @@
elif action == 'noop':
return False
else:
- raise error.ProgrammingError('unhandled event from reactor: %s' %
- action)
+ raise error.ProgrammingError(
+ 'unhandled event from reactor: %s' % action
+ )
+
def getdispatchrepo(repo, proto, command):
viewconfig = repo.ui.config('server', 'view')
return repo.filtered(viewconfig)
+
def dispatch(repo, proto, command, redirect):
"""Run a wire protocol command.
@@ -379,10 +422,15 @@
redirecttargets = []
redirecthashes = []
- cacher = makeresponsecacher(repo, proto, command, args,
- cborutil.streamencode,
- redirecttargets=redirecttargets,
- redirecthashes=redirecthashes)
+ cacher = makeresponsecacher(
+ repo,
+ proto,
+ command,
+ args,
+ cborutil.streamencode,
+ redirecttargets=redirecttargets,
+ redirecthashes=redirecthashes,
+ )
# But we have no cacher. Do default handling.
if not cacher:
@@ -391,8 +439,9 @@
return
with cacher:
- cachekey = entry.cachekeyfn(repo, proto, cacher,
- **pycompat.strkwargs(args))
+ cachekey = entry.cachekeyfn(
+ repo, proto, cacher, **pycompat.strkwargs(args)
+ )
# No cache key or the cacher doesn't like it. Do default handling.
if cachekey is None or not cacher.setcachekey(cachekey):
@@ -417,6 +466,7 @@
for o in cacher.onfinished():
yield o
+
@interfaceutil.implementer(wireprototypes.baseprotocolhandler)
class httpv2protocolhandler(object):
def __init__(self, req, ui, args=None):
@@ -434,15 +484,16 @@
extra = set(self._args) - set(args)
if extra:
raise error.WireprotoCommandError(
- 'unsupported argument to command: %s' %
- ', '.join(sorted(extra)))
+ 'unsupported argument to command: %s' % ', '.join(sorted(extra))
+ )
# And look for required arguments that are missing.
missing = {a for a in args if args[a]['required']} - set(self._args)
if missing:
raise error.WireprotoCommandError(
- 'missing required arguments: %s' % ', '.join(sorted(missing)))
+ 'missing required arguments: %s' % ', '.join(sorted(missing))
+ )
# Now derive the arguments to pass to the command, taking into
# account the arguments specified by the client.
@@ -485,11 +536,13 @@
def checkperm(self, perm):
raise NotImplementedError
+
def httpv2apidescriptor(req, repo):
proto = httpv2protocolhandler(req, repo.ui)
return _capabilitiesv2(repo, proto)
+
def _capabilitiesv2(repo, proto):
"""Obtain the set of capabilities for version 2 transports.
@@ -520,8 +573,10 @@
args[arg][b'validvalues'] = meta['validvalues']
# TODO this type of check should be defined in a per-command callback.
- if (command == b'rawstorefiledata'
- and not streamclone.allowservergeneration(repo)):
+ if (
+ command == b'rawstorefiledata'
+ and not streamclone.allowservergeneration(repo)
+ ):
continue
caps['commands'][command] = {
@@ -533,8 +588,7 @@
extracaps = entry.extracapabilitiesfn(repo, proto)
caps['commands'][command].update(extracaps)
- caps['rawrepoformats'] = sorted(repo.requirements &
- repo.supportedformats)
+ caps['rawrepoformats'] = sorted(repo.requirements & repo.supportedformats)
targets = getadvertisedredirecttargets(repo, proto)
if targets:
@@ -558,6 +612,7 @@
return proto.addcapabilities(repo, caps)
+
def getadvertisedredirecttargets(repo, proto):
"""Obtain a list of content redirect targets.
@@ -596,8 +651,14 @@
"""
return []
-def wireprotocommand(name, args=None, permission='push', cachekeyfn=None,
- extracapabilitiesfn=None):
+
+def wireprotocommand(
+ name,
+ args=None,
+ permission='push',
+ cachekeyfn=None,
+ extracapabilitiesfn=None,
+):
"""Decorator to declare a wire protocol command.
``name`` is the name of the wire protocol command being provided.
@@ -648,42 +709,53 @@
containing the key in a cache the response to this command may be cached
under.
"""
- transports = {k for k, v in wireprototypes.TRANSPORTS.items()
- if v['version'] == 2}
+ transports = {
+ k for k, v in wireprototypes.TRANSPORTS.items() if v['version'] == 2
+ }
if permission not in ('push', 'pull'):
- raise error.ProgrammingError('invalid wire protocol permission; '
- 'got %s; expected "push" or "pull"' %
- permission)
+ raise error.ProgrammingError(
+ 'invalid wire protocol permission; '
+ 'got %s; expected "push" or "pull"' % permission
+ )
if args is None:
args = {}
if not isinstance(args, dict):
- raise error.ProgrammingError('arguments for version 2 commands '
- 'must be declared as dicts')
+ raise error.ProgrammingError(
+ 'arguments for version 2 commands ' 'must be declared as dicts'
+ )
for arg, meta in args.items():
if arg == '*':
- raise error.ProgrammingError('* argument name not allowed on '
- 'version 2 commands')
+ raise error.ProgrammingError(
+ '* argument name not allowed on ' 'version 2 commands'
+ )
if not isinstance(meta, dict):
- raise error.ProgrammingError('arguments for version 2 commands '
- 'must declare metadata as a dict')
+ raise error.ProgrammingError(
+ 'arguments for version 2 commands '
+ 'must declare metadata as a dict'
+ )
if 'type' not in meta:
- raise error.ProgrammingError('%s argument for command %s does not '
- 'declare type field' % (arg, name))
+ raise error.ProgrammingError(
+ '%s argument for command %s does not '
+ 'declare type field' % (arg, name)
+ )
if meta['type'] not in ('bytes', 'int', 'list', 'dict', 'set', 'bool'):
- raise error.ProgrammingError('%s argument for command %s has '
- 'illegal type: %s' % (arg, name,
- meta['type']))
+ raise error.ProgrammingError(
+ '%s argument for command %s has '
+ 'illegal type: %s' % (arg, name, meta['type'])
+ )
if 'example' not in meta:
- raise error.ProgrammingError('%s argument for command %s does not '
- 'declare example field' % (arg, name))
+ raise error.ProgrammingError(
+ '%s argument for command %s does not '
+ 'declare example field' % (arg, name)
+ )
meta['required'] = 'default' not in meta
@@ -692,17 +764,24 @@
def register(func):
if name in COMMANDS:
- raise error.ProgrammingError('%s command already registered '
- 'for version 2' % name)
+ raise error.ProgrammingError(
+ '%s command already registered ' 'for version 2' % name
+ )
COMMANDS[name] = wireprototypes.commandentry(
- func, args=args, transports=transports, permission=permission,
- cachekeyfn=cachekeyfn, extracapabilitiesfn=extracapabilitiesfn)
+ func,
+ args=args,
+ transports=transports,
+ permission=permission,
+ cachekeyfn=cachekeyfn,
+ extracapabilitiesfn=extracapabilitiesfn,
+ )
return func
return register
+
def makecommandcachekeyfn(command, localversion=None, allargs=False):
"""Construct a cache key derivation function with common features.
@@ -777,8 +856,10 @@
return cachekeyfn
-def makeresponsecacher(repo, proto, command, args, objencoderfn,
- redirecttargets, redirecthashes):
+
+def makeresponsecacher(
+ repo, proto, command, args, objencoderfn, redirecttargets, redirecthashes
+):
"""Construct a cacher for a cacheable command.
Returns an ``iwireprotocolcommandcacher`` instance.
@@ -788,6 +869,7 @@
"""
return None
+
def resolvenodes(repo, revisions):
"""Resolve nodes from a revisions specifier data structure."""
cl = repo.changelog
@@ -797,13 +879,15 @@
nodes = []
if not isinstance(revisions, list):
- raise error.WireprotoCommandError('revisions must be defined as an '
- 'array')
+ raise error.WireprotoCommandError(
+ 'revisions must be defined as an ' 'array'
+ )
for spec in revisions:
if b'type' not in spec:
raise error.WireprotoCommandError(
- 'type key not present in revision specifier')
+ 'type key not present in revision specifier'
+ )
typ = spec[b'type']
@@ -811,7 +895,8 @@
if b'nodes' not in spec:
raise error.WireprotoCommandError(
'nodes key not present in changesetexplicit revision '
- 'specifier')
+ 'specifier'
+ )
for node in spec[b'nodes']:
if node not in seen:
@@ -823,10 +908,13 @@
if key not in spec:
raise error.WireprotoCommandError(
'%s key not present in changesetexplicitdepth revision '
- 'specifier', (key,))
+ 'specifier',
+ (key,),
+ )
- for rev in repo.revs(b'ancestors(%ln, %s)', spec[b'nodes'],
- spec[b'depth'] - 1):
+ for rev in repo.revs(
+ b'ancestors(%ln, %s)', spec[b'nodes'], spec[b'depth'] - 1
+ ):
node = cl.node(rev)
if node not in seen:
@@ -838,11 +926,14 @@
if key not in spec:
raise error.WireprotoCommandError(
'%s key not present in changesetdagrange revision '
- 'specifier', (key,))
+ 'specifier',
+ (key,),
+ )
if not spec[b'heads']:
raise error.WireprotoCommandError(
- 'heads key in changesetdagrange cannot be empty')
+ 'heads key in changesetdagrange cannot be empty'
+ )
if spec[b'roots']:
common = [n for n in spec[b'roots'] if clhasnode(n)]
@@ -856,28 +947,30 @@
else:
raise error.WireprotoCommandError(
- 'unknown revision specifier type: %s', (typ,))
+ 'unknown revision specifier type: %s', (typ,)
+ )
return nodes
+
@wireprotocommand('branchmap', permission='pull')
def branchmapv2(repo, proto):
- yield {encoding.fromlocal(k): v
- for k, v in repo.branchmap().iteritems()}
+ yield {encoding.fromlocal(k): v for k, v in repo.branchmap().iteritems()}
+
@wireprotocommand('capabilities', permission='pull')
def capabilitiesv2(repo, proto):
yield _capabilitiesv2(repo, proto)
+
@wireprotocommand(
'changesetdata',
args={
'revisions': {
'type': 'list',
- 'example': [{
- b'type': b'changesetexplicit',
- b'nodes': [b'abcdef...'],
- }],
+ 'example': [
+ {b'type': b'changesetexplicit', b'nodes': [b'abcdef...'],}
+ ],
},
'fields': {
'type': 'set',
@@ -886,7 +979,8 @@
'validvalues': {b'bookmarks', b'parents', b'phase', b'revision'},
},
},
- permission='pull')
+ permission='pull',
+)
def changesetdata(repo, proto, revisions, fields):
# TODO look for unknown fields and abort when they can't be serviced.
# This could probably be validated by dispatcher using validvalues.
@@ -963,6 +1057,7 @@
b'bookmarks': sorted(marks),
}
+
class FileAccessError(Exception):
"""Represents an error accessing a specific file."""
@@ -971,6 +1066,7 @@
self.msg = msg
self.args = args
+
def getfilestore(repo, proto, path):
"""Obtain a file storage object for use with wire protocol.
@@ -986,6 +1082,7 @@
return fl
+
def emitfilerevisions(repo, path, revisions, linknodes, fields):
for revision in revisions:
d = {
@@ -1018,6 +1115,7 @@
for extra in followingdata:
yield extra
+
def makefilematcher(repo, pathfilter):
"""Construct a matcher from a path filter dict."""
@@ -1028,12 +1126,17 @@
if not pattern.startswith((b'path:', b'rootfilesin:')):
raise error.WireprotoCommandError(
'%s pattern must begin with `path:` or `rootfilesin:`; '
- 'got %s', (key, pattern))
+ 'got %s',
+ (key, pattern),
+ )
if pathfilter:
- matcher = matchmod.match(repo.root, b'',
- include=pathfilter.get(b'include', []),
- exclude=pathfilter.get(b'exclude', []))
+ matcher = matchmod.match(
+ repo.root,
+ b'',
+ include=pathfilter.get(b'include', []),
+ exclude=pathfilter.get(b'exclude', []),
+ )
else:
matcher = matchmod.match(repo.root, b'')
@@ -1041,6 +1144,7 @@
# filter those out.
return repo.narrowmatch(matcher)
+
@wireprotocommand(
'filedata',
args={
@@ -1049,26 +1153,21 @@
'default': lambda: False,
'example': True,
},
- 'nodes': {
- 'type': 'list',
- 'example': [b'0123456...'],
- },
+ 'nodes': {'type': 'list', 'example': [b'0123456...'],},
'fields': {
'type': 'set',
'default': set,
'example': {b'parents', b'revision'},
'validvalues': {b'parents', b'revision', b'linknode'},
},
- 'path': {
- 'type': 'bytes',
- 'example': b'foo.txt',
- }
+ 'path': {'type': 'bytes', 'example': b'foo.txt',},
},
permission='pull',
# TODO censoring a file revision won't invalidate the cache.
# Figure out a way to take censoring into account when deriving
# the cache key.
- cachekeyfn=makecommandcachekeyfn('filedata', 1, allargs=True))
+ cachekeyfn=makecommandcachekeyfn('filedata', 1, allargs=True),
+)
def filedata(repo, proto, haveparents, nodes, fields, path):
# TODO this API allows access to file revisions that are attached to
# secret changesets. filesdata does not have this problem. Maybe this
@@ -1088,8 +1187,9 @@
try:
store.rev(node)
except error.LookupError:
- raise error.WireprotoCommandError('unknown file node: %s',
- (hex(node),))
+ raise error.WireprotoCommandError(
+ 'unknown file node: %s', (hex(node),)
+ )
# TODO by creating the filectx against a specific file revision
# instead of changeset, linkrev() is always used. This is wrong for
@@ -1099,9 +1199,11 @@
fctx = repo.filectx(path, fileid=node)
linknodes[node] = clnode(fctx.introrev())
- revisions = store.emitrevisions(nodes,
- revisiondata=b'revision' in fields,
- assumehaveparentrevisions=haveparents)
+ revisions = store.emitrevisions(
+ nodes,
+ revisiondata=b'revision' in fields,
+ assumehaveparentrevisions=haveparents,
+ )
yield {
b'totalitems': len(nodes),
@@ -1110,13 +1212,16 @@
for o in emitfilerevisions(repo, path, revisions, linknodes, fields):
yield o
+
def filesdatacapabilities(repo, proto):
batchsize = repo.ui.configint(
- b'experimental', b'server.filesdata.recommended-batch-size')
+ b'experimental', b'server.filesdata.recommended-batch-size'
+ )
return {
b'recommendedbatchsize': batchsize,
}
+
@wireprotocommand(
'filesdata',
args={
@@ -1129,8 +1234,12 @@
'type': 'set',
'default': set,
'example': {b'parents', b'revision'},
- 'validvalues': {b'firstchangeset', b'linknode', b'parents',
- b'revision'},
+ 'validvalues': {
+ b'firstchangeset',
+ b'linknode',
+ b'parents',
+ b'revision',
+ },
},
'pathfilter': {
'type': 'dict',
@@ -1139,10 +1248,9 @@
},
'revisions': {
'type': 'list',
- 'example': [{
- b'type': b'changesetexplicit',
- b'nodes': [b'abcdef...'],
- }],
+ 'example': [
+ {b'type': b'changesetexplicit', b'nodes': [b'abcdef...'],}
+ ],
},
},
permission='pull',
@@ -1150,7 +1258,8 @@
# Figure out a way to take censoring into account when deriving
# the cache key.
cachekeyfn=makecommandcachekeyfn('filesdata', 1, allargs=True),
- extracapabilitiesfn=filesdatacapabilities)
+ extracapabilitiesfn=filesdatacapabilities,
+)
def filesdata(repo, proto, haveparents, fields, pathfilter, revisions):
# TODO This should operate on a repo that exposes obsolete changesets. There
# is a race between a client making a push that obsoletes a changeset and
@@ -1193,7 +1302,7 @@
yield {
b'totalpaths': len(fnodes),
- b'totalitems': sum(len(v) for v in fnodes.values())
+ b'totalitems': sum(len(v) for v in fnodes.values()),
}
for path, filenodes in sorted(fnodes.items()):
@@ -1207,13 +1316,16 @@
b'totalitems': len(filenodes),
}
- revisions = store.emitrevisions(filenodes.keys(),
- revisiondata=b'revision' in fields,
- assumehaveparentrevisions=haveparents)
+ revisions = store.emitrevisions(
+ filenodes.keys(),
+ revisiondata=b'revision' in fields,
+ assumehaveparentrevisions=haveparents,
+ )
for o in emitfilerevisions(repo, path, revisions, filenodes, fields):
yield o
+
@wireprotocommand(
'heads',
args={
@@ -1223,52 +1335,47 @@
'example': False,
},
},
- permission='pull')
+ permission='pull',
+)
def headsv2(repo, proto, publiconly):
if publiconly:
repo = repo.filtered('immutable')
yield repo.heads()
+
@wireprotocommand(
'known',
args={
- 'nodes': {
- 'type': 'list',
- 'default': list,
- 'example': [b'deadbeef'],
- },
+ 'nodes': {'type': 'list', 'default': list, 'example': [b'deadbeef'],},
},
- permission='pull')
+ permission='pull',
+)
def knownv2(repo, proto, nodes):
result = b''.join(b'1' if n else b'0' for n in repo.known(nodes))
yield result
+
@wireprotocommand(
'listkeys',
- args={
- 'namespace': {
- 'type': 'bytes',
- 'example': b'ns',
- },
- },
- permission='pull')
+ args={'namespace': {'type': 'bytes', 'example': b'ns',},},
+ permission='pull',
+)
def listkeysv2(repo, proto, namespace):
keys = repo.listkeys(encoding.tolocal(namespace))
- keys = {encoding.fromlocal(k): encoding.fromlocal(v)
- for k, v in keys.iteritems()}
+ keys = {
+ encoding.fromlocal(k): encoding.fromlocal(v)
+ for k, v in keys.iteritems()
+ }
yield keys
+
@wireprotocommand(
'lookup',
- args={
- 'key': {
- 'type': 'bytes',
- 'example': b'foo',
- },
- },
- permission='pull')
+ args={'key': {'type': 'bytes', 'example': b'foo',},},
+ permission='pull',
+)
def lookupv2(repo, proto, key):
key = encoding.tolocal(key)
@@ -1277,21 +1384,21 @@
yield node
+
def manifestdatacapabilities(repo, proto):
batchsize = repo.ui.configint(
- b'experimental', b'server.manifestdata.recommended-batch-size')
+ b'experimental', b'server.manifestdata.recommended-batch-size'
+ )
return {
b'recommendedbatchsize': batchsize,
}
+
@wireprotocommand(
'manifestdata',
args={
- 'nodes': {
- 'type': 'list',
- 'example': [b'0123456...'],
- },
+ 'nodes': {'type': 'list', 'example': [b'0123456...'],},
'haveparents': {
'type': 'bool',
'default': lambda: False,
@@ -1303,14 +1410,12 @@
'example': {b'parents', b'revision'},
'validvalues': {b'parents', b'revision'},
},
- 'tree': {
- 'type': 'bytes',
- 'example': b'',
- },
+ 'tree': {'type': 'bytes', 'example': b'',},
},
permission='pull',
cachekeyfn=makecommandcachekeyfn('manifestdata', 1, allargs=True),
- extracapabilitiesfn=manifestdatacapabilities)
+ extracapabilitiesfn=manifestdatacapabilities,
+)
def manifestdata(repo, proto, haveparents, nodes, fields, tree):
store = repo.manifestlog.getstorage(tree)
@@ -1319,12 +1424,13 @@
try:
store.rev(node)
except error.LookupError:
- raise error.WireprotoCommandError(
- 'unknown node: %s', (node,))
+ raise error.WireprotoCommandError('unknown node: %s', (node,))
- revisions = store.emitrevisions(nodes,
- revisiondata=b'revision' in fields,
- assumehaveparentrevisions=haveparents)
+ revisions = store.emitrevisions(
+ nodes,
+ revisiondata=b'revision' in fields,
+ assumehaveparentrevisions=haveparents,
+ )
yield {
b'totalitems': len(nodes),
@@ -1358,49 +1464,39 @@
for extra in followingdata:
yield extra
+
@wireprotocommand(
'pushkey',
args={
- 'namespace': {
- 'type': 'bytes',
- 'example': b'ns',
- },
- 'key': {
- 'type': 'bytes',
- 'example': b'key',
- },
- 'old': {
- 'type': 'bytes',
- 'example': b'old',
- },
- 'new': {
- 'type': 'bytes',
- 'example': 'new',
- },
+ 'namespace': {'type': 'bytes', 'example': b'ns',},
+ 'key': {'type': 'bytes', 'example': b'key',},
+ 'old': {'type': 'bytes', 'example': b'old',},
+ 'new': {'type': 'bytes', 'example': 'new',},
},
- permission='push')
+ permission='push',
+)
def pushkeyv2(repo, proto, namespace, key, old, new):
# TODO handle ui output redirection
- yield repo.pushkey(encoding.tolocal(namespace),
- encoding.tolocal(key),
- encoding.tolocal(old),
- encoding.tolocal(new))
+ yield repo.pushkey(
+ encoding.tolocal(namespace),
+ encoding.tolocal(key),
+ encoding.tolocal(old),
+ encoding.tolocal(new),
+ )
@wireprotocommand(
'rawstorefiledata',
args={
- 'files': {
- 'type': 'list',
- 'example': [b'changelog', b'manifestlog'],
- },
+ 'files': {'type': 'list', 'example': [b'changelog', b'manifestlog'],},
'pathfilter': {
'type': 'list',
'default': lambda: None,
'example': {b'include': [b'path:tests']},
},
},
- permission='pull')
+ permission='pull',
+)
def rawstorefiledata(repo, proto, files, pathfilter):
if not streamclone.allowservergeneration(repo):
raise error.WireprotoCommandError(b'stream clone is disabled')
@@ -1412,8 +1508,9 @@
unsupported = files - allowedfiles
if unsupported:
- raise error.WireprotoCommandError(b'unknown file type: %s',
- (b', '.join(sorted(unsupported)),))
+ raise error.WireprotoCommandError(
+ b'unknown file type: %s', (b', '.join(sorted(unsupported)),)
+ )
with repo.lock():
topfiles = list(repo.store.topfiles())
@@ -1453,5 +1550,4 @@
for chunk in util.filechunkiter(fh, limit=size):
yield chunk
- yield wireprototypes.indefinitebytestringresponse(
- getfiledata())
+ yield wireprototypes.indefinitebytestringresponse(getfiledata())