comparison mercurial/formatter.py @ 45264:8cce9f77ca73

templatespec: create a factory function for each type there is Most of the arguments to the `templatespec` constructor are mutually exclusive, so each combination creates a different type of templatespec. Let's clarify that by creating factory functions. I've left the callers in `logcmdutil` unchanged for now because they are more complex and `logcmdutil.templatespec()` is slightly higher level in that it is specific to changesets. My larger goal is to add support frozen binaries (specifically PyOxidizer) by adding a specific type of `templatespec` for built-in templates. That will get its own factory function. Differential Revision: https://phab.mercurial-scm.org/D8845
author Martin von Zweigbergk <martinvonz@google.com>
date Thu, 16 Jul 2020 13:33:46 -0700
parents 22eafb16f1c5
children 215f08c8006c
comparison
equal deleted inserted replaced
45263:b7444cfc2c05 45264:8cce9f77ca73
540 tmpl = attr.ib() 540 tmpl = attr.ib()
541 mapfile = attr.ib() 541 mapfile = attr.ib()
542 refargs = attr.ib(default=None) 542 refargs = attr.ib(default=None)
543 543
544 544
545 def empty_templatespec():
546 return templatespec(None, None, None)
547
548
549 def reference_templatespec(ref, refargs=None):
550 return templatespec(ref, None, None, refargs)
551
552
553 def literal_templatespec(tmpl):
554 return templatespec(b'', tmpl, None)
555
556
557 def mapfile_templatespec(topic, mapfile):
558 return templatespec(topic, None, mapfile)
559
560
545 def lookuptemplate(ui, topic, tmpl): 561 def lookuptemplate(ui, topic, tmpl):
546 """Find the template matching the given -T/--template spec 'tmpl' 562 """Find the template matching the given -T/--template spec 'tmpl'
547 563
548 'tmpl' can be any of the following: 564 'tmpl' can be any of the following:
549 565
561 If no map file selected, all templates in [templates] section will be 577 If no map file selected, all templates in [templates] section will be
562 available as well as aliases in [templatealias]. 578 available as well as aliases in [templatealias].
563 """ 579 """
564 580
565 if not tmpl: 581 if not tmpl:
566 return templatespec(None, None, None) 582 return empty_templatespec()
567 583
568 # looks like a literal template? 584 # looks like a literal template?
569 if b'{' in tmpl: 585 if b'{' in tmpl:
570 return templatespec(b'', tmpl, None) 586 return literal_templatespec(tmpl)
571 587
572 # a reference to built-in (formatter) template 588 # a reference to built-in (formatter) template
573 if tmpl in {b'cbor', b'json', b'pickle', b'debug'}: 589 if tmpl in {b'cbor', b'json', b'pickle', b'debug'}:
574 return templatespec(tmpl, None, None) 590 return reference_templatespec(tmpl)
575 591
576 # a function-style reference to built-in template 592 # a function-style reference to built-in template
577 func, fsep, ftail = tmpl.partition(b'(') 593 func, fsep, ftail = tmpl.partition(b'(')
578 if func in {b'cbor', b'json'} and fsep and ftail.endswith(b')'): 594 if func in {b'cbor', b'json'} and fsep and ftail.endswith(b')'):
579 templater.parseexpr(tmpl) # make sure syntax errors are confined 595 templater.parseexpr(tmpl) # make sure syntax errors are confined
580 return templatespec(func, None, None, refargs=ftail[:-1]) 596 return reference_templatespec(func, refargs=ftail[:-1])
581 597
582 # perhaps a stock style? 598 # perhaps a stock style?
583 if not os.path.split(tmpl)[0]: 599 if not os.path.split(tmpl)[0]:
584 mapname = templater.templatepath( 600 mapname = templater.templatepath(
585 b'map-cmdline.' + tmpl 601 b'map-cmdline.' + tmpl
586 ) or templater.templatepath(tmpl) 602 ) or templater.templatepath(tmpl)
587 if mapname: 603 if mapname:
588 return templatespec(topic, None, mapname) 604 return mapfile_templatespec(topic, mapname)
589 605
590 # perhaps it's a reference to [templates] 606 # perhaps it's a reference to [templates]
591 if ui.config(b'templates', tmpl): 607 if ui.config(b'templates', tmpl):
592 return templatespec(tmpl, None, None) 608 return reference_templatespec(tmpl)
593 609
594 if tmpl == b'list': 610 if tmpl == b'list':
595 ui.write(_(b"available styles: %s\n") % templater.stylelist()) 611 ui.write(_(b"available styles: %s\n") % templater.stylelist())
596 raise error.Abort(_(b"specify a template")) 612 raise error.Abort(_(b"specify a template"))
597 613
598 # perhaps it's a path to a map or a template 614 # perhaps it's a path to a map or a template
599 if (b'/' in tmpl or b'\\' in tmpl) and os.path.isfile(tmpl): 615 if (b'/' in tmpl or b'\\' in tmpl) and os.path.isfile(tmpl):
600 # is it a mapfile for a style? 616 # is it a mapfile for a style?
601 if os.path.basename(tmpl).startswith(b"map-"): 617 if os.path.basename(tmpl).startswith(b"map-"):
602 return templatespec(topic, None, os.path.realpath(tmpl)) 618 return mapfile_templatespec(topic, os.path.realpath(tmpl))
603 with util.posixfile(tmpl, b'rb') as f: 619 with util.posixfile(tmpl, b'rb') as f:
604 tmpl = f.read() 620 tmpl = f.read()
605 return templatespec(b'', tmpl, None) 621 return literal_templatespec(tmpl)
606 622
607 # constant string? 623 # constant string?
608 return templatespec(b'', tmpl, None) 624 return literal_templatespec(tmpl)
609 625
610 626
611 def templatepartsmap(spec, t, partnames): 627 def templatepartsmap(spec, t, partnames):
612 """Create a mapping of {part: ref}""" 628 """Create a mapping of {part: ref}"""
613 partsmap = {spec.ref: spec.ref} # initial ref must exist in t 629 partsmap = {spec.ref: spec.ref} # initial ref must exist in t