From b3181b5493b4951c863b3fea96863ce6df5a78ce Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Thu, 3 Aug 2023 14:22:45 +0800 Subject: [PATCH] Add clang-format script --- scripts/clang-format.py | 123 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100755 scripts/clang-format.py diff --git a/scripts/clang-format.py b/scripts/clang-format.py new file mode 100755 index 00000000..36efbf57 --- /dev/null +++ b/scripts/clang-format.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 +# +# SPDX-FileCopyrightText: 2021 Anton Kochkov +# SPDX-License-Identifier: LGPL-3.0-only + +import argparse +import glob +import itertools +import subprocess +import sys + +from git import Repo + +dirlist = [ + "src", +] + +skiplist = [ + "translations", +] + +patterns = ["*.cpp", "*.h", "*.hpp"] + + +def should_scan(filename): + return any(directory in filename for directory in dirlist) and any( + pattern[1:] in filename for pattern in patterns + ) + + +def skip(filename): + return any(skipfile in filename for skipfile in skiplist) + + +def get_matching_files(): + for directory, pattern in itertools.product(dirlist, patterns): + for filename in glob.iglob(directory + "/**/" + pattern, recursive=True): + if not skip(filename): + yield filename + + +def get_edited_files(args): + repo = Repo() + + for diff in repo.index.diff(args.diff): + filename = diff.a_path + if should_scan(filename) and not skip(filename): + yield filename + + +def build_command(clangformat, check, filenames, verbose): + cmd = [clangformat, "--style=file"] + if verbose: + cmd += ["--verbose"] + if check: + cmd += ["--Werror", "--dry-run"] + else: + cmd += ["-i"] + return cmd + filenames + + +def format_files(args, files): + if len(files) == 0: + print("No C files to format.") + sys.exit(0) + cmd = build_command(args.clang_format, args.check, files, args.verbose) + r = subprocess.run(cmd, check=False) + sys.exit(r.returncode) + + +def get_file(args): + filename = args.file + if should_scan(filename) and not skip(filename): + return [filename] + + return [] + + +def get_files(args): + if args.diff: + return get_edited_files(args) + + if args.file: + return get_file(args) + + return get_matching_files() + + +def process(args): + files = get_files(args) + format_files(args, list(files)) + + +def parse(): + parser = argparse.ArgumentParser(description="Clang format the rizin project") + + parser.add_argument( + "-C", "--clang-format", default="clang-format", help="path of clang-format" + ) + parser.add_argument( + "-c", "--check", action="store_true", help="enable the check mode" + ) + parser.add_argument( + "-v", "--verbose", action="store_true", help="use verbose output" + ) + parser.add_argument("-f", "--file", help="formats (or checks) only the given file") + parser.add_argument( + "-d", + "--diff", + type=str, + default=None, + help="format all modified file related to branch", + ) + return parser.parse_args() + + +def main(): + args = parse() + process(args) + + +if __name__ == "__main__": + main()