comparison hgext/fastannotate/formatter.py @ 43076:2372284d9457

formatting: blacken the codebase This is using my patch to black (https://github.com/psf/black/pull/826) so we don't un-wrap collection literals. Done with: hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S # skip-blame mass-reformatting only # no-check-commit reformats foo_bar functions Differential Revision: https://phab.mercurial-scm.org/D6971
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:45:02 -0400
parents 2ff8994ac71d
children 687b865b95ad
comparison
equal deleted inserted replaced
43075:57875cf423c9 43076:2372284d9457
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 dateutil
17 dateutil,
18 )
19 17
20 # imitating mercurial.commands.annotate, not using the vanilla formatter since 18 # imitating mercurial.commands.annotate, not using the vanilla formatter since
21 # the data structures are a bit different, and we have some fast paths. 19 # the data structures are a bit different, and we have some fast paths.
22 class defaultformatter(object): 20 class defaultformatter(object):
23 """the default formatter that does leftpad and support some common flags""" 21 """the default formatter that does leftpad and support some common flags"""
39 orig = hexfunc 37 orig = hexfunc
40 hexfunc = lambda x: None if x is None else orig(x) 38 hexfunc = lambda x: None if x is None else orig(x)
41 wnode = hexfunc(repo['.'].node()) + '+' 39 wnode = hexfunc(repo['.'].node()) + '+'
42 wrev = '%d' % repo['.'].rev() 40 wrev = '%d' % repo['.'].rev()
43 wrevpad = '' 41 wrevpad = ''
44 if not opts.get('changeset'): # only show + if changeset is hidden 42 if not opts.get('changeset'): # only show + if changeset is hidden
45 wrev += '+' 43 wrev += '+'
46 wrevpad = ' ' 44 wrevpad = ' '
47 revenc = lambda x: wrev if x is None else ('%d' % x) + wrevpad 45 revenc = lambda x: wrev if x is None else ('%d' % x) + wrevpad
46
48 def csetenc(x): 47 def csetenc(x):
49 if x is None: 48 if x is None:
50 return wnode 49 return wnode
51 return pycompat.bytestr(x) + ' ' 50 return pycompat.bytestr(x) + ' '
51
52 else: 52 else:
53 revenc = csetenc = pycompat.bytestr 53 revenc = csetenc = pycompat.bytestr
54 54
55 # opt name, separator, raw value (for json/plain), encoder (for plain) 55 # opt name, separator, raw value (for json/plain), encoder (for plain)
56 opmap = [('user', ' ', lambda x: getctx(x).user(), ui.shortuser), 56 opmap = [
57 ('number', ' ', lambda x: getctx(x).rev(), revenc), 57 ('user', ' ', lambda x: getctx(x).user(), ui.shortuser),
58 ('changeset', ' ', lambda x: hexfunc(x[0]), csetenc), 58 ('number', ' ', lambda x: getctx(x).rev(), revenc),
59 ('date', ' ', lambda x: getctx(x).date(), datefunc), 59 ('changeset', ' ', lambda x: hexfunc(x[0]), csetenc),
60 ('file', ' ', lambda x: x[2], pycompat.bytestr), 60 ('date', ' ', lambda x: getctx(x).date(), datefunc),
61 ('line_number', ':', lambda x: x[1] + 1, pycompat.bytestr)] 61 ('file', ' ', lambda x: x[2], pycompat.bytestr),
62 ('line_number', ':', lambda x: x[1] + 1, pycompat.bytestr),
63 ]
62 fieldnamemap = {'number': 'rev', 'changeset': 'node'} 64 fieldnamemap = {'number': 'rev', 'changeset': 'node'}
63 funcmap = [(get, sep, fieldnamemap.get(op, op), enc) 65 funcmap = [
64 for op, sep, get, enc in opmap 66 (get, sep, fieldnamemap.get(op, op), enc)
65 if opts.get(op)] 67 for op, sep, get, enc in opmap
68 if opts.get(op)
69 ]
66 # no separator for first column 70 # no separator for first column
67 funcmap[0] = list(funcmap[0]) 71 funcmap[0] = list(funcmap[0])
68 funcmap[0][1] = '' 72 funcmap[0][1] = ''
69 self.funcmap = funcmap 73 self.funcmap = funcmap
70 74
71 def write(self, annotatedresult, lines=None, existinglines=None): 75 def write(self, annotatedresult, lines=None, existinglines=None):
72 """(annotateresult, [str], set([rev, linenum])) -> None. write output. 76 """(annotateresult, [str], set([rev, linenum])) -> None. write output.
73 annotateresult can be [(node, linenum, path)], or [(node, linenum)] 77 annotateresult can be [(node, linenum, path)], or [(node, linenum)]
74 """ 78 """
75 pieces = [] # [[str]] 79 pieces = [] # [[str]]
76 maxwidths = [] # [int] 80 maxwidths = [] # [int]
77 81
78 # calculate padding 82 # calculate padding
79 for f, sep, name, enc in self.funcmap: 83 for f, sep, name, enc in self.funcmap:
80 l = [enc(f(x)) for x in annotatedresult] 84 l = [enc(f(x)) for x in annotatedresult]
81 pieces.append(l) 85 pieces.append(l)
82 if name in ['node', 'date']: # node and date has fixed size 86 if name in ['node', 'date']: # node and date has fixed size
83 l = l[:1] 87 l = l[:1]
84 widths = pycompat.maplist(encoding.colwidth, set(l)) 88 widths = pycompat.maplist(encoding.colwidth, set(l))
85 maxwidth = (max(widths) if widths else 0) 89 maxwidth = max(widths) if widths else 0
86 maxwidths.append(maxwidth) 90 maxwidths.append(maxwidth)
87 91
88 # buffered output 92 # buffered output
89 result = '' 93 result = ''
90 for i in pycompat.xrange(len(annotatedresult)): 94 for i in pycompat.xrange(len(annotatedresult)):
93 padding = ' ' * (maxwidths[j] - len(p[i])) 97 padding = ' ' * (maxwidths[j] - len(p[i]))
94 result += sep + padding + p[i] 98 result += sep + padding + p[i]
95 if lines: 99 if lines:
96 if existinglines is None: 100 if existinglines is None:
97 result += ': ' + lines[i] 101 result += ': ' + lines[i]
98 else: # extra formatting showing whether a line exists 102 else: # extra formatting showing whether a line exists
99 key = (annotatedresult[i][0], annotatedresult[i][1]) 103 key = (annotatedresult[i][0], annotatedresult[i][1])
100 if key in existinglines: 104 if key in existinglines:
101 result += ': ' + lines[i] 105 result += ': ' + lines[i]
102 else: 106 else:
103 result += ': ' + self.ui.label('-' + lines[i], 107 result += ': ' + self.ui.label(
104 'diff.deleted') 108 '-' + lines[i], 'diff.deleted'
109 )
105 110
106 if result[-1:] != '\n': 111 if result[-1:] != '\n':
107 result += '\n' 112 result += '\n'
108 113
109 self.ui.write(result) 114 self.ui.write(result)
116 return node.short 121 return node.short
117 122
118 def end(self): 123 def end(self):
119 pass 124 pass
120 125
126
121 class jsonformatter(defaultformatter): 127 class jsonformatter(defaultformatter):
122 def __init__(self, ui, repo, opts): 128 def __init__(self, ui, repo, opts):
123 super(jsonformatter, self).__init__(ui, repo, opts) 129 super(jsonformatter, self).__init__(ui, repo, opts)
124 self.ui.write('[') 130 self.ui.write('[')
125 self.needcomma = False 131 self.needcomma = False
126 132
127 def write(self, annotatedresult, lines=None, existinglines=None): 133 def write(self, annotatedresult, lines=None, existinglines=None):
128 if annotatedresult: 134 if annotatedresult:
129 self._writecomma() 135 self._writecomma()
130 136
131 pieces = [(name, pycompat.maplist(f, annotatedresult)) 137 pieces = [
132 for f, sep, name, enc in self.funcmap] 138 (name, pycompat.maplist(f, annotatedresult))
139 for f, sep, name, enc in self.funcmap
140 ]
133 if lines is not None: 141 if lines is not None:
134 pieces.append(('line', lines)) 142 pieces.append(('line', lines))
135 pieces.sort() 143 pieces.sort()
136 144
137 seps = [','] * len(pieces[:-1]) + [''] 145 seps = [','] * len(pieces[:-1]) + ['']
140 lasti = len(annotatedresult) - 1 148 lasti = len(annotatedresult) - 1
141 for i in pycompat.xrange(len(annotatedresult)): 149 for i in pycompat.xrange(len(annotatedresult)):
142 result += '\n {\n' 150 result += '\n {\n'
143 for j, p in enumerate(pieces): 151 for j, p in enumerate(pieces):
144 k, vs = p 152 k, vs = p
145 result += (' "%s": %s%s\n' 153 result += ' "%s": %s%s\n' % (
146 % (k, templatefilters.json(vs[i], paranoid=False), 154 k,
147 seps[j])) 155 templatefilters.json(vs[i], paranoid=False),
156 seps[j],
157 )
148 result += ' }%s' % ('' if i == lasti else ',') 158 result += ' }%s' % ('' if i == lasti else ',')
149 if lasti >= 0: 159 if lasti >= 0:
150 self.needcomma = True 160 self.needcomma = True
151 161
152 self.ui.write(result) 162 self.ui.write(result)