our_knp/examples/tools/hooks/tools_lib/formatter_cmd.py
int 8f43927575 Initial import: KNP experiments (examples, viz, cats-dogs, reports)
examples/ is based on KasperskyLab/knp at 55470ed6 with local changes
to the mnist-learn altai/blifat models, cuda-backend CMake and model_loader.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:17:15 +03:00

64 lines
2.7 KiB
Python

import difflib
import os
import subprocess as sp
from typing import List
from .command import Command
class FormatterCmd(Command):
"""Commands that format code: clang-format, uncrustify."""
def __init__(self, command: str, look_behind: str, args: List[str]):
super().__init__(command, look_behind, args)
self.no_diff_flag = "--no-diff" in self.args
self.file_flag = None
def set_diff_flag(self):
if self.no_diff_flag:
self.args.remove("--no-diff")
def compare_to_formatted(self, filename_str: str) -> None:
"""Compare the expected formatted output to file contents."""
# This string encode is from argparse, so we should be able to trust it.
filename = filename_str.encode()
actual = self.get_filelines(filename_str)
expected = self.get_formatted_lines(filename_str)
if self.edit_in_place:
# If edit in place is used, the formatter will fix in place with
# no stdout. So compare the before and after files for hook pass or fail.
expected = self.get_filelines(filename_str)
diff = list(
difflib.diff_bytes(difflib.unified_diff, actual, expected, fromfile=b"original", tofile=b"formatted")
)
if len(diff) > 0:
if not self.no_diff_flag:
header = filename + b"\n" + 20 * b"=" + b"\n"
self.stderr += header + b"\n".join(diff) + b"\n"
self.returncode = 1
def get_filename_opts(self, filename: str):
"""uncrustify, like clang-format, requires the -f flag to get stdout."""
if self.file_flag and not self.edit_in_place:
return [self.file_flag, filename]
return [filename]
def get_formatted_lines(self, filename: str) -> List[bytes]:
"""Get the expected output for a command applied to a file."""
filename_opts = self.get_filename_opts(filename)
args = [self.command, *self.args, *filename_opts]
child = sp.run(args, stdout=sp.PIPE, stderr=sp.PIPE)
if len(child.stderr) > 0 or child.returncode != 0:
problem = f"Unexpected Stderr/return code received when analyzing {filename}.\nArgs: {args}."
self.raise_error(problem, child.stdout.decode() + child.stderr.decode())
if child.stdout == b"":
return []
return child.stdout.split(b"\x0a")
def get_filelines(self, filename: str):
"""Get the lines in a file."""
if not os.path.exists(filename):
self.raise_error(f"File {filename} not found", "Check your path to the file.")
with open(filename, "rb") as f:
filetext = f.read()
return filetext.split(b"\x0a")