##// END OF EJS Templates
py3: replace str() with pycompat.bytestr() or ('%d' % int)...
Pulkit Goyal -
r40763:001f2797 default
parent child Browse files
Show More
@@ -1,161 +1,164
1 # Copyright 2016-present Facebook. All Rights Reserved.
1 # Copyright 2016-present Facebook. All Rights Reserved.
2 #
2 #
3 # format: defines the format used to output annotate result
3 # format: defines the format used to output annotate result
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 from __future__ import absolute_import
7 from __future__ import absolute_import
8
8
9 from mercurial import (
9 from mercurial import (
10 encoding,
10 encoding,
11 node,
11 node,
12 pycompat,
12 pycompat,
13 templatefilters,
13 templatefilters,
14 util,
14 util,
15 )
15 )
16 from mercurial.utils import (
16 from mercurial.utils import (
17 dateutil,
17 dateutil,
18 )
18 )
19
19
20 # imitating mercurial.commands.annotate, not using the vanilla formatter since
20 # imitating mercurial.commands.annotate, not using the vanilla formatter since
21 # the data structures are a bit different, and we have some fast paths.
21 # the data structures are a bit different, and we have some fast paths.
22 class defaultformatter(object):
22 class defaultformatter(object):
23 """the default formatter that does leftpad and support some common flags"""
23 """the default formatter that does leftpad and support some common flags"""
24
24
25 def __init__(self, ui, repo, opts):
25 def __init__(self, ui, repo, opts):
26 self.ui = ui
26 self.ui = ui
27 self.opts = opts
27 self.opts = opts
28
28
29 if ui.quiet:
29 if ui.quiet:
30 datefunc = dateutil.shortdate
30 datefunc = dateutil.shortdate
31 else:
31 else:
32 datefunc = dateutil.datestr
32 datefunc = dateutil.datestr
33 datefunc = util.cachefunc(datefunc)
33 datefunc = util.cachefunc(datefunc)
34 getctx = util.cachefunc(lambda x: repo[x[0]])
34 getctx = util.cachefunc(lambda x: repo[x[0]])
35 hexfunc = self._hexfunc
35 hexfunc = self._hexfunc
36
36
37 # special handling working copy "changeset" and "rev" functions
37 # special handling working copy "changeset" and "rev" functions
38 if self.opts.get('rev') == 'wdir()':
38 if self.opts.get('rev') == 'wdir()':
39 orig = hexfunc
39 orig = hexfunc
40 hexfunc = lambda x: None if x is None else orig(x)
40 hexfunc = lambda x: None if x is None else orig(x)
41 wnode = hexfunc(repo[None].p1().node()) + '+'
41 wnode = hexfunc(repo[None].p1().node()) + '+'
42 wrev = str(repo[None].p1().rev())
42 wrev = '%d' % repo[None].p1().rev()
43 wrevpad = ''
43 wrevpad = ''
44 if not opts.get('changeset'): # only show + if changeset is hidden
44 if not opts.get('changeset'): # only show + if changeset is hidden
45 wrev += '+'
45 wrev += '+'
46 wrevpad = ' '
46 wrevpad = ' '
47 revenc = lambda x: wrev if x is None else str(x) + wrevpad
47 revenc = lambda x: wrev if x is None else ('%d' % x) + wrevpad
48 csetenc = lambda x: wnode if x is None else str(x) + ' '
48 def csetenc(x):
49 if x is None:
50 return wnode
51 return pycompat.bytestr(x) + ' '
49 else:
52 else:
50 revenc = csetenc = str
53 revenc = csetenc = pycompat.bytestr
51
54
52 # opt name, separator, raw value (for json/plain), encoder (for plain)
55 # opt name, separator, raw value (for json/plain), encoder (for plain)
53 opmap = [('user', ' ', lambda x: getctx(x).user(), ui.shortuser),
56 opmap = [('user', ' ', lambda x: getctx(x).user(), ui.shortuser),
54 ('number', ' ', lambda x: getctx(x).rev(), revenc),
57 ('number', ' ', lambda x: getctx(x).rev(), revenc),
55 ('changeset', ' ', lambda x: hexfunc(x[0]), csetenc),
58 ('changeset', ' ', lambda x: hexfunc(x[0]), csetenc),
56 ('date', ' ', lambda x: getctx(x).date(), datefunc),
59 ('date', ' ', lambda x: getctx(x).date(), datefunc),
57 ('file', ' ', lambda x: x[2], str),
60 ('file', ' ', lambda x: x[2], pycompat.bytestr),
58 ('line_number', ':', lambda x: x[1] + 1, str)]
61 ('line_number', ':', lambda x: x[1] + 1, pycompat.bytestr)]
59 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
62 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
60 funcmap = [(get, sep, fieldnamemap.get(op, op), enc)
63 funcmap = [(get, sep, fieldnamemap.get(op, op), enc)
61 for op, sep, get, enc in opmap
64 for op, sep, get, enc in opmap
62 if opts.get(op)]
65 if opts.get(op)]
63 # no separator for first column
66 # no separator for first column
64 funcmap[0] = list(funcmap[0])
67 funcmap[0] = list(funcmap[0])
65 funcmap[0][1] = ''
68 funcmap[0][1] = ''
66 self.funcmap = funcmap
69 self.funcmap = funcmap
67
70
68 def write(self, annotatedresult, lines=None, existinglines=None):
71 def write(self, annotatedresult, lines=None, existinglines=None):
69 """(annotateresult, [str], set([rev, linenum])) -> None. write output.
72 """(annotateresult, [str], set([rev, linenum])) -> None. write output.
70 annotateresult can be [(node, linenum, path)], or [(node, linenum)]
73 annotateresult can be [(node, linenum, path)], or [(node, linenum)]
71 """
74 """
72 pieces = [] # [[str]]
75 pieces = [] # [[str]]
73 maxwidths = [] # [int]
76 maxwidths = [] # [int]
74
77
75 # calculate padding
78 # calculate padding
76 for f, sep, name, enc in self.funcmap:
79 for f, sep, name, enc in self.funcmap:
77 l = [enc(f(x)) for x in annotatedresult]
80 l = [enc(f(x)) for x in annotatedresult]
78 pieces.append(l)
81 pieces.append(l)
79 if name in ['node', 'date']: # node and date has fixed size
82 if name in ['node', 'date']: # node and date has fixed size
80 l = l[:1]
83 l = l[:1]
81 widths = pycompat.maplist(encoding.colwidth, set(l))
84 widths = pycompat.maplist(encoding.colwidth, set(l))
82 maxwidth = (max(widths) if widths else 0)
85 maxwidth = (max(widths) if widths else 0)
83 maxwidths.append(maxwidth)
86 maxwidths.append(maxwidth)
84
87
85 # buffered output
88 # buffered output
86 result = ''
89 result = ''
87 for i in pycompat.xrange(len(annotatedresult)):
90 for i in pycompat.xrange(len(annotatedresult)):
88 for j, p in enumerate(pieces):
91 for j, p in enumerate(pieces):
89 sep = self.funcmap[j][1]
92 sep = self.funcmap[j][1]
90 padding = ' ' * (maxwidths[j] - len(p[i]))
93 padding = ' ' * (maxwidths[j] - len(p[i]))
91 result += sep + padding + p[i]
94 result += sep + padding + p[i]
92 if lines:
95 if lines:
93 if existinglines is None:
96 if existinglines is None:
94 result += ': ' + lines[i]
97 result += ': ' + lines[i]
95 else: # extra formatting showing whether a line exists
98 else: # extra formatting showing whether a line exists
96 key = (annotatedresult[i][0], annotatedresult[i][1])
99 key = (annotatedresult[i][0], annotatedresult[i][1])
97 if key in existinglines:
100 if key in existinglines:
98 result += ': ' + lines[i]
101 result += ': ' + lines[i]
99 else:
102 else:
100 result += ': ' + self.ui.label('-' + lines[i],
103 result += ': ' + self.ui.label('-' + lines[i],
101 'diff.deleted')
104 'diff.deleted')
102
105
103 if result[-1] != '\n':
106 if result[-1] != '\n':
104 result += '\n'
107 result += '\n'
105
108
106 self.ui.write(result)
109 self.ui.write(result)
107
110
108 @util.propertycache
111 @util.propertycache
109 def _hexfunc(self):
112 def _hexfunc(self):
110 if self.ui.debugflag or self.opts.get('long_hash'):
113 if self.ui.debugflag or self.opts.get('long_hash'):
111 return node.hex
114 return node.hex
112 else:
115 else:
113 return node.short
116 return node.short
114
117
115 def end(self):
118 def end(self):
116 pass
119 pass
117
120
118 class jsonformatter(defaultformatter):
121 class jsonformatter(defaultformatter):
119 def __init__(self, ui, repo, opts):
122 def __init__(self, ui, repo, opts):
120 super(jsonformatter, self).__init__(ui, repo, opts)
123 super(jsonformatter, self).__init__(ui, repo, opts)
121 self.ui.write('[')
124 self.ui.write('[')
122 self.needcomma = False
125 self.needcomma = False
123
126
124 def write(self, annotatedresult, lines=None, existinglines=None):
127 def write(self, annotatedresult, lines=None, existinglines=None):
125 if annotatedresult:
128 if annotatedresult:
126 self._writecomma()
129 self._writecomma()
127
130
128 pieces = [(name, map(f, annotatedresult))
131 pieces = [(name, map(f, annotatedresult))
129 for f, sep, name, enc in self.funcmap]
132 for f, sep, name, enc in self.funcmap]
130 if lines is not None:
133 if lines is not None:
131 pieces.append(('line', lines))
134 pieces.append(('line', lines))
132 pieces.sort()
135 pieces.sort()
133
136
134 seps = [','] * len(pieces[:-1]) + ['']
137 seps = [','] * len(pieces[:-1]) + ['']
135
138
136 result = ''
139 result = ''
137 lasti = len(annotatedresult) - 1
140 lasti = len(annotatedresult) - 1
138 for i in pycompat.xrange(len(annotatedresult)):
141 for i in pycompat.xrange(len(annotatedresult)):
139 result += '\n {\n'
142 result += '\n {\n'
140 for j, p in enumerate(pieces):
143 for j, p in enumerate(pieces):
141 k, vs = p
144 k, vs = p
142 result += (' "%s": %s%s\n'
145 result += (' "%s": %s%s\n'
143 % (k, templatefilters.json(vs[i], paranoid=False),
146 % (k, templatefilters.json(vs[i], paranoid=False),
144 seps[j]))
147 seps[j]))
145 result += ' }%s' % ('' if i == lasti else ',')
148 result += ' }%s' % ('' if i == lasti else ',')
146 if lasti >= 0:
149 if lasti >= 0:
147 self.needcomma = True
150 self.needcomma = True
148
151
149 self.ui.write(result)
152 self.ui.write(result)
150
153
151 def _writecomma(self):
154 def _writecomma(self):
152 if self.needcomma:
155 if self.needcomma:
153 self.ui.write(',')
156 self.ui.write(',')
154 self.needcomma = False
157 self.needcomma = False
155
158
156 @util.propertycache
159 @util.propertycache
157 def _hexfunc(self):
160 def _hexfunc(self):
158 return node.hex
161 return node.hex
159
162
160 def end(self):
163 def end(self):
161 self.ui.write('\n]\n')
164 self.ui.write('\n]\n')
General Comments 0
You need to be logged in to leave comments. Login now