mercurial/formatter.py
author Manuel Jacob <me@manueljacob.de>
Sun, 22 May 2022 03:50:34 +0200
changeset 49269 395f28064826
parent 48946 642e31cb55f0
child 51690 493034cc3265
permissions -rw-r--r--
worker: avoid potential partial write of pickled data Previously, the code wrote the pickled data using os.write(). However, os.write() can write less bytes than passed to it. To trigger the problem, the pickled data had to be larger than 2147479552 bytes on my system. Instead, open a file object and pass it to pickle.dump(). This also has the advantage that it doesn’t buffer the whole pickled data in memory. Note that the opened file must be buffered because pickle doesn’t support unbuffered streams because unbuffered streams’ write() method might write less bytes than passed to it (like os.write()) but pickle.dump() relies on that all bytes are written (see https://github.com/python/cpython/issues/93050). The side effect of using a file object and a with statement is that wfd is explicitly closed now while it seems like before it was implicitly closed by process exit.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# formatter.py - generic output formatting for mercurial
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46769
diff changeset
     3
# Copyright 2012 Olivia Mackall <olivia@selenic.com>
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
30560
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
     8
"""Generic output formatting for Mercurial
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
     9
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    10
The formatter provides API to show data in various ways. The following
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    11
functions should be used in place of ui.write():
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    12
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    13
- fm.write() for unconditional output
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    14
- fm.condwrite() to show some extra data conditionally in plain output
31172
16272d8c24f6 formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents: 31170
diff changeset
    15
- fm.context() to provide changectx to template output
30560
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    16
- fm.data() to provide extra data to JSON or template output
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    17
- fm.plain() to show raw text that isn't provided to JSON or template output
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    18
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    19
To show structured data (e.g. date tuples, dicts, lists), apply fm.format*()
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    20
beforehand so the data is converted to the appropriate data type. Use
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    21
fm.isplain() if you need to convert or format data conditionally which isn't
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    22
supported by the formatter API.
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    23
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    24
To build nested structure (i.e. a list of dicts), use fm.nested().
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    25
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    26
See also https://www.mercurial-scm.org/wiki/GenericTemplatingPlan
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    27
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    28
fm.condwrite() vs 'if cond:':
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    29
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    30
In most cases, use fm.condwrite() so users can selectively show the data
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    31
in template output. If it's costly to build data, use plain 'if cond:' with
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    32
fm.write().
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    33
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    34
fm.nested() vs fm.formatdict() (or fm.formatlist()):
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    35
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    36
fm.nested() should be used to form a tree structure (a list of dicts of
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    37
lists of dicts...) which can be accessed through template keywords, e.g.
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    38
"{foo % "{bar % {...}} {baz % {...}}"}". On the other hand, fm.formatdict()
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    39
exports a dict-type object to template, which can be accessed by e.g.
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    40
"{get(foo, key)}" function.
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    41
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    42
Doctest helper:
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    43
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    44
>>> def show(fn, verbose=False, **opts):
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    45
...     import sys
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    46
...     from . import ui as uimod
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    47
...     ui = uimod.ui()
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    48
...     ui.verbose = verbose
34255
d6af8da4a3b8 py3: rewrite stdout hack of doctest by using ui.pushbuffer()
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
    49
...     ui.pushbuffer()
d6af8da4a3b8 py3: rewrite stdout hack of doctest by using ui.pushbuffer()
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
    50
...     try:
34256
ebe3d0095c69 py3: convert system strings to bytes in doctest of formatter.py
Yuya Nishihara <yuya@tcha.org>
parents: 34255
diff changeset
    51
...         return fn(ui, ui.formatter(pycompat.sysbytes(fn.__name__),
ebe3d0095c69 py3: convert system strings to bytes in doctest of formatter.py
Yuya Nishihara <yuya@tcha.org>
parents: 34255
diff changeset
    52
...                   pycompat.byteskwargs(opts)))
34255
d6af8da4a3b8 py3: rewrite stdout hack of doctest by using ui.pushbuffer()
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
    53
...     finally:
d6af8da4a3b8 py3: rewrite stdout hack of doctest by using ui.pushbuffer()
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
    54
...         print(pycompat.sysstr(ui.popbuffer()), end='')
30560
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    55
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    56
Basic example:
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    57
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    58
>>> def files(ui, fm):
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33090
diff changeset
    59
...     files = [(b'foo', 123, (0, 0)), (b'bar', 456, (1, 0))]
30560
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    60
...     for f in files:
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    61
...         fm.startitem()
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33090
diff changeset
    62
...         fm.write(b'path', b'%s', f[0])
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33090
diff changeset
    63
...         fm.condwrite(ui.verbose, b'date', b'  %s',
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33090
diff changeset
    64
...                      fm.formatdate(f[2], b'%Y-%m-%d %H:%M:%S'))
30560
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    65
...         fm.data(size=f[1])
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33090
diff changeset
    66
...         fm.plain(b'\\n')
30560
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    67
...     fm.end()
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    68
>>> show(files)
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    69
foo
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    70
bar
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    71
>>> show(files, verbose=True)
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    72
foo  1970-01-01 00:00:00
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    73
bar  1970-01-01 00:00:01
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33090
diff changeset
    74
>>> show(files, template=b'json')
30560
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    75
[
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    76
 {
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    77
  "date": [0, 0],
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    78
  "path": "foo",
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    79
  "size": 123
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    80
 },
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    81
 {
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    82
  "date": [1, 0],
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    83
  "path": "bar",
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    84
  "size": 456
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    85
 }
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    86
]
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33090
diff changeset
    87
>>> show(files, template=b'path: {path}\\ndate: {date|rfc3339date}\\n')
30560
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    88
path: foo
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    89
date: 1970-01-01T00:00:00+00:00
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    90
path: bar
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    91
date: 1970-01-01T00:00:01+00:00
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    92
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    93
Nested example:
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    94
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    95
>>> def subrepos(ui, fm):
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    96
...     fm.startitem()
35470
a33be093ec62 templater: look up symbols/resources as if they were separated (issue5699)
Yuya Nishihara <yuya@tcha.org>
parents: 35469
diff changeset
    97
...     fm.write(b'reponame', b'[%s]\\n', b'baz')
37500
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37105
diff changeset
    98
...     files(ui, fm.nested(b'files', tmpl=b'{reponame}'))
30560
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
    99
...     fm.end()
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
   100
>>> show(subrepos)
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
   101
[baz]
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
   102
foo
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
   103
bar
35470
a33be093ec62 templater: look up symbols/resources as if they were separated (issue5699)
Yuya Nishihara <yuya@tcha.org>
parents: 35469
diff changeset
   104
>>> show(subrepos, template=b'{reponame}: {join(files % "{path}", ", ")}\\n')
30560
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
   105
baz: foo, bar
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
   106
"""
783016005122 formatter: add overview of API and example as doctest
Yuya Nishihara <yuya@tcha.org>
parents: 29949
diff changeset
   107
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   108
32580
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   109
import contextlib
31807
e6eb86b154c5 templater: provide loop counter as "index" keyword
Yuya Nishihara <yuya@tcha.org>
parents: 31805
diff changeset
   110
import itertools
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   111
import os
48870
df56e6bd37f6 py3: use pickle directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 46819
diff changeset
   112
import pickle
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   113
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   114
from .i18n import _
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   115
from .node import (
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   116
    hex,
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   117
    short,
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   118
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   119
from .thirdparty import attr
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   120
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   121
from . import (
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26373
diff changeset
   122
    error,
32159
0fd15522a848 py3: use pycompat.byteskwargs to converts kwargs to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31925
diff changeset
   123
    pycompat,
31782
654e9a1c8a6c formatter: use templatefilters.json()
Yuya Nishihara <yuya@tcha.org>
parents: 31396
diff changeset
   124
    templatefilters,
29676
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
   125
    templatekw,
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   126
    templater,
36920
6ff6e1d6b5b8 templater: move stringify() to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36634
diff changeset
   127
    templateutil,
29324
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28957
diff changeset
   128
    util,
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   129
)
40274
a8b9174517c7 formatter: use stringutil.pprint() in debug output to drop b''
Yuya Nishihara <yuya@tcha.org>
parents: 40140
diff changeset
   130
from .utils import (
41996
77ef3498ceb3 template: add CBOR output format
Yuya Nishihara <yuya@tcha.org>
parents: 40277
diff changeset
   131
    cborutil,
40274
a8b9174517c7 formatter: use stringutil.pprint() in debug output to drop b''
Yuya Nishihara <yuya@tcha.org>
parents: 40140
diff changeset
   132
    dateutil,
a8b9174517c7 formatter: use stringutil.pprint() in debug output to drop b''
Yuya Nishihara <yuya@tcha.org>
parents: 40140
diff changeset
   133
    stringutil,
a8b9174517c7 formatter: use stringutil.pprint() in debug output to drop b''
Yuya Nishihara <yuya@tcha.org>
parents: 40140
diff changeset
   134
)
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
   135
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   136
43335
242ad45b60b3 config: fix -Tjson to not crash due to unsupported defaultvalue types
Yuya Nishihara <yuya@tcha.org>
parents: 43106
diff changeset
   137
def isprintable(obj):
242ad45b60b3 config: fix -Tjson to not crash due to unsupported defaultvalue types
Yuya Nishihara <yuya@tcha.org>
parents: 43106
diff changeset
   138
    """Check if the given object can be directly passed in to formatter's
242ad45b60b3 config: fix -Tjson to not crash due to unsupported defaultvalue types
Yuya Nishihara <yuya@tcha.org>
parents: 43106
diff changeset
   139
    write() and data() functions
242ad45b60b3 config: fix -Tjson to not crash due to unsupported defaultvalue types
Yuya Nishihara <yuya@tcha.org>
parents: 43106
diff changeset
   140
242ad45b60b3 config: fix -Tjson to not crash due to unsupported defaultvalue types
Yuya Nishihara <yuya@tcha.org>
parents: 43106
diff changeset
   141
    Returns False if the object is unsupported or must be pre-processed by
242ad45b60b3 config: fix -Tjson to not crash due to unsupported defaultvalue types
Yuya Nishihara <yuya@tcha.org>
parents: 43106
diff changeset
   142
    formatdate(), formatdict(), or formatlist().
242ad45b60b3 config: fix -Tjson to not crash due to unsupported defaultvalue types
Yuya Nishihara <yuya@tcha.org>
parents: 43106
diff changeset
   143
    """
48932
176f1a0d15dc py3: use int instead of pycompat.long
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   144
    return isinstance(obj, (type(None), bool, int, int, float, bytes))
43335
242ad45b60b3 config: fix -Tjson to not crash due to unsupported defaultvalue types
Yuya Nishihara <yuya@tcha.org>
parents: 43106
diff changeset
   145
242ad45b60b3 config: fix -Tjson to not crash due to unsupported defaultvalue types
Yuya Nishihara <yuya@tcha.org>
parents: 43106
diff changeset
   146
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48932
diff changeset
   147
class _nullconverter:
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   148
    '''convert non-primitive data types to be processed by formatter'''
33090
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32952
diff changeset
   149
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32952
diff changeset
   150
    # set to True if context object should be stored as item
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32952
diff changeset
   151
    storecontext = False
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32952
diff changeset
   152
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   153
    @staticmethod
37500
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37105
diff changeset
   154
    def wrapnested(data, tmpl, sep):
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37105
diff changeset
   155
        '''wrap nested data by appropriate type'''
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37105
diff changeset
   156
        return data
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   157
37500
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37105
diff changeset
   158
    @staticmethod
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   159
    def formatdate(date, fmt):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   160
        '''convert date tuple to appropriate format'''
37770
31750413f8d7 formatter: convert timestamp to int
Yuya Nishihara <yuya@tcha.org>
parents: 37597
diff changeset
   161
        # timestamp can be float, but the canonical form should be int
31750413f8d7 formatter: convert timestamp to int
Yuya Nishihara <yuya@tcha.org>
parents: 37597
diff changeset
   162
        ts, tz = date
31750413f8d7 formatter: convert timestamp to int
Yuya Nishihara <yuya@tcha.org>
parents: 37597
diff changeset
   163
        return (int(ts), tz)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   164
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   165
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   166
    def formatdict(data, key, value, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   167
        '''convert dict or key-value pairs to appropriate dict format'''
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   168
        # use plain dict instead of util.sortdict so that data can be
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   169
        # serialized as a builtin dict in pickle output
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   170
        return dict(data)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   171
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   172
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   173
    def formatlist(data, name, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   174
        '''convert iterable to appropriate list format'''
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   175
        return list(data)
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   176
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   177
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48932
diff changeset
   178
class baseformatter:
46769
67a2ecea8bd9 debugdiscovery: also integrate the discovery output in the json one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45320
diff changeset
   179
67a2ecea8bd9 debugdiscovery: also integrate the discovery output in the json one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45320
diff changeset
   180
    # set to True if the formater output a strict format that does not support
67a2ecea8bd9 debugdiscovery: also integrate the discovery output in the json one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45320
diff changeset
   181
    # arbitrary output in the stream.
67a2ecea8bd9 debugdiscovery: also integrate the discovery output in the json one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45320
diff changeset
   182
    strict_format = False
67a2ecea8bd9 debugdiscovery: also integrate the discovery output in the json one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45320
diff changeset
   183
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   184
    def __init__(self, ui, topic, opts, converter):
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   185
        self._ui = ui
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   186
        self._topic = topic
37597
d110167610db formatter: carry opts to file-based formatters by basefm
Yuya Nishihara <yuya@tcha.org>
parents: 37596
diff changeset
   187
        self._opts = opts
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   188
        self._converter = converter
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   189
        self._item = None
22701
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
   190
        # function to convert node to string suitable for this output
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
   191
        self.hexfunc = hex
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   192
29882
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 29837
diff changeset
   193
    def __enter__(self):
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 29837
diff changeset
   194
        return self
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   195
29882
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 29837
diff changeset
   196
    def __exit__(self, exctype, excvalue, traceback):
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 29837
diff changeset
   197
        if exctype is None:
307b20e5e505 formatter: add context manager interface for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 29837
diff changeset
   198
            self.end()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   199
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   200
    def _showitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   201
        '''show a formatted item once all data is collected'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   202
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   203
    def startitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   204
        '''begin an item in the format list'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   205
        if self._item is not None:
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   206
            self._showitem()
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   207
        self._item = {}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   208
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   209
    def formatdate(self, date, fmt=b'%a %b %d %H:%M:%S %Y %1%2'):
29678
2f3f18ad55a2 formatter: add function to convert date tuple to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29676
diff changeset
   210
        '''convert date tuple to appropriate format'''
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   211
        return self._converter.formatdate(date, fmt)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   212
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   213
    def formatdict(self, data, key=b'key', value=b'value', fmt=None, sep=b' '):
29794
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29678
diff changeset
   214
        '''convert dict or key-value pairs to appropriate dict format'''
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   215
        return self._converter.formatdict(data, key, value, fmt, sep)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   216
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   217
    def formatlist(self, data, name, fmt=None, sep=b' '):
29676
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
   218
        '''convert iterable to appropriate list format'''
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   219
        # name is mandatory argument for now, but it could be optional if
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   220
        # we have default template keyword, e.g. {item}
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   221
        return self._converter.formatlist(data, name, fmt, sep)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   222
31172
16272d8c24f6 formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents: 31170
diff changeset
   223
    def context(self, **ctxs):
16272d8c24f6 formatter: add support for changeset templating
Yuya Nishihara <yuya@tcha.org>
parents: 31170
diff changeset
   224
        '''insert context objects to be used to render template keywords'''
33090
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32952
diff changeset
   225
        ctxs = pycompat.byteskwargs(ctxs)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   226
        assert all(k in {b'repo', b'ctx', b'fctx'} for k in ctxs)
33090
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32952
diff changeset
   227
        if self._converter.storecontext:
39583
ee1e74ee037c formatter: fill missing resources by formatter, not by resource mapper
Yuya Nishihara <yuya@tcha.org>
parents: 39582
diff changeset
   228
            # populate missing resources in fctx -> ctx -> repo order
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   229
            if b'fctx' in ctxs and b'ctx' not in ctxs:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   230
                ctxs[b'ctx'] = ctxs[b'fctx'].changectx()
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   231
            if b'ctx' in ctxs and b'repo' not in ctxs:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   232
                ctxs[b'repo'] = ctxs[b'ctx'].repo()
33090
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32952
diff changeset
   233
            self._item.update(ctxs)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   234
38356
8221df643176 formatter: provide hint of referenced field names
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
   235
    def datahint(self):
8221df643176 formatter: provide hint of referenced field names
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
   236
        '''set of field names to be referenced'''
8221df643176 formatter: provide hint of referenced field names
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
   237
        return set()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   238
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   239
    def data(self, **data):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   240
        '''insert data into item that's not shown in default output'''
32159
0fd15522a848 py3: use pycompat.byteskwargs to converts kwargs to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 31925
diff changeset
   241
        data = pycompat.byteskwargs(data)
17630
ff5ed1ecd43a formatter: improve implementation of data method
David M. Carr <david@carrclan.us>
parents: 17597
diff changeset
   242
        self._item.update(data)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   243
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   244
    def write(self, fields, deftext, *fielddata, **opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   245
        '''do default text output while assigning data to item'''
26372
55de800937e0 formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 25950
diff changeset
   246
        fieldkeys = fields.split()
40140
46f9b1d2daf0 formatter: more details on assertion failure
Boris Feld <boris.feld@octobus.net>
parents: 39624
diff changeset
   247
        assert len(fieldkeys) == len(fielddata), (fieldkeys, fielddata)
26373
aa610ffad4e8 formatter: use dict.update() to set arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 26372
diff changeset
   248
        self._item.update(zip(fieldkeys, fielddata))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   249
17909
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
   250
    def condwrite(self, cond, fields, deftext, *fielddata, **opts):
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
   251
        '''do conditional write (primarily for plain formatter)'''
26372
55de800937e0 formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 25950
diff changeset
   252
        fieldkeys = fields.split()
55de800937e0 formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 25950
diff changeset
   253
        assert len(fieldkeys) == len(fielddata)
26373
aa610ffad4e8 formatter: use dict.update() to set arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 26372
diff changeset
   254
        self._item.update(zip(fieldkeys, fielddata))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   255
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   256
    def plain(self, text, **opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   257
        '''show raw text for non-templated mode'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   258
29949
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 29882
diff changeset
   259
    def isplain(self):
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 29882
diff changeset
   260
        '''check for plain formatter usage'''
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 29882
diff changeset
   261
        return False
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   262
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   263
    def nested(self, field, tmpl=None, sep=b''):
29837
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29836
diff changeset
   264
        '''sub formatter to store nested data in the specified field'''
37500
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37105
diff changeset
   265
        data = []
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37105
diff changeset
   266
        self._item[field] = self._converter.wrapnested(data, tmpl, sep)
29837
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29836
diff changeset
   267
        return _nestedformatter(self._ui, self._converter, data)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   268
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   269
    def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   270
        '''end output for the formatter'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   271
        if self._item is not None:
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   272
            self._showitem()
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   273
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   274
37597
d110167610db formatter: carry opts to file-based formatters by basefm
Yuya Nishihara <yuya@tcha.org>
parents: 37596
diff changeset
   275
def nullformatter(ui, topic, opts):
32581
e9bf3e132ea9 formatter: add nullformatter
Yuya Nishihara <yuya@tcha.org>
parents: 32580
diff changeset
   276
    '''formatter that prints nothing'''
37597
d110167610db formatter: carry opts to file-based formatters by basefm
Yuya Nishihara <yuya@tcha.org>
parents: 37596
diff changeset
   277
    return baseformatter(ui, topic, opts, converter=_nullconverter)
32581
e9bf3e132ea9 formatter: add nullformatter
Yuya Nishihara <yuya@tcha.org>
parents: 32580
diff changeset
   278
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   279
29837
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29836
diff changeset
   280
class _nestedformatter(baseformatter):
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29836
diff changeset
   281
    '''build sub items and store them in the parent formatter'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   282
29837
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29836
diff changeset
   283
    def __init__(self, ui, converter, data):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   284
        baseformatter.__init__(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   285
            self, ui, topic=b'', opts={}, converter=converter
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   286
        )
29837
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29836
diff changeset
   287
        self._data = data
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   288
29837
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29836
diff changeset
   289
    def _showitem(self):
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29836
diff changeset
   290
        self._data.append(self._item)
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29836
diff changeset
   291
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   292
29794
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29678
diff changeset
   293
def _iteritems(data):
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29678
diff changeset
   294
    '''iterate key-value pairs in stable order'''
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29678
diff changeset
   295
    if isinstance(data, dict):
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48888
diff changeset
   296
        return sorted(data.items())
29794
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29678
diff changeset
   297
    return data
4891f3b93182 formatter: add function to convert dict to appropriate format
Yuya Nishihara <yuya@tcha.org>
parents: 29678
diff changeset
   298
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   299
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48932
diff changeset
   300
class _plainconverter:
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   301
    '''convert non-primitive data types to text'''
33090
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32952
diff changeset
   302
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32952
diff changeset
   303
    storecontext = False
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32952
diff changeset
   304
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   305
    @staticmethod
37500
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37105
diff changeset
   306
    def wrapnested(data, tmpl, sep):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   307
        raise error.ProgrammingError(b'plainformatter should never be nested')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   308
37500
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37105
diff changeset
   309
    @staticmethod
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   310
    def formatdate(date, fmt):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   311
        '''stringify date tuple in the given format'''
36607
c6061cadb400 util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents: 36445
diff changeset
   312
        return dateutil.datestr(date, fmt)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   313
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   314
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   315
    def formatdict(data, key, value, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   316
        '''stringify key-value pairs separated by sep'''
36634
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 36633
diff changeset
   317
        prefmt = pycompat.identity
36633
034a07e60e98 templater: allow dynamically switching the default dict/list formatting
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
   318
        if fmt is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   319
            fmt = b'%s=%s'
36634
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 36633
diff changeset
   320
            prefmt = pycompat.bytestr
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   321
        return sep.join(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   322
            fmt % (prefmt(k), prefmt(v)) for k, v in _iteritems(data)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   323
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   324
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   325
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   326
    def formatlist(data, name, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   327
        '''stringify iterable separated by sep'''
36634
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 36633
diff changeset
   328
        prefmt = pycompat.identity
36633
034a07e60e98 templater: allow dynamically switching the default dict/list formatting
Yuya Nishihara <yuya@tcha.org>
parents: 36607
diff changeset
   329
        if fmt is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   330
            fmt = b'%s'
36634
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 36633
diff changeset
   331
            prefmt = pycompat.bytestr
cafd0586876b templater: byte-stringify dict/list values before passing to default format
Yuya Nishihara <yuya@tcha.org>
parents: 36633
diff changeset
   332
        return sep.join(fmt % prefmt(e) for e in data)
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   333
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   334
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   335
class plainformatter(baseformatter):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   336
    '''the default text output scheme'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   337
32579
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   338
    def __init__(self, ui, out, topic, opts):
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   339
        baseformatter.__init__(self, ui, topic, opts, _plainconverter)
22701
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
   340
        if ui.debugflag:
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
   341
            self.hexfunc = hex
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
   342
        else:
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
   343
            self.hexfunc = short
32579
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   344
        if ui is out:
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   345
            self._write = ui.write
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   346
        else:
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   347
            self._write = lambda s, **opts: out.write(s)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   348
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   349
    def startitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   350
        pass
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   351
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   352
    def data(self, **data):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   353
        pass
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   354
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   355
    def write(self, fields, deftext, *fielddata, **opts):
32579
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   356
        self._write(deftext % fielddata, **opts)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   357
17909
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
   358
    def condwrite(self, cond, fields, deftext, *fielddata, **opts):
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
   359
        '''do conditional write'''
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
   360
        if cond:
32579
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   361
            self._write(deftext % fielddata, **opts)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   362
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   363
    def plain(self, text, **opts):
32579
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   364
        self._write(text, **opts)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   365
29949
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 29882
diff changeset
   366
    def isplain(self):
e7cacb45c4be formatter: introduce isplain() to replace (the inverse of) __nonzero__() (API)
Mathias De Maré <mathias.demare@gmail.com>
parents: 29882
diff changeset
   367
        return True
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   368
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   369
    def nested(self, field, tmpl=None, sep=b''):
29837
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29836
diff changeset
   370
        # nested data will be directly written to ui
5b886289a1ca formatter: add fm.nested(field) to either write or build sub items
Yuya Nishihara <yuya@tcha.org>
parents: 29836
diff changeset
   371
        return self
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   372
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   373
    def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   374
        pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   375
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   376
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   377
class debugformatter(baseformatter):
31182
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31172
diff changeset
   378
    def __init__(self, ui, out, topic, opts):
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   379
        baseformatter.__init__(self, ui, topic, opts, _nullconverter)
31182
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31172
diff changeset
   380
        self._out = out
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   381
        self._out.write(b"%s = [\n" % self._topic)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   382
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   383
    def _showitem(self):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   384
        self._out.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   385
            b'    %s,\n' % stringutil.pprint(self._item, indent=4, level=1)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   386
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   387
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   388
    def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   389
        baseformatter.end(self)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   390
        self._out.write(b"]\n")
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   391
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   392
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   393
class pickleformatter(baseformatter):
31182
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31172
diff changeset
   394
    def __init__(self, ui, out, topic, opts):
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   395
        baseformatter.__init__(self, ui, topic, opts, _nullconverter)
31182
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31172
diff changeset
   396
        self._out = out
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   397
        self._data = []
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   398
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   399
    def _showitem(self):
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   400
        self._data.append(self._item)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   401
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   402
    def end(self):
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   403
        baseformatter.end(self)
31182
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31172
diff changeset
   404
        self._out.write(pickle.dumps(self._data))
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   405
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   406
41996
77ef3498ceb3 template: add CBOR output format
Yuya Nishihara <yuya@tcha.org>
parents: 40277
diff changeset
   407
class cborformatter(baseformatter):
77ef3498ceb3 template: add CBOR output format
Yuya Nishihara <yuya@tcha.org>
parents: 40277
diff changeset
   408
    '''serialize items as an indefinite-length CBOR array'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   409
41996
77ef3498ceb3 template: add CBOR output format
Yuya Nishihara <yuya@tcha.org>
parents: 40277
diff changeset
   410
    def __init__(self, ui, out, topic, opts):
77ef3498ceb3 template: add CBOR output format
Yuya Nishihara <yuya@tcha.org>
parents: 40277
diff changeset
   411
        baseformatter.__init__(self, ui, topic, opts, _nullconverter)
77ef3498ceb3 template: add CBOR output format
Yuya Nishihara <yuya@tcha.org>
parents: 40277
diff changeset
   412
        self._out = out
77ef3498ceb3 template: add CBOR output format
Yuya Nishihara <yuya@tcha.org>
parents: 40277
diff changeset
   413
        self._out.write(cborutil.BEGIN_INDEFINITE_ARRAY)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   414
41996
77ef3498ceb3 template: add CBOR output format
Yuya Nishihara <yuya@tcha.org>
parents: 40277
diff changeset
   415
    def _showitem(self):
77ef3498ceb3 template: add CBOR output format
Yuya Nishihara <yuya@tcha.org>
parents: 40277
diff changeset
   416
        self._out.write(b''.join(cborutil.streamencode(self._item)))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   417
41996
77ef3498ceb3 template: add CBOR output format
Yuya Nishihara <yuya@tcha.org>
parents: 40277
diff changeset
   418
    def end(self):
77ef3498ceb3 template: add CBOR output format
Yuya Nishihara <yuya@tcha.org>
parents: 40277
diff changeset
   419
        baseformatter.end(self)
77ef3498ceb3 template: add CBOR output format
Yuya Nishihara <yuya@tcha.org>
parents: 40277
diff changeset
   420
        self._out.write(cborutil.BREAK)
77ef3498ceb3 template: add CBOR output format
Yuya Nishihara <yuya@tcha.org>
parents: 40277
diff changeset
   421
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   422
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   423
class jsonformatter(baseformatter):
46769
67a2ecea8bd9 debugdiscovery: also integrate the discovery output in the json one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45320
diff changeset
   424
67a2ecea8bd9 debugdiscovery: also integrate the discovery output in the json one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45320
diff changeset
   425
    strict_format = True
67a2ecea8bd9 debugdiscovery: also integrate the discovery output in the json one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45320
diff changeset
   426
31182
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31172
diff changeset
   427
    def __init__(self, ui, out, topic, opts):
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   428
        baseformatter.__init__(self, ui, topic, opts, _nullconverter)
31182
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31172
diff changeset
   429
        self._out = out
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   430
        self._out.write(b"[")
31298
59d09565ac77 formatter: set _first on formatter, not ui
Martin von Zweigbergk <martinvonz@google.com>
parents: 31182
diff changeset
   431
        self._first = True
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   432
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   433
    def _showitem(self):
31298
59d09565ac77 formatter: set _first on formatter, not ui
Martin von Zweigbergk <martinvonz@google.com>
parents: 31182
diff changeset
   434
        if self._first:
59d09565ac77 formatter: set _first on formatter, not ui
Martin von Zweigbergk <martinvonz@google.com>
parents: 31182
diff changeset
   435
            self._first = False
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   436
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   437
            self._out.write(b",")
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   438
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   439
        self._out.write(b"\n {\n")
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   440
        first = True
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   441
        for k, v in sorted(self._item.items()):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   442
            if first:
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   443
                first = False
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   444
            else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   445
                self._out.write(b",\n")
31782
654e9a1c8a6c formatter: use templatefilters.json()
Yuya Nishihara <yuya@tcha.org>
parents: 31396
diff changeset
   446
            u = templatefilters.json(v, paranoid=False)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   447
            self._out.write(b'  "%s": %s' % (k, u))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   448
        self._out.write(b"\n }")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   449
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   450
    def end(self):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   451
        baseformatter.end(self)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   452
        self._out.write(b"\n]\n")
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   453
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   454
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48932
diff changeset
   455
class _templateconverter:
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   456
    '''convert non-primitive data types to be processed by templater'''
33090
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32952
diff changeset
   457
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32952
diff changeset
   458
    storecontext = True
04b3743c1d7c formatter: proxy fm.context() through converter
Yuya Nishihara <yuya@tcha.org>
parents: 32952
diff changeset
   459
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   460
    @staticmethod
37500
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37105
diff changeset
   461
    def wrapnested(data, tmpl, sep):
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37105
diff changeset
   462
        '''wrap nested data by templatable type'''
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37105
diff changeset
   463
        return templateutil.mappinglist(data, tmpl=tmpl, sep=sep)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   464
37500
8bb3899a0f47 formatter: make nested items somewhat readable in template output
Yuya Nishihara <yuya@tcha.org>
parents: 37105
diff changeset
   465
    @staticmethod
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   466
    def formatdate(date, fmt):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   467
        '''return date tuple'''
38285
8d6109b49b31 templater: introduce a wrapper for date tuple (BC)
Yuya Nishihara <yuya@tcha.org>
parents: 37839
diff changeset
   468
        return templateutil.date(date)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   469
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   470
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   471
    def formatdict(data, key, value, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   472
        '''build object that can be evaluated as either plain string or dict'''
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   473
        data = util.sortdict(_iteritems(data))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   474
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   475
        def f():
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   476
            yield _plainconverter.formatdict(data, key, value, fmt, sep)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   477
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   478
        return templateutil.hybriddict(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   479
            data, key=key, value=value, fmt=fmt, gen=f
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   480
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   481
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   482
    @staticmethod
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   483
    def formatlist(data, name, fmt, sep):
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   484
        '''build object that can be evaluated as either plain string or list'''
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   485
        data = list(data)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   486
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   487
        def f():
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   488
            yield _plainconverter.formatlist(data, name, fmt, sep)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   489
36921
32f9b7e3f056 templater: move hybrid class and functions to templateutil module
Yuya Nishihara <yuya@tcha.org>
parents: 36920
diff changeset
   490
        return templateutil.hybridlist(data, name=name, fmt=fmt, gen=f)
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   491
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   492
25513
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
   493
class templateformatter(baseformatter):
43101
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   494
    def __init__(self, ui, out, topic, opts, spec, overridetemplates=None):
29836
18bac830eef3 formatter: factor out format*() functions to separate classes
Yuya Nishihara <yuya@tcha.org>
parents: 29794
diff changeset
   495
        baseformatter.__init__(self, ui, topic, opts, _templateconverter)
31182
5660c45ecba6 formatter: add argument to change output file of non-plain formatter
Yuya Nishihara <yuya@tcha.org>
parents: 31172
diff changeset
   496
        self._out = out
32841
883adaea9e80 formatter: render template specified by templatespec tuple
Yuya Nishihara <yuya@tcha.org>
parents: 32840
diff changeset
   497
        self._tref = spec.ref
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   498
        self._t = loadtemplater(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   499
            ui,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   500
            spec,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   501
            defaults=templatekw.keywords,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   502
            resources=templateresources(ui),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   503
            cache=templatekw.defaulttempl,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   504
        )
43101
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   505
        if overridetemplates:
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   506
            self._t.cache.update(overridetemplates)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   507
        self._parts = templatepartsmap(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   508
            spec, self._t, [b'docheader', b'docfooter', b'separator']
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   509
        )
31807
e6eb86b154c5 templater: provide loop counter as "index" keyword
Yuya Nishihara <yuya@tcha.org>
parents: 31805
diff changeset
   510
        self._counter = itertools.count()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   511
        self._renderitem(b'docheader', {})
32949
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   512
25513
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
   513
    def _showitem(self):
32948
12a0794fa2e3 formatter: extract helper function to render template
Yuya Nishihara <yuya@tcha.org>
parents: 32897
diff changeset
   514
        item = self._item.copy()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   515
        item[b'index'] = index = next(self._counter)
32950
5100ce217dfa formatter: add support for separator template
Yuya Nishihara <yuya@tcha.org>
parents: 32949
diff changeset
   516
        if index > 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   517
            self._renderitem(b'separator', {})
32948
12a0794fa2e3 formatter: extract helper function to render template
Yuya Nishihara <yuya@tcha.org>
parents: 32897
diff changeset
   518
        self._renderitem(self._tref, item)
12a0794fa2e3 formatter: extract helper function to render template
Yuya Nishihara <yuya@tcha.org>
parents: 32897
diff changeset
   519
32949
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   520
    def _renderitem(self, part, item):
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   521
        if part not in self._parts:
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   522
            return
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   523
        ref = self._parts[part]
43337
7e20b705da5b formatter: fix handling of None value in templater mapping
Yuya Nishihara <yuya@tcha.org>
parents: 43335
diff changeset
   524
        # None can't be put in the mapping dict since it means <unset>
7e20b705da5b formatter: fix handling of None value in templater mapping
Yuya Nishihara <yuya@tcha.org>
parents: 43335
diff changeset
   525
        for k, v in item.items():
7e20b705da5b formatter: fix handling of None value in templater mapping
Yuya Nishihara <yuya@tcha.org>
parents: 43335
diff changeset
   526
            if v is None:
7e20b705da5b formatter: fix handling of None value in templater mapping
Yuya Nishihara <yuya@tcha.org>
parents: 43335
diff changeset
   527
                item[k] = templateutil.wrappedvalue(v)
37103
be3f33f5e232 templater: switch 'revcache' based on new mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37102
diff changeset
   528
        self._out.write(self._t.render(ref, item))
25513
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
   529
38356
8221df643176 formatter: provide hint of referenced field names
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
   530
    @util.propertycache
8221df643176 formatter: provide hint of referenced field names
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
   531
    def _symbolsused(self):
38446
5b04a0c30f3f formatter: look for template symbols from the associated name
Yuya Nishihara <yuya@tcha.org>
parents: 38429
diff changeset
   532
        return self._t.symbolsused(self._tref)
38356
8221df643176 formatter: provide hint of referenced field names
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
   533
8221df643176 formatter: provide hint of referenced field names
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
   534
    def datahint(self):
8221df643176 formatter: provide hint of referenced field names
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
   535
        '''set of field names to be referenced from the template'''
8221df643176 formatter: provide hint of referenced field names
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
   536
        return self._symbolsused[0]
8221df643176 formatter: provide hint of referenced field names
Yuya Nishihara <yuya@tcha.org>
parents: 38285
diff changeset
   537
32949
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   538
    def end(self):
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   539
        baseformatter.end(self)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   540
        self._renderitem(b'docfooter', {})
32949
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   541
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   542
37839
395571419274 formatter: ditch namedtuple in favor of attr
Yuya Nishihara <yuya@tcha.org>
parents: 37770
diff changeset
   543
@attr.s(frozen=True)
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48932
diff changeset
   544
class templatespec:
37839
395571419274 formatter: ditch namedtuple in favor of attr
Yuya Nishihara <yuya@tcha.org>
parents: 37770
diff changeset
   545
    ref = attr.ib()
395571419274 formatter: ditch namedtuple in favor of attr
Yuya Nishihara <yuya@tcha.org>
parents: 37770
diff changeset
   546
    tmpl = attr.ib()
395571419274 formatter: ditch namedtuple in favor of attr
Yuya Nishihara <yuya@tcha.org>
parents: 37770
diff changeset
   547
    mapfile = attr.ib()
43101
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   548
    refargs = attr.ib(default=None)
45310
f3481e4fcc3a templater: pass opened file-like object to templatespec
Martin von Zweigbergk <martinvonz@google.com>
parents: 45309
diff changeset
   549
    fp = attr.ib(default=None)
32838
615ec3f14aa9 formatter: wrap (tmpl, mapfile) by named tuple
Yuya Nishihara <yuya@tcha.org>
parents: 32835
diff changeset
   550
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   551
45264
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   552
def empty_templatespec():
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   553
    return templatespec(None, None, None)
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   554
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   555
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   556
def reference_templatespec(ref, refargs=None):
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   557
    return templatespec(ref, None, None, refargs)
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   558
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   559
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   560
def literal_templatespec(tmpl):
48888
07a7b57d3e33 formatter: remove conditional assert
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   561
    assert not isinstance(tmpl, str), b'tmpl must not be a str'
45264
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   562
    return templatespec(b'', tmpl, None)
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   563
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   564
45310
f3481e4fcc3a templater: pass opened file-like object to templatespec
Martin von Zweigbergk <martinvonz@google.com>
parents: 45309
diff changeset
   565
def mapfile_templatespec(topic, mapfile, fp=None):
f3481e4fcc3a templater: pass opened file-like object to templatespec
Martin von Zweigbergk <martinvonz@google.com>
parents: 45309
diff changeset
   566
    return templatespec(topic, None, mapfile, fp=fp)
45264
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   567
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   568
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   569
def lookuptemplate(ui, topic, tmpl):
32835
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32833
diff changeset
   570
    """Find the template matching the given -T/--template spec 'tmpl'
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32833
diff changeset
   571
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32833
diff changeset
   572
    'tmpl' can be any of the following:
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32833
diff changeset
   573
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32833
diff changeset
   574
     - a literal template (e.g. '{rev}')
43100
90b9a7e06c2c formatter: parse name of built-in formatter templates in standard way
Yuya Nishihara <yuya@tcha.org>
parents: 43099
diff changeset
   575
     - a reference to built-in template (i.e. formatter)
32835
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32833
diff changeset
   576
     - a map-file name or path (e.g. 'changelog')
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32833
diff changeset
   577
     - a reference to [templates] in config file
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32833
diff changeset
   578
     - a path to raw template file
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32833
diff changeset
   579
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32833
diff changeset
   580
    A map file defines a stand-alone template environment. If a map file
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32833
diff changeset
   581
    selected, all templates defined in the file will be loaded, and the
34715
f17a0e18c47e templater: load aliases from [templatealias] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34425
diff changeset
   582
    template matching the given topic will be rendered. Aliases won't be
f17a0e18c47e templater: load aliases from [templatealias] section in map file
Yuya Nishihara <yuya@tcha.org>
parents: 34425
diff changeset
   583
    loaded from user config, but from the map file.
32875
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 32873
diff changeset
   584
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 32873
diff changeset
   585
    If no map file selected, all templates in [templates] section will be
c8f2cf18b82e formatter: load templates section like a map file
Yuya Nishihara <yuya@tcha.org>
parents: 32873
diff changeset
   586
    available as well as aliases in [templatealias].
32835
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32833
diff changeset
   587
    """
9d76812f9b0b formatter: document lookuptemplate()
Yuya Nishihara <yuya@tcha.org>
parents: 32833
diff changeset
   588
43100
90b9a7e06c2c formatter: parse name of built-in formatter templates in standard way
Yuya Nishihara <yuya@tcha.org>
parents: 43099
diff changeset
   589
    if not tmpl:
45264
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   590
        return empty_templatespec()
43100
90b9a7e06c2c formatter: parse name of built-in formatter templates in standard way
Yuya Nishihara <yuya@tcha.org>
parents: 43099
diff changeset
   591
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   592
    # looks like a literal template?
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   593
    if b'{' in tmpl:
45264
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   594
        return literal_templatespec(tmpl)
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   595
43100
90b9a7e06c2c formatter: parse name of built-in formatter templates in standard way
Yuya Nishihara <yuya@tcha.org>
parents: 43099
diff changeset
   596
    # a reference to built-in (formatter) template
90b9a7e06c2c formatter: parse name of built-in formatter templates in standard way
Yuya Nishihara <yuya@tcha.org>
parents: 43099
diff changeset
   597
    if tmpl in {b'cbor', b'json', b'pickle', b'debug'}:
45264
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   598
        return reference_templatespec(tmpl)
43100
90b9a7e06c2c formatter: parse name of built-in formatter templates in standard way
Yuya Nishihara <yuya@tcha.org>
parents: 43099
diff changeset
   599
43101
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   600
    # a function-style reference to built-in template
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   601
    func, fsep, ftail = tmpl.partition(b'(')
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   602
    if func in {b'cbor', b'json'} and fsep and ftail.endswith(b')'):
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   603
        templater.parseexpr(tmpl)  # make sure syntax errors are confined
45264
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   604
        return reference_templatespec(func, refargs=ftail[:-1])
43101
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   605
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   606
    # perhaps a stock style?
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   607
    if not os.path.split(tmpl)[0]:
45320
4aa484efc926 templater: add exception-raising version of open_template()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45310
diff changeset
   608
        (mapname, fp) = templater.try_open_template(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   609
            b'map-cmdline.' + tmpl
45320
4aa484efc926 templater: add exception-raising version of open_template()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45310
diff changeset
   610
        ) or templater.try_open_template(tmpl)
45260
653b2a439412 formatter: remove now-unnecessary check for file-ness
Martin von Zweigbergk <martinvonz@google.com>
parents: 43337
diff changeset
   611
        if mapname:
45310
f3481e4fcc3a templater: pass opened file-like object to templatespec
Martin von Zweigbergk <martinvonz@google.com>
parents: 45309
diff changeset
   612
            return mapfile_templatespec(topic, mapname, fp)
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   613
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   614
    # perhaps it's a reference to [templates]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   615
    if ui.config(b'templates', tmpl):
45264
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   616
        return reference_templatespec(tmpl)
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   617
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   618
    if tmpl == b'list':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   619
        ui.write(_(b"available styles: %s\n") % templater.stylelist())
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   620
        raise error.Abort(_(b"specify a template"))
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   621
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   622
    # perhaps it's a path to a map or a template
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   623
    if (b'/' in tmpl or b'\\' in tmpl) and os.path.isfile(tmpl):
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   624
        # is it a mapfile for a style?
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   625
        if os.path.basename(tmpl).startswith(b"map-"):
45264
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   626
            return mapfile_templatespec(topic, os.path.realpath(tmpl))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   627
        with util.posixfile(tmpl, b'rb') as f:
32828
526f9f12f707 formatter: close raw template file explicitly
Yuya Nishihara <yuya@tcha.org>
parents: 32581
diff changeset
   628
            tmpl = f.read()
45264
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   629
        return literal_templatespec(tmpl)
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   630
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   631
    # constant string?
45264
8cce9f77ca73 templatespec: create a factory function for each type there is
Martin von Zweigbergk <martinvonz@google.com>
parents: 45262
diff changeset
   632
    return literal_templatespec(tmpl)
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
   633
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   634
32949
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   635
def templatepartsmap(spec, t, partnames):
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   636
    """Create a mapping of {part: ref}"""
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   637
    partsmap = {spec.ref: spec.ref}  # initial ref must exist in t
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   638
    if spec.mapfile:
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   639
        partsmap.update((p, p) for p in partnames if p in t)
32952
61b60b28c381 formatter: add support for parts map of [templates] section
Yuya Nishihara <yuya@tcha.org>
parents: 32950
diff changeset
   640
    elif spec.ref:
61b60b28c381 formatter: add support for parts map of [templates] section
Yuya Nishihara <yuya@tcha.org>
parents: 32950
diff changeset
   641
        for part in partnames:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   642
            ref = b'%s:%s' % (spec.ref, part)  # select config sub-section
32952
61b60b28c381 formatter: add support for parts map of [templates] section
Yuya Nishihara <yuya@tcha.org>
parents: 32950
diff changeset
   643
            if ref in t:
61b60b28c381 formatter: add support for parts map of [templates] section
Yuya Nishihara <yuya@tcha.org>
parents: 32950
diff changeset
   644
                partsmap[part] = ref
32949
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   645
    return partsmap
13eebc189ff3 formatter: add support for docheader and docfooter templates
Yuya Nishihara <yuya@tcha.org>
parents: 32948
diff changeset
   646
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   647
35483
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 35470
diff changeset
   648
def loadtemplater(ui, spec, defaults=None, resources=None, cache=None):
32832
11e667a8fcba formatter: factor out function to create templater from literal or map file
Yuya Nishihara <yuya@tcha.org>
parents: 32830
diff changeset
   649
    """Create a templater from either a literal template or loading from
11e667a8fcba formatter: factor out function to create templater from literal or map file
Yuya Nishihara <yuya@tcha.org>
parents: 32830
diff changeset
   650
    a map file"""
32838
615ec3f14aa9 formatter: wrap (tmpl, mapfile) by named tuple
Yuya Nishihara <yuya@tcha.org>
parents: 32835
diff changeset
   651
    assert not (spec.tmpl and spec.mapfile)
615ec3f14aa9 formatter: wrap (tmpl, mapfile) by named tuple
Yuya Nishihara <yuya@tcha.org>
parents: 32835
diff changeset
   652
    if spec.mapfile:
45262
22eafb16f1c5 formatter: inline a variable assigned from `templater.templater.frommapfile`
Martin von Zweigbergk <martinvonz@google.com>
parents: 45260
diff changeset
   653
        return templater.templater.frommapfile(
45310
f3481e4fcc3a templater: pass opened file-like object to templatespec
Martin von Zweigbergk <martinvonz@google.com>
parents: 45309
diff changeset
   654
            spec.mapfile,
f3481e4fcc3a templater: pass opened file-like object to templatespec
Martin von Zweigbergk <martinvonz@google.com>
parents: 45309
diff changeset
   655
            spec.fp,
f3481e4fcc3a templater: pass opened file-like object to templatespec
Martin von Zweigbergk <martinvonz@google.com>
parents: 45309
diff changeset
   656
            defaults=defaults,
f3481e4fcc3a templater: pass opened file-like object to templatespec
Martin von Zweigbergk <martinvonz@google.com>
parents: 45309
diff changeset
   657
            resources=resources,
f3481e4fcc3a templater: pass opened file-like object to templatespec
Martin von Zweigbergk <martinvonz@google.com>
parents: 45309
diff changeset
   658
            cache=cache,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   659
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   660
    return maketemplater(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   661
        ui, spec.tmpl, defaults=defaults, resources=resources, cache=cache
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   662
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   663
28955
78759f78a44e templater: factor out function that creates templater from string template
Yuya Nishihara <yuya@tcha.org>
parents: 28954
diff changeset
   664
35483
817a3d20dd01 templater: register keywords to defaults table
Yuya Nishihara <yuya@tcha.org>
parents: 35470
diff changeset
   665
def maketemplater(ui, tmpl, defaults=None, resources=None, cache=None):
28955
78759f78a44e templater: factor out function that creates templater from string template
Yuya Nishihara <yuya@tcha.org>
parents: 28954
diff changeset
   666
    """Create a templater from a string template 'tmpl'"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   667
    aliases = ui.configitems(b'templatealias')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   668
    t = templater.templater(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   669
        defaults=defaults, resources=resources, cache=cache, aliases=aliases
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   670
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   671
    t.cache.update(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   672
        (k, templater.unquotestring(v)) for k, v in ui.configitems(b'templates')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   673
    )
25512
8463433c2689 formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents: 25511
diff changeset
   674
    if tmpl:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   675
        t.cache[b''] = tmpl
25512
8463433c2689 formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents: 25511
diff changeset
   676
    return t
8463433c2689 formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents: 25511
diff changeset
   677
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   678
39586
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   679
# marker to denote a resource to be loaded on demand based on mapping values
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   680
# (e.g. (ctx, path) -> fctx)
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   681
_placeholder = object()
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   682
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   683
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
   684
class templateresources(templater.resourcemapper):
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
   685
    """Resource mapper designed for the default templatekw and function"""
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
   686
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
   687
    def __init__(self, ui, repo=None):
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
   688
        self._resmap = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   689
            b'cache': {},  # for templatekw/funcs to store reusable data
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   690
            b'repo': repo,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   691
            b'ui': ui,
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
   692
        }
35469
f1c54d003327 templater: move repo, ui and cache to per-engine resources
Yuya Nishihara <yuya@tcha.org>
parents: 35468
diff changeset
   693
39582
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38446
diff changeset
   694
    def availablekeys(self, mapping):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   695
        return {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   696
            k for k in self.knownkeys() if self._getsome(mapping, k) is not None
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   697
        }
37075
46859b437697 templater: drop symbols which should be overridden by new 'ctx' (issue5612)
Yuya Nishihara <yuya@tcha.org>
parents: 37073
diff changeset
   698
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
   699
    def knownkeys(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   700
        return {b'cache', b'ctx', b'fctx', b'repo', b'revcache', b'ui'}
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
   701
39582
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38446
diff changeset
   702
    def lookup(self, mapping, key):
39584
109b2c2d9942 formatter: inline _gettermap and _knownkeys
Yuya Nishihara <yuya@tcha.org>
parents: 39583
diff changeset
   703
        if key not in self.knownkeys():
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
   704
            return None
39586
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   705
        v = self._getsome(mapping, key)
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   706
        if v is _placeholder:
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   707
            v = mapping[key] = self._loadermap[key](self, mapping)
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   708
        return v
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
   709
37102
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37075
diff changeset
   710
    def populatemap(self, context, origmapping, newmapping):
37103
be3f33f5e232 templater: switch 'revcache' based on new mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37102
diff changeset
   711
        mapping = {}
39585
990a0b071ea5 formatter: factor out function that detects node change and document it
Yuya Nishihara <yuya@tcha.org>
parents: 39584
diff changeset
   712
        if self._hasnodespec(newmapping):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   713
            mapping[b'revcache'] = {}  # per-ctx cache
39585
990a0b071ea5 formatter: factor out function that detects node change and document it
Yuya Nishihara <yuya@tcha.org>
parents: 39584
diff changeset
   714
        if self._hasnodespec(origmapping) and self._hasnodespec(newmapping):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   715
            orignode = templateutil.runsymbol(context, origmapping, b'node')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   716
            mapping[b'originalnode'] = orignode
39623
34ecc0a09c76 formatter: populate ctx from repo and node value
Yuya Nishihara <yuya@tcha.org>
parents: 39586
diff changeset
   717
        # put marker to override 'ctx'/'fctx' in mapping if any, and flag
39586
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   718
        # its existence to be reported by availablekeys()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   719
        if b'ctx' not in newmapping and self._hasliteral(newmapping, b'node'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   720
            mapping[b'ctx'] = _placeholder
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   721
        if b'fctx' not in newmapping and self._hasliteral(newmapping, b'path'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   722
            mapping[b'fctx'] = _placeholder
37103
be3f33f5e232 templater: switch 'revcache' based on new mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37102
diff changeset
   723
        return mapping
37102
638a241202a3 templater: add hook point to populate additional mapping items
Yuya Nishihara <yuya@tcha.org>
parents: 37075
diff changeset
   724
39582
28f974d83c0a templater: remove unused context argument from most resourcemapper functions
Yuya Nishihara <yuya@tcha.org>
parents: 38446
diff changeset
   725
    def _getsome(self, mapping, key):
36983
036e4483d3a1 templater: process mapping dict by resource callables
Yuya Nishihara <yuya@tcha.org>
parents: 36982
diff changeset
   726
        v = mapping.get(key)
036e4483d3a1 templater: process mapping dict by resource callables
Yuya Nishihara <yuya@tcha.org>
parents: 36982
diff changeset
   727
        if v is not None:
036e4483d3a1 templater: process mapping dict by resource callables
Yuya Nishihara <yuya@tcha.org>
parents: 36982
diff changeset
   728
            return v
37073
44757e6dad93 templater: introduce resourcemapper class
Yuya Nishihara <yuya@tcha.org>
parents: 36989
diff changeset
   729
        return self._resmap.get(key)
36982
255f635c3204 templater: convert resources to a table of callables for future extension
Yuya Nishihara <yuya@tcha.org>
parents: 36921
diff changeset
   730
39586
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   731
    def _hasliteral(self, mapping, key):
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   732
        """Test if a literal value is set or unset in the given mapping"""
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   733
        return key in mapping and not callable(mapping[key])
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   734
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   735
    def _getliteral(self, mapping, key):
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   736
        """Return value of the given name if it is a literal"""
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   737
        v = mapping.get(key)
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   738
        if callable(v):
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   739
            return None
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   740
        return v
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   741
39585
990a0b071ea5 formatter: factor out function that detects node change and document it
Yuya Nishihara <yuya@tcha.org>
parents: 39584
diff changeset
   742
    def _hasnodespec(self, mapping):
990a0b071ea5 formatter: factor out function that detects node change and document it
Yuya Nishihara <yuya@tcha.org>
parents: 39584
diff changeset
   743
        """Test if context revision is set or unset in the given mapping"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   744
        return b'node' in mapping or b'ctx' in mapping
36984
939e0983c1d9 formatter: unblock storing fctx as a template resource
Yuya Nishihara <yuya@tcha.org>
parents: 36983
diff changeset
   745
39623
34ecc0a09c76 formatter: populate ctx from repo and node value
Yuya Nishihara <yuya@tcha.org>
parents: 39586
diff changeset
   746
    def _loadctx(self, mapping):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   747
        repo = self._getsome(mapping, b'repo')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   748
        node = self._getliteral(mapping, b'node')
39623
34ecc0a09c76 formatter: populate ctx from repo and node value
Yuya Nishihara <yuya@tcha.org>
parents: 39586
diff changeset
   749
        if repo is None or node is None:
34ecc0a09c76 formatter: populate ctx from repo and node value
Yuya Nishihara <yuya@tcha.org>
parents: 39586
diff changeset
   750
            return
34ecc0a09c76 formatter: populate ctx from repo and node value
Yuya Nishihara <yuya@tcha.org>
parents: 39586
diff changeset
   751
        try:
34ecc0a09c76 formatter: populate ctx from repo and node value
Yuya Nishihara <yuya@tcha.org>
parents: 39586
diff changeset
   752
            return repo[node]
34ecc0a09c76 formatter: populate ctx from repo and node value
Yuya Nishihara <yuya@tcha.org>
parents: 39586
diff changeset
   753
        except error.RepoLookupError:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   754
            return None  # maybe hidden/non-existent node
39623
34ecc0a09c76 formatter: populate ctx from repo and node value
Yuya Nishihara <yuya@tcha.org>
parents: 39586
diff changeset
   755
39586
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   756
    def _loadfctx(self, mapping):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   757
        ctx = self._getsome(mapping, b'ctx')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   758
        path = self._getliteral(mapping, b'path')
39586
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   759
        if ctx is None or path is None:
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   760
            return None
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   761
        try:
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   762
            return ctx[path]
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   763
        except error.LookupError:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   764
            return None  # maybe removed file?
39586
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   765
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   766
    _loadermap = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   767
        b'ctx': _loadctx,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   768
        b'fctx': _loadfctx,
39586
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   769
    }
b1239aeef4d9 formatter: populate fctx from ctx and path value
Yuya Nishihara <yuya@tcha.org>
parents: 39585
diff changeset
   770
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   771
43101
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   772
def _internaltemplateformatter(
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   773
    ui,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   774
    out,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   775
    topic,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   776
    opts,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   777
    spec,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   778
    tmpl,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   779
    docheader=b'',
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   780
    docfooter=b'',
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   781
    separator=b'',
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   782
):
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   783
    """Build template formatter that handles customizable built-in templates
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   784
    such as -Tjson(...)"""
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   785
    templates = {spec.ref: tmpl}
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   786
    if docheader:
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   787
        templates[b'%s:docheader' % spec.ref] = docheader
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   788
    if docfooter:
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   789
        templates[b'%s:docfooter' % spec.ref] = docfooter
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   790
    if separator:
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   791
        templates[b'%s:separator' % spec.ref] = separator
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   792
    return templateformatter(
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   793
        ui, out, topic, opts, spec, overridetemplates=templates
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   794
    )
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   795
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   796
32579
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   797
def formatter(ui, out, topic, opts):
43100
90b9a7e06c2c formatter: parse name of built-in formatter templates in standard way
Yuya Nishihara <yuya@tcha.org>
parents: 43099
diff changeset
   798
    spec = lookuptemplate(ui, topic, opts.get(b'template', b''))
43101
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   799
    if spec.ref == b"cbor" and spec.refargs is not None:
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   800
        return _internaltemplateformatter(
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   801
            ui,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   802
            out,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   803
            topic,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   804
            opts,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   805
            spec,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   806
            tmpl=b'{dict(%s)|cbor}' % spec.refargs,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   807
            docheader=cborutil.BEGIN_INDEFINITE_ARRAY,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   808
            docfooter=cborutil.BREAK,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   809
        )
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   810
    elif spec.ref == b"cbor":
41996
77ef3498ceb3 template: add CBOR output format
Yuya Nishihara <yuya@tcha.org>
parents: 40277
diff changeset
   811
        return cborformatter(ui, out, topic, opts)
43101
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   812
    elif spec.ref == b"json" and spec.refargs is not None:
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   813
        return _internaltemplateformatter(
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   814
            ui,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   815
            out,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   816
            topic,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   817
            opts,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   818
            spec,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   819
            tmpl=b'{dict(%s)|json}' % spec.refargs,
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   820
            docheader=b'[\n ',
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   821
            docfooter=b'\n]\n',
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   822
            separator=b',\n ',
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   823
        )
43100
90b9a7e06c2c formatter: parse name of built-in formatter templates in standard way
Yuya Nishihara <yuya@tcha.org>
parents: 43099
diff changeset
   824
    elif spec.ref == b"json":
32579
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   825
        return jsonformatter(ui, out, topic, opts)
43100
90b9a7e06c2c formatter: parse name of built-in formatter templates in standard way
Yuya Nishihara <yuya@tcha.org>
parents: 43099
diff changeset
   826
    elif spec.ref == b"pickle":
43101
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   827
        assert spec.refargs is None, r'function-style not supported'
32579
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   828
        return pickleformatter(ui, out, topic, opts)
43100
90b9a7e06c2c formatter: parse name of built-in formatter templates in standard way
Yuya Nishihara <yuya@tcha.org>
parents: 43099
diff changeset
   829
    elif spec.ref == b"debug":
43101
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   830
        assert spec.refargs is None, r'function-style not supported'
32579
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   831
        return debugformatter(ui, out, topic, opts)
43100
90b9a7e06c2c formatter: parse name of built-in formatter templates in standard way
Yuya Nishihara <yuya@tcha.org>
parents: 43099
diff changeset
   832
    elif spec.ref or spec.tmpl or spec.mapfile:
43101
1d12ae5096d1 formatter: map -Tjson(...) and -Tcbor(...) to templater
Yuya Nishihara <yuya@tcha.org>
parents: 43100
diff changeset
   833
        assert spec.refargs is None, r'function-style not supported'
43099
f1c5358f0d65 formatter: pass in template spec to templateformatter as argument
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   834
        return templateformatter(ui, out, topic, opts, spec)
25838
31137258ae8b formatter: mark developer options
Matt Mackall <mpm@selenic.com>
parents: 25513
diff changeset
   835
    # developer config: ui.formatdebug
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   836
    elif ui.configbool(b'ui', b'formatdebug'):
32579
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   837
        return debugformatter(ui, out, topic, opts)
25838
31137258ae8b formatter: mark developer options
Matt Mackall <mpm@selenic.com>
parents: 25513
diff changeset
   838
    # deprecated config: ui.formatjson
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   839
    elif ui.configbool(b'ui', b'formatjson'):
32579
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   840
        return jsonformatter(ui, out, topic, opts)
012e0da5b759 formatter: add option to redirect output to file object
Yuya Nishihara <yuya@tcha.org>
parents: 32159
diff changeset
   841
    return plainformatter(ui, out, topic, opts)
32580
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   842
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   843
32580
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   844
@contextlib.contextmanager
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   845
def openformatter(ui, filename, topic, opts):
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   846
    """Create a formatter that writes outputs to the specified file
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   847
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   848
    Must be invoked using the 'with' statement.
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   849
    """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   850
    with util.posixfile(filename, b'wb') as out:
32580
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   851
        with formatter(ui, out, topic, opts) as fm:
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   852
            yield fm
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   853
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   854
32580
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   855
@contextlib.contextmanager
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   856
def _neverending(fm):
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   857
    yield fm
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   858
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41996
diff changeset
   859
37597
d110167610db formatter: carry opts to file-based formatters by basefm
Yuya Nishihara <yuya@tcha.org>
parents: 37596
diff changeset
   860
def maybereopen(fm, filename):
32580
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   861
    """Create a formatter backed by file if filename specified, else return
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   862
    the given formatter
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   863
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   864
    Must be invoked using the 'with' statement. This will never call fm.end()
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   865
    of the given formatter.
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   866
    """
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   867
    if filename:
37597
d110167610db formatter: carry opts to file-based formatters by basefm
Yuya Nishihara <yuya@tcha.org>
parents: 37596
diff changeset
   868
        return openformatter(fm._ui, filename, fm._topic, fm._opts)
32580
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   869
    else:
35985d407d49 formatter: add helper to create a formatter optionally backed by file
Yuya Nishihara <yuya@tcha.org>
parents: 32579
diff changeset
   870
        return _neverending(fm)