##// END OF EJS Templates
templater: store revisions as ints so min/max won't compare them as strings...
Yuya Nishihara -
r34582:ee0d7408 default
parent child Browse files
Show More
@@ -37,12 +37,13 class _hybrid(object):
37 - "{files|json}"
37 - "{files|json}"
38 """
38 """
39
39
40 def __init__(self, gen, values, makemap, joinfmt):
40 def __init__(self, gen, values, makemap, joinfmt, keytype=None):
41 if gen is not None:
41 if gen is not None:
42 self.gen = gen # generator or function returning generator
42 self.gen = gen # generator or function returning generator
43 self._values = values
43 self._values = values
44 self._makemap = makemap
44 self._makemap = makemap
45 self.joinfmt = joinfmt
45 self.joinfmt = joinfmt
46 self.keytype = keytype # hint for 'x in y' where type(x) is unresolved
46 def gen(self):
47 def gen(self):
47 """Default generator to stringify this as {join(self, ' ')}"""
48 """Default generator to stringify this as {join(self, ' ')}"""
48 for i, x in enumerate(self._values):
49 for i, x in enumerate(self._values):
@@ -788,15 +789,14 def showparents(**args):
788 repo = args['repo']
789 repo = args['repo']
789 ctx = args['ctx']
790 ctx = args['ctx']
790 pctxs = scmutil.meaningfulparents(repo, ctx)
791 pctxs = scmutil.meaningfulparents(repo, ctx)
791 # ifcontains() needs a list of str
792 prevs = [p.rev() for p in pctxs]
792 prevs = ["%d" % p.rev() for p in pctxs]
793 parents = [[('rev', p.rev()),
793 parents = [[('rev', p.rev()),
794 ('node', p.hex()),
794 ('node', p.hex()),
795 ('phase', p.phasestr())]
795 ('phase', p.phasestr())]
796 for p in pctxs]
796 for p in pctxs]
797 f = _showlist('parent', parents, args)
797 f = _showlist('parent', parents, args)
798 return _hybrid(f, prevs, lambda x: {'ctx': repo[int(x)], 'revcache': {}},
798 return _hybrid(f, prevs, lambda x: {'ctx': repo[x], 'revcache': {}},
799 lambda x: scmutil.formatchangeid(repo[int(x)]))
799 lambda x: scmutil.formatchangeid(repo[x]), keytype=int)
800
800
801 @templatekeyword('phase')
801 @templatekeyword('phase')
802 def showphase(repo, ctx, templ, **args):
802 def showphase(repo, ctx, templ, **args):
@@ -818,12 +818,10 def showrevslist(name, revs, **args):
818 be evaluated"""
818 be evaluated"""
819 args = pycompat.byteskwargs(args)
819 args = pycompat.byteskwargs(args)
820 repo = args['ctx'].repo()
820 repo = args['ctx'].repo()
821 # ifcontains() needs a list of str
821 f = _showlist(name, ['%d' % r for r in revs], args)
822 revs = ["%d" % r for r in revs]
823 f = _showlist(name, revs, args)
824 return _hybrid(f, revs,
822 return _hybrid(f, revs,
825 lambda x: {name: x, 'ctx': repo[int(x)], 'revcache': {}},
823 lambda x: {name: x, 'ctx': repo[x], 'revcache': {}},
826 pycompat.identity)
824 pycompat.identity, keytype=int)
827
825
828 @templatekeyword('subrepos')
826 @templatekeyword('subrepos')
829 def showsubrepos(**args):
827 def showsubrepos(**args):
@@ -333,12 +333,12 def evalboolean(context, mapping, arg):
333 # empty dict/list should be False as they are expected to be ''
333 # empty dict/list should be False as they are expected to be ''
334 return bool(stringify(thing))
334 return bool(stringify(thing))
335
335
336 def evalinteger(context, mapping, arg, err):
336 def evalinteger(context, mapping, arg, err=None):
337 v = evalfuncarg(context, mapping, arg)
337 v = evalfuncarg(context, mapping, arg)
338 try:
338 try:
339 return int(v)
339 return int(v)
340 except (TypeError, ValueError):
340 except (TypeError, ValueError):
341 raise error.ParseError(err)
341 raise error.ParseError(err or _('not an integer'))
342
342
343 def evalstring(context, mapping, arg):
343 def evalstring(context, mapping, arg):
344 return stringify(evalrawexp(context, mapping, arg))
344 return stringify(evalrawexp(context, mapping, arg))
@@ -353,6 +353,20 def evalstringliteral(context, mapping,
353 thing = func(context, mapping, data)
353 thing = func(context, mapping, data)
354 return stringify(thing)
354 return stringify(thing)
355
355
356 _evalfuncbytype = {
357 bool: evalboolean,
358 bytes: evalstring,
359 int: evalinteger,
360 }
361
362 def evalastype(context, mapping, arg, typ):
363 """Evaluate given argument and coerce its type"""
364 try:
365 f = _evalfuncbytype[typ]
366 except KeyError:
367 raise error.ProgrammingError('invalid type specified: %r' % typ)
368 return f(context, mapping, arg)
369
356 def runinteger(context, mapping, data):
370 def runinteger(context, mapping, data):
357 return int(data)
371 return int(data)
358
372
@@ -782,8 +796,9 def ifcontains(context, mapping, args):
782 # i18n: "ifcontains" is a keyword
796 # i18n: "ifcontains" is a keyword
783 raise error.ParseError(_("ifcontains expects three or four arguments"))
797 raise error.ParseError(_("ifcontains expects three or four arguments"))
784
798
785 needle = evalstring(context, mapping, args[0])
786 haystack = evalfuncarg(context, mapping, args[1])
799 haystack = evalfuncarg(context, mapping, args[1])
800 needle = evalastype(context, mapping, args[0],
801 getattr(haystack, 'keytype', None) or bytes)
787
802
788 if needle in haystack:
803 if needle in haystack:
789 yield evalrawexp(context, mapping, args[2])
804 yield evalrawexp(context, mapping, args[2])
@@ -3147,6 +3147,13 Test manifest/get() can be join()-ed as
3147 $ hg log -R latesttag -r tip -T '{join(get(extras, "branch"), "")}\n'
3147 $ hg log -R latesttag -r tip -T '{join(get(extras, "branch"), "")}\n'
3148 default
3148 default
3149
3149
3150 Test min/max of integers
3151
3152 $ hg log -R latesttag -l1 -T '{min(revset("9:10"))}\n'
3153 9
3154 $ hg log -R latesttag -l1 -T '{max(revset("9:10"))}\n'
3155 10
3156
3150 Test dot operator precedence:
3157 Test dot operator precedence:
3151
3158
3152 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
3159 $ hg debugtemplate -R latesttag -r0 -v '{manifest.node|short}\n'
General Comments 0
You need to be logged in to leave comments. Login now