diff --git a/pylint/testutils/_primer/comparator.py b/pylint/testutils/_primer/comparator.py new file mode 100644 index 0000000000..03b3fcfc37 --- /dev/null +++ b/pylint/testutils/_primer/comparator.py @@ -0,0 +1,41 @@ +# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE +# Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt + +from __future__ import annotations + +import json +from collections.abc import Generator +from pathlib import Path + +from pylint.testutils._primer.primer_command import Messages, PackageMessages + + +class Comparator: + def __init__(self, main_json: Path, pr_json: Path): + main_messages = self._load_json(main_json) + self.pr_messages = self._load_json(pr_json) + self.missing_messages: PackageMessages = {} + for package, messages in main_messages.items(): + self.missing_messages[package] = [] + for message in messages: + try: + self.pr_messages[package].remove(message) + except ValueError: + self.missing_messages[package].append(message) + + def __iter__( + self, + ) -> Generator[tuple[str, Messages, Messages], None, None]: + for package, missing_messages in self.missing_messages.items(): + new_messages = self.pr_messages[package] + if not missing_messages and not new_messages: + print(f"PRIMER: No changes in {package}.") + continue + yield package, missing_messages, new_messages + + @staticmethod + def _load_json(file_path: Path | str) -> PackageMessages: + with open(file_path, encoding="utf-8") as f: + result: PackageMessages = json.load(f) + return result diff --git a/pylint/testutils/_primer/primer_compare_command.py b/pylint/testutils/_primer/primer_compare_command.py index 442ffa227a..93c4f76466 100644 --- a/pylint/testutils/_primer/primer_compare_command.py +++ b/pylint/testutils/_primer/primer_compare_command.py @@ -3,65 +3,31 @@ # Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt from __future__ import annotations -import json -from pathlib import Path, PurePosixPath +from pathlib import PurePosixPath -from pylint.reporters.json_reporter import OldJsonExport -from pylint.testutils._primer.primer_command import ( - PackageData, - PackageMessages, - PrimerCommand, -) +from pylint.testutils._primer.comparator import Comparator +from pylint.testutils._primer.primer_command import Messages, PrimerCommand MAX_GITHUB_COMMENT_LENGTH = 65536 class CompareCommand(PrimerCommand): def run(self) -> None: - main_data = self._load_json(self.config.base_file) - pr_data = self._load_json(self.config.new_file) - missing_messages_data, new_messages_data = self._cross_reference( - main_data, pr_data - ) - comment = self._create_comment(missing_messages_data, new_messages_data) + comparator = Comparator(self.config.base_file, self.config.new_file) + comment = self._create_comment(comparator) with open(self.primer_directory / "comment.txt", "w", encoding="utf-8") as f: f.write(comment) - @staticmethod - def _cross_reference( - main_data: PackageMessages, pr_data: PackageMessages - ) -> tuple[PackageMessages, PackageMessages]: - missing_messages_data: PackageMessages = {} - for package, data in main_data.items(): - package_missing_messages: list[OldJsonExport] = [] - for message in data["messages"]: - try: - pr_data[package]["messages"].remove(message) - except ValueError: - package_missing_messages.append(message) - missing_messages_data[package] = PackageData( - commit=pr_data[package]["commit"], messages=package_missing_messages - ) - return missing_messages_data, pr_data - - @staticmethod - def _load_json(file_path: Path | str) -> PackageMessages: - with open(file_path, encoding="utf-8") as f: - result: PackageMessages = json.load(f) - return result - - def _create_comment( - self, all_missing_messages: PackageMessages, all_new_messages: PackageMessages - ) -> str: + def _create_comment(self, comparator: Comparator) -> str: comment = "" - for package, missing_messages in all_missing_messages.items(): + for package, missing_messages, new_messages in comparator: if len(comment) >= MAX_GITHUB_COMMENT_LENGTH: break new_messages = all_new_messages[package] if not missing_messages["messages"] and not new_messages["messages"]: continue comment += self._create_comment_for_package( - package, new_messages, missing_messages + package, missing_messages, new_messages ) comment = ( f"🤖 **Effect of this PR on checked open source code:** 🤖\n\n{comment}" @@ -74,7 +40,7 @@ def _create_comment( return self._truncate_comment(comment) def _create_comment_for_package( - self, package: str, new_messages: PackageData, missing_messages: PackageData + self, package: str, missing_messages: Messages, new_messages: Messages ) -> str: comment = f"\n\n**Effect on [{package}]({self.packages[package].url}):**\n" # Create comment for new messages diff --git a/tests/testutils/_primer/test_primer.py b/tests/testutils/_primer/test_primer.py index d57e98d213..beab35166b 100644 --- a/tests/testutils/_primer/test_primer.py +++ b/tests/testutils/_primer/test_primer.py @@ -21,7 +21,7 @@ PACKAGES_TO_PRIME_PATH = TEST_DIR_ROOT / "primer/packages_to_prime.json" FIXTURES_PATH = HERE / "fixtures" -PRIMER_CURRENT_INTERPRETER = (3, 10) +PRIMER_CURRENT_INTERPRETER = (3, 8) DEFAULT_ARGS = ["python tests/primer/__main__.py", "compare", "--commit=v2.14.2"]