annotate mercurial/formatter.py @ 29690:c3a9cd78b151

formatter: add function to convert list to appropriate format (issue5217) Before, it wasn't possible for formatter to handle array structure other than date tuple. We've discussed that at the last sprint, which ended we would probably want to allow only templatable data structure, i.e. a list of dicts: data(tags=[{'tag': a}, {'tag': b}, ...]) Unfortunately, it turned out not working well with template functions: "{ifcontains(a, tags, ...)}" ^^^^^^^^^^^^^^^^^^ "a in tags", where tags should be a plain list/set of tags So the formatter must at least know if the type [{}] was constructed from a plain list or was actually a list of dicts. This patch introduces new explicit interface to convert an array structure to an appropriate data type for the current formatter, which can be used as follows: fm.write('tags', _('tags: %s\n'), fm.formatlist(tags, name='tag')) No separate fm.data() call should be necessary.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 10 Jul 2016 21:03:06 +0900
parents b501579147f1
children 2f3f18ad55a2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
8 from __future__ import absolute_import
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
9
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
10 import os
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
11
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
12 from .i18n import _
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
13 from .node import (
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
14 hex,
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
15 short,
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
16 )
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
17
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
18 from . import (
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
19 encoding,
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26373
diff changeset
20 error,
29690
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
21 templatekw,
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
22 templater,
29324
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28957
diff changeset
23 util,
25950
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
24 )
175873e36d03 formatter: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25838
diff changeset
25
29324
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28957
diff changeset
26 pickle = util.pickle
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28957
diff changeset
27
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
28 class baseformatter(object):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
29 def __init__(self, ui, topic, opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
30 self._ui = ui
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
31 self._topic = topic
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
32 self._style = opts.get("style")
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
33 self._template = opts.get("template")
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
34 self._item = None
22701
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
35 # 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
36 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
37 def __nonzero__(self):
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
38 '''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
39 skip extra work'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
40 return True
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
41 def _showitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
42 '''show a formatted item once all data is collected'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
43 pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
44 def startitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
45 '''begin an item in the format list'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
46 if self._item is not None:
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
47 self._showitem()
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
48 self._item = {}
29690
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
49 @staticmethod
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
50 def formatlist(data, name, fmt='%s', sep=' '):
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
51 '''convert iterable to appropriate list format'''
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
52 return list(data)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
53 def data(self, **data):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
54 '''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
55 self._item.update(data)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
56 def write(self, fields, deftext, *fielddata, **opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
57 '''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
58 fieldkeys = fields.split()
55de800937e0 formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 25950
diff changeset
59 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
60 self._item.update(zip(fieldkeys, fielddata))
17909
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
61 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
62 '''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
63 fieldkeys = fields.split()
55de800937e0 formatter: verify number of arguments passed to write functions
Yuya Nishihara <yuya@tcha.org>
parents: 25950
diff changeset
64 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
65 self._item.update(zip(fieldkeys, fielddata))
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
66 def plain(self, text, **opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
67 '''show raw text for non-templated mode'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
68 pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
69 def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
70 '''end output for the formatter'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
71 if self._item is not None:
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
72 self._showitem()
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
73
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
74 class plainformatter(baseformatter):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
75 '''the default text output scheme'''
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
76 def __init__(self, ui, topic, opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
77 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
78 if ui.debugflag:
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
79 self.hexfunc = hex
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
80 else:
cb28d2b3db0b formatter: add general way to switch hex/short functions
Yuya Nishihara <yuya@tcha.org>
parents: 22674
diff changeset
81 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
82 def __nonzero__(self):
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
83 return False
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
84 def startitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
85 pass
29690
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
86 @staticmethod
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
87 def formatlist(data, name, fmt='%s', sep=' '):
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
88 '''stringify iterable separated by sep'''
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
89 return sep.join(fmt % e for e in data)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
90 def data(self, **data):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
91 pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
92 def write(self, fields, deftext, *fielddata, **opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
93 self._ui.write(deftext % fielddata, **opts)
17909
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
94 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
95 '''do conditional write'''
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
96 if cond:
3326fd05eb1f formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents: 17630
diff changeset
97 self._ui.write(deftext % fielddata, **opts)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
98 def plain(self, text, **opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
99 self._ui.write(text, **opts)
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
100 def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
101 pass
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
102
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
103 class debugformatter(baseformatter):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
104 def __init__(self, ui, topic, opts):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
105 baseformatter.__init__(self, ui, topic, opts)
22424
1f72226064b8 formatter: make debug style match Python syntax
Matt Mackall <mpm@selenic.com>
parents: 17909
diff changeset
106 self._ui.write("%s = [\n" % self._topic)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
107 def _showitem(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
108 self._ui.write(" " + repr(self._item) + ",\n")
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
109 def end(self):
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
110 baseformatter.end(self)
22424
1f72226064b8 formatter: make debug style match Python syntax
Matt Mackall <mpm@selenic.com>
parents: 17909
diff changeset
111 self._ui.write("]\n")
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
112
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
113 class pickleformatter(baseformatter):
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
114 def __init__(self, ui, topic, opts):
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
115 baseformatter.__init__(self, ui, topic, opts)
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
116 self._data = []
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
117 def _showitem(self):
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
118 self._data.append(self._item)
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
119 def end(self):
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
120 baseformatter.end(self)
29324
b501579147f1 py3: conditionalize cPickle import by adding in util
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28957
diff changeset
121 self._ui.write(pickle.dumps(self._data))
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
122
22474
9da0ef363861 formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents: 22447
diff changeset
123 def _jsonifyobj(v):
29690
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
124 if isinstance(v, (list, tuple)):
22475
17eeda31e52b formatter: have jsonformatter accept tuple as value
Yuya Nishihara <yuya@tcha.org>
parents: 22474
diff changeset
125 return '[' + ', '.join(_jsonifyobj(e) for e in v) + ']'
24321
0a714a1f7d5c formatter: convert None to json null
Yuya Nishihara <yuya@tcha.org>
parents: 22701
diff changeset
126 elif v is None:
0a714a1f7d5c formatter: convert None to json null
Yuya Nishihara <yuya@tcha.org>
parents: 22701
diff changeset
127 return 'null'
22674
06c8b58647b9 formatter: convert booleans to json
Yuya Nishihara <yuya@tcha.org>
parents: 22476
diff changeset
128 elif v is True:
06c8b58647b9 formatter: convert booleans to json
Yuya Nishihara <yuya@tcha.org>
parents: 22476
diff changeset
129 return 'true'
06c8b58647b9 formatter: convert booleans to json
Yuya Nishihara <yuya@tcha.org>
parents: 22476
diff changeset
130 elif v is False:
06c8b58647b9 formatter: convert booleans to json
Yuya Nishihara <yuya@tcha.org>
parents: 22476
diff changeset
131 return 'false'
22476
a0829ec34dbd formatter: convert float value to json
Yuya Nishihara <yuya@tcha.org>
parents: 22475
diff changeset
132 elif isinstance(v, (int, float)):
a0829ec34dbd formatter: convert float value to json
Yuya Nishihara <yuya@tcha.org>
parents: 22475
diff changeset
133 return str(v)
22474
9da0ef363861 formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents: 22447
diff changeset
134 else:
9da0ef363861 formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents: 22447
diff changeset
135 return '"%s"' % encoding.jsonescape(v)
9da0ef363861 formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents: 22447
diff changeset
136
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
137 class jsonformatter(baseformatter):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
138 def __init__(self, ui, topic, opts):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
139 baseformatter.__init__(self, ui, topic, opts)
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
140 self._ui.write("[")
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
141 self._ui._first = True
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
142 def _showitem(self):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
143 if self._ui._first:
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
144 self._ui._first = False
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
145 else:
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
146 self._ui.write(",")
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
147
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
148 self._ui.write("\n {\n")
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
149 first = True
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
150 for k, v in sorted(self._item.items()):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
151 if first:
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
152 first = False
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
153 else:
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
154 self._ui.write(",\n")
22474
9da0ef363861 formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents: 22447
diff changeset
155 self._ui.write(' "%s": %s' % (k, _jsonifyobj(v)))
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
156 self._ui.write("\n }")
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
157 def end(self):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
158 baseformatter.end(self)
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
159 self._ui.write("\n]\n")
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
160
25513
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
161 class templateformatter(baseformatter):
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
162 def __init__(self, ui, topic, opts):
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
163 baseformatter.__init__(self, ui, topic, opts)
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
164 self._topic = topic
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
165 self._t = gettemplater(ui, topic, opts.get('template', ''))
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
166 def _showitem(self):
28384
3356bf61fa25 formatter: make labels work with templated output
Kostia Balytskyi <ikostia@fb.com>
parents: 26587
diff changeset
167 g = self._t(self._topic, ui=self._ui, **self._item)
25513
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
168 self._ui.write(templater.stringify(g))
29690
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
169 @staticmethod
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
170 def formatlist(data, name, fmt='%s', sep=' '):
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
171 '''build object that can be evaluated as either plain string or list'''
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
172 # name is mandatory argument for now, but it could be optional if
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
173 # we have default template keyword, e.g. {item}
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
174 data = list(data)
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
175 def f():
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
176 yield plainformatter.formatlist(data, name, fmt, sep)
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
177 return templatekw._hybrid(f(), data, lambda x: {name: x},
c3a9cd78b151 formatter: add function to convert list to appropriate format (issue5217)
Yuya Nishihara <yuya@tcha.org>
parents: 29324
diff changeset
178 lambda d: fmt % d[name])
25513
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
179
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
180 def lookuptemplate(ui, topic, tmpl):
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
181 # looks like a literal template?
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
182 if '{' in tmpl:
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
183 return tmpl, None
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
184
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
185 # perhaps a stock style?
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
186 if not os.path.split(tmpl)[0]:
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
187 mapname = (templater.templatepath('map-cmdline.' + tmpl)
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
188 or templater.templatepath(tmpl))
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
189 if mapname and os.path.isfile(mapname):
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
190 return None, mapname
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
191
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
192 # perhaps it's a reference to [templates]
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
193 t = ui.config('templates', tmpl)
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
194 if t:
28630
bf35644b9f3a templater: relax unquotestring() to fall back to bare string
Yuya Nishihara <yuya@tcha.org>
parents: 28384
diff changeset
195 return templater.unquotestring(t), None
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
196
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
197 if tmpl == 'list':
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
198 ui.write(_("available styles: %s\n") % templater.stylelist())
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26373
diff changeset
199 raise error.Abort(_("specify a template"))
25511
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
200
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
201 # perhaps it's a path to a map or a template
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
202 if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl):
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
203 # is it a mapfile for a style?
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
204 if os.path.basename(tmpl).startswith("map-"):
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
205 return None, os.path.realpath(tmpl)
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
206 tmpl = open(tmpl).read()
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
207 return tmpl, None
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
208
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
209 # constant string?
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
210 return tmpl, None
c2a4dfe2a336 formatter: move most of template option helper to formatter
Matt Mackall <mpm@selenic.com>
parents: 24321
diff changeset
211
25512
8463433c2689 formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents: 25511
diff changeset
212 def gettemplater(ui, topic, spec):
8463433c2689 formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents: 25511
diff changeset
213 tmpl, mapfile = lookuptemplate(ui, topic, spec)
28954
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 28630
diff changeset
214 assert not (tmpl and mapfile)
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 28630
diff changeset
215 if mapfile:
f97a0bcfd7a1 templater: separate function to create templater from map file (API)
Yuya Nishihara <yuya@tcha.org>
parents: 28630
diff changeset
216 return templater.templater.frommapfile(mapfile)
28955
78759f78a44e templater: factor out function that creates templater from string template
Yuya Nishihara <yuya@tcha.org>
parents: 28954
diff changeset
217 return maketemplater(ui, topic, tmpl)
78759f78a44e templater: factor out function that creates templater from string template
Yuya Nishihara <yuya@tcha.org>
parents: 28954
diff changeset
218
78759f78a44e templater: factor out function that creates templater from string template
Yuya Nishihara <yuya@tcha.org>
parents: 28954
diff changeset
219 def maketemplater(ui, topic, tmpl, filters=None, cache=None):
78759f78a44e templater: factor out function that creates templater from string template
Yuya Nishihara <yuya@tcha.org>
parents: 28954
diff changeset
220 """Create a templater from a string template 'tmpl'"""
28957
d813132ea361 templater: load and expand aliases by template engine (API) (issue4842)
Yuya Nishihara <yuya@tcha.org>
parents: 28955
diff changeset
221 aliases = ui.configitems('templatealias')
d813132ea361 templater: load and expand aliases by template engine (API) (issue4842)
Yuya Nishihara <yuya@tcha.org>
parents: 28955
diff changeset
222 t = templater.templater(filters=filters, cache=cache, aliases=aliases)
25512
8463433c2689 formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents: 25511
diff changeset
223 if tmpl:
8463433c2689 formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents: 25511
diff changeset
224 t.cache[topic] = tmpl
8463433c2689 formatter: add a method to build a full templater from a -T option
Matt Mackall <mpm@selenic.com>
parents: 25511
diff changeset
225 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
226
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
227 def formatter(ui, topic, opts):
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
228 template = opts.get("template", "")
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
229 if template == "json":
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
230 return jsonformatter(ui, topic, opts)
22430
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
231 elif template == "pickle":
968247e8f4ac formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents: 22428
diff changeset
232 return pickleformatter(ui, topic, opts)
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
233 elif template == "debug":
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
234 return debugformatter(ui, topic, opts)
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
235 elif template != "":
25513
0c6f98398f8a formatter: add template support
Matt Mackall <mpm@selenic.com>
parents: 25512
diff changeset
236 return templateformatter(ui, topic, opts)
25838
31137258ae8b formatter: mark developer options
Matt Mackall <mpm@selenic.com>
parents: 25513
diff changeset
237 # developer config: ui.formatdebug
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
238 elif ui.configbool('ui', 'formatdebug'):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
239 return debugformatter(ui, topic, opts)
25838
31137258ae8b formatter: mark developer options
Matt Mackall <mpm@selenic.com>
parents: 25513
diff changeset
240 # deprecated config: ui.formatjson
22428
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
241 elif ui.configbool('ui', 'formatjson'):
427e80a18ef8 formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents: 22424
diff changeset
242 return jsonformatter(ui, topic, opts)
16134
3c0327ea20c0 formatter: add basic formatters
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
243 return plainformatter(ui, topic, opts)