mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-04-21 21:52:03 +02:00

→ base 64 → Base64 cancelled → canceled {cannot, can't, couldn't} → unable to inexistent → nonexistent informations → information not possible → impossible retrieven → retrieved SIP try → attempt URI WebEngine wish → want Can this replace https://review.jami.net/c/jami-client-qt/+/27607 ? Change-Id: I21e1615a0c6e2979f02f913093c503c03ab32c82
182 lines
6.1 KiB
Python
Executable file
182 lines
6.1 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
"""
|
|
Clang format C/C++ source files with clang-format (C/C++), and
|
|
qmlformat (QML) if installed.
|
|
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
|
|
from platform import uname
|
|
|
|
CFVERSION = "9"
|
|
CLANGFORMAT = None
|
|
|
|
QMLFORMAT = None
|
|
|
|
|
|
def command_exists(cmd):
|
|
""" Check if a command exists """
|
|
return shutil.which(cmd) is not None
|
|
|
|
|
|
def find_qmlformat(qt_path):
|
|
"""Find the path to the qmlformat binary."""
|
|
|
|
# Correct the path if it's a Windows WSL path.
|
|
is_windows = os.name == "nt"
|
|
if 'Microsoft' in uname().release:
|
|
qt_path = qt_path.replace('C:', '/mnt/c')
|
|
is_windows = True
|
|
|
|
# Check if qmlformat is in a subdirectory called bin.
|
|
qmlformat_path = os.path.join(qt_path, "bin", "qmlformat")
|
|
qmlformat_path += ".exe" if is_windows else ""
|
|
return qmlformat_path if os.path.exists(qmlformat_path) else 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 """
|
|
if not files:
|
|
return
|
|
for filename in files:
|
|
print(f"Formatting: {filename}", end='\r')
|
|
clang_format_file(filename)
|
|
|
|
|
|
def qml_format_files(files):
|
|
""" Format a file using qmlformat """
|
|
if QMLFORMAT is None or not files:
|
|
return
|
|
for filename in files:
|
|
if os.path.isfile(filename):
|
|
print(f"Formatting: {filename}", end='\r')
|
|
subprocess.call([QMLFORMAT, '--inplace', filename])
|
|
# This may generate a backup file (ending with ~), so delete it.
|
|
backup_file = filename + "~"
|
|
if os.path.isfile(backup_file):
|
|
os.remove(backup_file)
|
|
|
|
|
|
def exit_if_no_files():
|
|
""" Exit if no files to format """
|
|
print("No files to format")
|
|
sys.exit(0)
|
|
|
|
|
|
def install_hook(hooks_path, qt_path=None):
|
|
""" 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])
|
|
+ f' --qt={qt_path}' if qt_path else '')
|
|
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 for formatter installations, install hooks, 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")
|
|
parser.add_argument("-q", "--qt", default=None,
|
|
help="The Qt root path")
|
|
# Add an option to only format a specific type (qml, cpp, or both)
|
|
parser.add_argument("-t", "--type", default="both",
|
|
help="The type of files to format (qml, cpp, or both)")
|
|
args = parser.parse_args()
|
|
|
|
if args.type in ["cpp", "both"]:
|
|
if command_exists("clang-format-" + CFVERSION):
|
|
CLANGFORMAT = "clang-format-" + CFVERSION
|
|
elif command_exists("clang-format"):
|
|
CLANGFORMAT = "clang-format"
|
|
|
|
if CLANGFORMAT is not None:
|
|
print("Using source formatter: " + CLANGFORMAT)
|
|
else:
|
|
print("clang-format not found, unable to format source files")
|
|
|
|
if args.qt is not None and args.type in ["qml", "both"]:
|
|
global QMLFORMAT # pylint: disable=global-statement
|
|
QMLFORMAT = find_qmlformat(args.qt)
|
|
if QMLFORMAT is not None:
|
|
print("Using qmlformatter: " + QMLFORMAT)
|
|
else:
|
|
print("qmlformat not found, unable to format QML files")
|
|
|
|
if args.install:
|
|
if CLANGFORMAT is not None or QMLFORMAT is not None:
|
|
install_hook(args.install, args.qt)
|
|
else:
|
|
print("No formatters found, skipping hook install")
|
|
sys.exit(0)
|
|
|
|
src_files = get_files([".cpp", ".cxx", ".cc", ".h", ".hpp"],
|
|
committed_only=not args.all)
|
|
qml_files = get_files([".qml"], committed_only=not args.all)
|
|
|
|
if not src_files and not qml_files:
|
|
exit_if_no_files()
|
|
else:
|
|
if src_files and args.type in ["cpp", "both"] and CLANGFORMAT:
|
|
print("Formatting source files…")
|
|
clang_format_files(src_files)
|
|
if qml_files and args.type in ["qml", "both"] and QMLFORMAT:
|
|
print("Formatting QML files…")
|
|
qml_format_files(qml_files)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|