Skip to content

Commit a6c1aaf

Browse files
committed
build: use temporary sanitized compile_commands.json for clang-tidy
1 parent e8dc837 commit a6c1aaf

File tree

1 file changed

+82
-35
lines changed

1 file changed

+82
-35
lines changed

scripts/run-clang-tidy.py

Lines changed: 82 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import re
1515
import subprocess
1616
import sys
17+
import tempfile
1718
from pathlib import Path
1819
from 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+
127156
def 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"\nBatch {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"\nBatch {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("\nInterrupted 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("\nInterrupted 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

179225
def 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

Comments
 (0)