diff --git a/src/compwa_policy/check_dev_files/black.py b/src/compwa_policy/check_dev_files/black.py index a9e601b2..750e1f83 100644 --- a/src/compwa_policy/check_dev_files/black.py +++ b/src/compwa_policy/check_dev_files/black.py @@ -54,7 +54,7 @@ def _remove_outdated_settings(pyproject: ModifiablePyproject) -> None: removed_options.add(option) if removed_options: msg = f"Removed {', '.join(sorted(removed_options))} option from black configuration" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def _update_black_settings(pyproject: ModifiablePyproject) -> None: @@ -68,7 +68,7 @@ def _update_black_settings(pyproject: ModifiablePyproject) -> None: if not complies_with_subset(settings, minimal_settings): settings.update(minimal_settings) msg = "Updated black configuration" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def _update_precommit_repo(precommit: ModifiablePrecommit, has_notebooks: bool) -> None: diff --git a/src/compwa_policy/check_dev_files/citation.py b/src/compwa_policy/check_dev_files/citation.py index a4f01558..fb075236 100644 --- a/src/compwa_policy/check_dev_files/citation.py +++ b/src/compwa_policy/check_dev_files/citation.py @@ -207,7 +207,7 @@ def add_json_schema_precommit(precommit: ModifiablePrecommit) -> None: repos_yaml = cast(CommentedSeq, existing_repos) repos_yaml.yaml_set_comment_before_after_key(repo_idx + 1, before="\n") msg = f"Updated pre-commit hook {repo_url}" - precommit.append_to_changelog(msg) + precommit.changelog.append(msg) def update_vscode_settings() -> None: diff --git a/src/compwa_policy/check_dev_files/cspell.py b/src/compwa_policy/check_dev_files/cspell.py index 949173aa..4e06528e 100644 --- a/src/compwa_policy/check_dev_files/cspell.py +++ b/src/compwa_policy/check_dev_files/cspell.py @@ -67,7 +67,7 @@ def _update_cspell_repo_url(precommit: ModifiablePrecommit) -> None: continue repo["repo"] = __REPO_URL msg = f"Updated cSpell pre-commit repo URL to {__REPO_URL}" - precommit.append_to_changelog(msg) + precommit.changelog.append(msg) def _remove_configuration() -> None: diff --git a/src/compwa_policy/check_dev_files/mypy.py b/src/compwa_policy/check_dev_files/mypy.py index 8a2ec0a5..02f714c6 100644 --- a/src/compwa_policy/check_dev_files/mypy.py +++ b/src/compwa_policy/check_dev_files/mypy.py @@ -28,7 +28,7 @@ def _merge_mypy_into_pyproject(pyproject: ModifiablePyproject) -> None: tool_table.update(mypy_config) os.remove(old_config_path) msg = f"Imported mypy configuration from {old_config_path}" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def _update_vscode_settings(pyproject: Pyproject) -> None: diff --git a/src/compwa_policy/check_dev_files/pixi.py b/src/compwa_policy/check_dev_files/pixi.py index 20711a37..65cc6dc9 100644 --- a/src/compwa_policy/check_dev_files/pixi.py +++ b/src/compwa_policy/check_dev_files/pixi.py @@ -87,7 +87,7 @@ def __configure_setuptools_scm(pyproject: ModifiablePyproject) -> None: if not complies_with_subset(setuptools_scm, expected_scheme): setuptools_scm.update(expected_scheme) msg = "Configured setuptools_scm to not include git info in package version for pixi" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def __define_combined_ci_job(pyproject: ModifiablePyproject) -> None: @@ -109,7 +109,7 @@ def __define_combined_ci_job(pyproject: ModifiablePyproject) -> None: depends_on = expected | existing & tasks ci["depends_on"] = to_toml_array(sorted(depends_on), multiline=False) msg = "Updated combined CI job for Pixi" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def __define_minimal_project(pyproject: ModifiablePyproject) -> None: @@ -122,7 +122,7 @@ def __define_minimal_project(pyproject: ModifiablePyproject) -> None: if not complies_with_subset(settings, minimal_settings, exact_value_match=False): settings.update(minimal_settings) msg = "Defined minimal Pixi project settings" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def __import_conda_dependencies(pyproject: ModifiablePyproject) -> None: @@ -146,7 +146,7 @@ def __import_conda_dependencies(pyproject: ModifiablePyproject) -> None: if not complies_with_subset(dependencies, expected_dependencies): dependencies.update(expected_dependencies) msg = "Imported conda dependencies into Pixi" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def ___to_pixi_dependency(conda_dependency: str) -> tuple[str, str]: @@ -192,7 +192,7 @@ def __import_conda_environment(pyproject: ModifiablePyproject) -> None: new_env.update(conda_variables) activation_table["env"] = new_env msg = "Imported conda environment variables for Pixi" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def __import_tox_tasks(pyproject: ModifiablePyproject) -> None: @@ -224,7 +224,7 @@ def __import_tox_tasks(pyproject: ModifiablePyproject) -> None: imported_tasks.append(task_name) if imported_tasks: msg = f"Imported the following tox jobs: {', '.join(sorted(imported_tasks))}" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def ___get_tox_job_names(cfg: ConfigParser) -> dict[str, str]: @@ -270,7 +270,7 @@ def __clean_up_task_env(pyproject: ModifiablePyproject) -> None: updated_tasks.append(task_name) if updated_tasks: msg = f"Removed redundant environment variables from Pixi tasks {', '.join(updated_tasks)}" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def ___load_pixi_environment_variables(pyproject: Pyproject) -> dict[str, str]: @@ -310,7 +310,7 @@ def __install_package_editable(pyproject: ModifiablePyproject) -> None: if dict(existing.get(package_name, {})) != dict(editable): existing[package_name] = editable msg = "Installed Python package in editable mode in Pixi" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def __outsource_pixi_tasks_to_tox(pyproject: ModifiablePyproject) -> None: @@ -332,7 +332,7 @@ def __outsource_pixi_tasks_to_tox(pyproject: ModifiablePyproject) -> None: updated_tasks.append(pixi_task) if updated_tasks: msg = f"Outsourced Pixi tasks to tox: {', '.join(updated_tasks)}" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def __set_dev_python_version( @@ -343,7 +343,7 @@ def __set_dev_python_version( if dependencies.get("python") != version: dependencies["python"] = version msg = f"Set Python version for Pixi developer environment to {version}" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def __update_gitattributes() -> None: @@ -372,7 +372,7 @@ def __update_dev_environment(pyproject: ModifiablePyproject) -> None: if environments.get("default") != expected: environments["default"] = expected msg = "Updated Pixi developer environment" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def __update_docnb_and_doclive(pyproject: ModifiablePyproject, table_key: str) -> None: @@ -393,7 +393,7 @@ def __update_docnb_and_doclive(pyproject: ModifiablePyproject, table_key: str) - updated_tasks.append(task_name) if updated_tasks: msg = f"Updated `cmd` of Pixi tasks {', '.join(updated_tasks)}" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def ___outsource_cmd(task: Table, other_task_name: str) -> bool: @@ -422,7 +422,7 @@ def __remove_pixi_configuration(pyproject: ModifiablePyproject) -> None: updated = True if updated: msg = "Removed Pixi configuration files" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def ___remove(path: Path) -> bool: diff --git a/src/compwa_policy/check_dev_files/precommit.py b/src/compwa_policy/check_dev_files/precommit.py index bcab151c..9c4b8d96 100644 --- a/src/compwa_policy/check_dev_files/precommit.py +++ b/src/compwa_policy/check_dev_files/precommit.py @@ -42,7 +42,7 @@ def _sort_hooks(precommit: ModifiablePrecommit) -> None: if sorted_repos != repos: precommit.document["repos"] = sorted_repos msg = "Sorted all pre-commit hooks" - precommit.append_to_changelog(msg) + precommit.changelog.append(msg) def __repo_sort_key(repo: Repo) -> tuple[int, str]: @@ -101,7 +101,7 @@ def _update_precommit_ci_commit_msg(precommit: ModifiablePrecommit) -> None: if autoupdate_commit_msg != expected_msg: precommit_ci[key] = expected_msg # type:ignore[literal-required] msg = f"Set ci.{key} to {expected_msg!r}" - precommit.append_to_changelog(msg) + precommit.changelog.append(msg) def _update_precommit_ci_skip(precommit: ModifiablePrecommit) -> None: @@ -115,13 +115,13 @@ def _update_precommit_ci_skip(precommit: ModifiablePrecommit) -> None: if not expected_skips and existing_skips is not None: del precommit_ci["skip"] msg = "Removed redundant ci.skip section" - precommit.append_to_changelog(msg) + precommit.changelog.append(msg) if existing_skips != expected_skips: precommit_ci["skip"] = sorted(expected_skips) yaml_config = cast(CommentedMap, precommit.document) yaml_config.yaml_set_comment_before_after_key("repos", before="\n") msg = "Updated ci.skip section" - precommit.append_to_changelog(msg) + precommit.changelog.append(msg) def get_local_hooks(config: PrecommitConfig) -> list[str]: @@ -196,4 +196,4 @@ def _update_repo_urls(precommit: ModifiablePrecommit) -> None: msg = "Updated repo URLs:" for url, new_url in updated_repos: msg += f"\n {url} -> {new_url}" - precommit.append_to_changelog(msg) + precommit.changelog.append(msg) diff --git a/src/compwa_policy/check_dev_files/pyright.py b/src/compwa_policy/check_dev_files/pyright.py index 95e8c184..e926dcdb 100644 --- a/src/compwa_policy/check_dev_files/pyright.py +++ b/src/compwa_policy/check_dev_files/pyright.py @@ -44,7 +44,7 @@ def _merge_config_into_pyproject( if remove: os.remove(old_config_path) msg = f"Imported pyright configuration from {old_config_path}" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def _update_precommit(precommit: ModifiablePrecommit, pyproject: Pyproject) -> None: @@ -68,7 +68,7 @@ def _update_settings(pyproject: ModifiablePyproject) -> None: if not complies_with_subset(pyright_settings, minimal_settings): pyright_settings.update(minimal_settings) msg = "Updated pyright configuration" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def __has_pyright(pyproject: Pyproject) -> bool: diff --git a/src/compwa_policy/check_dev_files/pytest.py b/src/compwa_policy/check_dev_files/pytest.py index a342d43d..18255498 100644 --- a/src/compwa_policy/check_dev_files/pytest.py +++ b/src/compwa_policy/check_dev_files/pytest.py @@ -40,7 +40,7 @@ def _merge_coverage_into_pyproject(pyproject: ModifiablePyproject) -> None: tool_table = pyproject.get_table("tool.coverage.run", create=True) tool_table.update(coverage_config) msg = f"Imported Coverage.py configuration from {CONFIG_PATH.pytest_ini}" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def _merge_pytest_into_pyproject(pyproject: ModifiablePyproject) -> None: @@ -55,7 +55,7 @@ def _merge_pytest_into_pyproject(pyproject: ModifiablePyproject) -> None: tool_table.update(pytest_config) CONFIG_PATH.pytest_ini.unlink() msg = f"Imported pytest configuration from {CONFIG_PATH.pytest_ini}" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def _update_settings(pyproject: ModifiablePyproject) -> None: @@ -68,7 +68,7 @@ def _update_settings(pyproject: ModifiablePyproject) -> None: if isinstance(existing, str) or sorted(existing) != sorted(expected): config["addopts"] = expected msg = f"Updated [{table_key}]" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def __get_expected_addopts(existing: str | Iterable) -> Array: diff --git a/src/compwa_policy/check_dev_files/ruff.py b/src/compwa_policy/check_dev_files/ruff.py index bb099df8..4953e136 100644 --- a/src/compwa_policy/check_dev_files/ruff.py +++ b/src/compwa_policy/check_dev_files/ruff.py @@ -109,7 +109,7 @@ def __remove_nbqa_option(pyproject: ModifiablePyproject, option: str) -> None: return nbqa_table.pop(option) msg = f"Removed {option!r} nbQA options from [{table_key}]" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def __remove_tool_table(pyproject: ModifiablePyproject, tool_table: str) -> None: @@ -117,7 +117,7 @@ def __remove_tool_table(pyproject: ModifiablePyproject, tool_table: str) -> None if isinstance(tools, dict) and tool_table in tools: tools.pop(tool_table) msg = f"Removed [tool.{tool_table}] table" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def _remove_pydocstyle( @@ -180,7 +180,7 @@ def _move_ruff_lint_config(pyproject: ModifiablePyproject) -> None: for key in lint_settings: del global_settings[key] if lint_arrays or lint_tables: - pyproject.append_to_changelog("Moved linting configuration to [tool.ruff.lint]") + pyproject.changelog.append("Moved linting configuration to [tool.ruff.lint]") def _update_ruff_config( @@ -231,7 +231,7 @@ def __update_global_settings( if not complies_with_subset(settings, minimal_settings): settings.update(minimal_settings) msg = "Updated Ruff configuration" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def ___get_target_version(pyproject: Pyproject) -> str: @@ -273,7 +273,7 @@ def __update_ruff_format_settings(pyproject: ModifiablePyproject) -> None: if not complies_with_subset(settings, minimal_settings): settings.update(minimal_settings) msg = "Updated Ruff formatter configuration" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def __update_ruff_lint_settings(pyproject: ModifiablePyproject) -> None: @@ -314,11 +314,11 @@ def __update_ruff_lint_settings(pyproject: ModifiablePyproject) -> None: if not complies_with_subset(settings, minimal_settings): settings.update(minimal_settings) msg = "Updated Ruff linting configuration" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) if "extend-select" in settings: del settings["extend-select"] msg = "Removed [tool.ruff.lint.extend-select] configuration" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def ___get_task_tags(ruff_settings: Mapping[str, Any]) -> Array: @@ -415,7 +415,7 @@ def __update_per_file_ignores( if not complies_with_subset(per_file_ignores, minimal_settings): per_file_ignores.update(minimal_settings) msg = "Updated Ruff configuration" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def ___get_per_file_ignores( @@ -527,7 +527,7 @@ def ___update_ruff_lint_table( if not complies_with_subset(settings, minimal_settings): settings.update(minimal_settings) msg = f"Updated Ruff {table_name} settings" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def __remove_nbqa( @@ -548,7 +548,7 @@ def ___remove_nbqa_settings(pyproject: ModifiablePyproject) -> None: del tool_table["nbqa"] if nbqa_addopts: msg = "Removed Ruff configuration for nbQA" - pyproject.append_to_changelog(msg) + pyproject.changelog.append(msg) def _update_precommit_hook(precommit: ModifiablePrecommit, has_notebooks: bool) -> None: diff --git a/src/compwa_policy/check_dev_files/toml.py b/src/compwa_policy/check_dev_files/toml.py index 0f7aa640..2f7a9803 100644 --- a/src/compwa_policy/check_dev_files/toml.py +++ b/src/compwa_policy/check_dev_files/toml.py @@ -64,7 +64,7 @@ def _update_tomlsort_config() -> None: if tool_table.get("tomlsort") == expected_config: return tool_table["tomlsort"] = expected_config - pyproject.append_to_changelog("Updated toml-sort configuration") + pyproject.changelog.append("Updated toml-sort configuration") def _update_tomlsort_hook(precommit: ModifiablePrecommit) -> None: @@ -129,7 +129,7 @@ def _rename_precommit_url(precommit: ModifiablePrecommit) -> None: idx, repo = mirrors_repo_with_idx rev = repo["rev"] precommit.document["repos"].pop(idx) - precommit.append_to_changelog("Renamed mirrors-taplo repo to taplo-pre-commit") + precommit.changelog.append("Renamed mirrors-taplo repo to taplo-pre-commit") expected_hook = Repo( repo="https://github.com/ComPWA/taplo-pre-commit", rev=rev, @@ -143,7 +143,7 @@ def _update_precommit_repo(precommit: ModifiablePrecommit) -> None: if mirrors_repo_with_idx is not None: idx, _ = mirrors_repo_with_idx precommit.document["repos"].pop(idx) - precommit.append_to_changelog("Renamed mirrors-taplo repo to taplo-pre-commit") + precommit.changelog.append("Renamed mirrors-taplo repo to taplo-pre-commit") expected_hook = Repo( repo="https://github.com/ComPWA/taplo-pre-commit", rev="", diff --git a/src/compwa_policy/utilities/precommit/__init__.py b/src/compwa_policy/utilities/precommit/__init__.py index 5380c099..9d829009 100644 --- a/src/compwa_policy/utilities/precommit/__init__.py +++ b/src/compwa_policy/utilities/precommit/__init__.py @@ -127,9 +127,10 @@ def dump(self, target: IO | Path | str | None = None) -> None: msg = f"Target of type {type(target).__name__} is not supported" raise TypeError(msg) - def append_to_changelog(self, message: str) -> None: + @property + def changelog(self) -> list[str]: self.__assert_is_in_context() - self.__changelog.append(message) + return self.__changelog def __assert_is_in_context(self) -> None: if not self.__is_in_context: diff --git a/src/compwa_policy/utilities/precommit/setters.py b/src/compwa_policy/utilities/precommit/setters.py index b9a7b626..53f4e581 100644 --- a/src/compwa_policy/utilities/precommit/setters.py +++ b/src/compwa_policy/utilities/precommit/setters.py @@ -28,7 +28,7 @@ def remove_precommit_hook( else: hooks.pop(hook_idx) msg = f"Removed {hook_id!r} hook" - precommit.append_to_changelog(msg) + precommit.changelog.append(msg) def __find_repo_and_hook_idx( @@ -71,7 +71,7 @@ def update_single_hook_precommit_repo( before="\n", ) msg = f"Added {hook_id} hook to {CONFIG_PATH.precommit}." - precommit.append_to_changelog(msg) + precommit.changelog.append(msg) if idx_and_repo is None: return idx, existing_hook = idx_and_repo @@ -83,7 +83,7 @@ def update_single_hook_precommit_repo( repos_map = cast(CommentedMap, repos) repos_map.yaml_set_comment_before_after_key(idx + 1, before="\n") msg = f"Updated {hook_id} hook" - precommit.append_to_changelog(msg) + precommit.changelog.append(msg) def _determine_expected_repo_index(config: PrecommitConfig, hook_id: str) -> int: @@ -128,12 +128,12 @@ def update_precommit_hook( repos = cast(CommentedMap, precommit.document["repos"]) repos.yaml_set_comment_before_after_key(repo_idx + 1, before="\n") msg = f"Added {expected_hook['id']!r} to {repo_name} pre-commit config" - precommit.append_to_changelog(msg) + precommit.changelog.append(msg) if hooks[hook_idx] != expected_hook: hooks[hook_idx] = expected_hook msg = f"Updated args of {expected_hook['id']!r} {repo_name} pre-commit hook" - precommit.append_to_changelog(msg) + precommit.changelog.append(msg) def __find_hook_idx(hooks: list[Hook], hook_id: str) -> int | None: diff --git a/src/compwa_policy/utilities/pyproject/__init__.py b/src/compwa_policy/utilities/pyproject/__init__.py index a05ec440..15335f96 100644 --- a/src/compwa_policy/utilities/pyproject/__init__.py +++ b/src/compwa_policy/utilities/pyproject/__init__.py @@ -227,9 +227,10 @@ def __assert_is_in_context(self) -> None: msg = "Modifications can only be made within a context" raise RuntimeError(msg) - def append_to_changelog(self, message: str) -> None: + @property + def changelog(self) -> list[str]: self.__assert_is_in_context() - self._changelog.append(message) + return self._changelog def complies_with_subset( diff --git a/tests/utilities/precommit/test_class.py b/tests/utilities/precommit/test_class.py index cfec28ed..f7e440d5 100644 --- a/tests/utilities/precommit/test_class.py +++ b/tests/utilities/precommit/test_class.py @@ -26,7 +26,7 @@ def test_no_context_manager(self, example_config: str): expected_exception=RuntimeError, match=r"^Modifications can only be made within a context$", ): - precommit.append_to_changelog("Fake modification") + precommit.changelog.append("Fake modification") def test_context_manager_path(self, example_config: str): input_stream = io.StringIO(example_config) @@ -34,7 +34,7 @@ def test_context_manager_path(self, example_config: str): PrecommitError, match=r"Fake modification$", ), ModifiablePrecommit.load(input_stream) as precommit: - precommit.append_to_changelog("Fake modification") + precommit.changelog.append("Fake modification") yaml = precommit.dumps() assert yaml == example_config @@ -43,7 +43,7 @@ def test_context_manager_string_stream(self, example_config: str): with pytest.raises( PrecommitError, match=r"Fake modification$" ), ModifiablePrecommit.load(stream) as precommit: - precommit.append_to_changelog("Fake modification") + precommit.changelog.append("Fake modification") stream.seek(0) yaml = stream.read() assert yaml == example_config