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[ |
|
798 | return _hybrid(f, prevs, lambda x: {'ctx': repo[x], 'revcache': {}}, | |
799 |
lambda x: scmutil.formatchangeid(repo[ |
|
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[ |
|
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