forked from MinaProtocol/mina
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrequire-ppxs.py
More file actions
executable file
·137 lines (113 loc) · 4.74 KB
/
Copy pathrequire-ppxs.py
File metadata and controls
executable file
·137 lines (113 loc) · 4.74 KB
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env python3
# In dune files, require preprocessing by ppx_version, so that the version syntax linter is always run
import subprocess
import string
import sexpdata
dune_string = subprocess.check_output(['find', 'src', '-name', 'dune'])
dune_paths_raw = dune_string.decode('utf-8').split('\n')
# filter out dune paths where we don't require linting
def dune_paths_ok(dune):
path = dune.split('/')
path_prefix2 = path[1:2]
path_prefix3 = path[1:3]
return (not (path_prefix2 == ['_build'] or path_prefix2 == ['external']
or path_prefix3 == ['lib', 'marlin']
or path_prefix3 == ['lib', 'snarky']
or path_prefix3 == ['lib', 'ppx_version']
or path_prefix3 == ['app', 'reformat']
or path_prefix3 == ['lib', 'ppx_coda']))
dune_paths = list(
filter(lambda s: len(s) > 0 and dune_paths_ok(s), dune_paths_raw))
library = sexpdata.loads('library')
executable = sexpdata.loads('executable')
preprocess = sexpdata.loads('preprocess')
pps = sexpdata.loads('pps')
backend = sexpdata.loads('backend')
no_preprocessing = sexpdata.loads('no_preprocessing')
instrumentation = sexpdata.loads('instrumentation')
ppx_lint = sexpdata.loads('ppx_version')
ppx_coverage = sexpdata.loads('bisect_ppx')
version_lint_as_warning_flag = sexpdata.loads('-lint-version-syntax-warnings')
exit_code = 0
def missing_ppx_error(dune, ppx):
print(
"In dune file " + dune +
", the preprocessing clause is missing; there should be one containing "
+ (sexpdata.dumps(ppx)))
global exit_code
exit_code = 1
def missing_backend_error(dune, ppx):
print(
"In dune file " + dune +
", the instrumentation clause is missing; there should be one containing a backend for "
+ (sexpdata.dumps(ppx)))
global exit_code
exit_code = 1
def no_ppx_error(dune, ppxs):
print(
"In dune file " + dune +
", the preprocessing clause indicates no preprocessing, but it should include "
+ (sexpdata.dumps(ppxs)))
global exit_code
exit_code = 1
def get_ppx_ndx(dune, ppxs, ppx):
try:
ppxs.index(ppx)
except:
print("In dune file " + dune +
", the preprocessing clause does not contain " +
(sexpdata.dumps(ppx)))
global exit_code
exit_code = 1
def check_for_proscribed_flag(dune, ppxs, flag):
try:
ndx = ppxs.index(flag)
print("In dune file " + dune +
", the preprocessing clause contains proscribed flag " + (sexpdata.dumps(flag)))
global exit_code
exit_code = 1
except:
None
def get_backends_ndx(dune, backends, ppx):
try:
backends.index(ppx)
except:
print("In dune file " + dune +
", the instrumentation backends clause does not contain " +
(sexpdata.dumps(ppx)))
global exit_code
exit_code = 1
for dune in dune_paths:
with open(dune) as fp:
# wrap in parens to get list of top-level clauses
sexps = sexpdata.loads('(' + fp.read() + ')')
for sexp in sexps:
if isinstance(sexp, list) and len(sexp) > 0 and (
sexpdata.car(sexp) == library
or sexpdata.car(sexp) == executable):
clauses = sexpdata.cdr(sexp)
found_preprocess = False
found_instrumentation = False
for clause in clauses:
if sexpdata.car(clause) == preprocess:
found_preprocess = True
subclause = sexpdata.car(sexpdata.cdr(clause))
if subclause == no_preprocessing:
# error if no preprocessing explicitly
no_ppx_error(dune, ppx_lint)
elif sexpdata.car(subclause) == pps:
ppxs = sexpdata.cdr(subclause)
check_for_proscribed_flag(dune,ppxs,version_lint_as_warning_flag)
lint_ppx_ndx = get_ppx_ndx(dune, ppxs, ppx_lint)
if sexpdata.car(clause) == instrumentation:
found_instrumentation = True
subclause = sexpdata.car(sexpdata.cdr(clause))
if sexpdata.car(subclause) == backend:
backends = sexpdata.cdr(subclause)
coverage_ppx_ndx = get_backends_ndx(dune, backends, ppx_coverage)
if found_preprocess == False:
# error if no preprocessing implicitly
missing_ppx_error(dune, ppx_lint)
if found_instrumentation == False:
missing_backend_error(dune, ppx_coverage)
exit(exit_code)