##// END OF EJS Templates
templater: wrap get/min/max result so map operation can apply to element...
Yuya Nishihara -
r34535:b3073e17 default
parent child Browse files
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 self.gen = gen
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 return dictarg.get(key)
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 return max(iterable)
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 return min(iterable)
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