comparison mercurial/hgweb/webcommands.py @ 36887:4daa22071d5d

hgweb: stop passing req and tmpl into @webcommand functions (API) We have effectively removed all consumers of the old wsgirequest type. The templater can be accessed on the requestcontext passed into the @webcommand function. For the most part, these arguments are unused. They only exist to provide backwards compatibility. And in the case of wsgirequest, use of that object could actively interfere with the new request object. So let's stop passing these objects to @webcommand functions. With this commit, wsgirequest is practically dead from the hgweb WSGI application. There are still some uses in hgwebdir though... .. api:: @webcommand functions now only receive a single argument. The request and templater instances can be accessed via the ``req`` and ``templater`` attributes of the first argument. Note that the request object is different from previous Mercurial releases and consumers of the previous ``req`` 2nd argument will need updating to use the new API. Differential Revision: https://phab.mercurial-scm.org/D2803
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 10 Mar 2018 20:51:46 -0800
parents 563fd95a6efb
children a82fc3922446
comparison
equal deleted inserted replaced
36886:563fd95a6efb 36887:4daa22071d5d
63 to render a template. 63 to render a template.
64 64
65 Usage: 65 Usage:
66 66
67 @webcommand('mycommand') 67 @webcommand('mycommand')
68 def mycommand(web, req, tmpl): 68 def mycommand(web):
69 pass 69 pass
70 """ 70 """
71 71
72 def __init__(self, name): 72 def __init__(self, name):
73 self.name = name 73 self.name = name
76 __all__.append(self.name) 76 __all__.append(self.name)
77 commands[self.name] = func 77 commands[self.name] = func
78 return func 78 return func
79 79
80 @webcommand('log') 80 @webcommand('log')
81 def log(web, req, tmpl): 81 def log(web):
82 """ 82 """
83 /log[/{revision}[/{path}]] 83 /log[/{revision}[/{path}]]
84 -------------------------- 84 --------------------------
85 85
86 Show repository or file history. 86 Show repository or file history.
93 For URLs of the form ``/log/{revision}/{file}``, the history for a specific 93 For URLs of the form ``/log/{revision}/{file}``, the history for a specific
94 file will be shown. This form is equivalent to the ``filelog`` handler. 94 file will be shown. This form is equivalent to the ``filelog`` handler.
95 """ 95 """
96 96
97 if web.req.qsparams.get('file'): 97 if web.req.qsparams.get('file'):
98 return filelog(web, req, None) 98 return filelog(web)
99 else: 99 else:
100 return changelog(web, req, None) 100 return changelog(web)
101 101
102 @webcommand('rawfile') 102 @webcommand('rawfile')
103 def rawfile(web, req, tmpl): 103 def rawfile(web):
104 guessmime = web.configbool('web', 'guessmime') 104 guessmime = web.configbool('web', 'guessmime')
105 105
106 path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', '')) 106 path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', ''))
107 if not path: 107 if not path:
108 return manifest(web, req, None) 108 return manifest(web)
109 109
110 try: 110 try:
111 fctx = webutil.filectx(web.repo, web.req) 111 fctx = webutil.filectx(web.repo, web.req)
112 except error.LookupError as inst: 112 except error.LookupError as inst:
113 try: 113 try:
114 return manifest(web, req, None) 114 return manifest(web)
115 except ErrorResponse: 115 except ErrorResponse:
116 raise inst 116 raise inst
117 117
118 path = fctx.path() 118 path = fctx.path()
119 text = fctx.data() 119 text = fctx.data()
133 .replace('\\', '\\\\').replace('"', '\\"')) 133 .replace('\\', '\\\\').replace('"', '\\"'))
134 web.res.headers['Content-Disposition'] = 'inline; filename="%s"' % filename 134 web.res.headers['Content-Disposition'] = 'inline; filename="%s"' % filename
135 web.res.setbodybytes(text) 135 web.res.setbodybytes(text)
136 return web.res.sendresponse() 136 return web.res.sendresponse()
137 137
138 def _filerevision(web, req, fctx): 138 def _filerevision(web, fctx):
139 f = fctx.path() 139 f = fctx.path()
140 text = fctx.data() 140 text = fctx.data()
141 parity = paritygen(web.stripecount) 141 parity = paritygen(web.stripecount)
142 ishead = fctx.filerev() in fctx.filelog().headrevs() 142 ishead = fctx.filerev() in fctx.filelog().headrevs()
143 143
162 permissions=fctx.manifest().flags(f), 162 permissions=fctx.manifest().flags(f),
163 ishead=int(ishead), 163 ishead=int(ishead),
164 **pycompat.strkwargs(webutil.commonentry(web.repo, fctx))) 164 **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
165 165
166 @webcommand('file') 166 @webcommand('file')
167 def file(web, req, tmpl): 167 def file(web):
168 """ 168 """
169 /file/{revision}[/{path}] 169 /file/{revision}[/{path}]
170 ------------------------- 170 -------------------------
171 171
172 Show information about a directory or file in the repository. 172 Show information about a directory or file in the repository.
182 182
183 If ``path`` is not defined, information about the root directory will 183 If ``path`` is not defined, information about the root directory will
184 be rendered. 184 be rendered.
185 """ 185 """
186 if web.req.qsparams.get('style') == 'raw': 186 if web.req.qsparams.get('style') == 'raw':
187 return rawfile(web, req, None) 187 return rawfile(web)
188 188
189 path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', '')) 189 path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', ''))
190 if not path: 190 if not path:
191 return manifest(web, req, None) 191 return manifest(web)
192 try: 192 try:
193 return _filerevision(web, req, webutil.filectx(web.repo, web.req)) 193 return _filerevision(web, webutil.filectx(web.repo, web.req))
194 except error.LookupError as inst: 194 except error.LookupError as inst:
195 try: 195 try:
196 return manifest(web, req, None) 196 return manifest(web)
197 except ErrorResponse: 197 except ErrorResponse:
198 raise inst 198 raise inst
199 199
200 def _search(web): 200 def _search(web):
201 MODE_REVISION = 'rev' 201 MODE_REVISION = 'rev'
352 modedesc=searchfunc[1], 352 modedesc=searchfunc[1],
353 showforcekw=showforcekw, 353 showforcekw=showforcekw,
354 showunforcekw=showunforcekw) 354 showunforcekw=showunforcekw)
355 355
356 @webcommand('changelog') 356 @webcommand('changelog')
357 def changelog(web, req, tmpl, shortlog=False): 357 def changelog(web, shortlog=False):
358 """ 358 """
359 /changelog[/{revision}] 359 /changelog[/{revision}]
360 ----------------------- 360 -----------------------
361 361
362 Show information about multiple changesets. 362 Show information about multiple changesets.
450 morevars=morevars, 450 morevars=morevars,
451 lessvars=lessvars, 451 lessvars=lessvars,
452 query=query) 452 query=query)
453 453
454 @webcommand('shortlog') 454 @webcommand('shortlog')
455 def shortlog(web, req, tmpl): 455 def shortlog(web):
456 """ 456 """
457 /shortlog 457 /shortlog
458 --------- 458 ---------
459 459
460 Show basic information about a set of changesets. 460 Show basic information about a set of changesets.
461 461
462 This accepts the same parameters as the ``changelog`` handler. The only 462 This accepts the same parameters as the ``changelog`` handler. The only
463 difference is the ``shortlog`` template will be rendered instead of the 463 difference is the ``shortlog`` template will be rendered instead of the
464 ``changelog`` template. 464 ``changelog`` template.
465 """ 465 """
466 return changelog(web, req, None, shortlog=True) 466 return changelog(web, shortlog=True)
467 467
468 @webcommand('changeset') 468 @webcommand('changeset')
469 def changeset(web, req, tmpl): 469 def changeset(web):
470 """ 470 """
471 /changeset[/{revision}] 471 /changeset[/{revision}]
472 ----------------------- 472 -----------------------
473 473
474 Show information about a single changeset. 474 Show information about a single changeset.
496 Extensions (e.g., largefiles) can override this to remap files in 496 Extensions (e.g., largefiles) can override this to remap files in
497 the virtual file system presented by the manifest command below.""" 497 the virtual file system presented by the manifest command below."""
498 return path 498 return path
499 499
500 @webcommand('manifest') 500 @webcommand('manifest')
501 def manifest(web, req, tmpl): 501 def manifest(web):
502 """ 502 """
503 /manifest[/{revision}[/{path}]] 503 /manifest[/{revision}[/{path}]]
504 ------------------------------- 504 -------------------------------
505 505
506 Show information about a directory. 506 Show information about a directory.
596 dentries=dirlist, 596 dentries=dirlist,
597 archives=web.archivelist(hex(node)), 597 archives=web.archivelist(hex(node)),
598 **pycompat.strkwargs(webutil.commonentry(web.repo, ctx))) 598 **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
599 599
600 @webcommand('tags') 600 @webcommand('tags')
601 def tags(web, req, tmpl): 601 def tags(web):
602 """ 602 """
603 /tags 603 /tags
604 ----- 604 -----
605 605
606 Show information about tags. 606 Show information about tags.
630 entries=lambda **x: entries(False, False, **x), 630 entries=lambda **x: entries(False, False, **x),
631 entriesnotip=lambda **x: entries(True, False, **x), 631 entriesnotip=lambda **x: entries(True, False, **x),
632 latestentry=lambda **x: entries(True, True, **x)) 632 latestentry=lambda **x: entries(True, True, **x))
633 633
634 @webcommand('bookmarks') 634 @webcommand('bookmarks')
635 def bookmarks(web, req, tmpl): 635 def bookmarks(web):
636 """ 636 """
637 /bookmarks 637 /bookmarks
638 ---------- 638 ----------
639 639
640 Show information about bookmarks. 640 Show information about bookmarks.
669 lastchange=[{'date': web.repo[latestrev].date()}], 669 lastchange=[{'date': web.repo[latestrev].date()}],
670 entries=lambda **x: entries(latestonly=False, **x), 670 entries=lambda **x: entries(latestonly=False, **x),
671 latestentry=lambda **x: entries(latestonly=True, **x)) 671 latestentry=lambda **x: entries(latestonly=True, **x))
672 672
673 @webcommand('branches') 673 @webcommand('branches')
674 def branches(web, req, tmpl): 674 def branches(web):
675 """ 675 """
676 /branches 676 /branches
677 --------- 677 ---------
678 678
679 Show information about branches. 679 Show information about branches.
692 node=hex(web.repo.changelog.tip()), 692 node=hex(web.repo.changelog.tip()),
693 entries=entries, 693 entries=entries,
694 latestentry=latestentry) 694 latestentry=latestentry)
695 695
696 @webcommand('summary') 696 @webcommand('summary')
697 def summary(web, req, tmpl): 697 def summary(web):
698 """ 698 """
699 /summary 699 /summary
700 -------- 700 --------
701 701
702 Show a summary of repository state. 702 Show a summary of repository state.
776 symrev='tip', 776 symrev='tip',
777 archives=web.archivelist('tip'), 777 archives=web.archivelist('tip'),
778 labels=web.configlist('web', 'labels')) 778 labels=web.configlist('web', 'labels'))
779 779
780 @webcommand('filediff') 780 @webcommand('filediff')
781 def filediff(web, req, tmpl): 781 def filediff(web):
782 """ 782 """
783 /diff/{revision}/{path} 783 /diff/{revision}/{path}
784 ----------------------- 784 -----------------------
785 785
786 Show how a file changed in a particular commit. 786 Show how a file changed in a particular commit.
825 **pycompat.strkwargs(webutil.commonentry(web.repo, ctx))) 825 **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
826 826
827 diff = webcommand('diff')(filediff) 827 diff = webcommand('diff')(filediff)
828 828
829 @webcommand('comparison') 829 @webcommand('comparison')
830 def comparison(web, req, tmpl): 830 def comparison(web):
831 """ 831 """
832 /comparison/{revision}/{path} 832 /comparison/{revision}/{path}
833 ----------------------------- 833 -----------------------------
834 834
835 Show a comparison between the old and new versions of a file from changes 835 Show a comparison between the old and new versions of a file from changes
900 rightnode=hex(rightnode), 900 rightnode=hex(rightnode),
901 comparison=comparison, 901 comparison=comparison,
902 **pycompat.strkwargs(webutil.commonentry(web.repo, ctx))) 902 **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
903 903
904 @webcommand('annotate') 904 @webcommand('annotate')
905 def annotate(web, req, tmpl): 905 def annotate(web):
906 """ 906 """
907 /annotate/{revision}/{path} 907 /annotate/{revision}/{path}
908 --------------------------- 908 ---------------------------
909 909
910 Show changeset information for each line in a file. 910 Show changeset information for each line in a file.
992 ishead=int(ishead), 992 ishead=int(ishead),
993 diffopts=diffopts, 993 diffopts=diffopts,
994 **pycompat.strkwargs(webutil.commonentry(web.repo, fctx))) 994 **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
995 995
996 @webcommand('filelog') 996 @webcommand('filelog')
997 def filelog(web, req, tmpl): 997 def filelog(web):
998 """ 998 """
999 /filelog/{revision}/{path} 999 /filelog/{revision}/{path}
1000 -------------------------- 1000 --------------------------
1001 1001
1002 Show information about the history of a file in the repository. 1002 Show information about the history of a file in the repository.
1130 morevars=morevars, 1130 morevars=morevars,
1131 lessvars=lessvars, 1131 lessvars=lessvars,
1132 **pycompat.strkwargs(webutil.commonentry(web.repo, fctx))) 1132 **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
1133 1133
1134 @webcommand('archive') 1134 @webcommand('archive')
1135 def archive(web, req, tmpl): 1135 def archive(web):
1136 """ 1136 """
1137 /archive/{revision}.{format}[/{path}] 1137 /archive/{revision}.{format}[/{path}]
1138 ------------------------------------- 1138 -------------------------------------
1139 1139
1140 Obtain an archive of repository content. 1140 Obtain an archive of repository content.
1204 subrepos=web.configbool("web", "archivesubrepos")) 1204 subrepos=web.configbool("web", "archivesubrepos"))
1205 1205
1206 return [] 1206 return []
1207 1207
1208 @webcommand('static') 1208 @webcommand('static')
1209 def static(web, req, tmpl): 1209 def static(web):
1210 fname = web.req.qsparams['file'] 1210 fname = web.req.qsparams['file']
1211 # a repo owner may set web.static in .hg/hgrc to get any file 1211 # a repo owner may set web.static in .hg/hgrc to get any file
1212 # readable by the user running the CGI script 1212 # readable by the user running the CGI script
1213 static = web.config("web", "static", None, untrusted=False) 1213 static = web.config("web", "static", None, untrusted=False)
1214 if not static: 1214 if not static:
1219 1219
1220 staticfile(static, fname, web.res) 1220 staticfile(static, fname, web.res)
1221 return web.res.sendresponse() 1221 return web.res.sendresponse()
1222 1222
1223 @webcommand('graph') 1223 @webcommand('graph')
1224 def graph(web, req, tmpl): 1224 def graph(web):
1225 """ 1225 """
1226 /graph[/{revision}] 1226 /graph[/{revision}]
1227 ------------------- 1227 -------------------
1228 1228
1229 Show information about the graphical topology of the repository. 1229 Show information about the graphical topology of the repository.
1386 else: 1386 else:
1387 doc = _('(no help text available)') 1387 doc = _('(no help text available)')
1388 return doc 1388 return doc
1389 1389
1390 @webcommand('help') 1390 @webcommand('help')
1391 def help(web, req, tmpl): 1391 def help(web):
1392 """ 1392 """
1393 /help[/{topic}] 1393 /help[/{topic}]
1394 --------------- 1394 ---------------
1395 1395
1396 Render help documentation. 1396 Render help documentation.