Source code for erc7730.lint.lint

from pathlib import Path

from pydantic import ValidationError
from rich import print

from erc7730 import ERC_7730_REGISTRY_CALLDATA_PREFIX, ERC_7730_REGISTRY_EIP712_PREFIX
from erc7730.common.output import ConsoleOutputAdder, FileOutputAdder, GithubAnnotationsAdder, OutputAdder
from erc7730.convert.convert_erc7730_input_to_resolved import ERC7730InputToResolved
from erc7730.lint import ERC7730Linter
from erc7730.lint.lint_base import MultiLinter
from erc7730.lint.lint_transaction_type_classifier import ClassifyTransactionTypeLinter
from erc7730.lint.lint_validate_abi import ValidateABILinter
from erc7730.lint.lint_validate_display_fields import ValidateDisplayFieldsLinter
from erc7730.model.input.descriptor import InputERC7730Descriptor


[docs] def lint_all_and_print_errors(paths: list[Path], gha: bool) -> bool: out = GithubAnnotationsAdder() if gha else ConsoleOutputAdder() lint_all(paths, out) if out.has_errors: print("[red]some errors found ❌[/red]") return False if out.has_warnings: print("[yellow]some warnings found ⚠️[/yellow]") return True print("[green]no issues found ✅[/green]") return True
[docs] def lint_all(paths: list[Path], out: OutputAdder) -> None: """ Lint all ERC-7730 descriptor files at given paths. Paths can be files or directories, in which case all JSON files in the directory are recursively linted. :param paths: paths to apply linter on :param out: output adder :return: output errors """ linter = MultiLinter( [ ValidateABILinter(), ValidateDisplayFieldsLinter(), ClassifyTransactionTypeLinter(), ] ) for path in paths: if path.is_file(): lint_file(path, linter, out) elif path.is_dir(): for file in path.rglob("*.json"): if file.name.startswith(ERC_7730_REGISTRY_CALLDATA_PREFIX) or file.name.startswith( ERC_7730_REGISTRY_EIP712_PREFIX ): lint_file(file, linter, out) else: raise ValueError(f"Invalid path: {path}")
[docs] def lint_file(path: Path, linter: ERC7730Linter, out: OutputAdder) -> None: """ Lint a single ERC-7730 descriptor file. :param path: ERC-7730 descriptor file path :param linter: linter instance :param out: error handler """ print(f"[italic]checking {path}...[/italic]") adder = FileOutputAdder(delegate=out, file=path) try: input_descriptor = InputERC7730Descriptor.load(path) resolved_descriptor = ERC7730InputToResolved().convert(input_descriptor, adder) if resolved_descriptor is not None: linter.lint(resolved_descriptor, adder) except ValidationError as e: for ex in e.errors(include_url=False, include_context=True, include_input=True): loc = ex["loc"] if loc == (): adder.error(title="Validation error", message=str(ex)) else: adder.error(title=f"{loc} is invalid", message=ex["msg"]) except Exception as e: # TODO unwrap pydantic validation errors here to provide more user-friendly error messages adder.error(title="Failed to parse descriptor", message=str(e)) finally: print()