diff --git a/changelogs/fragments/183-deprecation-removal.yml b/changelogs/fragments/183-deprecation-removal.yml new file mode 100644 index 00000000..51d7bfb2 --- /dev/null +++ b/changelogs/fragments/183-deprecation-removal.yml @@ -0,0 +1,9 @@ +removed_features: + - "Python API: remove ``antsibull_changelog.rst`` module + (https://github.com/ansible-community/antsibull-changelog/pull/183)." + - "Python API: remove method ``ChangelogEntry.add_section_content``, class ``ChangelogGenerator``, + and function ``generate_changelog`` from ``antsibull_changelog.changelog_generator`` + (https://github.com/ansible-community/antsibull-changelog/pull/183)." + - "Python API: remove constructor arguments ``plugins`` and ``fragments`` from + class ``ChangelogGenerator`` in ``antsibull_changelog.rendering.changelog`` + (https://github.com/ansible-community/antsibull-changelog/pull/183)." diff --git a/src/antsibull_changelog/changelog_generator.py b/src/antsibull_changelog/changelog_generator.py index 6a3af4c9..8ccde778 100644 --- a/src/antsibull_changelog/changelog_generator.py +++ b/src/antsibull_changelog/changelog_generator.py @@ -13,16 +13,12 @@ import abc import collections -import os from collections.abc import MutableMapping from typing import Any, cast from .changes import ChangesData, FragmentResolver, PluginResolver -from .config import ChangelogConfig, PathsConfig, TextFormat -from .fragment import ChangelogFragment +from .config import ChangelogConfig, TextFormat from .logger import LOGGER -from .plugins import PluginDescription -from .rst import RstBuilder from .utils import collect_versions @@ -72,23 +68,6 @@ def empty(self) -> bool: and self.has_no_changes() ) - def add_section_content(self, builder: RstBuilder, section_name: str) -> None: - """ - Add a section's content of fragments to the changelog. - - This function is DEPRECATED! It will be removed in a future version. - """ - if section_name not in self.changes: - return - - content = self.changes[section_name] - - if isinstance(content, list): - for rst in sorted(content): - builder.add_list_item(rst) - else: - builder.add_raw_rst(content) - def get_entry_config( release_entries: MutableMapping[str, ChangelogEntry], entry_version: str @@ -273,334 +252,3 @@ def get_plugin_name( if fqcn_prefix: name = "%s.%s" % (fqcn_prefix, name) return name - - -class ChangelogGenerator(ChangelogGeneratorBase): - # antsibull_changelog.rendering.changelog.ChangelogGenerator is a modified - # copy of this class adjust to the document rendering framework in - # antsibull_changelog.rendering. To avoid pylint complaining too much, we - # disable 'duplicate-code' for this class. - - # pylint: disable=duplicate-code - - """ - Generate changelog as reStructuredText. - - This class can be both used to create a full changelog, or to append a - changelog to an existing RstBuilder. This is for example useful to create - a combined ACD changelog. - - This class is DEPRECATED! It will be removed in a future version. - """ - - def __init__( # pylint: disable=too-many-arguments - self, - config: ChangelogConfig, - changes: ChangesData, - *, - # pylint: disable-next=unused-argument - plugins: list[PluginDescription] | None = None, # DEPRECATED - # pylint: disable-next=unused-argument - fragments: list[ChangelogFragment] | None = None, # DEPRECATED - flatmap: bool = True, - ): - """ - Create a changelog generator. - """ - super().__init__(config, changes, flatmap=flatmap) - - def append_changelog_entry( - self, - builder: RstBuilder, - changelog_entry: ChangelogEntry, - start_level: int = 0, - add_version: bool = False, - ) -> None: - """ - Append changelog entry to a reStructuredText (RST) builder. - - :arg start_level: Level to add to headings in the generated RST - """ - if add_version: - builder.add_section("v%s" % changelog_entry.version, start_level) - - for section_name in self.config.sections: - self._add_section( - builder, changelog_entry, section_name, start_level=start_level - ) - - fqcn_prefix = self.get_fqcn_prefix() - self._add_plugins( - builder, - changelog_entry.plugins, - fqcn_prefix=fqcn_prefix, - start_level=start_level, - ) - self._add_modules( - builder, - changelog_entry.modules, - flatmap=self.flatmap, - fqcn_prefix=fqcn_prefix, - start_level=start_level, - ) - self._add_objects( - builder, - changelog_entry.objects, - fqcn_prefix=fqcn_prefix, - start_level=start_level, - ) - - def generate_to( # pylint: disable=too-many-arguments - self, - builder: RstBuilder, - start_level: int = 0, - squash: bool = False, - after_version: str | None = None, - until_version: str | None = None, - only_latest: bool = False, - ) -> None: - """ - Append changelog to a reStructuredText (RST) builder. - - :arg start_level: Level to add to headings in the generated RST - :arg squash: Squash all releases into one entry - :arg after_version: If given, only consider versions after this one - :arg until_version: If given, do not consider versions following this one - :arg only_latest: If set to ``True``, only generate the latest entry - """ - release_entries = self.collect( - squash=squash, after_version=after_version, until_version=until_version - ) - - for release in release_entries: - self.append_changelog_entry( - builder, - release, - start_level=start_level, - add_version=not squash and not only_latest, - ) - if only_latest: - break - - def generate(self, only_latest: bool = False) -> str: - """ - Generate the changelog as reStructuredText. - """ - builder = RstBuilder() - - if not only_latest: - builder.set_title(self.get_title()) - builder.add_raw_rst(".. contents:: Topics\n") - - if self.changes.ancestor and self.config.mention_ancestor: - builder.add_raw_rst( - "This changelog describes changes after version {0}.\n".format( - self.changes.ancestor - ) - ) - else: - builder.add_raw_rst("") - - self.generate_to(builder, 0, only_latest=only_latest) - - return builder.generate() - - def _add_section( - self, - builder: RstBuilder, - changelog_entry: ChangelogEntry, - section_name: str, - start_level: int, - ) -> None: - """ - Add a section of fragments to the changelog. - """ - if section_name not in changelog_entry.changes: - return - - section_title = self.config.sections[section_name] - builder.add_section(section_title, start_level + 1) - - changelog_entry.add_section_content(builder, section_name) - - builder.add_raw_rst("") - - @staticmethod - def _add_plugins( - builder: RstBuilder, - plugins_database: dict[str, list[dict[str, Any]]], - fqcn_prefix: str | None, - start_level: int = 0, - ) -> None: - """ - Add new plugins to the changelog. - """ - if not plugins_database: - return - - have_section = False - - for plugin_type in sorted(plugins_database): - plugins = plugins_database.get(plugin_type) - if not plugins: - continue - - if not have_section: - have_section = True - builder.add_section("New Plugins", start_level + 1) - - builder.add_section(plugin_type.title(), start_level + 2) - - ChangelogGenerator.add_plugins(builder, plugins, fqcn_prefix) - - builder.add_raw_rst("") - - @staticmethod - def add_plugins( - builder: RstBuilder, plugins: list[dict[str, Any]], fqcn_prefix: str | None - ) -> None: - """ - Add new plugins of one type to the changelog. - """ - for plugin in sorted(plugins, key=lambda plugin: plugin["name"]): - plugin_name = get_plugin_name(plugin["name"], fqcn_prefix=fqcn_prefix) - builder.add_raw_rst("- %s - %s" % (plugin_name, plugin["description"])) - - @staticmethod - def _add_modules( - builder: RstBuilder, - modules: list[dict[str, Any]], - flatmap: bool, - fqcn_prefix: str | None, - start_level: int = 0, - ) -> None: - """ - Add new modules to the changelog. - """ - if not modules: - return - - builder.add_section("New Modules", start_level + 1) - ChangelogGenerator.add_modules( - builder, modules, flatmap, fqcn_prefix, start_level + 2 - ) - - @staticmethod - def add_modules( - builder: RstBuilder, - modules: list[dict[str, Any]], - flatmap: bool, - fqcn_prefix: str | None, - level: int, - ) -> None: - """ - Add new modules to the changelog. - """ - modules_by_namespace = collections.defaultdict(list) - for module in sorted(modules, key=lambda module: module["name"]): - modules_by_namespace[module["namespace"]].append(module) - - previous_section = None - for namespace in sorted(modules_by_namespace): - parts = namespace.split(".") - - section = parts.pop(0).replace("_", " ").title() - - if section != previous_section and section: - builder.add_section(section, level) - - previous_section = section - - subsection = ".".join(parts) - - if subsection: - builder.add_section(subsection, level + 1) - - for module in modules_by_namespace[namespace]: - module_name = get_plugin_name( - module["name"], - fqcn_prefix=fqcn_prefix, - namespace=namespace, - flatmap=flatmap, - ) - builder.add_raw_rst("- %s - %s" % (module_name, module["description"])) - - builder.add_raw_rst("") - - @staticmethod - def _add_objects( - builder: RstBuilder, - objects_database: dict[str, list[dict[str, Any]]], - fqcn_prefix: str | None, - start_level: int = 0, - ) -> None: - """ - Add new objects to the changelog. - """ - if not objects_database: - return - - for object_type in sorted(objects_database): - objects = objects_database.get(object_type) - if not objects: - continue - - builder.add_section("New " + object_type.title() + "s", start_level + 1) - - ChangelogGenerator.add_objects(builder, objects, fqcn_prefix) - - builder.add_raw_rst("") - - @staticmethod - def add_objects( - builder: RstBuilder, objects: list[dict[str, Any]], fqcn_prefix: str | None - ) -> None: - """ - Add new objects of one type to the changelog. - """ - for ansible_object in sorted( - objects, key=lambda ansible_object: ansible_object["name"] - ): - object_name = get_plugin_name( - ansible_object["name"], fqcn_prefix=fqcn_prefix - ) - builder.add_raw_rst( - "- %s - %s" % (object_name, ansible_object["description"]) - ) - - -def generate_changelog( # pylint: disable=too-many-arguments - paths: PathsConfig, - config: ChangelogConfig, - changes: ChangesData, - *, - flatmap: bool = True, - changelog_path: str | None = None, - only_latest: bool = False, -): - """ - Generate the changelog as reStructuredText. - - This function is DEPRECATED! It will be removed in a future version. - - :arg flatmap: Whether the collection uses flatmapping or not - :arg changelog_path: Write the output to this path instead of the default path. - :arg only_latest: Only write the last changelog entry without any preamble - """ - if changelog_path is None: - major_minor_version = ".".join( - changes.latest_version.split(".")[: config.changelog_filename_version_depth] - ) - if "%s" in config.changelog_filename_template: - changelog_filename = config.changelog_filename_template % ( - major_minor_version, - ) - else: - changelog_filename = config.changelog_filename_template - changelog_path = os.path.join(paths.changelog_dir, changelog_filename) - - generator = ChangelogGenerator(config, changes, flatmap=flatmap) - rst = generator.generate(only_latest=only_latest) - - with open(changelog_path, "wb") as changelog_fd: - changelog_fd.write(rst.encode("utf-8")) diff --git a/src/antsibull_changelog/rendering/changelog.py b/src/antsibull_changelog/rendering/changelog.py index 86e1a1aa..d0c15f6a 100644 --- a/src/antsibull_changelog/rendering/changelog.py +++ b/src/antsibull_changelog/rendering/changelog.py @@ -22,9 +22,7 @@ ) from ..changes import ChangesData from ..config import ChangelogConfig, PathsConfig, TextFormat -from ..fragment import ChangelogFragment from ..logger import LOGGER -from ..plugins import PluginDescription from .document import AbstractRenderer, DocumentRenderer, SectionRenderer from .md_document import MDDocumentRenderer from .rst_document import RSTDocumentRenderer @@ -57,15 +55,11 @@ class ChangelogGenerator(ChangelogGeneratorBase): a combined ACD changelog. """ - def __init__( # pylint: disable=too-many-arguments + def __init__( # pylint: disable=useless-parent-delegation self, config: ChangelogConfig, changes: ChangesData, *, - # pylint: disable-next=unused-argument - plugins: list[PluginDescription] | None = None, # DEPRECATED - # pylint: disable-next=unused-argument - fragments: list[ChangelogFragment] | None = None, # DEPRECATED flatmap: bool = True, ): """ diff --git a/src/antsibull_changelog/rst.py b/src/antsibull_changelog/rst.py deleted file mode 100644 index 5d199d6c..00000000 --- a/src/antsibull_changelog/rst.py +++ /dev/null @@ -1,76 +0,0 @@ -# Author: Matt Clay -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or -# https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later -# SPDX-FileCopyrightText: 2020, Ansible Project - -""" -ReStructuredText helpers. - -This module is DEPRECATED! It will be removed in a future version. -""" - -from __future__ import annotations - - -class RstBuilder: - """ - Simple reStructuredText (RST) builder. - - This class is DEPRECATED! It will be removed in a future version. - """ - - lines: list[str] - section_underlines: str - - def __init__(self): - """ - Create RST builder. - """ - self.lines = [] - self.section_underlines = """=-~^.*+:`'"_#""" - - def set_title(self, title: str) -> None: - """ - Add a document title. Must be called before other functions. - - :arg title: The document title - """ - self.lines.append(self.section_underlines[0] * len(title)) - self.lines.append(title) - self.lines.append(self.section_underlines[0] * len(title)) - self.lines.append("") - - def add_section(self, name: str, depth: int = 0) -> None: - """ - Add a section. - - :arg name: The section title - :arg depth: The section depth - """ - self.lines.append(name) - self.lines.append(self.section_underlines[depth] * len(name)) - self.lines.append("") - - def add_raw_rst(self, content: str) -> None: - """ - Add a raw RST line. - """ - self.lines.append(content) - - def add_list_item(self, content: str) -> None: - """ - Add a list item. Content can be multi-lined. - """ - lines = content.splitlines() - for line_no, line in enumerate(lines): - if line_no > 0 and not line: - self.lines.append("") - continue - self.lines.append("%s %s" % (" " if line_no else "-", line)) - - def generate(self) -> str: - """ - Generate RST content. - """ - return "\n".join(self.lines)