Upgrade to clang-format-19

Fixes #4577
This commit is contained in:
Paulo Matos committed 2025-07-10 17:11:44 +02:00
1 parent 95b4618833
commit c7b7cbcac1
4 files changed
+9 -136

No files matched your search

+5 -11
View File
@@ -40,11 +40,8 @@ jobs:
echo "Formatting files:"
echo "$CHANGED_FILES"
- name: Check for correct clang-format version
run: clang-format --version | grep -qF '16.0.6'
- name: Check git-clang-format-16 exists
run: which git-clang-format-16
- name: Check git-clang-format-19 exists
run: which git-clang-format-19
- name: Setup Python env
uses: actions/setup-python@v4
@@ -58,19 +55,16 @@ jobs:
- name: Run code formatter
env:
CLANG_FORMAT_PATH: 'git-clang-format-16'
CLANG_FORMAT_PATH: 'git-clang-format-19'
GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
START_REV: ${{ github.event.pull_request.base.sha }}
END_REV: ${{ github.event.pull_request.head.sha }}
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
# TODO(pmatos): Once we adopt v18, we should be able
# to take advantage of the new --diff_from_common_commit option
# explicitly in code-format-helper.py and not have to diff starting at
# the merge base.
# Using --diff_from_common_commit option available in clang-format-19
run: |
python ./External/code-format-helper/code-format-helper.py \
--repo "FEX-emu/FEX" \
--issue-number $GITHUB_PR_NUMBER \
--start-rev $(git merge-base $START_REV $END_REV) \
--start-rev $START_REV \
--end-rev $END_REV \
--changed-files "$CHANGED_FILES"
+3 -8
View File
@@ -169,14 +169,9 @@ View the diff from {self.name} here.
class ClangFormatHelper(FormatHelper):
name = "clang-format"
name = "git-clang-format"
friendly_name = "C/C++ code formatter"
@property
def cformat_wrapper_path(self) -> str:
relpath = "../../Scripts/clang-format.py"
curpath = os.path.dirname(os.path.abspath(__file__))
return os.path.abspath(os.path.normpath(os.path.join(curpath, relpath)))
@property
def instructions(self) -> str:
@@ -199,7 +194,7 @@ class ClangFormatHelper(FormatHelper):
def clang_fmt_path(self) -> str:
if "CLANG_FORMAT_PATH" in os.environ:
return os.environ["CLANG_FORMAT_PATH"]
return "git-clang-format"
return "git-clang-format-19"
def has_tool(self) -> bool:
cmd = [self.clang_fmt_path, "-h"]
@@ -217,8 +212,8 @@ class ClangFormatHelper(FormatHelper):
cf_cmd = [
self.clang_fmt_path,
f"--binary={self.cformat_wrapper_path}",
"--diff",
"--diff_from_common_commit",
]
if args.start_rev and args.end_rev:
-116
View File
@@ -1,116 +0,0 @@
#!/usr/bin/env python3
# Imported from LLVM
# It's basically a clang-format wrapper with .clang-format-ignore support.
# Can be removed once we adopt Clang19, which supports this out of the box.
#
# This is called by git-clang-format and it works in two modes.
# It has a path in the command line to format, and it will output the result post format to stdout.
# Or it has -assume-filename=<path> in the command line, and the file is passed via stdin.
# Post format output will be given in stdout.
import subprocess
import sys
import os
import re
import fnmatch
# Wrapper globals
project_root = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..")
ignore_file_path = os.path.join(project_root, ".clang-format-ignore")
clang_format_command = os.getenv("CLANG_FORMAT") or "clang-format"
def glob_to_regex(pattern):
# Normalize directory separators
pattern = pattern.replace("\\", "/")
return fnmatch.translate(pattern)
def load_ignore_patterns(ignore_file_path):
# Check if the file exists
if not os.path.exists(ignore_file_path):
raise FileNotFoundError(f"No such file: '{ignore_file_path}'")
with open(ignore_file_path, "r") as file:
lines = file.readlines()
patterns = []
for line in lines:
line = line.strip()
if line and not line.startswith("#"): # Ignore empty lines and comments
pattern = glob_to_regex(line)
patterns.append(re.compile(pattern))
# Print the number of patterns found
print(f"Number of patterns found: {len(patterns)}", file=sys.stderr)
return patterns
def normalize_path(file_path):
absolute_path = os.path.abspath(file_path)
normalized_path = absolute_path.replace("\\", "/")
return normalized_path
def should_ignore(file_path, ignore_patterns):
normalized_path = normalize_path(file_path)
relative_path = os.path.relpath(normalized_path, start=project_root).replace(
"\\", "/"
)
for pattern in ignore_patterns:
if pattern.match(relative_path):
return True
return False
def main():
ignore_patterns = load_ignore_patterns(ignore_file_path)
assume_filename = None
args = sys.argv[1:]
# Extract and handle `-assume-filename=<filename>`
args_filtered = []
for arg in args:
if arg.startswith("-assume-filename="):
_, assume_filename = arg.split("=", 1)
else:
args_filtered.append(arg)
args = args_filtered
if assume_filename is not None:
if should_ignore(assume_filename, ignore_patterns):
print(
f"Ignoring {assume_filename} based on ignore patterns.", file=sys.stderr
)
sys.stdout.write(sys.stdin.read())
sys.exit(0)
input_stream = sys.stdin.read()
subprocess.run(
[clang_format_command, "-assume-filename=" + assume_filename] + args,
input=input_stream.encode(),
check=True,
)
else:
# Find all valid file paths
valid_paths = [arg for arg in args if os.path.isfile(arg)]
if len(valid_paths) != 1:
print(
"Error: Exactly one valid file path is required when -assume-filename is not present.",
file=sys.stderr,
)
sys.exit(1)
file_path = valid_paths[0]
if should_ignore(file_path, ignore_patterns):
print(f"Ignoring {file_path} based on ignore patterns.", file=sys.stderr)
with open(file_path, "r") as file:
sys.stdout.write(file.read())
sys.exit(0)
subprocess.run([clang_format_command] + args, check=True)
if __name__ == "__main__":
main()
+1 -1
View File
@@ -10,5 +10,5 @@ fi
# Reformat whole tree.
# This is run by the reformat target.
git ls-files -z '*.cpp' '*.h' '*.inl' | xargs -0 -n 1 -P $(nproc) python3 Scripts/clang-format.py -i
git ls-files -z '*.cpp' '*.h' '*.inl' | xargs -0 -n 1 -P $(nproc) clang-format-19 -i
cd $DIR