@@ -18,6 +18,9 @@ EXCEPTIONAL_FILES = [
18
18
FEATURE_USAGE_RE = re .compile (
19
19
r"-enable-(?:experimental|upcoming)-feature (?:-Xfrontend )?([A-Za-z0-9]*)"
20
20
)
21
+ # Be careful of not using REQUIRES or RUN with a colon after them or Lit will
22
+ # pick them up.
23
+ FEATURE_LIT_MARKER_RE = re .compile (r"swift_feature_([A-Za-z0-9]*)" )
21
24
22
25
23
26
def find_test_files_with_features_usage (swift_src_root ):
@@ -38,6 +41,24 @@ def find_test_files_with_features_usage(swift_src_root):
38
41
return output .splitlines ()
39
42
40
43
44
+ def find_test_files_with_marker_usage (swift_src_root ):
45
+ # Look for every test file in the test directories with `REQUIRES` lines
46
+ # that mention `swift_feature_`.
47
+ # Be careful of not using REQUIRES with a colon after them or Lit will
48
+ # pick them up.
49
+ output = subprocess .check_output ([
50
+ "grep" ,
51
+ "--extended-regexp" ,
52
+ "--recursive" ,
53
+ "-e" ,
54
+ "REQUIRES[:].*swift_feature_" ,
55
+ "--files-with-matches" ,
56
+ str (swift_src_root / "test" ),
57
+ str (swift_src_root / "validation-test" ),
58
+ ], text = True )
59
+ return output .splitlines ()
60
+
61
+
41
62
def find_run_lines (test_file ):
42
63
output = subprocess .check_output ([
43
64
"grep" ,
@@ -50,6 +71,18 @@ def find_run_lines(test_file):
50
71
return output .splitlines ()
51
72
52
73
74
+ def find_requires_lines (test_file ):
75
+ output = subprocess .check_output ([
76
+ "grep" ,
77
+ "--extended-regexp" ,
78
+ "--no-filename" ,
79
+ "-e" ,
80
+ "REQUIRES[:]" ,
81
+ str (test_file ),
82
+ ], text = True )
83
+ return output .splitlines ()
84
+
85
+
53
86
def check_existing_requires (test_file , feature ):
54
87
returncode = subprocess .call ([
55
88
"grep" ,
@@ -62,6 +95,21 @@ def check_existing_requires(test_file, feature):
62
95
return returncode != 0
63
96
64
97
98
+ def check_existing_feature_usage (test_file , feature ):
99
+ returncode = subprocess .call ([
100
+ "grep" ,
101
+ "--extended-regexp" ,
102
+ "--quiet" ,
103
+ "-e" ,
104
+ (
105
+ "RUN[:].*-enable-(experimental|upcoming)-feature (?:-Xfrontend )?"
106
+ + re .escape (feature )
107
+ ),
108
+ str (test_file ),
109
+ ])
110
+ return returncode != 0
111
+
112
+
65
113
def check_existing_error_message_checks (test_file , feature ):
66
114
returncode = subprocess .call ([
67
115
"grep" ,
@@ -103,6 +151,30 @@ def check_test_file_feature_usage(test_file):
103
151
return num_failures == 0
104
152
105
153
154
+ def check_test_file_marker_usage (test_file ):
155
+ require_lines = find_requires_lines (test_file )
156
+ features = set (
157
+ feature
158
+ for line in require_lines
159
+ for feature in FEATURE_LIT_MARKER_RE .findall (line )
160
+ )
161
+ num_failures = 0
162
+ for feature in features :
163
+ # No warning if -enable-experimental/upcoming-feature is there
164
+ if not check_existing_feature_usage (test_file , feature ):
165
+ continue
166
+
167
+ # For everything else, print a warning and add to the invalid exit code
168
+ print (
169
+ "error: {}: Missing '-enable-experimental/upcoming-feature: {}'" .format (
170
+ str (test_file ),
171
+ feature
172
+ )
173
+ )
174
+ num_failures += 1
175
+ return num_failures == 0
176
+
177
+
106
178
def main ():
107
179
if len (sys .argv ) < 2 :
108
180
print ('Invalid number of arguments.' )
@@ -121,6 +193,17 @@ def main():
121
193
if not check_test_file_feature_usage (test_file ):
122
194
num_failures += 1
123
195
196
+ test_files_with_marker_usage = find_test_files_with_marker_usage (swift_src_root )
197
+ for test_file in test_files_with_marker_usage :
198
+ test_file = pathlib .Path (test_file )
199
+
200
+ # First lets check this is not one of the exceptional files
201
+ if test_file .relative_to (swift_src_root ) in EXCEPTIONAL_FILES :
202
+ continue
203
+
204
+ if not check_test_file_marker_usage (test_file ):
205
+ num_failures += 1
206
+
124
207
if num_failures > 0 :
125
208
sys .exit (1 )
126
209
0 commit comments