Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clang-format and clang-tidy scripts: More robust algorithm to find correct executable #6041

Merged
merged 9 commits into from
Jan 3, 2024
1 change: 1 addition & 0 deletions requirements_test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ asyncmock==0.4.2
hypothesis==5.49.0

clang-format==13.0.1 ; platform_machine != 'armv7l'
clang-tidy==14.0.6 ; platform_machine != 'armv7l'
clydebarrow marked this conversation as resolved.
Show resolved Hide resolved
40 changes: 17 additions & 23 deletions script/clang-format
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#!/usr/bin/env python3

from helpers import print_error_for_file, get_output, git_ls_files, filter_changed
from helpers import (
print_error_for_file,
get_output,
git_ls_files,
filter_changed,
get_binary,
)
import argparse
import click
import colorama
Expand All @@ -13,11 +19,12 @@ import sys
import threading


def run_format(args, queue, lock, failed_files):

def run_format(executable, args, queue, lock, failed_files):
"""Takes filenames out of queue and runs clang-format on them."""
while True:
path = queue.get()
invocation = ["clang-format-13"]
invocation = [executable]
if args.inplace:
invocation.append("-i")
else:
Expand Down Expand Up @@ -58,22 +65,6 @@ def main():
)
args = parser.parse_args()

try:
get_output("clang-format-13", "-version")
except:
print(
"""
Oops. It looks like clang-format is not installed.

Please check you can run "clang-format-13 -version" in your terminal and install
clang-format (v13) if necessary.

Note you can also upload your code as a pull request on GitHub and see the CI check
output to apply clang-format.
"""
)
return 1

files = []
for path in git_ls_files(["*.cpp", "*.h", "*.tcc"]):
files.append(os.path.relpath(path, os.getcwd()))
Expand All @@ -90,11 +81,12 @@ def main():

failed_files = []
try:
executable = get_binary("clang-format", 13)
task_queue = queue.Queue(args.jobs)
lock = threading.Lock()
for _ in range(args.jobs):
t = threading.Thread(
target=run_format, args=(args, task_queue, lock, failed_files)
target=run_format, args=(executable, args, task_queue, lock, failed_files)
)
t.daemon = True
t.start()
Expand All @@ -109,13 +101,15 @@ def main():
# Wait for all threads to be done.
task_queue.join()

except FileNotFoundError as ex:
return 1
except KeyboardInterrupt:
print()
print("Ctrl-C detected, goodbye.")
os.kill(0, 9)
return 2
clydebarrow marked this conversation as resolved.
Show resolved Hide resolved

sys.exit(len(failed_files))
return len(failed_files)


if __name__ == "__main__":
main()
sys.exit(main())
33 changes: 11 additions & 22 deletions script/clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ from helpers import (
load_idedata,
root_path,
basepath,
get_binary,
)
import argparse
import click
Expand All @@ -26,6 +27,7 @@ import tempfile
import threading



def clang_options(idedata):
cmd = []

Expand Down Expand Up @@ -110,10 +112,10 @@ def clang_options(idedata):
return cmd


def run_tidy(args, options, tmpdir, queue, lock, failed_files):
def run_tidy(executable, args, options, tmpdir, queue, lock, failed_files):
while True:
path = queue.get()
invocation = ["clang-tidy-14"]
invocation = [executable]

if tmpdir is not None:
invocation.append("--export-fixes")
Expand Down Expand Up @@ -193,22 +195,6 @@ def main():
)
args = parser.parse_args()

try:
get_output("clang-tidy-14", "-version")
except:
print(
"""
Oops. It looks like clang-tidy-14 is not installed.

Please check you can run "clang-tidy-14 -version" in your terminal and install
clang-tidy (v14) if necessary.

Note you can also upload your code as a pull request on GitHub and see the CI check
output to apply clang-tidy.
"""
)
return 1

idedata = load_idedata(args.environment)
options = clang_options(idedata)

Expand Down Expand Up @@ -242,12 +228,13 @@ def main():

failed_files = []
try:
executable = get_binary("clang-tidy", 14)
task_queue = queue.Queue(args.jobs)
lock = threading.Lock()
for _ in range(args.jobs):
t = threading.Thread(
target=run_tidy,
args=(args, options, tmpdir, task_queue, lock, failed_files),
args=(executable, args, options, tmpdir, task_queue, lock, failed_files),
)
t.daemon = True
t.start()
Expand All @@ -262,12 +249,14 @@ def main():
# Wait for all threads to be done.
task_queue.join()

except FileNotFoundError as ex:
return 1
except KeyboardInterrupt:
print()
print("Ctrl-C detected, goodbye.")
if tmpdir:
shutil.rmtree(tmpdir)
os.kill(0, 9)
return 2

if args.fix and failed_files:
print("Applying fixes ...")
Expand All @@ -277,8 +266,8 @@ def main():
print("Error applying fixes.\n", file=sys.stderr)
raise

sys.exit(len(failed_files))
return len(failed_files)


if __name__ == "__main__":
main()
sys.exit(main())
36 changes: 36 additions & 0 deletions script/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,39 @@ def load_idedata(environment):

temp_idedata.write_text(json.dumps(data, indent=2) + "\n")
return data


def get_binary(name: str, version: str) -> str:
binary_file = f"{name}-{version}"
try:
result = subprocess.check_output([binary_file, "-version"])
if result.returncode == 0:
return binary_file
except Exception:
pass
binary_file = name
try:
result = subprocess.run(
[binary_file, "-version"], text=True, capture_output=True
)
if result.returncode == 0 and (f"version {version}") in result.stdout:
return binary_file
raise FileNotFoundError(f"{name} not found")

except FileNotFoundError as ex:
print(
f"""
Oops. It looks like {name} is not installed. It should be available under venv/bin
and in PATH after running in turn:
script/setup
source venv/bin/activate.

Please confirm you can run "{name} -version" or "{name}-{version} -version"
in your terminal and install
{name} (v{version}) if necessary.

Note you can also upload your code as a pull request on GitHub and see the CI check
output to apply {name}
"""
)
raise
4 changes: 4 additions & 0 deletions script/setup
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ pip3 install --no-use-pep517 -e .
pre-commit install

script/platformio_install_deps.py platformio.ini --libraries --tools --platforms

echo
echo
echo "Virtual environment created; source venv/bin/activate to use it"
clydebarrow marked this conversation as resolved.
Show resolved Hide resolved
Loading