##// END OF EJS Templates
formatter: mark developer options
Matt Mackall -
r25838:31137258 default
parent child Browse files
Show More
@@ -1,204 +1,206 b''
1 # formatter.py - generic output formatting for mercurial
1 # formatter.py - generic output formatting for mercurial
2 #
2 #
3 # Copyright 2012 Matt Mackall <mpm@selenic.com>
3 # Copyright 2012 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
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.
6 # GNU General Public License version 2 or any later version.
7
7
8 import cPickle
8 import cPickle
9 from node import hex, short
9 from node import hex, short
10 from i18n import _
10 from i18n import _
11 import encoding, util
11 import encoding, util
12 import templater
12 import templater
13 import os
13 import os
14
14
15 class baseformatter(object):
15 class baseformatter(object):
16 def __init__(self, ui, topic, opts):
16 def __init__(self, ui, topic, opts):
17 self._ui = ui
17 self._ui = ui
18 self._topic = topic
18 self._topic = topic
19 self._style = opts.get("style")
19 self._style = opts.get("style")
20 self._template = opts.get("template")
20 self._template = opts.get("template")
21 self._item = None
21 self._item = None
22 # function to convert node to string suitable for this output
22 # function to convert node to string suitable for this output
23 self.hexfunc = hex
23 self.hexfunc = hex
24 def __nonzero__(self):
24 def __nonzero__(self):
25 '''return False if we're not doing real templating so we can
25 '''return False if we're not doing real templating so we can
26 skip extra work'''
26 skip extra work'''
27 return True
27 return True
28 def _showitem(self):
28 def _showitem(self):
29 '''show a formatted item once all data is collected'''
29 '''show a formatted item once all data is collected'''
30 pass
30 pass
31 def startitem(self):
31 def startitem(self):
32 '''begin an item in the format list'''
32 '''begin an item in the format list'''
33 if self._item is not None:
33 if self._item is not None:
34 self._showitem()
34 self._showitem()
35 self._item = {}
35 self._item = {}
36 def data(self, **data):
36 def data(self, **data):
37 '''insert data into item that's not shown in default output'''
37 '''insert data into item that's not shown in default output'''
38 self._item.update(data)
38 self._item.update(data)
39 def write(self, fields, deftext, *fielddata, **opts):
39 def write(self, fields, deftext, *fielddata, **opts):
40 '''do default text output while assigning data to item'''
40 '''do default text output while assigning data to item'''
41 for k, v in zip(fields.split(), fielddata):
41 for k, v in zip(fields.split(), fielddata):
42 self._item[k] = v
42 self._item[k] = v
43 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
43 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
44 '''do conditional write (primarily for plain formatter)'''
44 '''do conditional write (primarily for plain formatter)'''
45 for k, v in zip(fields.split(), fielddata):
45 for k, v in zip(fields.split(), fielddata):
46 self._item[k] = v
46 self._item[k] = v
47 def plain(self, text, **opts):
47 def plain(self, text, **opts):
48 '''show raw text for non-templated mode'''
48 '''show raw text for non-templated mode'''
49 pass
49 pass
50 def end(self):
50 def end(self):
51 '''end output for the formatter'''
51 '''end output for the formatter'''
52 if self._item is not None:
52 if self._item is not None:
53 self._showitem()
53 self._showitem()
54
54
55 class plainformatter(baseformatter):
55 class plainformatter(baseformatter):
56 '''the default text output scheme'''
56 '''the default text output scheme'''
57 def __init__(self, ui, topic, opts):
57 def __init__(self, ui, topic, opts):
58 baseformatter.__init__(self, ui, topic, opts)
58 baseformatter.__init__(self, ui, topic, opts)
59 if ui.debugflag:
59 if ui.debugflag:
60 self.hexfunc = hex
60 self.hexfunc = hex
61 else:
61 else:
62 self.hexfunc = short
62 self.hexfunc = short
63 def __nonzero__(self):
63 def __nonzero__(self):
64 return False
64 return False
65 def startitem(self):
65 def startitem(self):
66 pass
66 pass
67 def data(self, **data):
67 def data(self, **data):
68 pass
68 pass
69 def write(self, fields, deftext, *fielddata, **opts):
69 def write(self, fields, deftext, *fielddata, **opts):
70 self._ui.write(deftext % fielddata, **opts)
70 self._ui.write(deftext % fielddata, **opts)
71 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
71 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
72 '''do conditional write'''
72 '''do conditional write'''
73 if cond:
73 if cond:
74 self._ui.write(deftext % fielddata, **opts)
74 self._ui.write(deftext % fielddata, **opts)
75 def plain(self, text, **opts):
75 def plain(self, text, **opts):
76 self._ui.write(text, **opts)
76 self._ui.write(text, **opts)
77 def end(self):
77 def end(self):
78 pass
78 pass
79
79
80 class debugformatter(baseformatter):
80 class debugformatter(baseformatter):
81 def __init__(self, ui, topic, opts):
81 def __init__(self, ui, topic, opts):
82 baseformatter.__init__(self, ui, topic, opts)
82 baseformatter.__init__(self, ui, topic, opts)
83 self._ui.write("%s = [\n" % self._topic)
83 self._ui.write("%s = [\n" % self._topic)
84 def _showitem(self):
84 def _showitem(self):
85 self._ui.write(" " + repr(self._item) + ",\n")
85 self._ui.write(" " + repr(self._item) + ",\n")
86 def end(self):
86 def end(self):
87 baseformatter.end(self)
87 baseformatter.end(self)
88 self._ui.write("]\n")
88 self._ui.write("]\n")
89
89
90 class pickleformatter(baseformatter):
90 class pickleformatter(baseformatter):
91 def __init__(self, ui, topic, opts):
91 def __init__(self, ui, topic, opts):
92 baseformatter.__init__(self, ui, topic, opts)
92 baseformatter.__init__(self, ui, topic, opts)
93 self._data = []
93 self._data = []
94 def _showitem(self):
94 def _showitem(self):
95 self._data.append(self._item)
95 self._data.append(self._item)
96 def end(self):
96 def end(self):
97 baseformatter.end(self)
97 baseformatter.end(self)
98 self._ui.write(cPickle.dumps(self._data))
98 self._ui.write(cPickle.dumps(self._data))
99
99
100 def _jsonifyobj(v):
100 def _jsonifyobj(v):
101 if isinstance(v, tuple):
101 if isinstance(v, tuple):
102 return '[' + ', '.join(_jsonifyobj(e) for e in v) + ']'
102 return '[' + ', '.join(_jsonifyobj(e) for e in v) + ']'
103 elif v is None:
103 elif v is None:
104 return 'null'
104 return 'null'
105 elif v is True:
105 elif v is True:
106 return 'true'
106 return 'true'
107 elif v is False:
107 elif v is False:
108 return 'false'
108 return 'false'
109 elif isinstance(v, (int, float)):
109 elif isinstance(v, (int, float)):
110 return str(v)
110 return str(v)
111 else:
111 else:
112 return '"%s"' % encoding.jsonescape(v)
112 return '"%s"' % encoding.jsonescape(v)
113
113
114 class jsonformatter(baseformatter):
114 class jsonformatter(baseformatter):
115 def __init__(self, ui, topic, opts):
115 def __init__(self, ui, topic, opts):
116 baseformatter.__init__(self, ui, topic, opts)
116 baseformatter.__init__(self, ui, topic, opts)
117 self._ui.write("[")
117 self._ui.write("[")
118 self._ui._first = True
118 self._ui._first = True
119 def _showitem(self):
119 def _showitem(self):
120 if self._ui._first:
120 if self._ui._first:
121 self._ui._first = False
121 self._ui._first = False
122 else:
122 else:
123 self._ui.write(",")
123 self._ui.write(",")
124
124
125 self._ui.write("\n {\n")
125 self._ui.write("\n {\n")
126 first = True
126 first = True
127 for k, v in sorted(self._item.items()):
127 for k, v in sorted(self._item.items()):
128 if first:
128 if first:
129 first = False
129 first = False
130 else:
130 else:
131 self._ui.write(",\n")
131 self._ui.write(",\n")
132 self._ui.write(' "%s": %s' % (k, _jsonifyobj(v)))
132 self._ui.write(' "%s": %s' % (k, _jsonifyobj(v)))
133 self._ui.write("\n }")
133 self._ui.write("\n }")
134 def end(self):
134 def end(self):
135 baseformatter.end(self)
135 baseformatter.end(self)
136 self._ui.write("\n]\n")
136 self._ui.write("\n]\n")
137
137
138 class templateformatter(baseformatter):
138 class templateformatter(baseformatter):
139 def __init__(self, ui, topic, opts):
139 def __init__(self, ui, topic, opts):
140 baseformatter.__init__(self, ui, topic, opts)
140 baseformatter.__init__(self, ui, topic, opts)
141 self._topic = topic
141 self._topic = topic
142 self._t = gettemplater(ui, topic, opts.get('template', ''))
142 self._t = gettemplater(ui, topic, opts.get('template', ''))
143 def _showitem(self):
143 def _showitem(self):
144 g = self._t(self._topic, **self._item)
144 g = self._t(self._topic, **self._item)
145 self._ui.write(templater.stringify(g))
145 self._ui.write(templater.stringify(g))
146
146
147 def lookuptemplate(ui, topic, tmpl):
147 def lookuptemplate(ui, topic, tmpl):
148 # looks like a literal template?
148 # looks like a literal template?
149 if '{' in tmpl:
149 if '{' in tmpl:
150 return tmpl, None
150 return tmpl, None
151
151
152 # perhaps a stock style?
152 # perhaps a stock style?
153 if not os.path.split(tmpl)[0]:
153 if not os.path.split(tmpl)[0]:
154 mapname = (templater.templatepath('map-cmdline.' + tmpl)
154 mapname = (templater.templatepath('map-cmdline.' + tmpl)
155 or templater.templatepath(tmpl))
155 or templater.templatepath(tmpl))
156 if mapname and os.path.isfile(mapname):
156 if mapname and os.path.isfile(mapname):
157 return None, mapname
157 return None, mapname
158
158
159 # perhaps it's a reference to [templates]
159 # perhaps it's a reference to [templates]
160 t = ui.config('templates', tmpl)
160 t = ui.config('templates', tmpl)
161 if t:
161 if t:
162 try:
162 try:
163 tmpl = templater.unquotestring(t)
163 tmpl = templater.unquotestring(t)
164 except SyntaxError:
164 except SyntaxError:
165 tmpl = t
165 tmpl = t
166 return tmpl, None
166 return tmpl, None
167
167
168 if tmpl == 'list':
168 if tmpl == 'list':
169 ui.write(_("available styles: %s\n") % templater.stylelist())
169 ui.write(_("available styles: %s\n") % templater.stylelist())
170 raise util.Abort(_("specify a template"))
170 raise util.Abort(_("specify a template"))
171
171
172 # perhaps it's a path to a map or a template
172 # perhaps it's a path to a map or a template
173 if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl):
173 if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl):
174 # is it a mapfile for a style?
174 # is it a mapfile for a style?
175 if os.path.basename(tmpl).startswith("map-"):
175 if os.path.basename(tmpl).startswith("map-"):
176 return None, os.path.realpath(tmpl)
176 return None, os.path.realpath(tmpl)
177 tmpl = open(tmpl).read()
177 tmpl = open(tmpl).read()
178 return tmpl, None
178 return tmpl, None
179
179
180 # constant string?
180 # constant string?
181 return tmpl, None
181 return tmpl, None
182
182
183 def gettemplater(ui, topic, spec):
183 def gettemplater(ui, topic, spec):
184 tmpl, mapfile = lookuptemplate(ui, topic, spec)
184 tmpl, mapfile = lookuptemplate(ui, topic, spec)
185 t = templater.templater(mapfile, {})
185 t = templater.templater(mapfile, {})
186 if tmpl:
186 if tmpl:
187 t.cache[topic] = tmpl
187 t.cache[topic] = tmpl
188 return t
188 return t
189
189
190 def formatter(ui, topic, opts):
190 def formatter(ui, topic, opts):
191 template = opts.get("template", "")
191 template = opts.get("template", "")
192 if template == "json":
192 if template == "json":
193 return jsonformatter(ui, topic, opts)
193 return jsonformatter(ui, topic, opts)
194 elif template == "pickle":
194 elif template == "pickle":
195 return pickleformatter(ui, topic, opts)
195 return pickleformatter(ui, topic, opts)
196 elif template == "debug":
196 elif template == "debug":
197 return debugformatter(ui, topic, opts)
197 return debugformatter(ui, topic, opts)
198 elif template != "":
198 elif template != "":
199 return templateformatter(ui, topic, opts)
199 return templateformatter(ui, topic, opts)
200 # developer config: ui.formatdebug
200 elif ui.configbool('ui', 'formatdebug'):
201 elif ui.configbool('ui', 'formatdebug'):
201 return debugformatter(ui, topic, opts)
202 return debugformatter(ui, topic, opts)
203 # deprecated config: ui.formatjson
202 elif ui.configbool('ui', 'formatjson'):
204 elif ui.configbool('ui', 'formatjson'):
203 return jsonformatter(ui, topic, opts)
205 return jsonformatter(ui, topic, opts)
204 return plainformatter(ui, topic, opts)
206 return plainformatter(ui, topic, opts)
General Comments 0
You need to be logged in to leave comments. Login now