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 template |
|
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 |
$ |
|
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