1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
#!/usr/bin/env bash
# needs to be executed from the src directory.
# generates a report at src/mypy_report.txt
set -e
python3 -m venv .mypy_venv
. .mypy_venv/bin/activate
! pip install $(find -name requirements.txt -not -path './frontend/*' -printf '-r%p ')
pip install mypy
MYPY_INI="$PWD"/mypy.ini
export MYPYPATH="$PWD/pybind/rados:$PWD/pybind/rbd:$PWD/pybind/cephfs"
echo -n > mypy_report.txt
pushd pybind
mypy --config-file="$MYPY_INI" *.py | awk '{print "pybind/" $0}' >> ../mypy_report.txt
popd
pushd pybind/mgr
mypy --config-file="$MYPY_INI" $(find * -name '*.py' | grep -v -e venv -e tox -e env -e gyp -e node_modules) | awk '{print "pybind/mgr/" $0}' >> ../../mypy_report.txt
popd
pushd ceph-volume/ceph_volume
mypy --config-file="$MYPY_INI" $(find * -name '*.py' | grep -v -e venv -e tox -e env -e gyp -e node_modules -e tests) | awk '{print "ceph-volume/ceph_volume/" $0}' >> ../../mypy_report.txt
popd
SORT_MYPY=$(cat <<-EOF
#!/bin/python3
import re
from collections import namedtuple
class Line(namedtuple('Line', 'prefix no rest')):
@classmethod
def parse(cls, l):
if not l:
return cls('', 0, '')
if re.search('Found [0-9]+ errors in [0-9]+ files', l):
return cls('', 0, '')
p, *rest = l.split(':', 2)
if len(rest) == 1:
return cls(p, 0, rest[0])
elif len(rest) == 2:
try:
return cls(p, int(rest[0]), rest[1])
except ValueError:
return cls(p, 0, rest[0] + ':' + rest[1])
assert False, rest
class Group(object):
def __init__(self, line):
self.line = line
self.lines = []
def matches(self, other):
return Line.parse(self.line).prefix == Line.parse(other).prefix
def __bool__(self):
return bool(self.lines) or ': note: In' not in self.line
def __str__(self):
return '\n'.join([self.line] + self.lines)
def key(self):
l1 = Line.parse(self.line)
if l1.no:
return l1.prefix, int(l1.no)
if not self.lines:
return l1.prefix, None
return l1.prefix, Line.parse(self.lines[0]).no
def parse(text):
groups = []
def group():
try:
return groups[-1]
except IndexError:
groups.append(Group(''))
return groups[-1]
for l in text:
l = l.strip()
if ': note: In' in l or not group().matches(l):
groups.append(Group(l))
elif not l:
pass
else:
group().lines.append(l)
return (g for g in groups if g)
def render(groups):
groups = sorted(groups, key=Group.key)
return '\n'.join(map(str, groups))
with open('mypy_report.txt') as f:
new = render(parse(f))
with open('mypy_report.txt', 'w') as f:
f.write(new)
EOF
)
python <(echo "$SORT_MYPY")
|