Mercurial > hg
changeset 29471:c4fc33c477da
hgweb: expose list of per-repo labels to templates
hgweb currently offers limited functionality for "classifying"
repositories. This patch aims to change that.
The web.labels config option list is introduced. Its values
are exposed to the "index" and "summary" templates. Custom
templates can use template features like ifcontains() to e.g.
look for the presence of a specific label and engage specific
behavior. For example, a site operator may wish to assign a
"defunct" label to a repository so the repository is prominently
marked as dead in repository indexes.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Thu, 30 Jun 2016 18:59:53 -0700 |
parents | 2ff243c415b4 |
children | f585ce6878e3 |
files | mercurial/help/config.txt mercurial/hgweb/hgwebdir_mod.py mercurial/hgweb/webcommands.py mercurial/templates/json/map tests/test-hgweb-json.t tests/test-hgwebdir.t |
diffstat | 6 files changed, 236 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/help/config.txt Tue Jun 21 14:58:49 2016 -0700 +++ b/mercurial/help/config.txt Thu Jun 30 18:59:53 2016 -0700 @@ -2026,6 +2026,14 @@ ``ipv6`` Whether to use IPv6. (default: False) +``labels`` + List of string *labels* associated with the repository. + + Labels are exposed as a template keyword and can be used to customize + output. e.g. the ``index`` template can group or filter repositories + by labels and the ``summary`` template can display additional content + if a specific label is present. + ``logoimg`` File name of the logo image that some templates display on each page. The file name is relative to ``staticurl``. That is, the full path to
--- a/mercurial/hgweb/hgwebdir_mod.py Tue Jun 21 14:58:49 2016 -0700 +++ b/mercurial/hgweb/hgwebdir_mod.py Thu Jun 30 18:59:53 2016 -0700 @@ -366,7 +366,9 @@ 'lastchange': d, 'lastchange_sort': d[1]-d[0], 'archives': [], - 'isdirectory': True} + 'isdirectory': True, + 'labels': [], + } seendirs.add(name) yield row @@ -416,6 +418,7 @@ 'lastchange_sort': d[1]-d[0], 'archives': archivelist(u, "tip", url), 'isdirectory': None, + 'labels': u.configlist('web', 'labels', untrusted=True), } yield row
--- a/mercurial/hgweb/webcommands.py Tue Jun 21 14:58:49 2016 -0700 +++ b/mercurial/hgweb/webcommands.py Thu Jun 30 18:59:53 2016 -0700 @@ -725,7 +725,8 @@ shortlog=changelist, node=tip.hex(), symrev='tip', - archives=web.archivelist("tip")) + archives=web.archivelist("tip"), + labels=web.configlist('web', 'labels')) @webcommand('filediff') def filediff(web, req, tmpl):
--- a/mercurial/templates/json/map Tue Jun 21 14:58:49 2016 -0700 +++ b/mercurial/templates/json/map Thu Jun 30 18:59:53 2016 -0700 @@ -109,7 +109,8 @@ "branches": [{join(branches%branchentry, ", ")}], "shortlog": [{join(shortlog%shortlogentry, ", ")}], "tags": [{join(tags%tagentry, ", ")}], - "archives": [{join(archives%archiveentry, ", ")}] + "archives": [{join(archives%archiveentry, ", ")}], + "labels": {labels|json} }' archiveentry = '\{ "node": {node|json}, @@ -220,5 +221,6 @@ "name": {name|utf8|json}, "description": {description|utf8|json}, "contact": {contact|utf8|json}, - "lastchange": {lastchange|json} + "lastchange": {lastchange|json}, + "labels": {labels|json} }'
--- a/tests/test-hgweb-json.t Tue Jun 21 14:58:49 2016 -0700 +++ b/tests/test-hgweb-json.t Thu Jun 30 18:59:53 2016 -0700 @@ -848,6 +848,7 @@ "status": "inactive" } ], + "labels": [], "lastchange": [ 0.0, 0
--- a/tests/test-hgwebdir.t Tue Jun 21 14:58:49 2016 -0700 +++ b/tests/test-hgwebdir.t Thu Jun 30 18:59:53 2016 -0700 @@ -62,6 +62,7 @@ $ cat >> f/.hg/hgrc << EOF > [web] > name = fancy name for repo f + > labels = foo, bar > EOF $ cd .. @@ -108,12 +109,14 @@ "name": "a", "description": "unknown", "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", - "lastchange": [*, *] (glob) + "lastchange": [*, *], (glob) + "labels": [] }, { "name": "b", "description": "unknown", "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", - "lastchange": [*, *] (glob) + "lastchange": [*, *], (glob) + "labels": [] }] } (no-eol) @@ -201,6 +204,218 @@ /astar/ /astar/.hg/patches/ + + $ get-with-headers.py localhost:$HGPORT1 '?style=json' + 200 Script output follows + + { + "entries": [{ + "name": "t/a", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "b", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "coll/a", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "coll/a/.hg/patches", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "coll/b", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "coll/c", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "coll/notrepo/e", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "fancy name for repo f", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": ["foo", "bar"] + }, { + "name": "rcoll/a", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "rcoll/a/.hg/patches", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "rcoll/b", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "rcoll/b/d", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "rcoll/c", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "rcoll/notrepo/e", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "rcoll/notrepo/e/e2", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "fancy name for repo f", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": ["foo", "bar"] + }, { + "name": "rcoll/notrepo/f/f2", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "star/webdir/a", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "star/webdir/a/.hg/patches", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "star/webdir/b", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "star/webdir/c", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "star/webdir/notrepo/e", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "fancy name for repo f", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": ["foo", "bar"] + }, { + "name": "starstar/webdir/a", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "starstar/webdir/a/.hg/patches", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "starstar/webdir/b", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "starstar/webdir/b/d", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "starstar/webdir/c", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "starstar/webdir/notrepo/e", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "starstar/webdir/notrepo/e/e2", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "fancy name for repo f", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": ["foo", "bar"] + }, { + "name": "starstar/webdir/notrepo/f/f2", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "astar", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }, { + "name": "astar/.hg/patches", + "description": "unknown", + "contact": "Foo Bar \u003cfoo.bar@example.com\u003e", + "lastchange": [*, *], (glob) + "labels": [] + }] + } (no-eol) + $ get-with-headers.py localhost:$HGPORT1 '?style=paper' 200 Script output follows