From c094e5f0a17d53f5b86038c3fdbef5479083af4c Mon Sep 17 00:00:00 2001 From: Vladimir Nadulich Date: Tue, 4 Nov 2025 17:28:45 +0300 Subject: [PATCH] pretty print --- onec_codetemplate_parser/__init__.py | 4 ++-- onec_codetemplate_parser/api.py | 6 ++++++ onec_codetemplate_parser/cli.py | 23 ++++++++++++++++++++--- tests/test_cli.py | 9 +++++++++ 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/onec_codetemplate_parser/__init__.py b/onec_codetemplate_parser/__init__.py index 205a0d0..a1f5eac 100644 --- a/onec_codetemplate_parser/__init__.py +++ b/onec_codetemplate_parser/__init__.py @@ -1,3 +1,3 @@ -from .api import parse_to_src, render_from_src +from .api import parse_to_src, render_from_src, pretty_print -__all__ = ["parse_to_src", "render_from_src"] +__all__ = ["parse_to_src", "render_from_src", "pretty_print"] diff --git a/onec_codetemplate_parser/api.py b/onec_codetemplate_parser/api.py index 78a2ea9..e15fb7a 100644 --- a/onec_codetemplate_parser/api.py +++ b/onec_codetemplate_parser/api.py @@ -15,3 +15,9 @@ def render_from_src(src: str, path: str): root = Root.from_src(src) text = root.compile() Path(path).write_text(text, encoding='utf-8-sig') + +def pretty_print(path: str): + """Выводит в консоль дерево шаблона""" + text = Path(path).read_text(encoding='utf-8-sig') + root = parse(text) + root.pretty_print() diff --git a/onec_codetemplate_parser/cli.py b/onec_codetemplate_parser/cli.py index 104f24f..2674ca5 100644 --- a/onec_codetemplate_parser/cli.py +++ b/onec_codetemplate_parser/cli.py @@ -1,14 +1,15 @@ """Консольное приложение для вызова API библиотеки """ -import typer from pathlib import Path -from .api import parse_to_src, render_from_src +import typer +from .api import parse_to_src, render_from_src, pretty_print app = typer.Typer( help="Парсер шаблонов кода 1С.\n\n" "Позволяет разбирать шаблоны *.st в исходники src и обратно.") def validate_file_enable(value: str): + """Проверка существования и размера файла""" path = Path(value) if not path.is_file(): raise typer.BadParameter(f"Файл отсутствует '{value}'") @@ -17,6 +18,7 @@ def validate_file_enable(value: str): return path def validate_empty_dir(value: str): + """Проверка существования и пустоты папки""" path = Path(value) if not path.is_dir() or not any(path.iterdir()): raise typer.BadParameter(f"Папка '{value}' не существует или пуста.") @@ -24,7 +26,7 @@ def validate_empty_dir(value: str): @app.command(help="Разобрать шаблон из 1С-файла *.st в исходники src") def parse( - path: str = typer.Argument(..., + path: str = typer.Argument(..., callback=validate_file_enable, help="Путь к исходному 1С-файлу шаблона *.st", ), src: str = typer.Argument('./src', help="Папка, в которую будут сохранены исходники src") @@ -54,5 +56,20 @@ def render( typer.echo(f"Шаблон собран из папки {src} в файл {path}") +@app.command(help="Показать структуру файла *.st") +def pretty( + path: str = typer.Argument(..., + callback=validate_file_enable, + help="Путь к исходному 1С-файлу шаблона *.st", ) + ): + """ + Визуализация структуры 1С-шаблон (*.st) в виде дерева. + + Пример: + onec_codetemplate_parser pretty my_template.st + """ + pretty_print(path) + + if __name__ == "__main__": app() diff --git a/tests/test_cli.py b/tests/test_cli.py index d3c9050..39d6229 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -45,3 +45,12 @@ class Test_CLI: result = runner.invoke(app, ["render", str(temp_output_st), str(temp_src)], catch_exceptions=False) assert result.exit_code == 0, result.stdout + result.stderr assert test_file_path.read_text(encoding='utf-8-sig') == temp_output_st.read_text(encoding='utf-8-sig'), 'Собранный файл не совпадает с исходным' + + def test_pretty_print_command(self, test_file_path): + """Тест выполнения команды парсинга""" + result = runner.invoke(app, ["pretty", str(test_file_path)]) + assert result.exit_code == 0, result.stdout + result.stderr + if test_file_path.name == '00-empty.st_': + assert len(result.stdout.splitlines()) == 1, result.stdout + result.stderr + else: + assert len(result.stdout.splitlines()) > 1, result.stdout + result.stderr