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