Show More
@@ -78,13 +78,18 b' class _mappable(object):' | |||||
78 | value. Use unwrapvalue() or unwraphybrid() to obtain the inner object. |
|
78 | value. Use unwrapvalue() or unwraphybrid() to obtain the inner object. | |
79 | """ |
|
79 | """ | |
80 |
|
80 | |||
81 | def __init__(self, gen, value, makemap): |
|
81 | def __init__(self, gen, key, value, makemap): | |
82 |
|
|
82 | if gen is not None: | |
|
83 | self.gen = gen # generator or function returning generator | |||
|
84 | self._key = key | |||
83 | self._value = value # may be generator of strings |
|
85 | self._value = value # may be generator of strings | |
84 | self._makemap = makemap |
|
86 | self._makemap = makemap | |
85 |
|
87 | |||
|
88 | def gen(self): | |||
|
89 | yield pycompat.bytestr(self._value) | |||
|
90 | ||||
86 | def tomap(self): |
|
91 | def tomap(self): | |
87 | return self._makemap() |
|
92 | return self._makemap(self._key) | |
88 |
|
93 | |||
89 | def itermaps(self): |
|
94 | def itermaps(self): | |
90 | yield self.tomap() |
|
95 | yield self.tomap() | |
@@ -114,6 +119,20 b' def unwrapvalue(thing):' | |||||
114 | return thing |
|
119 | return thing | |
115 | return thing._value |
|
120 | return thing._value | |
116 |
|
121 | |||
|
122 | def wraphybridvalue(container, key, value): | |||
|
123 | """Wrap an element of hybrid container to be mappable | |||
|
124 | ||||
|
125 | The key is passed to the makemap function of the given container, which | |||
|
126 | should be an item generated by iter(container). | |||
|
127 | """ | |||
|
128 | makemap = getattr(container, '_makemap', None) | |||
|
129 | if makemap is None: | |||
|
130 | return value | |||
|
131 | if util.safehasattr(value, '_makemap'): | |||
|
132 | # a nested hybrid list/dict, which has its own way of map operation | |||
|
133 | return value | |||
|
134 | return _mappable(None, key, value, makemap) | |||
|
135 | ||||
117 | def showdict(name, data, mapping, plural=None, key='key', value='value', |
|
136 | def showdict(name, data, mapping, plural=None, key='key', value='value', | |
118 | fmt='%s=%s', separator=' '): |
|
137 | fmt='%s=%s', separator=' '): | |
119 | c = [{key: k, value: v} for k, v in data.iteritems()] |
|
138 | c = [{key: k, value: v} for k, v in data.iteritems()] | |
@@ -578,7 +597,7 b' def showmanifest(**args):' | |||||
578 | f = templ('manifest', **args) |
|
597 | f = templ('manifest', **args) | |
579 | # TODO: perhaps 'ctx' should be dropped from mapping because manifest |
|
598 | # TODO: perhaps 'ctx' should be dropped from mapping because manifest | |
580 | # rev and node are completely different from changeset's. |
|
599 | # rev and node are completely different from changeset's. | |
581 | return _mappable(f, f, lambda: {'rev': mrev, 'node': mhex}) |
|
600 | return _mappable(f, None, f, lambda x: {'rev': mrev, 'node': mhex}) | |
582 |
|
601 | |||
583 | def shownames(namespace, **args): |
|
602 | def shownames(namespace, **args): | |
584 | """helper method to generate a template keyword for a namespace""" |
|
603 | """helper method to generate a template keyword for a namespace""" |
@@ -730,7 +730,10 b' def get(context, mapping, args):' | |||||
730 | raise error.ParseError(_("get() expects a dict as first argument")) |
|
730 | raise error.ParseError(_("get() expects a dict as first argument")) | |
731 |
|
731 | |||
732 | key = evalfuncarg(context, mapping, args[1]) |
|
732 | key = evalfuncarg(context, mapping, args[1]) | |
733 |
|
|
733 | val = dictarg.get(key) | |
|
734 | if val is None: | |||
|
735 | return | |||
|
736 | return templatekw.wraphybridvalue(dictarg, key, val) | |||
734 |
|
737 | |||
735 | @templatefunc('if(expr, then[, else])') |
|
738 | @templatefunc('if(expr, then[, else])') | |
736 | def if_(context, mapping, args): |
|
739 | def if_(context, mapping, args): | |
@@ -874,10 +877,11 b' def max_(context, mapping, args, **kwarg' | |||||
874 |
|
877 | |||
875 | iterable = evalfuncarg(context, mapping, args[0]) |
|
878 | iterable = evalfuncarg(context, mapping, args[0]) | |
876 | try: |
|
879 | try: | |
877 |
|
|
880 | x = max(iterable) | |
878 | except (TypeError, ValueError): |
|
881 | except (TypeError, ValueError): | |
879 | # i18n: "max" is a keyword |
|
882 | # i18n: "max" is a keyword | |
880 | raise error.ParseError(_("max first argument should be an iterable")) |
|
883 | raise error.ParseError(_("max first argument should be an iterable")) | |
|
884 | return templatekw.wraphybridvalue(iterable, x, x) | |||
881 |
|
885 | |||
882 | @templatefunc('min(iterable)') |
|
886 | @templatefunc('min(iterable)') | |
883 | def min_(context, mapping, args, **kwargs): |
|
887 | def min_(context, mapping, args, **kwargs): | |
@@ -888,10 +892,11 b' def min_(context, mapping, args, **kwarg' | |||||
888 |
|
892 | |||
889 | iterable = evalfuncarg(context, mapping, args[0]) |
|
893 | iterable = evalfuncarg(context, mapping, args[0]) | |
890 | try: |
|
894 | try: | |
891 |
|
|
895 | x = min(iterable) | |
892 | except (TypeError, ValueError): |
|
896 | except (TypeError, ValueError): | |
893 | # i18n: "min" is a keyword |
|
897 | # i18n: "min" is a keyword | |
894 | raise error.ParseError(_("min first argument should be an iterable")) |
|
898 | raise error.ParseError(_("min first argument should be an iterable")) | |
|
899 | return templatekw.wraphybridvalue(iterable, x, x) | |||
895 |
|
900 | |||
896 | @templatefunc('mod(a, b)') |
|
901 | @templatefunc('mod(a, b)') | |
897 | def mod(context, mapping, args): |
|
902 | def mod(context, mapping, args): |
@@ -3128,10 +3128,24 b' Test new-style inline templating of non-' | |||||
3128 | $ hg log -R latesttag -r tip -T '{manifest % "{rev}:{node}"}\n' |
|
3128 | $ hg log -R latesttag -r tip -T '{manifest % "{rev}:{node}"}\n' | |
3129 | 11:2bc6e9006ce29882383a22d39fd1f4e66dd3e2fc |
|
3129 | 11:2bc6e9006ce29882383a22d39fd1f4e66dd3e2fc | |
3130 |
|
3130 | |||
3131 | Test manifest can be join()-ed as before, though it's silly: |
|
3131 | $ hg log -R latesttag -r tip -T '{get(extras, "branch") % "{key}: {value}\n"}' | |
|
3132 | branch: default | |||
|
3133 | $ hg log -R latesttag -r tip -T '{get(extras, "unknown") % "{key}\n"}' | |||
|
3134 | hg: parse error: None is not iterable | |||
|
3135 | [255] | |||
|
3136 | $ hg log -R latesttag -r tip -T '{min(extras) % "{key}: {value}\n"}' | |||
|
3137 | branch: default | |||
|
3138 | $ hg log -R latesttag -l1 -T '{min(revset("0:9")) % "{rev}:{node|short}\n"}' | |||
|
3139 | 0:ce3cec86e6c2 | |||
|
3140 | $ hg log -R latesttag -l1 -T '{max(revset("0:9")) % "{rev}:{node|short}\n"}' | |||
|
3141 | 9:fbc7cd862e9c | |||
|
3142 | ||||
|
3143 | Test manifest/get() can be join()-ed as before, though it's silly: | |||
3132 |
|
3144 | |||
3133 | $ hg log -R latesttag -r tip -T '{join(manifest, "")}\n' |
|
3145 | $ hg log -R latesttag -r tip -T '{join(manifest, "")}\n' | |
3134 | 11:2bc6e9006ce2 |
|
3146 | 11:2bc6e9006ce2 | |
|
3147 | $ hg log -R latesttag -r tip -T '{join(get(extras, "branch"), "")}\n' | |||
|
3148 | default | |||
3135 |
|
3149 | |||
3136 | Test the sub function of templating for expansion: |
|
3150 | Test the sub function of templating for expansion: | |
3137 |
|
3151 |
General Comments 0
You need to be logged in to leave comments.
Login now