comparison mercurial/hgweb/webcommands.py @ 36876:1f42d621f090

hgweb: support using new response object for web commands We have a "requestcontext" type for holding state for the current request. Why we pass in the wsgirequest and templater instance to @webcommand functions, I don't know. I like the idea of standardizing on using "requestcontext" for passing all state to @webcommand functions because that scales well without API changes every time you want to pass a new piece of data. So, we add our new request and response instances to "requestcontext" so @webcommand functions can access them. We also teach our command dispatcher to recognize a new calling convention. Instead of returning content from the @webcommand function, we return our response object. This signals that this response object is to be used for sending output. The keyword extension was wrapping various @webcommand and assuming the output was iterable, so we had to teach it about the new calling convention. To prove everything works, we convert the "filelog" @webcommand to use the new convention. The new calling convention is a bit wonky. I intend to improve this once all commands are ported to use the new response object. Differential Revision: https://phab.mercurial-scm.org/D2786
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 10 Mar 2018 17:02:57 -0800
parents 3d60a22e27f5
children 9fc3d814646e
comparison
equal deleted inserted replaced
36875:7ad6a275316f 36876:1f42d621f090
50 class webcommand(object): 50 class webcommand(object):
51 """Decorator used to register a web command handler. 51 """Decorator used to register a web command handler.
52 52
53 The decorator takes as its positional arguments the name/path the 53 The decorator takes as its positional arguments the name/path the
54 command should be accessible under. 54 command should be accessible under.
55
56 When called, functions receive as arguments a ``requestcontext``,
57 ``wsgirequest``, and a templater instance for generatoring output.
58 The functions should populate the ``rctx.res`` object with details
59 about the HTTP response.
60
61 The function can return the ``requestcontext.res`` instance to signal
62 that it wants to use this object to generate the response. If an iterable
63 is returned, the ``wsgirequest`` instance will be used and the returned
64 content will constitute the response body.
55 65
56 Usage: 66 Usage:
57 67
58 @webcommand('mycommand') 68 @webcommand('mycommand')
59 def mycommand(web, req, tmpl): 69 def mycommand(web, req, tmpl):
1066 revnav = webutil.filerevnav(web.repo, fctx.path()) 1076 revnav = webutil.filerevnav(web.repo, fctx.path())
1067 nav = revnav.gen(end - 1, revcount, count) 1077 nav = revnav.gen(end - 1, revcount, count)
1068 1078
1069 latestentry = entries[:1] 1079 latestentry = entries[:1]
1070 1080
1071 return tmpl("filelog", 1081 web.res.setbodygen(tmpl(
1072 file=f, 1082 'filelog',
1073 nav=nav, 1083 file=f,
1074 symrev=webutil.symrevorshortnode(req, fctx), 1084 nav=nav,
1075 entries=entries, 1085 symrev=webutil.symrevorshortnode(req, fctx),
1076 descend=descend, 1086 entries=entries,
1077 patch=patch, 1087 descend=descend,
1078 latestentry=latestentry, 1088 patch=patch,
1079 linerange=linerange, 1089 latestentry=latestentry,
1080 revcount=revcount, 1090 linerange=linerange,
1081 morevars=morevars, 1091 revcount=revcount,
1082 lessvars=lessvars, 1092 morevars=morevars,
1083 **pycompat.strkwargs(webutil.commonentry(web.repo, fctx))) 1093 lessvars=lessvars,
1094 **pycompat.strkwargs(webutil.commonentry(web.repo, fctx))))
1095
1096 return web.res
1084 1097
1085 @webcommand('archive') 1098 @webcommand('archive')
1086 def archive(web, req, tmpl): 1099 def archive(web, req, tmpl):
1087 """ 1100 """
1088 /archive/{revision}.{format}[/{path}] 1101 /archive/{revision}.{format}[/{path}]