66# some specific cases (e.g., empty files, files that configure dataflow for queries).
77
88# The script takes a list of languages and processes the corresponding directories.
9+ # If the optional --check argument is provided, the script checks for missing annotations,
10+ # but does not modify any files.
911
10- # Usage: python3 add-overlay-annotations.py <language1> <language2> ...
12+ # Usage: python3 add-overlay-annotations.py [--check] <language1> <language2> ...
1113
1214# The script will modify the files in place and print the changes made.
1315# The script is designed to be run from the root of the repository.
@@ -128,15 +130,20 @@ def annotate_as_appropriate(filename, lines):
128130 return insert_toplevel_maybe_local_annotation (filename , lines )
129131
130132
131- def process_single_file (filename ):
133+ def process_single_file (write , filename ):
132134 '''
133- Process a single file, annotating it as appropriate and writing the changes back to the file.
135+ Process a single file, annotating it as appropriate.
136+ If write is set, the changes are written back to the file.
137+ Returns True if the file requires changes.
134138 '''
135139 old = [line for line in open (filename )]
136140
137141 annotate_result = annotate_as_appropriate (filename , old )
138142 if annotate_result is None :
139- return
143+ return False
144+
145+ if not write :
146+ return True
140147
141148 new = annotate_result [1 ]
142149
@@ -150,9 +157,18 @@ def process_single_file(filename):
150157 for line in new :
151158 out_file .write (line )
152159
160+ return True
161+
162+
163+ if len (sys .argv ) > 1 and sys .argv [1 ] == "--check" :
164+ check = True
165+ langs = sys .argv [2 :]
166+ else :
167+ check = False
168+ langs = sys .argv [1 :]
153169
154170dirs = []
155- for lang in sys . argv [ 1 :] :
171+ for lang in langs :
156172 if lang in ["cpp" , "go" , "csharp" , "java" , "javascript" , "python" , "ruby" , "rust" , "swift" ]:
157173 dirs .append (f"{ lang } /ql/lib" )
158174 else :
@@ -161,8 +177,24 @@ def process_single_file(filename):
161177if dirs :
162178 dirs .append ("shared" )
163179
180+ missingAnnotations = []
181+
164182for roots in dirs :
165183 for dirpath , dirnames , filenames in os .walk (roots ):
166184 for filename in filenames :
167185 if filename .endswith (".qll" ) and not dirpath .endswith ("tutorial" ):
168- process_single_file (os .path .join (dirpath , filename ))
186+ path = os .path .join (dirpath , filename )
187+ res = process_single_file (not check , path )
188+ if check and res :
189+ missingAnnotations .append (path )
190+
191+
192+ if len (missingAnnotations ) > 0 :
193+ print ("The following files have no overlay annotations:" )
194+ for path in missingAnnotations [:10 ]:
195+ print ("- " + path )
196+ if len (missingAnnotations ) > 10 :
197+ print ("and " + str (len (missingAnnotations ) - 10 ) + " additional files." )
198+ print ()
199+ print ("Please manually add overlay annotations or use the config/add-overlay-annotations.py script to automatically add sensible default overlay annotations." )
200+ exit (- 1 )
0 commit comments