mercurial/formatter.py
author Mads Kiilerich <madski@unity3d.com>
Thu, 06 Nov 2014 01:48:29 +0100
changeset 23233 c1f370dab456
parent 22701 cb28d2b3db0b
child 24321 0a714a1f7d5c
permissions -rw-r--r--
discovery: test coverage for issue4438 / 86c35b7ae300 / 73cfaa348650 The randomness in the discovery protocol made this problem hard to reproduce. The test mocks random.sample to make sure we hit the problem every time. The set iteration order also made the output unstable ... but with the issue fixed, it is stable.
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
#
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2012 Matt Mackall <mpm@selenic.com>
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
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
     8
import cPickle
22701
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
     9
from node import hex, short
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
    10
from i18n import _
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
    11
import encoding, util
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
    12
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
class baseformatter(object):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    14
    def __init__(self, ui, topic, opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
        self._ui = ui
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    16
        self._topic = topic
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
        self._style = opts.get("style")
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
        self._template = opts.get("template")
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
        self._item = None
22701
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
    20
        # 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
    21
        self.hexfunc = hex
22447
2642ce9be6ef formatter: correct bool testing which should be __nonzero__ in Python 2
Yuya Nishihara <yuya@tcha.org>
parents: 22430
diff changeset
    22
    def __nonzero__(self):
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
        '''return False if we're not doing real templating so we can
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
        skip extra work'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
        return True
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
    def _showitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    27
        '''show a formatted item once all data is collected'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    28
        pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    29
    def startitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
        '''begin an item in the format list'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    31
        if self._item is not None:
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
            self._showitem()
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    33
        self._item = {}
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
    def data(self, **data):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
        '''insert data into item that's not shown in default output'''
17630
ff5ed1ecd43a formatter: improve implementation of data method
David M. Carr <david@carrclan.us>
parents: 17597
diff changeset
    36
        self._item.update(data)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
    def write(self, fields, deftext, *fielddata, **opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
        '''do default text output while assigning data to item'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    39
        for k, v in zip(fields.split(), fielddata):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    40
            self._item[k] = v
17909
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
    41
    def condwrite(self, cond, fields, deftext, *fielddata, **opts):
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
    42
        '''do conditional write (primarily for plain formatter)'''
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
    43
        for k, v in zip(fields.split(), fielddata):
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
    44
            self._item[k] = v
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
    def plain(self, text, **opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
        '''show raw text for non-templated mode'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
        pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
    def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    49
        '''end output for the formatter'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
        if self._item is not None:
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
            self._showitem()
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    52
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
class plainformatter(baseformatter):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    54
    '''the default text output scheme'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    55
    def __init__(self, ui, topic, opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    56
        baseformatter.__init__(self, ui, topic, opts)
22701
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
    57
        if ui.debugflag:
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
    58
            self.hexfunc = hex
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
    59
        else:
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
    60
            self.hexfunc = short
22447
2642ce9be6ef formatter: correct bool testing which should be __nonzero__ in Python 2
Yuya Nishihara <yuya@tcha.org>
parents: 22430
diff changeset
    61
    def __nonzero__(self):
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
        return False
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
    def startitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
        pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
    def data(self, **data):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
        pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
    def write(self, fields, deftext, *fielddata, **opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
        self._ui.write(deftext % fielddata, **opts)
17909
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
    69
    def condwrite(self, cond, fields, deftext, *fielddata, **opts):
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
    70
        '''do conditional write'''
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
    71
        if cond:
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
    72
            self._ui.write(deftext % fielddata, **opts)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
    def plain(self, text, **opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    74
        self._ui.write(text, **opts)
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
    def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
        pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    77
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    78
class debugformatter(baseformatter):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    79
    def __init__(self, ui, topic, opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
        baseformatter.__init__(self, ui, topic, opts)
22424
1f72226064b8 formatter: make debug style match Python syntax
Matt Mackall <mpm@selenic.com>
parents: 17909
diff changeset
    81
        self._ui.write("%s = [\n" % self._topic)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    82
    def _showitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    83
        self._ui.write("    " + repr(self._item) + ",\n")
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    84
    def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
        baseformatter.end(self)
22424
1f72226064b8 formatter: make debug style match Python syntax
Matt Mackall <mpm@selenic.com>
parents: 17909
diff changeset
    86
        self._ui.write("]\n")
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    87
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
    88
class pickleformatter(baseformatter):
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
    89
    def __init__(self, ui, topic, opts):
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
    90
        baseformatter.__init__(self, ui, topic, opts)
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
    91
        self._data = []
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
    92
    def _showitem(self):
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
    93
        self._data.append(self._item)
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
    94
    def end(self):
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
    95
        baseformatter.end(self)
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
    96
        self._ui.write(cPickle.dumps(self._data))
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
    97
22474
9da0ef363861 formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents: 22447
diff changeset
    98
def _jsonifyobj(v):
22475
17eeda31e52b formatter: have jsonformatter accept tuple as value
Yuya Nishihara <yuya@tcha.org>
parents: 22474
diff changeset
    99
    if isinstance(v, tuple):
17eeda31e52b formatter: have jsonformatter accept tuple as value
Yuya Nishihara <yuya@tcha.org>
parents: 22474
diff changeset
   100
        return '[' + ', '.join(_jsonifyobj(e) for e in v) + ']'
22674
06c8b58647b9 formatter: convert booleans to json
Yuya Nishihara <yuya@tcha.org>
parents: 22476
diff changeset
   101
    elif v is True:
06c8b58647b9 formatter: convert booleans to json
Yuya Nishihara <yuya@tcha.org>
parents: 22476
diff changeset
   102
        return 'true'
06c8b58647b9 formatter: convert booleans to json
Yuya Nishihara <yuya@tcha.org>
parents: 22476
diff changeset
   103
    elif v is False:
06c8b58647b9 formatter: convert booleans to json
Yuya Nishihara <yuya@tcha.org>
parents: 22476
diff changeset
   104
        return 'false'
22476
a0829ec34dbd formatter: convert float value to json
Yuya Nishihara <yuya@tcha.org>
parents: 22475
diff changeset
   105
    elif isinstance(v, (int, float)):
a0829ec34dbd formatter: convert float value to json
Yuya Nishihara <yuya@tcha.org>
parents: 22475
diff changeset
   106
        return str(v)
22474
9da0ef363861 formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents: 22447
diff changeset
   107
    else:
9da0ef363861 formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents: 22447
diff changeset
   108
        return '"%s"' % encoding.jsonescape(v)
9da0ef363861 formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents: 22447
diff changeset
   109
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   110
class jsonformatter(baseformatter):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   111
    def __init__(self, ui, topic, opts):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   112
        baseformatter.__init__(self, ui, topic, opts)
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   113
        self._ui.write("[")
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   114
        self._ui._first = True
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   115
    def _showitem(self):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   116
        if self._ui._first:
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   117
            self._ui._first = False
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   118
        else:
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   119
            self._ui.write(",")
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   120
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   121
        self._ui.write("\n {\n")
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   122
        first = True
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   123
        for k, v in sorted(self._item.items()):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   124
            if first:
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   125
                first = False
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   126
            else:
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   127
                self._ui.write(",\n")
22474
9da0ef363861 formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents: 22447
diff changeset
   128
            self._ui.write('  "%s": %s' % (k, _jsonifyobj(v)))
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   129
        self._ui.write("\n }")
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   130
    def end(self):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   131
        baseformatter.end(self)
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   132
        self._ui.write("\n]\n")
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   133
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   134
def formatter(ui, topic, opts):
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   135
    template = opts.get("template", "")
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   136
    if template == "json":
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   137
        return jsonformatter(ui, topic, opts)
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   138
    elif template == "pickle":
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
   139
        return pickleformatter(ui, topic, opts)
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   140
    elif template == "debug":
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   141
        return debugformatter(ui, topic, opts)
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   142
    elif template != "":
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   143
        raise util.Abort(_("custom templates not yet supported"))
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   144
    elif ui.configbool('ui', 'formatdebug'):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   145
        return debugformatter(ui, topic, opts)
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   146
    elif ui.configbool('ui', 'formatjson'):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
   147
        return jsonformatter(ui, topic, opts)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   148
    return plainformatter(ui, topic, opts)