Mercurial > public > mercurial-scm > hg
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 |