Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/formatter.py @ 22475:17eeda31e52b
formatter: have jsonformatter accept tuple as value
This is necessary for "annotate" to encode ctx.date() in the same manner
as jsonchangeset printer.
It doesn't support list object because keeping mutable object in _item could
be a source of hidden bugs. Also, I can't think of the use case.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Wed, 17 Sep 2014 21:30:22 +0900 |
parents | 9da0ef363861 |
children | a0829ec34dbd |
rev | line source |
---|---|
16134 | 1 # formatter.py - generic output formatting for mercurial |
2 # | |
3 # Copyright 2012 Matt Mackall <mpm@selenic.com> | |
4 # | |
5 # This software may be used and distributed according to the terms of the | |
6 # GNU General Public License version 2 or any later version. | |
7 | |
22430
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
8 import cPickle |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
9 from i18n import _ |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
10 import encoding, util |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
11 |
16134 | 12 class baseformatter(object): |
13 def __init__(self, ui, topic, opts): | |
14 self._ui = ui | |
15 self._topic = topic | |
16 self._style = opts.get("style") | |
17 self._template = opts.get("template") | |
18 self._item = None | |
22447
2642ce9be6ef
formatter: correct bool testing which should be __nonzero__ in Python 2
Yuya Nishihara <yuya@tcha.org>
parents:
22430
diff
changeset
|
19 def __nonzero__(self): |
16134 | 20 '''return False if we're not doing real templating so we can |
21 skip extra work''' | |
22 return True | |
23 def _showitem(self): | |
24 '''show a formatted item once all data is collected''' | |
25 pass | |
26 def startitem(self): | |
27 '''begin an item in the format list''' | |
28 if self._item is not None: | |
29 self._showitem() | |
30 self._item = {} | |
31 def data(self, **data): | |
32 '''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
|
33 self._item.update(data) |
16134 | 34 def write(self, fields, deftext, *fielddata, **opts): |
35 '''do default text output while assigning data to item''' | |
36 for k, v in zip(fields.split(), fielddata): | |
37 self._item[k] = v | |
17909
3326fd05eb1f
formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents:
17630
diff
changeset
|
38 def condwrite(self, cond, fields, deftext, *fielddata, **opts): |
3326fd05eb1f
formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents:
17630
diff
changeset
|
39 '''do conditional write (primarily for plain formatter)''' |
3326fd05eb1f
formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents:
17630
diff
changeset
|
40 for k, v in zip(fields.split(), fielddata): |
3326fd05eb1f
formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents:
17630
diff
changeset
|
41 self._item[k] = v |
16134 | 42 def plain(self, text, **opts): |
43 '''show raw text for non-templated mode''' | |
44 pass | |
45 def end(self): | |
46 '''end output for the formatter''' | |
47 if self._item is not None: | |
48 self._showitem() | |
49 | |
50 class plainformatter(baseformatter): | |
51 '''the default text output scheme''' | |
52 def __init__(self, ui, topic, opts): | |
53 baseformatter.__init__(self, ui, topic, opts) | |
22447
2642ce9be6ef
formatter: correct bool testing which should be __nonzero__ in Python 2
Yuya Nishihara <yuya@tcha.org>
parents:
22430
diff
changeset
|
54 def __nonzero__(self): |
16134 | 55 return False |
56 def startitem(self): | |
57 pass | |
58 def data(self, **data): | |
59 pass | |
60 def write(self, fields, deftext, *fielddata, **opts): | |
61 self._ui.write(deftext % fielddata, **opts) | |
17909
3326fd05eb1f
formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents:
17630
diff
changeset
|
62 def condwrite(self, cond, fields, deftext, *fielddata, **opts): |
3326fd05eb1f
formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents:
17630
diff
changeset
|
63 '''do conditional write''' |
3326fd05eb1f
formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents:
17630
diff
changeset
|
64 if cond: |
3326fd05eb1f
formatter: add condwrite method
Matt Mackall <mpm@selenic.com>
parents:
17630
diff
changeset
|
65 self._ui.write(deftext % fielddata, **opts) |
16134 | 66 def plain(self, text, **opts): |
67 self._ui.write(text, **opts) | |
68 def end(self): | |
69 pass | |
70 | |
71 class debugformatter(baseformatter): | |
72 def __init__(self, ui, topic, opts): | |
73 baseformatter.__init__(self, ui, topic, opts) | |
22424
1f72226064b8
formatter: make debug style match Python syntax
Matt Mackall <mpm@selenic.com>
parents:
17909
diff
changeset
|
74 self._ui.write("%s = [\n" % self._topic) |
16134 | 75 def _showitem(self): |
76 self._ui.write(" " + repr(self._item) + ",\n") | |
77 def end(self): | |
78 baseformatter.end(self) | |
22424
1f72226064b8
formatter: make debug style match Python syntax
Matt Mackall <mpm@selenic.com>
parents:
17909
diff
changeset
|
79 self._ui.write("]\n") |
16134 | 80 |
22430
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
81 class pickleformatter(baseformatter): |
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
82 def __init__(self, ui, topic, opts): |
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
83 baseformatter.__init__(self, ui, topic, opts) |
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
84 self._data = [] |
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
85 def _showitem(self): |
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
86 self._data.append(self._item) |
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
87 def end(self): |
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
88 baseformatter.end(self) |
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
89 self._ui.write(cPickle.dumps(self._data)) |
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
90 |
22474
9da0ef363861
formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents:
22447
diff
changeset
|
91 def _jsonifyobj(v): |
22475
17eeda31e52b
formatter: have jsonformatter accept tuple as value
Yuya Nishihara <yuya@tcha.org>
parents:
22474
diff
changeset
|
92 if isinstance(v, tuple): |
17eeda31e52b
formatter: have jsonformatter accept tuple as value
Yuya Nishihara <yuya@tcha.org>
parents:
22474
diff
changeset
|
93 return '[' + ', '.join(_jsonifyobj(e) for e in v) + ']' |
17eeda31e52b
formatter: have jsonformatter accept tuple as value
Yuya Nishihara <yuya@tcha.org>
parents:
22474
diff
changeset
|
94 elif isinstance(v, int): |
22474
9da0ef363861
formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents:
22447
diff
changeset
|
95 return '%d' % v |
9da0ef363861
formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents:
22447
diff
changeset
|
96 else: |
9da0ef363861
formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents:
22447
diff
changeset
|
97 return '"%s"' % encoding.jsonescape(v) |
9da0ef363861
formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents:
22447
diff
changeset
|
98 |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
99 class jsonformatter(baseformatter): |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
100 def __init__(self, ui, topic, opts): |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
101 baseformatter.__init__(self, ui, topic, opts) |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
102 self._ui.write("[") |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
103 self._ui._first = True |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
104 def _showitem(self): |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
105 if self._ui._first: |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
106 self._ui._first = False |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
107 else: |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
108 self._ui.write(",") |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
109 |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
110 self._ui.write("\n {\n") |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
111 first = True |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
112 for k, v in sorted(self._item.items()): |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
113 if first: |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
114 first = False |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
115 else: |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
116 self._ui.write(",\n") |
22474
9da0ef363861
formatter: extract function that encode values to json string
Yuya Nishihara <yuya@tcha.org>
parents:
22447
diff
changeset
|
117 self._ui.write(' "%s": %s' % (k, _jsonifyobj(v))) |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
118 self._ui.write("\n }") |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
119 def end(self): |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
120 baseformatter.end(self) |
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 |
16134 | 123 def formatter(ui, topic, opts): |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
124 template = opts.get("template", "") |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
125 if template == "json": |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
126 return jsonformatter(ui, topic, opts) |
22430
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
127 elif template == "pickle": |
968247e8f4ac
formatter: add pickle format
Matt Mackall <mpm@selenic.com>
parents:
22428
diff
changeset
|
128 return pickleformatter(ui, topic, opts) |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
129 elif template == "debug": |
16134 | 130 return debugformatter(ui, topic, opts) |
22428
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
131 elif template != "": |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
132 raise util.Abort(_("custom templates not yet supported")) |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
133 elif ui.configbool('ui', 'formatdebug'): |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
134 return debugformatter(ui, topic, opts) |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
135 elif ui.configbool('ui', 'formatjson'): |
427e80a18ef8
formatter: add json formatter
Matt Mackall <mpm@selenic.com>
parents:
22424
diff
changeset
|
136 return jsonformatter(ui, topic, opts) |
16134 | 137 return plainformatter(ui, topic, opts) |