1414import re
1515import subprocess
1616import sys
17+ import tempfile
1718from pathlib import Path
1819from typing import List , Optional , Set
1920
@@ -124,7 +125,36 @@ def filter_source_files(compile_commands: List[dict],
124125 return sorted (source_files )
125126
126127
128+ def create_sanitized_compile_commands (compile_commands : List [dict ],
129+ original_path : Path ) -> Path :
130+ """Create a temporary sanitized compile_commands.json file.
131+
132+ Returns the path to the temporary file that should be used with clang-tidy.
133+ """
134+ # Create temp file in the same directory as the original for consistency
135+ temp_dir = original_path .parent
136+ temp_fd , temp_path = tempfile .mkstemp (
137+ suffix = '_sanitized.json' ,
138+ prefix = 'compile_commands_' ,
139+ dir = temp_dir ,
140+ text = True
141+ )
142+
143+ try :
144+ with os .fdopen (temp_fd , 'w' ) as f :
145+ json .dump (compile_commands , f , indent = 2 )
146+ return Path (temp_path )
147+ except Exception as e :
148+ # Clean up on error
149+ try :
150+ os .unlink (temp_path )
151+ except :
152+ pass
153+ raise RuntimeError (f"Failed to create sanitized compile commands: { e } " )
154+
155+
127156def run_clang_tidy (source_files : List [str ],
157+ compile_commands : List [dict ],
128158 compile_commands_path : Path ,
129159 extra_args : List [str ],
130160 fix : bool = False ,
@@ -134,46 +164,62 @@ def run_clang_tidy(source_files: List[str],
134164 print ("No source files to analyze." )
135165 return 0
136166
137- # Process files in batches to avoid command line length limits on Windows
138- # Windows cmd.exe has a limit of ~8191 characters
139- BATCH_SIZE = 50 # Conservative batch size for Windows compatibility
140- total_files = len (source_files )
141- batches = [source_files [i :i + BATCH_SIZE ] for i in range (0 , total_files , BATCH_SIZE )]
142-
143- print (f"Running clang-tidy on { total_files } files in { len (batches )} batch(es)..." )
144- if jobs > 1 :
145- print (f"Note: Parallel execution with { jobs } jobs not implemented yet." )
167+ # Create a temporary sanitized compile_commands.json
168+ print ("Creating sanitized compile commands..." )
169+ temp_compile_commands = create_sanitized_compile_commands (
170+ compile_commands ,
171+ compile_commands_path
172+ )
146173
147- overall_returncode = 0
148- for batch_num , batch in enumerate (batches , 1 ):
149- cmd = [
150- 'clang-tidy' ,
151- f'-p={ compile_commands_path .parent } ' ,
152- ]
153-
154- if fix :
155- cmd .append ('--fix' )
156-
157- if extra_args :
158- cmd .extend (extra_args )
174+ try :
175+ # Process files in batches to avoid command line length limits on Windows
176+ # Windows cmd.exe has a limit of ~8191 characters
177+ BATCH_SIZE = 50 # Conservative batch size for Windows compatibility
178+ total_files = len (source_files )
179+ batches = [source_files [i :i + BATCH_SIZE ] for i in range (0 , total_files , BATCH_SIZE )]
159180
160- # Add source files for this batch
161- cmd .extend (batch )
181+ print (f"Running clang-tidy on { total_files } files in { len (batches )} batch(es)..." )
182+ if jobs > 1 :
183+ print (f"Note: Parallel execution with { jobs } jobs not implemented yet." )
162184
163- print (f"\n Batch { batch_num } /{ len (batches )} : Analyzing { len (batch )} file(s)..." )
185+ overall_returncode = 0
186+ for batch_num , batch in enumerate (batches , 1 ):
187+ cmd = [
188+ 'clang-tidy' ,
189+ f'-p={ temp_compile_commands .parent } ' ,
190+ ]
191+
192+ if fix :
193+ cmd .append ('--fix' )
194+
195+ if extra_args :
196+ cmd .extend (extra_args )
197+
198+ # Add source files for this batch
199+ cmd .extend (batch )
200+
201+ print (f"\n Batch { batch_num } /{ len (batches )} : Analyzing { len (batch )} file(s)..." )
202+
203+ try :
204+ result = subprocess .run (cmd , cwd = find_project_root ())
205+ if result .returncode != 0 :
206+ overall_returncode = result .returncode
207+ except FileNotFoundError :
208+ print ("Error: clang-tidy not found. Please install clang-tidy." )
209+ return 1
210+ except KeyboardInterrupt :
211+ print ("\n Interrupted by user." )
212+ return 130
164213
165- try :
166- result = subprocess .run (cmd , cwd = find_project_root ())
167- if result .returncode != 0 :
168- overall_returncode = result .returncode
169- except FileNotFoundError :
170- print ("Error: clang-tidy not found. Please install clang-tidy." )
171- return 1
172- except KeyboardInterrupt :
173- print ("\n Interrupted by user." )
174- return 130
214+ return overall_returncode
175215
176- return overall_returncode
216+ finally :
217+ # Clean up the temporary file
218+ try :
219+ temp_compile_commands .unlink ()
220+ print (f"Cleaned up temporary file: { temp_compile_commands .name } " )
221+ except Exception as e :
222+ print (f"Warning: Could not remove temporary file { temp_compile_commands } : { e } " )
177223
178224
179225def main ():
@@ -276,6 +322,7 @@ def main():
276322 # Run clang-tidy
277323 return run_clang_tidy (
278324 source_files ,
325+ compile_commands ,
279326 compile_commands_path ,
280327 args .clang_tidy_args ,
281328 args .fix ,
0 commit comments