|
57 | 57 | ModifiedLine(line=" total += price", line_number=12, relative_line_number=5, modification_type="added"), |
58 | 58 | ], |
59 | 59 | ) |
| 60 | + |
| 61 | +COMPLEX_DIFF_TEXT = ''' |
| 62 | +'@@ -2,7 +2,7 @@ |
| 63 | + import logging |
| 64 | + from collections.abc import Callable |
| 65 | + from importlib.metadata import version |
| 66 | +-from typing import get_args |
| 67 | ++from typing import Any, assert_never, get_args |
| 68 | +
|
| 69 | + import click |
| 70 | + import rich |
| 71 | +@@ -13,10 +13,12 @@ |
| 72 | + get_summarizing_agent_with_settings, |
| 73 | + ) |
| 74 | + from lgtm_ai.ai.schemas import AgentSettings, CommentCategory, SupportedAIModels, SupportedAIModelsList |
| 75 | +-from lgtm_ai.base.schemas import PRUrl |
| 76 | ++from lgtm_ai.base.schemas import OutputFormat, PRUrl |
| 77 | + from lgtm_ai.config.handler import ConfigHandler, PartialConfig |
| 78 | ++from lgtm_ai.formatters.base import Formatter |
| 79 | ++from lgtm_ai.formatters.json import JsonFormatter |
| 80 | + from lgtm_ai.formatters.markdown import MarkDownFormatter |
| 81 | +-from lgtm_ai.formatters.terminal import TerminalFormatter |
| 82 | ++from lgtm_ai.formatters.pretty import PrettyFormatter |
| 83 | + from lgtm_ai.git_client.utils import get_git_client |
| 84 | + from lgtm_ai.review import CodeReviewer |
| 85 | + from lgtm_ai.review.guide import ReviewGuideGenerator |
| 86 | +@@ -25,14 +27,15 @@ |
| 87 | + parse_pr_url, |
| 88 | + validate_model_url, |
| 89 | + ) |
| 90 | ++from rich.console import Console |
| 91 | + from rich.logging import RichHandler |
| 92 | +
|
| 93 | + __version__ = version("lgtm-ai") |
| 94 | +
|
| 95 | + logging.basicConfig( |
| 96 | + format="%(message)s", |
| 97 | + datefmt="[%X]", |
| 98 | +- handlers=[RichHandler(rich_tracebacks=True, show_path=False)], |
| 99 | ++ handlers=[RichHandler(rich_tracebacks=True, show_path=False, console=Console(stderr=True))], |
| 100 | + ) |
| 101 | + logger = logging.getLogger("lgtm") |
| 102 | +
|
| 103 | +@@ -68,6 +71,7 @@ def _common_options[**P, T](func: Callable[P, T]) -> Callable[P, T]: |
| 104 | + help="Exclude files from the review. If not provided, all files in the PR will be reviewed. Uses UNIX-style wildcards.", |
| 105 | + ) |
| 106 | + @click.option("--publish", is_flag=True, help="Publish the review or guide to the git service.") |
| 107 | ++ @click.option("--output-format", type=click.Choice([format.value for format in OutputFormat])) |
| 108 | + @click.option("--silent", is_flag=True, help="Do not print the review or guide to the console.") |
| 109 | + @click.option( |
| 110 | + "--ai-retries", |
| 111 | +@@ -104,6 +108,7 @@ def review( |
| 112 | + config: str | None, |
| 113 | + exclude: tuple[str, ...], |
| 114 | + publish: bool, |
| 115 | ++ output_format: OutputFormat | None, |
| 116 | + silent: bool, |
| 117 | + ai_retries: int | None, |
| 118 | + verbose: int, |
| 119 | +@@ -125,6 +130,7 @@ def review( |
| 120 | + model=model, |
| 121 | + model_url=model_url, |
| 122 | + publish=publish, |
| 123 | ++ output_format=output_format, |
| 124 | + silent=silent, |
| 125 | + ai_retries=ai_retries, |
| 126 | + ), |
| 127 | +@@ -146,10 +152,10 @@ def review( |
| 128 | +
|
| 129 | + if not resolved_config.silent: |
| 130 | + logger.info("Printing review to console") |
| 131 | +- terminal_formatter = TerminalFormatter() |
| 132 | +- rich.print(terminal_formatter.format_review_summary_section(review)) |
| 133 | ++ formatter, printer = _get_formatter_and_printer(resolved_config.output_format) |
| 134 | ++ printer(formatter.format_review_summary_section(review)) |
| 135 | + if review.review_response.comments: |
| 136 | +- rich.print(terminal_formatter.format_review_comments_section(review.review_response.comments)) |
| 137 | ++ printer(formatter.format_review_comments_section(review.review_response.comments)) |
| 138 | +
|
| 139 | + if resolved_config.publish: |
| 140 | + logger.info("Publishing review to git service") |
| 141 | +@@ -168,6 +174,7 @@ def guide( |
| 142 | + config: str | None, |
| 143 | + exclude: tuple[str, ...], |
| 144 | + publish: bool, |
| 145 | ++ output_format: OutputFormat | None, |
| 146 | + silent: bool, |
| 147 | + ai_retries: int | None, |
| 148 | + verbose: int, |
| 149 | +@@ -184,6 +191,7 @@ def guide( |
| 150 | + ai_api_key=ai_api_key, |
| 151 | + model=model, |
| 152 | + publish=publish, |
| 153 | ++ output_format=output_format, |
| 154 | + silent=silent, |
| 155 | + ai_retries=ai_retries, |
| 156 | + ), |
| 157 | +@@ -203,8 +211,8 @@ def guide( |
| 158 | +
|
| 159 | + if not resolved_config.silent: |
| 160 | + logger.info("Printing review to console") |
| 161 | +- terminal_formatter = TerminalFormatter() |
| 162 | +- rich.print(terminal_formatter.format_guide(guide)) |
| 163 | ++ formatter, printer = _get_formatter_and_printer(resolved_config.output_format) |
| 164 | ++ printer(formatter.format_guide(guide)) |
| 165 | +
|
| 166 | + if resolved_config.publish: |
| 167 | + logger.info("Publishing review guide to git service") |
| 168 | +@@ -220,3 +228,15 @@ def _set_logging_level(logger: logging.Logger, verbose: int) -> None: |
| 169 | + else: |
| 170 | + logger.setLevel(logging.DEBUG) |
| 171 | + logger.info("Logging level set to %s", logging.getLevelName(logger.level)) |
| 172 | ++ |
| 173 | ++ |
| 174 | ++def _get_formatter_and_printer(output_format: OutputFormat) -> tuple[Formatter[Any], Callable[[Any], None]]: |
| 175 | ++ """Get the formatter and the print method based on the output format.""" |
| 176 | ++ if output_format == OutputFormat.pretty: |
| 177 | ++ return PrettyFormatter(), rich.print |
| 178 | ++ elif output_format == OutputFormat.markdown: |
| 179 | ++ return MarkDownFormatter(), print |
| 180 | ++ elif output_format == OutputFormat.json: |
| 181 | ++ return JsonFormatter(), print |
| 182 | ++ else: |
| 183 | ++ assert_never(output_format)' |
| 184 | +''' |
0 commit comments