##// END OF EJS Templates
revset: introduce new operator "##" to concatenate strings/symbols at runtime...
revset: introduce new operator "##" to concatenate strings/symbols at runtime Before this patch, there is no way to concatenate strings at runtime. For example, to search for the issue ID "1234" in descriptions against all of "issue 1234", "issue:1234", issue1234" and "bug(1234)" patterns, the revset below should be written fully from scratch for each issue ID. grep(r"\bissue[ :]?1234\b|\bbug\(1234\)") This patch introduces new infix operator "##" to concatenate strings/symbols at runtime. Operator symbol "##" comes from the same one of C pre-processor. This concatenation allows parametrizing a part of strings in revset queries. In the case of example above, the definition of the revset alias using operator "##" below can search issue ID "1234" in complicated patterns by "issue(1234)" simply: issue($1) = grep(r"\bissue[ :]?" ## $1 ## r"\b|\bbug\(" ## $1 ## r"\)") "##" operator does: - concatenate not only strings but also symbols into the string Exact distinction between strings and symbols seems not to be convenience, because it is tiresome for users (and "revset.getstring" treats both similarly) For example of revset alias "issue()", "issue(1234)" is easier than "issue('1234')". - have higher priority than any other prefix, infix and postfix operators (like as "##" of C pre-processor) This patch (re-)assigns the priority 20 to "##", and 21 to "(", because priority 19 is already assigned to "-" as prefix "negate".

File last commit:

r20903:8d477543 default
r23742:3a4d8a6c default
Show More
protocol.py
98 lines | 3.1 KiB | text/x-python | PythonLexer
Dirkjan Ochtman
separate the wire protocol commands from the user interface commands
r5598 #
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
#
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Dirkjan Ochtman
separate the wire protocol commands from the user interface commands
r5598
Idan Kamara
ui: use I/O descriptors internally...
r14614 import cgi, cStringIO, zlib, urllib
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 from mercurial import util, wireproto
from common import HTTP_OK
Dirkjan Ochtman
hgweb: explicitly check if requested command exists
r5963
Dirkjan Ochtman
hgweb: explicit response status
r5993 HGTYPE = 'application/mercurial-0.1'
Andrew Pritchard
wireproto: add out-of-band error class to allow remote repo to report errors...
r15017 HGERRTYPE = 'application/hg-error'
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595
Pierre-Yves David
wireproto: introduce an abstractserverproto class...
r20903 class webproto(wireproto.abstractserverproto):
Idan Kamara
ui: use I/O descriptors internally...
r14614 def __init__(self, req, ui):
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 self.req = req
self.response = ''
Idan Kamara
ui: use I/O descriptors internally...
r14614 self.ui = ui
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 def getargs(self, args):
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 knownargs = self._args()
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 data = {}
keys = args.split()
for k in keys:
if k == '*':
star = {}
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 for key in knownargs.keys():
Peter Arrenbrecht
wireproto: fix handling of '*' args for HTTP and SSH
r13721 if key != 'cmd' and key not in keys:
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 star[key] = knownargs[key][0]
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 data['*'] = star
else:
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 data[k] = knownargs[k][0]
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 return [data[k] for k in keys]
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 def _args(self):
args = self.req.form.copy()
chunks = []
Matt Mackall
http: minor tweaks to long arg handling...
r14094 i = 1
Martin Geisler
check-code: flag 0/1 used as constant Boolean expression
r14494 while True:
Matt Mackall
http: minor tweaks to long arg handling...
r14094 h = self.req.env.get('HTTP_X_HGARG_' + str(i))
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 if h is None:
break
chunks += [h]
Matt Mackall
http: minor tweaks to long arg handling...
r14094 i += 1
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 args.update(cgi.parse_qs(''.join(chunks), keep_blank_values=True))
return args
Dirkjan Ochtman
protocol: shuffle server methods to group send methods
r11621 def getfile(self, fp):
length = int(self.req.env['CONTENT_LENGTH'])
for s in util.filechunkiter(self.req, limit=length):
fp.write(s)
def redirect(self):
Idan Kamara
ui: use I/O descriptors internally...
r14614 self.oldio = self.ui.fout, self.ui.ferr
self.ui.ferr = self.ui.fout = cStringIO.StringIO()
def restore(self):
val = self.ui.fout.getvalue()
self.ui.ferr, self.ui.fout = self.oldio
return val
Dirkjan Ochtman
protocol: extract compression from streaming mechanics
r11623 def groupchunks(self, cg):
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 z = zlib.compressobj()
Martin Geisler
check-code: flag 0/1 used as constant Boolean expression
r14494 while True:
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 chunk = cg.read(4096)
if not chunk:
break
Dirkjan Ochtman
protocol: extract compression from streaming mechanics
r11623 yield z.compress(chunk)
yield z.flush()
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 def _client(self):
return 'remote:%s:%s:%s' % (
self.req.env.get('wsgi.url_scheme') or 'http',
urllib.quote(self.req.env.get('REMOTE_HOST', '')),
urllib.quote(self.req.env.get('REMOTE_USER', '')))
def iscmd(cmd):
return cmd in wireproto.commands
def call(repo, req, cmd):
Idan Kamara
ui: use I/O descriptors internally...
r14614 p = webproto(req, repo.ui)
Dirkjan Ochtman
protocol: wrap non-string protocol responses in classes
r11625 rsp = wireproto.dispatch(repo, p, cmd)
Dirkjan Ochtman
protocol: use generators instead of req.write() for hgweb stream responses
r11626 if isinstance(rsp, str):
Mads Kiilerich
hgweb: pass the actual response body to request.response, not just the length...
r18352 req.respond(HTTP_OK, HGTYPE, body=rsp)
return []
Dirkjan Ochtman
protocol: use generators instead of req.write() for hgweb stream responses
r11626 elif isinstance(rsp, wireproto.streamres):
req.respond(HTTP_OK, HGTYPE)
return rsp.gen
elif isinstance(rsp, wireproto.pushres):
Idan Kamara
ui: use I/O descriptors internally...
r14614 val = p.restore()
Mads Kiilerich
hgweb: use Content-Length for pushres...
r18346 rsp = '%d\n%s' % (rsp.res, val)
Mads Kiilerich
hgweb: pass the actual response body to request.response, not just the length...
r18352 req.respond(HTTP_OK, HGTYPE, body=rsp)
return []
Benoit Boissinot
wireproto: introduce pusherr() to deal with "unsynced changes" error...
r12703 elif isinstance(rsp, wireproto.pusherr):
Benoit Boissinot
wireproto/http: drain the incoming bundle in case of errors
r12704 # drain the incoming bundle
req.drain()
Idan Kamara
ui: use I/O descriptors internally...
r14614 p.restore()
Benoit Boissinot
wireproto: introduce pusherr() to deal with "unsynced changes" error...
r12703 rsp = '0\n%s\n' % rsp.res
Mads Kiilerich
hgweb: pass the actual response body to request.response, not just the length...
r18352 req.respond(HTTP_OK, HGTYPE, body=rsp)
return []
Andrew Pritchard
wireproto: add out-of-band error class to allow remote repo to report errors...
r15017 elif isinstance(rsp, wireproto.ooberror):
rsp = rsp.message
Mads Kiilerich
hgweb: pass the actual response body to request.response, not just the length...
r18352 req.respond(HTTP_OK, HGERRTYPE, body=rsp)
return []