1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-04-22 14:12:03 +02:00
jami-client-qt/extras/scripts/format.py
Andreas Traczyk f3a578d8ac misc: migrate source formatting script to python
Devs will need to remove the existing pre-commit hook or regenerate the hook with `build.py --init`.

Gitlab: #1059
Change-Id: I1cec9150c7781d769cb229dfd170a9dcfc819edb
2023-04-13 13:08:57 -04:00

127 lines
4 KiB
Python
Executable file

#!/usr/bin/env python3
"""
Clang format C/C++ source files with clang-format.
Also optionally installs a pre-commit hook to run this script.
Usage:
format.py [-a | --all] [-i | --install PATH]
-a | --all
Format all files instead of only committed ones
-i | --install PATH
Install a pre-commit hook to run this script in PATH
"""
import os
import sys
import subprocess
import argparse
import shutil
CFVERSION = "9"
CLANGFORMAT = ""
def command_exists(cmd):
""" Check if a command exists """
return shutil.which(cmd) is not None
def clang_format_file(filename):
""" Format a file using clang-format """
if os.path.isfile(filename):
subprocess.call([CLANGFORMAT, "-i", "-style=file", filename])
def clang_format_files(files):
""" Format a list of files """
for filename in files:
print(f"Formatting: {filename}", end='\r')
clang_format_file(filename)
def exit_if_no_files():
""" Exit if no files to format """
print("No files to format")
sys.exit(0)
def install_hook(hooks_path):
""" Install a pre-commit hook to run this script """
if not os.path.isdir(hooks_path):
print(f"{hooks_path} path does not exist")
sys.exit(1)
print(f"Installing pre-commit hook in {hooks_path}")
with open(os.path.join(hooks_path, "pre-commit"),
"w", encoding="utf-8") as file:
file.write(os.path.realpath(sys.argv[0]))
os.chmod(os.path.join(hooks_path, "pre-commit"), 0o755)
def get_files(file_types, recursive=True, committed_only=False):
"""
Get a list of files in the src directory [and subdirectories].
Filters by file types and whether the file is committed.
"""
file_list = []
committed_files = []
if committed_only:
committed_files = subprocess.check_output(
"git diff-index --cached --name-only HEAD",
shell=True).decode().strip().split('\n')
for dirpath, _, filenames in os.walk('src'):
for filename in filenames:
file_path = os.path.join(dirpath, filename)
if file_types and not any(file_path.endswith(file_type)
for file_type in file_types):
continue # Skip files that don't match any file types.
if committed_only:
if file_path not in committed_files:
continue # Skip uncommitted files.
file_list.append(file_path)
if not recursive:
break # Stop searching if not recursive.
return file_list
def main():
"""Check if clang-format is installed, and format files."""
global CLANGFORMAT # pylint: disable=global-statement
parser = argparse.ArgumentParser(
description="Format source filess with a clang-format")
parser.add_argument("-a", "--all", action="store_true",
help="format all files instead of only committed ones")
parser.add_argument("-i", "--install", metavar="PATH",
help="install a pre-commit hook to run this script")
args = parser.parse_args()
if not command_exists("clang-format-" + CFVERSION):
if not command_exists("clang-format"):
print("Required version of clang-format not found")
sys.exit(1)
else:
CLANGFORMAT = "clang-format"
else:
CLANGFORMAT = "clang-format-" + CFVERSION
if args.install:
install_hook(args.install)
sys.exit(0)
if args.all:
print("Formatting all files...")
# Find all files in the recursively in the current directory.
clang_format_files(get_files((".cpp", ".cxx", ".cc", ".h", ".hpp"),
committed_only=False))
else:
files = get_files((".cpp", ".cxx", ".cc", ".h", ".hpp"),
committed_only=True)
if not files:
exit_if_no_files()
print("Formatting committed source files...")
clang_format_files(files)
if __name__ == "__main__":
main()