Skip to content

Fix tidy review write conflicts #130

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

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions cpp_linter/clang_tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ def _run_on_single_file(
) -> Tuple[str, str, Optional[TidyAdvice], Optional[FormatAdvice]]:
log_stream = worker_log_init(log_lvl)

format_advice = None
if format_cmd is not None and (
format_filter is None or format_filter.is_source_or_ignored(file.name)
):
format_advice = run_clang_format(
command=format_cmd,
file_obj=file,
style=args.style,
lines_changed_only=args.lines_changed_only,
format_review=args.format_review,
)

tidy_note = None
if tidy_cmd is not None and (
tidy_filter is None or tidy_filter.is_source_or_ignored(file.name)
Expand All @@ -62,18 +74,6 @@ def _run_on_single_file(
style=args.style,
)

format_advice = None
if format_cmd is not None and (
format_filter is None or format_filter.is_source_or_ignored(file.name)
):
format_advice = run_clang_format(
command=format_cmd,
file_obj=file,
style=args.style,
lines_changed_only=args.lines_changed_only,
format_review=args.format_review,
)

return file.name, log_stream.getvalue(), tidy_note, format_advice


Expand Down
43 changes: 38 additions & 5 deletions cpp_linter/clang_tools/clang_tidy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from pathlib import Path, PurePath
import re
import subprocess
import time
from typing import Tuple, Union, List, cast, Optional, Dict, Set
from ..loggers import logger
from ..common_fs import FileObj
Expand Down Expand Up @@ -246,7 +247,7 @@ def run_clang_tidy(
if tidy_review:
# clang-tidy overwrites the file contents when applying fixes.
# create a cache of original contents
original_buf = Path(file_obj.name).read_bytes()
original_buf = Path(filename).read_bytes()
cmds.append("--fix-errors") # include compiler-suggested fixes
cmds.append(filename)
logger.info('Running "%s"', " ".join(cmds))
Expand All @@ -260,10 +261,42 @@ def run_clang_tidy(
advice = parse_tidy_output(results.stdout.decode(), database=db_json)

if tidy_review:
# store the modified output from clang-tidy
advice.patched = Path(file_obj.name).read_bytes()
# re-write original file contents
Path(file_obj.name).write_bytes(original_buf)
timeout = time.monotonic_ns() + 1000000000
# wait 1s for file to become accessible
success = False
exception = None
while not success and time.monotonic_ns() < timeout:
try:
with open(filename, "r+b") as src:
# wait 1s for file to become readable
read_timeout = time.monotonic_ns() + 1000000000
while not src.readable() and time.monotonic_ns() < read_timeout:
pass # pragma: no cover
if src.readable():
advice.patched = b"".join(src.readlines())
src.seek(0) # back to start of file
else: # pragma: no cover
continue # we need those changes before overwriting them
# wait 1s for file to become writable
write_timeout = time.monotonic_ns() + 1000000000
while not src.writable() and time.monotonic_ns() < write_timeout:
pass # pragma: no cover
if src.writable():
src.write(original_buf)
success = True
break
except OSError as exc: # pragma: no cover
exception = exc
if not success: # pragma: no cover
logger.error(
"Failed to write back contents of file: %s.%s",
filename,
" timeout."
if not exception
else " {}: {}".format(
exception.__class__.__name__, ", ".join(exception.args)
),
)

return advice

Expand Down
Loading