Mercurial > hg
annotate mercurial/formatter.py @ 24283:ef22cfff7052
transaction: add a validation stage
The 'transaction' object can now be fed a 'validator' function. This function
will be run right before the transaction is closed to validate its content. The
target usage is hooks. The validation function is expected to raise an exception
when it wants to abort the transaction.
This only introduce the idea with a default no-op validator. Actual usage is in
the next changeset.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Mon, 09 Mar 2015 22:43:36 -0700 |
parents | cb28d2b3db0b |
children | 0a714a1f7d5c |
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 |
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 | 13 class baseformatter(object): |
14 def __init__(self, ui, topic, opts): | |
15 self._ui = ui | |
16 self._topic = topic | |
17 self._style = opts.get("style") | |
18 self._template = opts.get("template") | |
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 | 23 '''return False if we're not doing real templating so we can |
24 skip extra work''' | |
25 return True | |
26 def _showitem(self): | |
27 '''show a formatted item once all data is collected''' | |
28 pass | |
29 def startitem(self): | |
30 '''begin an item in the format list''' | |
31 if self._item is not None: | |
32 self._showitem() | |
33 self._item = {} | |
34 def data(self, **data): | |
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 | 37 def write(self, fields, deftext, *fielddata, **opts): |
38 '''do default text output while assigning data to item''' | |
39 for k, v in zip(fields.split(), fielddata): | |
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 | 45 def plain(self, text, **opts): |
46 '''show raw text for non-templated mode''' | |
47 pass | |
48 def end(self): | |
49 '''end output for the formatter''' | |
50 if self._item is not None: | |
51 self._showitem() | |
52 | |
53 class plainformatter(baseformatter): | |
54 '''the default text output scheme''' | |
55 def __init__(self, ui, topic, opts): | |
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 | 62 return False |
63 def startitem(self): | |
64 pass | |
65 def data(self, **data): | |
66 pass | |
67 def write(self, fields, deftext, *fielddata, **opts): | |
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 | 73 def plain(self, text, **opts): |
74 self._ui.write(text, **opts) | |
75 def end(self): | |
76 pass | |
77 | |
78 class debugformatter(baseformatter): | |
79 def __init__(self, ui, topic, opts): | |
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 | 82 def _showitem(self): |
83 self._ui.write(" " + repr(self._item) + ",\n") | |
84 def end(self): | |
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 | 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 | 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 | 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 | 148 return plainformatter(ui, topic, opts) |