chore: Enable clang-tidy include cleaner - #6947
Conversation
|
This PR has conflicts, please resolve them in order for the PR to be reviewed. |
|
All conflicts have been resolved. Assigned reviewers can now start or resume their review. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #6947 +/- ##
=========================================
- Coverage 81.6% 81.6% -0.0%
=========================================
Files 1010 1010
Lines 75992 75992
Branches 7603 7620 +17
=========================================
- Hits 62013 61988 -25
- Misses 13979 14004 +25
🚀 New features to boost your workflow:
|
| test.toplevel > test.jtx | ||
|
|
||
| Loop: test.jtx test.unit_test | ||
| test.unit_test == test.jtx |
There was a problem hiding this comment.
Note: yes we have more includes now but at least no newly added loops
| #include <openssl/crypto.h> | ||
| #include <openssl/evp.h> | ||
| #include <openssl/objects.h> | ||
| #include <openssl/objects.h> // IWYU pragma: keep |
There was a problem hiding this comment.
Why do we need these IWYU pragmas?
Could you please check that they are actually neeeded?
There was a problem hiding this comment.
Yes they are needed, without them clang-tidy would add obj_mac.h on mac etc. I also had to add the other one to ignores list
mathbunnyru
left a comment
There was a problem hiding this comment.
I have no idea how to review this, but lgtm
|
Stripped out Attaching the script here: #!/usr/bin/env python3
"""Strip #include-related changes from a unified diff file.
Identifies contiguous change blocks and drops them if they are include-related.
A block is include-related if ALL changes are #include/#pragma once, blanks, or comments.
Preprocessor guards (#if/#endif) are NOT considered include-related.
"""
import re, sys
def classify(text):
s = text.strip()
if s == '':
return 'blank'
if s.startswith('//'):
return 'comment'
if re.match(r'#\s*include\b', s):
return 'include'
if re.match(r'#\s*pragma\s+once', s):
return 'include'
return 'code'
def block_is_include_related(block):
"""A change block is include-related if:
- it has at least one include/pragma line, AND
- all other lines are blank/comment
"""
classes = [classify(bl[1:]) for bl in block]
has_include = 'include' in classes
has_code = 'code' in classes
if has_code:
return False
if has_include:
return True
# Only blanks and comments, no includes - still drop as trivial
return True
def process_diff(input_path, output_path):
with open(input_path, 'r') as f:
lines = f.readlines()
out = []
i = 0
while i < len(lines):
line = lines[i]
if line.startswith(('diff --git ', 'index ', '--- ', '+++ ', 'Binary files ')):
out.append(line)
i += 1
continue
m = re.match(r'^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)', line)
if not m:
out.append(line)
i += 1
continue
old_start, new_start, trailing = int(m.group(1)), int(m.group(3)), m.group(5)
i += 1
hunk_lines = []
while i < len(lines) and not lines[i].startswith(('diff --git ', '@@ ')):
hunk_lines.append(lines[i])
i += 1
# Split into segments and filter change blocks
filtered = []
j = 0
while j < len(hunk_lines):
hl = hunk_lines[j]
is_change = (hl.startswith('+') and not hl.startswith('+++')) or \
(hl.startswith('-') and not hl.startswith('---'))
if not is_change:
filtered.append(hl)
j += 1
continue
block = []
while j < len(hunk_lines):
h = hunk_lines[j]
ic = (h.startswith('+') and not h.startswith('+++')) or \
(h.startswith('-') and not h.startswith('---'))
if not ic:
break
block.append(h)
j += 1
if not block_is_include_related(block):
filtered.extend(block)
has_changes = any(
(l.startswith('+') and not l.startswith('+++')) or
(l.startswith('-') and not l.startswith('---'))
for l in filtered
)
if not has_changes:
continue
old_count = sum(1 for l in filtered if l.startswith(' ') or (l.startswith('-') and not l.startswith('---')))
new_count = sum(1 for l in filtered if l.startswith(' ') or (l.startswith('+') and not l.startswith('+++')))
out.append(f'@@ -{old_start},{old_count} +{new_start},{new_count} @@{trailing}\n')
out.extend(filtered)
# Remove file entries with no hunks
final = []
i = 0
while i < len(out):
if out[i].startswith('diff --git '):
file_block = [out[i]]
i += 1
while i < len(out) and not out[i].startswith(('diff --git ', '@@ ')):
file_block.append(out[i])
i += 1
if i < len(out) and out[i].startswith('@@ '):
final.extend(file_block)
else:
final.append(out[i])
i += 1
with open(output_path, 'w') as f:
f.writelines(final)
print(f"Written {len(final)} lines to {output_path}")
if __name__ == '__main__':
process_diff(sys.argv[1], sys.argv[2]) |
High Level Overview of Change
This PR enables the misc-include-cleaner check which automatically keeps the includes tidy.
As a bonus this PR also fixes clang-format to automatically detect and place the main include first, without having to add extra '//' markers to separate them.
Context of Change
Fixing clang-tidy for all source.
API Impact
No impact.