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