##// END OF EJS Templates
templater: introduce wrapper for smartset (API)...
Yuya Nishihara -
r45080:fc1fa3a0 default
parent child Browse files
Show More
@@ -668,7 +668,7 b' def revset(context, mapping, args):'
668 else:
668 else:
669 revs = query(raw)
669 revs = query(raw)
670 revsetcache[raw] = revs
670 revsetcache[raw] = revs
671 return templatekw.showrevslist(context, mapping, b"revision", revs)
671 return templateutil.revslist(repo, revs, name=b'revision')
672
672
673
673
674 @templatefunc(b'rstdoc(text, style)')
674 @templatefunc(b'rstdoc(text, style)')
@@ -873,24 +873,6 b' def showrev(context, mapping):'
873 return scmutil.intrev(ctx)
873 return scmutil.intrev(ctx)
874
874
875
875
876 def showrevslist(context, mapping, name, revs):
877 """helper to generate a list of revisions in which a mapped template will
878 be evaluated"""
879 repo = context.resource(mapping, b'repo')
880 # revs may be a smartset; don't compute it until f() has to be evaluated
881 def f():
882 srevs = [b'%d' % r for r in revs]
883 return _showcompatlist(context, mapping, name, srevs)
884
885 return _hybrid(
886 f,
887 revs,
888 lambda x: {name: x, b'ctx': repo[x]},
889 pycompat.identity,
890 keytype=int,
891 )
892
893
894 @templatekeyword(b'subrepos', requires={b'ctx'})
876 @templatekeyword(b'subrepos', requires={b'ctx'})
895 def showsubrepos(context, mapping):
877 def showsubrepos(context, mapping):
896 """List of strings. Updated subrepositories in the changeset."""
878 """List of strings. Updated subrepositories in the changeset."""
@@ -45,6 +45,9 b' hybrid'
45 hybriditem
45 hybriditem
46 represents a scalar printable value, also supports % operator.
46 represents a scalar printable value, also supports % operator.
47
47
48 revslist
49 represents a list of revision numbers.
50
48 mappinggenerator, mappinglist
51 mappinggenerator, mappinglist
49 represents mappings (i.e. a list of dicts), which may have default
52 represents mappings (i.e. a list of dicts), which may have default
50 output format.
53 output format.
@@ -15,6 +15,7 b' from .pycompat import getattr'
15 from . import (
15 from . import (
16 error,
16 error,
17 pycompat,
17 pycompat,
18 smartset,
18 util,
19 util,
19 )
20 )
20 from .utils import (
21 from .utils import (
@@ -408,6 +409,74 b' class hybriditem(mappable, wrapped):'
408 return _unthunk(context, mapping, self._value)
409 return _unthunk(context, mapping, self._value)
409
410
410
411
412 class revslist(wrapped):
413 """Wrapper for a smartset (a list/set of revision numbers)
414
415 If name specified, the revs will be rendered with the old-style list
416 template of the given name by default.
417 """
418
419 def __init__(self, repo, revs, name=None):
420 assert isinstance(revs, smartset.abstractsmartset)
421 self._repo = repo
422 self._revs = revs
423 self._name = name
424
425 def contains(self, context, mapping, item):
426 rev = unwrapinteger(context, mapping, item)
427 return rev in self._revs
428
429 def getmember(self, context, mapping, key):
430 raise error.ParseError(_(b'not a dictionary'))
431
432 def getmin(self, context, mapping):
433 makehybriditem = self._makehybriditemfunc()
434 return makehybriditem(self._revs.min())
435
436 def getmax(self, context, mapping):
437 makehybriditem = self._makehybriditemfunc()
438 return makehybriditem(self._revs.max())
439
440 def filter(self, context, mapping, select):
441 makehybriditem = self._makehybriditemfunc()
442 frevs = self._revs.filter(lambda r: select(makehybriditem(r)))
443 # once filtered, no need to support old-style list template
444 return revslist(self._repo, frevs, name=None)
445
446 def itermaps(self, context):
447 makemap = self._makemapfunc()
448 for r in self._revs:
449 yield makemap(r)
450
451 def _makehybriditemfunc(self):
452 makemap = self._makemapfunc()
453 return lambda r: hybriditem(None, r, r, makemap)
454
455 def _makemapfunc(self):
456 repo = self._repo
457 name = self._name
458 if name:
459 return lambda r: {name: r, b'ctx': repo[r]}
460 else:
461 return lambda r: {b'ctx': repo[r]}
462
463 def join(self, context, mapping, sep):
464 return joinitems(self._revs, sep)
465
466 def show(self, context, mapping):
467 if self._name:
468 srevs = [b'%d' % r for r in self._revs]
469 return _showcompatlist(context, mapping, self._name, srevs)
470 else:
471 return self.join(context, mapping, b' ')
472
473 def tobool(self, context, mapping):
474 return bool(self._revs)
475
476 def tovalue(self, context, mapping):
477 return list(self._revs)
478
479
411 class _mappingsequence(wrapped):
480 class _mappingsequence(wrapped):
412 """Wrapper for sequence of template mappings
481 """Wrapper for sequence of template mappings
413
482
@@ -820,6 +820,8 b' Test json filter applied to wrapped obje'
820 {"branch": "default"}
820 {"branch": "default"}
821 $ hg log -r0 -T '{date|json}\n'
821 $ hg log -r0 -T '{date|json}\n'
822 [0, 0]
822 [0, 0]
823 $ hg log -r0 -T '{revset(":")|json}\n'
824 [0, 1]
823
825
824 Test json filter applied to map result:
826 Test json filter applied to map result:
825
827
@@ -1263,6 +1265,28 b' default. join() should agree with the de'
1263 5:13207e5a10d9fd28ec424934298e176197f2c67f,
1265 5:13207e5a10d9fd28ec424934298e176197f2c67f,
1264 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1266 4:bbe44766e73d5f11ed2177f1838de10c53ef3e74
1265
1267
1268 for historical reasons, revset() supports old-style list template
1269
1270 $ hg log -T '{revset(":")}\n' -l1 \
1271 > --config templates.start_revisions='"["' \
1272 > --config templates.end_revisions='"]"' \
1273 > --config templates.revision='"{revision}, "' \
1274 > --config templates.last_revision='"{revision}"'
1275 [0, 1, 2]
1276 $ hg log -T '{revset(":") % " {revision}"}\n' -l1
1277 0 1 2
1278
1279 but a filtered one doesn't
1280
1281 $ hg log -T '{filter(revset(":"), ifeq(rev, 1, "", "y"))}\n' -l1 \
1282 > --config templates.start_revisions='"["' \
1283 > --config templates.end_revisions='"]"' \
1284 > --config templates.revision='"{revision}, "' \
1285 > --config templates.last_revision='"{revision}"'
1286 0 2
1287 $ hg log -T '{filter(revset(":"), ifeq(rev, 1, "", "y")) % "x{revision}"}\n' -l1
1288 xx
1289
1266 %d parameter handling:
1290 %d parameter handling:
1267
1291
1268 $ hg log -T '{revset("%d", rev)}\n' -r'wdir()'
1292 $ hg log -T '{revset("%d", rev)}\n' -r'wdir()'
@@ -1318,6 +1342,13 b' Invalid arguments passed to revset()'
1318 hg: parse error: invalid argument for revspec
1342 hg: parse error: invalid argument for revspec
1319 [255]
1343 [255]
1320
1344
1345 Invalid operation on revset()
1346
1347 $ hg log -T '{get(revset(":"), "foo")}\n'
1348 hg: parse error: not a dictionary
1349 (get() expects a dict as first argument)
1350 [255]
1351
1321 Test files function
1352 Test files function
1322
1353
1323 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
1354 $ hg log -T "{rev}\n{join(files('*'), '\n')}\n"
@@ -1568,6 +1599,23 b' Test cbor filter:'
1568 }
1599 }
1569 ]
1600 ]
1570
1601
1602 $ hg log -T "{revset(':')|cbor}" -R a -l1 | "$PYTHON" "$TESTTMP/decodecbor.py"
1603 [
1604 [
1605 0,
1606 1,
1607 2,
1608 3,
1609 4,
1610 5,
1611 6,
1612 7,
1613 8,
1614 9,
1615 10
1616 ]
1617 ]
1618
1571 json filter should escape HTML tags so that the output can be embedded in hgweb:
1619 json filter should escape HTML tags so that the output can be embedded in hgweb:
1572
1620
1573 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
1621 $ hg log -T "{'<foo@example.org>'|json}\n" -R a -l1
General Comments 0
You need to be logged in to leave comments. Login now