mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-03-28 14:56:19 +01:00
misc: format QML files using the python format script
+ Requires that the Qt path is supplied when calling build.py --init. + format.py now also takes a --qt argument to specify the Qt path, used to locate qmlformat. + format.py takes a --type argument to specify the type of files to format (qml, cpp, or both). qmlformat is called with `--normalize` and `--force`. Gitlab: #1059 Change-Id: Id9ff4b17018370696792b44f55ed2f4bc8091193
This commit is contained in:
parent
a8f48df4f9
commit
ae1cde4dc1
4 changed files with 104 additions and 30 deletions
|
@ -63,7 +63,7 @@ for getting the latest development versions; otherwise, you can use
|
||||||
submodule).
|
submodule).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./build.py --init
|
./build.py --init [--qt=<path/to/qt> (this is required for qmlformatting to work)]
|
||||||
```
|
```
|
||||||
|
|
||||||
Then you will need to install dependencies:
|
Then you will need to install dependencies:
|
||||||
|
|
|
@ -29,7 +29,7 @@ For more information about the jami project, see the following:
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- Coding style is managed by the clang-format, if you want to contribute, please use the pre-commit hook automatically installed with `./build.py --init`
|
- Coding style is managed by the clang-format and qmlformat, if you want to contribute, please use the pre-commit hook automatically installed with `./build.py --init --qt=<path/to/qt>`
|
||||||
- We use gerrit for our review. Please read about [working with Gerrit](https://docs.jami.net/developer/working-with-gerrit.html) if you want to submit patches.
|
- We use gerrit for our review. Please read about [working with Gerrit](https://docs.jami.net/developer/working-with-gerrit.html) if you want to submit patches.
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
32
build.py
32
build.py
|
@ -304,18 +304,37 @@ def run_dependencies(args):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def run_init():
|
def run_init(args):
|
||||||
|
"""Initialize the git submodules and install the commit-msg hook."""
|
||||||
subprocess.run(["git", "submodule", "update", "--init"],
|
subprocess.run(["git", "submodule", "update", "--init"],
|
||||||
check=True)
|
check=True)
|
||||||
|
|
||||||
hooks_directories = ['.git/hooks/', f'.git/modules/daemon/hooks']
|
client_hooks_dir = '.git/hooks'
|
||||||
for hooks_dir in hooks_directories:
|
daemon_hooks_dir = '.git/modules/daemon/hooks'
|
||||||
|
|
||||||
|
print("Installing commit-msg hooks...")
|
||||||
|
# Copy the commit-msg hook to all modules in the same way.
|
||||||
|
for hooks_dir in [client_hooks_dir, daemon_hooks_dir]:
|
||||||
if not os.path.exists(hooks_dir):
|
if not os.path.exists(hooks_dir):
|
||||||
os.makedirs(hooks_dir)
|
os.makedirs(hooks_dir)
|
||||||
copy_file("./extras/scripts/commit-msg",
|
copy_file("./extras/scripts/commit-msg",
|
||||||
os.path.join(hooks_dir, "commit-msg"))
|
os.path.join(hooks_dir, "commit-msg"))
|
||||||
execute_script(['./extras/scripts/format.py --install %(path)s'],
|
|
||||||
{"path": hooks_dir})
|
print("Installing pre-commit hooks...")
|
||||||
|
format_script = "./extras/scripts/format.py"
|
||||||
|
# Prepend with the python executable if on Windows (not WSL).
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
format_script = f'python {format_script}'
|
||||||
|
# The client submodule has QML files, so we need to run qmlformat on it,
|
||||||
|
# and thus need to supply the Qt path.
|
||||||
|
execute_script([f'{format_script} --install {client_hooks_dir}'
|
||||||
|
f' --qt {args.qt}' if args.qt else ''],
|
||||||
|
{"path": client_hooks_dir})
|
||||||
|
|
||||||
|
# The daemon submodule has no QML files, so we don't need to run
|
||||||
|
# qmlformat on it, and thus don't need to supply the Qt path.
|
||||||
|
execute_script([f'{format_script} --install {daemon_hooks_dir}'],
|
||||||
|
{"path": daemon_hooks_dir})
|
||||||
|
|
||||||
|
|
||||||
def copy_file(src, dest):
|
def copy_file(src, dest):
|
||||||
|
@ -651,7 +670,8 @@ def main():
|
||||||
run_dependencies(parsed_args)
|
run_dependencies(parsed_args)
|
||||||
|
|
||||||
elif parsed_args.init:
|
elif parsed_args.init:
|
||||||
run_init()
|
run_init(parsed_args)
|
||||||
|
|
||||||
elif parsed_args.clean:
|
elif parsed_args.clean:
|
||||||
run_clean()
|
run_clean()
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
Clang format C/C++ source files with clang-format.
|
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.
|
Also optionally installs a pre-commit hook to run this script.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
@ -18,16 +19,34 @@ import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
import argparse
|
import argparse
|
||||||
import shutil
|
import shutil
|
||||||
|
from platform import uname
|
||||||
|
|
||||||
CFVERSION = "9"
|
CFVERSION = "9"
|
||||||
CLANGFORMAT = ""
|
CLANGFORMAT = ""
|
||||||
|
|
||||||
|
QMLFORMAT = None
|
||||||
|
|
||||||
|
|
||||||
def command_exists(cmd):
|
def command_exists(cmd):
|
||||||
""" Check if a command exists """
|
""" Check if a command exists """
|
||||||
return shutil.which(cmd) is not None
|
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):
|
def clang_format_file(filename):
|
||||||
""" Format a file using clang-format """
|
""" Format a file using clang-format """
|
||||||
if os.path.isfile(filename):
|
if os.path.isfile(filename):
|
||||||
|
@ -36,18 +55,35 @@ def clang_format_file(filename):
|
||||||
|
|
||||||
def clang_format_files(files):
|
def clang_format_files(files):
|
||||||
""" Format a list of files """
|
""" Format a list of files """
|
||||||
|
if not files:
|
||||||
|
return
|
||||||
for filename in files:
|
for filename in files:
|
||||||
print(f"Formatting: {filename}", end='\r')
|
print(f"Formatting: {filename}", end='\r')
|
||||||
clang_format_file(filename)
|
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')
|
||||||
|
extra_args = ['--normalize', '--force']
|
||||||
|
subprocess.call([QMLFORMAT, '--inplace', filename] + extra_args)
|
||||||
|
# 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():
|
def exit_if_no_files():
|
||||||
""" Exit if no files to format """
|
""" Exit if no files to format """
|
||||||
print("No files to format")
|
print("No files to format")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
def install_hook(hooks_path):
|
def install_hook(hooks_path, qt_path=None):
|
||||||
""" Install a pre-commit hook to run this script """
|
""" Install a pre-commit hook to run this script """
|
||||||
if not os.path.isdir(hooks_path):
|
if not os.path.isdir(hooks_path):
|
||||||
print(f"{hooks_path} path does not exist")
|
print(f"{hooks_path} path does not exist")
|
||||||
|
@ -55,7 +91,8 @@ def install_hook(hooks_path):
|
||||||
print(f"Installing pre-commit hook in {hooks_path}")
|
print(f"Installing pre-commit hook in {hooks_path}")
|
||||||
with open(os.path.join(hooks_path, "pre-commit"),
|
with open(os.path.join(hooks_path, "pre-commit"),
|
||||||
"w", encoding="utf-8") as file:
|
"w", encoding="utf-8") as file:
|
||||||
file.write(os.path.realpath(sys.argv[0]))
|
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)
|
os.chmod(os.path.join(hooks_path, "pre-commit"), 0o755)
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,7 +123,7 @@ def get_files(file_types, recursive=True, committed_only=False):
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""Check if clang-format is installed, and format files."""
|
"""Check for formatter installations, install hooks, and format files."""
|
||||||
global CLANGFORMAT # pylint: disable=global-statement
|
global CLANGFORMAT # pylint: disable=global-statement
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Format source filess with a clang-format")
|
description="Format source filess with a clang-format")
|
||||||
|
@ -94,33 +131,50 @@ def main():
|
||||||
help="format all files instead of only committed ones")
|
help="format all files instead of only committed ones")
|
||||||
parser.add_argument("-i", "--install", metavar="PATH",
|
parser.add_argument("-i", "--install", metavar="PATH",
|
||||||
help="install a pre-commit hook to run this script")
|
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()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if not command_exists("clang-format-" + CFVERSION):
|
if args.type in ["cpp", "both"]:
|
||||||
if not command_exists("clang-format"):
|
if not command_exists("clang-format-" + CFVERSION):
|
||||||
print("Required version of clang-format not found")
|
if not command_exists("clang-format"):
|
||||||
sys.exit(1)
|
print("Required version of clang-format not found")
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
CLANGFORMAT = "clang-format"
|
||||||
else:
|
else:
|
||||||
CLANGFORMAT = "clang-format"
|
CLANGFORMAT = "clang-format-" + CFVERSION
|
||||||
|
print("Using source formatter: " + CLANGFORMAT)
|
||||||
|
|
||||||
|
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:
|
else:
|
||||||
CLANGFORMAT = "clang-format-" + CFVERSION
|
print("No qmlformat found, can't format QML files")
|
||||||
|
|
||||||
if args.install:
|
if args.install:
|
||||||
install_hook(args.install)
|
install_hook(args.install, args.qt)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
if args.all:
|
src_files = get_files([".cpp", ".cxx", ".cc", ".h", ".hpp"],
|
||||||
print("Formatting all files...")
|
committed_only=not args.all)
|
||||||
# Find all files in the recursively in the current directory.
|
qml_files = get_files([".qml"], committed_only=not args.all)
|
||||||
clang_format_files(get_files((".cpp", ".cxx", ".cc", ".h", ".hpp"),
|
|
||||||
committed_only=False))
|
if not src_files and not qml_files:
|
||||||
|
exit_if_no_files()
|
||||||
else:
|
else:
|
||||||
files = get_files((".cpp", ".cxx", ".cc", ".h", ".hpp"),
|
if src_files and args.type in ["cpp", "both"] and CLANGFORMAT:
|
||||||
committed_only=True)
|
print("Formatting source files...")
|
||||||
if not files:
|
clang_format_files(src_files)
|
||||||
exit_if_no_files()
|
if qml_files and args.type in ["qml", "both"] and QMLFORMAT:
|
||||||
print("Formatting committed source files...")
|
print("Formatting QML files...")
|
||||||
clang_format_files(files)
|
qml_format_files(qml_files)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Add table
Reference in a new issue