Show More
@@ -48,6 +48,10 b' mappable' | |||||
48 | mappinggenerator, mappinglist |
|
48 | mappinggenerator, mappinglist | |
49 | represents mappings (i.e. a list of dicts), which may have default |
|
49 | represents mappings (i.e. a list of dicts), which may have default | |
50 | output format. |
|
50 | output format. | |
|
51 | ||||
|
52 | mappedgenerator | |||
|
53 | a lazily-evaluated list of byte strings, which is e.g. a result of % | |||
|
54 | operation. | |||
51 | """ |
|
55 | """ | |
52 |
|
56 | |||
53 | from __future__ import absolute_import, print_function |
|
57 | from __future__ import absolute_import, print_function |
@@ -227,6 +227,33 b' class mappinglist(_mappingsequence):' | |||||
227 | def itermaps(self, context): |
|
227 | def itermaps(self, context): | |
228 | return iter(self._mappings) |
|
228 | return iter(self._mappings) | |
229 |
|
229 | |||
|
230 | class mappedgenerator(wrapped): | |||
|
231 | """Wrapper for generator of strings which acts as a list | |||
|
232 | ||||
|
233 | The function ``make(context, *args)`` should return a generator of | |||
|
234 | byte strings, or a generator of (possibly nested) generators of byte | |||
|
235 | strings (i.e. a generator for a list of byte strings.) | |||
|
236 | """ | |||
|
237 | ||||
|
238 | def __init__(self, make, args=()): | |||
|
239 | self._make = make | |||
|
240 | self._args = args | |||
|
241 | ||||
|
242 | def _gen(self, context): | |||
|
243 | return self._make(context, *self._args) | |||
|
244 | ||||
|
245 | def itermaps(self, context): | |||
|
246 | raise error.ParseError(_('list of strings is not mappable')) | |||
|
247 | ||||
|
248 | def join(self, context, mapping, sep): | |||
|
249 | return joinitems(self._gen(context), sep) | |||
|
250 | ||||
|
251 | def show(self, context, mapping): | |||
|
252 | return self.join(context, mapping, '') | |||
|
253 | ||||
|
254 | def tovalue(self, context, mapping): | |||
|
255 | return [stringify(context, mapping, x) for x in self._gen(context)] | |||
|
256 | ||||
230 | def hybriddict(data, key='key', value='value', fmt=None, gen=None): |
|
257 | def hybriddict(data, key='key', value='value', fmt=None, gen=None): | |
231 | """Wrap data to support both dict-like and string-like operations""" |
|
258 | """Wrap data to support both dict-like and string-like operations""" | |
232 | prefmt = pycompat.identity |
|
259 | prefmt = pycompat.identity | |
@@ -589,18 +616,23 b' def _iteroverlaymaps(context, origmappin' | |||||
589 | lm['index'] = i |
|
616 | lm['index'] = i | |
590 | yield lm |
|
617 | yield lm | |
591 |
|
618 | |||
|
619 | def _applymap(context, mapping, diter, targ): | |||
|
620 | for lm in _iteroverlaymaps(context, mapping, diter): | |||
|
621 | yield evalrawexp(context, lm, targ) | |||
|
622 | ||||
592 | def runmap(context, mapping, data): |
|
623 | def runmap(context, mapping, data): | |
593 | darg, targ = data |
|
624 | darg, targ = data | |
594 | d = evalrawexp(context, mapping, darg) |
|
625 | d = evalrawexp(context, mapping, darg) | |
595 | # TODO: a generator should be rejected because it is a thunk of lazy |
|
626 | # TODO: a generator should be rejected because it is a thunk of lazy | |
596 | # string, but we can't because hgweb abuses generator as a keyword |
|
627 | # string, but we can't because hgweb abuses generator as a keyword | |
597 | # that returns a list of dicts. |
|
628 | # that returns a list of dicts. | |
|
629 | # TODO: drop _checkeditermaps() and pass 'd' to mappedgenerator so it | |||
|
630 | # can be restarted. | |||
598 | if isinstance(d, wrapped): |
|
631 | if isinstance(d, wrapped): | |
599 | diter = d.itermaps(context) |
|
632 | diter = d.itermaps(context) | |
600 | else: |
|
633 | else: | |
601 | diter = _checkeditermaps(darg, d) |
|
634 | diter = _checkeditermaps(darg, d) | |
602 | for lm in _iteroverlaymaps(context, mapping, diter): |
|
635 | return mappedgenerator(_applymap, args=(mapping, diter, targ)) | |
603 | yield evalrawexp(context, lm, targ) |
|
|||
604 |
|
636 | |||
605 | def runmember(context, mapping, data): |
|
637 | def runmember(context, mapping, data): | |
606 | darg, memb = data |
|
638 | darg, memb = data |
@@ -3217,7 +3217,7 b' Test new-style inline templating:' | |||||
3217 | hg: parse error: None is not iterable of mappings |
|
3217 | hg: parse error: None is not iterable of mappings | |
3218 | [255] |
|
3218 | [255] | |
3219 | $ hg log -R latesttag -r tip -T '{extras % "{key}\n" % "{key}\n"}' |
|
3219 | $ hg log -R latesttag -r tip -T '{extras % "{key}\n" % "{key}\n"}' | |
3220 | hg: parse error: <generator *> is not iterable of mappings (glob) |
|
3220 | hg: parse error: list of strings is not mappable | |
3221 | [255] |
|
3221 | [255] | |
3222 |
|
3222 | |||
3223 | Test new-style inline templating of non-list/dict type: |
|
3223 | Test new-style inline templating of non-list/dict type: | |
@@ -3255,6 +3255,13 b' Test min/max of integers' | |||||
3255 | $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n' |
|
3255 | $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n' | |
3256 | 10 |
|
3256 | 10 | |
3257 |
|
3257 | |||
|
3258 | Test min/max over map operation: | |||
|
3259 | ||||
|
3260 | $ hg log -R latesttag -r3 -T '{min(tags % "{tag}")}\n' | |||
|
3261 | at3 | |||
|
3262 | $ hg log -R latesttag -r3 -T '{max(tags % "{tag}")}\n' | |||
|
3263 | t3 | |||
|
3264 | ||||
3258 | Test min/max of if() result |
|
3265 | Test min/max of if() result | |
3259 |
|
3266 | |||
3260 | $ cd latesttag |
|
3267 | $ cd latesttag | |
@@ -3842,6 +3849,11 b' Test json filter applied to hybrid objec' | |||||
3842 | $ hg log -r0 -T '{extras|json}\n' |
|
3849 | $ hg log -r0 -T '{extras|json}\n' | |
3843 | {"branch": "default"} |
|
3850 | {"branch": "default"} | |
3844 |
|
3851 | |||
|
3852 | Test json filter applied to map result: | |||
|
3853 | ||||
|
3854 | $ hg log -r0 -T '{json(extras % "{key}")}\n' | |||
|
3855 | ["branch"] | |||
|
3856 | ||||
3845 | Test localdate(date, tz) function: |
|
3857 | Test localdate(date, tz) function: | |
3846 |
|
3858 | |||
3847 | $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n' |
|
3859 | $ TZ=JST-09 hg log -r0 -T '{date|localdate|isodate}\n' |
General Comments 0
You need to be logged in to leave comments.
Login now