diff --git a/changelogs/fragments/179-cleanup.yml b/changelogs/fragments/179-cleanup.yml new file mode 100644 index 00000000..fd9cd02a --- /dev/null +++ b/changelogs/fragments/179-cleanup.yml @@ -0,0 +1,7 @@ +breaking_changes: + - "More internal code related to the old changelog format has been removed. + This only potentially affects other projects which consume antsibull-changelog + as a library. The sister antsibull projects antsibull-build and antsibull-docs + might only be affected in older versions. **Users of the antsibull-changelog CLI + tool are not affected by this change** + (https://github.com/ansible-community/antsibull-changelog/pull/179)." diff --git a/src/antsibull_changelog/changelog_generator.py b/src/antsibull_changelog/changelog_generator.py index c0680518..6a3af4c9 100644 --- a/src/antsibull_changelog/changelog_generator.py +++ b/src/antsibull_changelog/changelog_generator.py @@ -6,7 +6,7 @@ # SPDX-FileCopyrightText: 2020, Ansible Project """ -Generate reStructuredText changelog from ChangesBase instance. +Generate reStructuredText changelog from ChangesData instance. """ from __future__ import annotations @@ -17,7 +17,7 @@ from collections.abc import MutableMapping from typing import Any, cast -from .changes import ChangesBase, FragmentResolver, PluginResolver +from .changes import ChangesData, FragmentResolver, PluginResolver from .config import ChangelogConfig, PathsConfig, TextFormat from .fragment import ChangelogFragment from .logger import LOGGER @@ -110,17 +110,15 @@ class ChangelogGeneratorBase(abc.ABC): """ config: ChangelogConfig - changes: ChangesBase + changes: ChangesData plugin_resolver: PluginResolver fragment_resolver: FragmentResolver - def __init__( # pylint: disable=too-many-arguments + def __init__( self, config: ChangelogConfig, - changes: ChangesBase, - /, - plugins: list[PluginDescription] | None = None, - fragments: list[ChangelogFragment] | None = None, + changes: ChangesData, + *, flatmap: bool = True, ): """ @@ -130,9 +128,9 @@ def __init__( # pylint: disable=too-many-arguments self.changes = changes self.flatmap = flatmap - self.plugin_resolver = changes.get_plugin_resolver(plugins) + self.plugin_resolver = changes.get_plugin_resolver() self.object_resolver = changes.get_object_resolver() - self.fragment_resolver = changes.get_fragment_resolver(fragments) + self.fragment_resolver = changes.get_fragment_resolver() def _update_modules_plugins_objects( self, entry_config: ChangelogEntry, release: dict @@ -298,17 +296,18 @@ class ChangelogGenerator(ChangelogGeneratorBase): def __init__( # pylint: disable=too-many-arguments self, config: ChangelogConfig, - changes: ChangesBase, - plugins: list[PluginDescription] | None = None, - fragments: list[ChangelogFragment] | None = None, + 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, plugins=plugins, fragments=fragments, flatmap=flatmap - ) + super().__init__(config, changes, flatmap=flatmap) def append_changelog_entry( self, @@ -573,9 +572,8 @@ def add_objects( def generate_changelog( # pylint: disable=too-many-arguments paths: PathsConfig, config: ChangelogConfig, - changes: ChangesBase, - plugins: list[PluginDescription] | None = None, - fragments: list[ChangelogFragment] | None = None, + changes: ChangesData, + *, flatmap: bool = True, changelog_path: str | None = None, only_latest: bool = False, @@ -585,8 +583,6 @@ def generate_changelog( # pylint: disable=too-many-arguments This function is DEPRECATED! It will be removed in a future version. - :arg plugins: Will be loaded if necessary. Only provide when you already have them - :arg fragments: Will be loaded if necessary. Only provide when you already have them :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 @@ -603,7 +599,7 @@ def generate_changelog( # pylint: disable=too-many-arguments changelog_filename = config.changelog_filename_template changelog_path = os.path.join(paths.changelog_dir, changelog_filename) - generator = ChangelogGenerator(config, changes, plugins, fragments, flatmap) + generator = ChangelogGenerator(config, changes, flatmap=flatmap) rst = generator.generate(only_latest=only_latest) with open(changelog_path, "wb") as changelog_fd: diff --git a/src/antsibull_changelog/changes.py b/src/antsibull_changelog/changes.py index 605dbd0b..4480dd24 100644 --- a/src/antsibull_changelog/changes.py +++ b/src/antsibull_changelog/changes.py @@ -11,7 +11,6 @@ from __future__ import annotations -import abc import collections import datetime import os @@ -25,7 +24,6 @@ ChangesDataObjectResolver, ChangesDataPluginResolver, FragmentResolver, - LegacyPluginResolver, PluginResolver, ) from .config import ChangelogConfig @@ -36,9 +34,23 @@ from .utils import get_version_constructor, is_release_version -class ChangesBase(metaclass=abc.ABCMeta): +def _sort_dict_by_key(dictionary: Mapping[str, Any]) -> dict[str, Any]: + return dict(sorted(dictionary.items())) + + +def _sort_modules_plugins_objects( + object_list: Sequence[Mapping[str, Any]] +) -> list[dict[str, Any]]: + return sorted( + (_sort_dict_by_key(obj) for obj in object_list), key=lambda obj: obj["name"] + ) + + +class ChangesData: # pylint: disable=too-many-public-methods """ - Read, write and manage change metadata. + Read, write and manage modern change metadata. + + This is the format used for ansible-base 2.10, ansible-core 2.11+, and for Ansible collections. """ config: ChangelogConfig @@ -49,7 +61,14 @@ class ChangesBase(metaclass=abc.ABCMeta): known_fragments: set[str] ancestor: str | None - def __init__(self, config: ChangelogConfig, path: str): + def __init__( + self, config: ChangelogConfig, path: str, data_override: dict | None = None + ): + """ + Create modern change metadata. + + :arg data_override: Allows to load data from dictionary instead from disk + """ self.config = config self.path = path self.data = self.empty() @@ -57,12 +76,8 @@ def __init__(self, config: ChangelogConfig, path: str): self.known_plugins = set() self.known_objects = set() self.ancestor = None - - def version_constructor(self, version: str) -> Any: - """ - Create a version object. - """ - return get_version_constructor(self.config)(version) + self.config = config + self.load(data_override=data_override) @staticmethod def empty() -> dict: @@ -74,29 +89,6 @@ def empty() -> dict: "releases": {}, } - @property - def latest_version(self) -> str: - """ - Latest version in the changes. - - Must only be called if ``has_release`` is ``True``. - """ - return sorted(self.releases, reverse=True, key=self.version_constructor)[0] - - @property - def has_release(self) -> bool: - """ - Whether there is at least one release. - """ - return bool(self.releases) - - @property - def releases(self) -> dict[str, dict[str, Any]]: - """ - Dictionary of releases. - """ - return cast(dict[str, dict[str, Any]], self.data["releases"]) - def load(self, data_override: dict | None = None) -> None: """ Load the change metadata from disk. @@ -111,40 +103,25 @@ def load(self, data_override: dict | None = None) -> None: self.data = self.empty() self.ancestor = self.data.get("ancestor") - @abc.abstractmethod - def update_plugins( - self, plugins: list[PluginDescription], allow_removals: bool | None - ) -> None: - """ - Update plugin descriptions, and remove plugins which are not in the provided list - of plugins. - """ + for _, config in self.releases.items(): + for plugin_type, plugins in config.get("plugins", {}).items(): + self.known_plugins |= set( + "%s/%s" % (plugin_type, plugin["name"]) for plugin in plugins + ) - @abc.abstractmethod - def update_objects( - self, objects: list[PluginDescription], allow_removals: bool | None - ) -> None: - """ - Update object descriptions, and remove objects which are not in the provided list - of objects. - """ + for object_type, objects in config.get("objects", {}).items(): + self.known_objects |= set( + "%s/%s" % (object_type, ansible_object["name"]) + for ansible_object in objects + ) - @abc.abstractmethod - def update_fragments( - self, - fragments: list[ChangelogFragment], - load_extra_fragments: Callable[[str], list[ChangelogFragment]] | None = None, - ) -> None: - """ - Update fragment contents, and remove fragment contents which are not in the provided - list of fragments. - """ + modules = config.get("modules", []) - @abc.abstractmethod - def sort(self) -> None: - """ - Sort change metadata in place. - """ + self.known_plugins |= set( + "module/%s" % module["name"] for module in modules + ) + + self.known_fragments |= set(config.get("fragments", [])) def save(self) -> None: """ @@ -160,201 +137,34 @@ def save(self) -> None: sort_keys=sort_keys, ) - def add_release( - self, - version: str, - codename: str | None, - release_date: datetime.date, - update_existing=False, - ): - """ - Add a new releases to the changes metadata. - """ - if version not in self.releases: - self.releases[version] = {} - elif not update_existing: - LOGGER.warning("release {} already exists", version) - return - - self.releases[version]["release_date"] = release_date.isoformat() - if codename is not None: - self.releases[version]["codename"] = codename - - @abc.abstractmethod - def add_fragment(self, fragment: ChangelogFragment, version: str): - """ - Add a new changelog fragment to the change metadata for the given version. - """ - - def restrict_to(self, version: str) -> None: - """ - Restrict to all versions up to the specified one. - """ - version_obj = self.version_constructor(version) - if version not in self.releases: - raise ValueError(f"Unknown version {version}") - for a_version in list(self.releases): - if self.version_constructor(a_version) > version_obj: - del self.releases[a_version] - - @staticmethod - def _create_plugin_entry(plugin: PluginDescription) -> Any: - return plugin.name - - def add_plugin(self, plugin: PluginDescription, version: str): - """ - Add a new plugin to the change metadata for the given version. - - If the plugin happens to be already known (for another version), - it will not be added. - - :return: ``True`` if the plugin was added for this version - """ - if plugin.category != "plugin": - return False - - composite_name = "%s/%s" % (plugin.type, plugin.name) - - if composite_name in self.known_plugins: - return False - - self.known_plugins.add(composite_name) - - if plugin.type == "module": - if "modules" not in self.releases[version]: - self.releases[version]["modules"] = [] - - modules = self.releases[version]["modules"] - modules.append(self._create_plugin_entry(plugin)) - else: - if "plugins" not in self.releases[version]: - self.releases[version]["plugins"] = {} - - plugins = self.releases[version]["plugins"] - - if plugin.type not in plugins: - plugins[plugin.type] = [] - - plugins[plugin.type].append(self._create_plugin_entry(plugin)) - - return True - - def add_object(self, ansible_object: PluginDescription, version: str): - """ - Add a new object to the change metadata for the given version. - - If the object happens to be already known (for another version), - it will not be added. - - :return: ``True`` if the object was added for this version - """ - if ansible_object.category != "object": - return False - - composite_name = "%s/%s" % (ansible_object.type, ansible_object.name) - - if composite_name in self.known_objects: - return False - - self.known_objects.add(composite_name) - - if "objects" not in self.releases[version]: - self.releases[version]["objects"] = {} - - objects = self.releases[version]["objects"] - - if ansible_object.type not in objects: - objects[ansible_object.type] = [] - - objects[ansible_object.type].append(self._create_plugin_entry(ansible_object)) - - return True - - @abc.abstractmethod - def get_plugin_resolver( - self, plugins: list[PluginDescription] | None = None - ) -> PluginResolver: - """ - Create a plugin resolver. - - If the plugins are not provided and needed by this object, they might be loaded. - """ - - @abc.abstractmethod - def get_object_resolver(self) -> PluginResolver: + def version_constructor(self, version: str) -> Any: """ - Create a object resolver. + Create a version object. """ + return get_version_constructor(self.config)(version) - @abc.abstractmethod - def get_fragment_resolver( - self, fragments: list[ChangelogFragment] | None = None - ) -> FragmentResolver: + @property + def latest_version(self) -> str: """ - Create a fragment resolver. + Latest version in the changes. - If the fragments are not provided and needed by this object, they might be loaded. + Must only be called if ``has_release`` is ``True``. """ + return sorted(self.releases, reverse=True, key=self.version_constructor)[0] - -def _sort_dict_by_key(dictionary: Mapping[str, Any]) -> dict[str, Any]: - return dict(sorted(dictionary.items())) - - -def _sort_modules_plugins_objects( - object_list: Sequence[Mapping[str, Any]] -) -> list[dict[str, Any]]: - return sorted( - (_sort_dict_by_key(obj) for obj in object_list), key=lambda obj: obj["name"] - ) - - -class ChangesData(ChangesBase): - """ - Read, write and manage modern change metadata. - - This is the format used for ansible-base 2.10, ansible-core 2.11+, and for Ansible collections. - """ - - config: ChangelogConfig - - def __init__( - self, config: ChangelogConfig, path: str, data_override: dict | None = None - ): + @property + def has_release(self) -> bool: """ - Create modern change metadata. - - :arg data_override: Allows to load data from dictionary instead from disk + Whether there is at least one release. """ - super().__init__(config, path) - self.config = config - self.load(data_override=data_override) + return bool(self.releases) - def load(self, data_override: dict | None = None) -> None: + @property + def releases(self) -> dict[str, dict[str, Any]]: """ - Load the change metadata from disk. + Dictionary of releases. """ - super().load(data_override=data_override) - - for _, config in self.releases.items(): - for plugin_type, plugins in config.get("plugins", {}).items(): - self.known_plugins |= set( - "%s/%s" % (plugin_type, plugin["name"]) for plugin in plugins - ) - - for object_type, objects in config.get("objects", {}).items(): - self.known_objects |= set( - "%s/%s" % (object_type, ansible_object["name"]) - for ansible_object in objects - ) - - modules = config.get("modules", []) - - self.known_plugins |= set( - "module/%s" % module["name"] for module in modules - ) - - self.known_fragments |= set(config.get("fragments", [])) + return cast(dict[str, dict[str, Any]], self.data["releases"]) def update_plugins( self, plugins: list[PluginDescription], allow_removals: bool | None @@ -679,15 +489,11 @@ def add_fragment(self, fragment: ChangelogFragment, version: str): @staticmethod def _create_plugin_entry(plugin: PluginDescription) -> dict: - return LegacyPluginResolver.resolve_plugin(plugin) + return PluginResolver.resolve_plugin(plugin) - def get_plugin_resolver( - self, plugins: list[PluginDescription] | None = None - ) -> PluginResolver: + def get_plugin_resolver(self) -> PluginResolver: """ Create a plugin resolver. - - The plugins list is not used. """ return ChangesDataPluginResolver() @@ -697,13 +503,9 @@ def get_object_resolver(self) -> PluginResolver: """ return ChangesDataObjectResolver() - def get_fragment_resolver( - self, fragments: list[ChangelogFragment] | None = None - ) -> FragmentResolver: + def get_fragment_resolver(self) -> FragmentResolver: """ Create a fragment resolver. - - The fragments list is not used. """ return ChangesDataFragmentResolver() @@ -735,6 +537,106 @@ def prune_versions( del self.data["releases"][version] continue + def add_release( + self, + version: str, + codename: str | None, + release_date: datetime.date, + update_existing=False, + ): + """ + Add a new releases to the changes metadata. + """ + if version not in self.releases: + self.releases[version] = {} + elif not update_existing: + LOGGER.warning("release {} already exists", version) + return + + self.releases[version]["release_date"] = release_date.isoformat() + if codename is not None: + self.releases[version]["codename"] = codename + + def restrict_to(self, version: str) -> None: + """ + Restrict to all versions up to the specified one. + """ + version_obj = self.version_constructor(version) + if version not in self.releases: + raise ValueError(f"Unknown version {version}") + for a_version in list(self.releases): + if self.version_constructor(a_version) > version_obj: + del self.releases[a_version] + + def add_plugin(self, plugin: PluginDescription, version: str): + """ + Add a new plugin to the change metadata for the given version. + + If the plugin happens to be already known (for another version), + it will not be added. + + :return: ``True`` if the plugin was added for this version + """ + if plugin.category != "plugin": + return False + + composite_name = "%s/%s" % (plugin.type, plugin.name) + + if composite_name in self.known_plugins: + return False + + self.known_plugins.add(composite_name) + + if plugin.type == "module": + if "modules" not in self.releases[version]: + self.releases[version]["modules"] = [] + + modules = self.releases[version]["modules"] + modules.append(self._create_plugin_entry(plugin)) + else: + if "plugins" not in self.releases[version]: + self.releases[version]["plugins"] = {} + + plugins = self.releases[version]["plugins"] + + if plugin.type not in plugins: + plugins[plugin.type] = [] + + plugins[plugin.type].append(self._create_plugin_entry(plugin)) + + return True + + def add_object(self, ansible_object: PluginDescription, version: str): + """ + Add a new object to the change metadata for the given version. + + If the object happens to be already known (for another version), + it will not be added. + + :return: ``True`` if the object was added for this version + """ + if ansible_object.category != "object": + return False + + composite_name = "%s/%s" % (ansible_object.type, ansible_object.name) + + if composite_name in self.known_objects: + return False + + self.known_objects.add(composite_name) + + if "objects" not in self.releases[version]: + self.releases[version]["objects"] = {} + + objects = self.releases[version]["objects"] + + if ansible_object.type not in objects: + objects[ansible_object.type] = [] + + objects[ansible_object.type].append(self._create_plugin_entry(ansible_object)) + + return True + @staticmethod def concatenate(changes_datas: list["ChangesData"]) -> "ChangesData": """ @@ -746,7 +648,7 @@ def concatenate(changes_datas: list["ChangesData"]) -> "ChangesData": """ assert len(changes_datas) > 0 last = changes_datas[-1] - data = ChangesBase.empty() + data = ChangesData.empty() ancestor = None no_ancestor = False for changes in changes_datas: @@ -767,7 +669,7 @@ def concatenate(changes_datas: list["ChangesData"]) -> "ChangesData": return ChangesData(last.config, last.path, data) -def load_changes(config: ChangelogConfig) -> ChangesBase: +def load_changes(config: ChangelogConfig) -> ChangesData: """ Load changes metadata. """ @@ -803,7 +705,7 @@ def f(version_added: str | None) -> bool: def _add_plugins_filters( - changes: ChangesBase, + changes: ChangesData, plugins: list[PluginDescription], objects: list[PluginDescription], version: str, @@ -844,7 +746,7 @@ def version_filter(obj: PluginDescription) -> bool: def _add_fragments( - changes: ChangesBase, + changes: ChangesData, fragments: list[ChangelogFragment], version: str, show_release_summary_warning: bool, @@ -870,7 +772,7 @@ def _add_fragments( def add_release( # pylint: disable=too-many-arguments,too-many-locals config: ChangelogConfig, - changes: ChangesBase, + changes: ChangesData, plugins: list[PluginDescription], fragments: list[ChangelogFragment], version: str, diff --git a/src/antsibull_changelog/changes_resolvers.py b/src/antsibull_changelog/changes_resolvers.py index dd8fa18a..85e050b0 100644 --- a/src/antsibull_changelog/changes_resolvers.py +++ b/src/antsibull_changelog/changes_resolvers.py @@ -34,56 +34,10 @@ def resolve(self, release: dict) -> list[ChangelogFragment]: class PluginResolver(metaclass=abc.ABCMeta): - # pylint: disable=too-few-public-methods """ Allows to resolve a release section to a plugin description database. """ - @abc.abstractmethod - def resolve(self, release: dict) -> dict[str, list[dict[str, Any]]]: - """ - Return a dictionary of plugin types mapping to lists of plugin descriptions - for the given release. - - :arg release: A release description - :return: A map of plugin types to lists of plugin descriptions - """ - - -class LegacyFragmentResolver(FragmentResolver): - # pylint: disable=too-few-public-methods - """ - Given a list of changelog fragments, allows to resolve from a list of fragment names. - """ - - fragments: dict[str, ChangelogFragment] - - def __init__(self, fragments: list[ChangelogFragment]): - """ - Create a simple fragment resolver. - """ - self.fragments = {} - for fragment in fragments: - self.fragments[fragment.name] = fragment - - def resolve(self, release: dict) -> list[ChangelogFragment]: - """ - Return a list of ``ChangelogFragment`` objects from the given release object. - - :arg release: A release description - :return: A list of changelog fragments - """ - fragment_names: list[str] = release.get("fragments", []) - return [self.fragments[fragment] for fragment in fragment_names] - - -class LegacyPluginResolver(PluginResolver): - """ - Provides a plugin resolved based on a list of ``PluginDescription`` objects. - """ - - plugins: dict[str, dict[str, dict[str, Any]]] - @staticmethod def resolve_plugin(plugin: PluginDescription) -> dict[str, Any]: """ @@ -95,17 +49,7 @@ def resolve_plugin(plugin: PluginDescription) -> dict[str, Any]: "description": plugin.description, } - def __init__(self, plugins: list[PluginDescription]): - """ - Create a simple plugin resolver from a list of ``PluginDescription`` objects. - """ - self.plugins = {} - for plugin in plugins: - if plugin.type not in self.plugins: - self.plugins[plugin.type] = {} - - self.plugins[plugin.type][plugin.name] = self.resolve_plugin(plugin) - + @abc.abstractmethod def resolve(self, release: dict) -> dict[str, list[dict[str, Any]]]: """ Return a dictionary of plugin types mapping to lists of plugin descriptions @@ -114,36 +58,6 @@ def resolve(self, release: dict) -> dict[str, list[dict[str, Any]]]: :arg release: A release description :return: A map of plugin types to lists of plugin descriptions """ - result = {} - if "modules" in release: - result["module"] = [ - self.plugins["module"][module_name] - for module_name in release["modules"] - ] - if "plugins" in release: - for plugin_type, plugin_names in release["plugins"].items(): - result[plugin_type] = [ - self.plugins[plugin_type][plugin_name] - for plugin_name in plugin_names - ] - return result - - -class LegacyObjectResolver(PluginResolver): - # pylint: disable=too-few-public-methods - """ - Provides a object resolved based on a list of ``PluginDescription`` objects. - """ - - def resolve(self, release: dict) -> dict[str, list[dict[str, Any]]]: - """ - Return a dictionary of object types mapping to lists of object descriptions - for the given release. - - :arg release: A release description - :return: A map of object types to lists of plugin descriptions - """ - return {} class ChangesDataFragmentResolver(FragmentResolver): @@ -166,7 +80,6 @@ def resolve(self, release: dict) -> list[ChangelogFragment]: class ChangesDataPluginResolver(PluginResolver): - # pylint: disable=too-few-public-methods """ A ``PluginResolver`` class for modern ``ChangesData`` objects. """ @@ -188,7 +101,6 @@ def resolve(self, release: dict) -> dict[str, list[dict[str, Any]]]: class ChangesDataObjectResolver(PluginResolver): - # pylint: disable=too-few-public-methods """ A ``PluginResolver`` class for modern ``ChangesData`` objects. """ diff --git a/src/antsibull_changelog/cli.py b/src/antsibull_changelog/cli.py index e3a13837..62b04e05 100644 --- a/src/antsibull_changelog/cli.py +++ b/src/antsibull_changelog/cli.py @@ -33,7 +33,7 @@ from . import __version__ as _version from . import constants as C from .ansible import get_ansible_release -from .changes import ChangesBase, add_release, load_changes +from .changes import ChangesData, add_release, load_changes from .config import ChangelogConfig, CollectionDetails, PathsConfig, TextFormat from .errors import ChangelogError from .fragment import ChangelogFragment, ChangelogFragmentLinter, load_fragments @@ -466,7 +466,7 @@ def _do_refresh( # pylint: disable=too-many-arguments paths: PathsConfig, collection_details: CollectionDetails, config: ChangelogConfig, - changes: ChangesBase, + changes: ChangesData, plugins: list[PluginDescription] | None = None, fragments: list[ChangelogFragment] | None = None, ) -> tuple[list[PluginDescription] | None, list[ChangelogFragment] | None]: @@ -702,15 +702,13 @@ def command_release(args: Any) -> int: config, changes, document_format, - plugins=plugins, - fragments=fragments, flatmap=flatmap, ) return C.RC_SUCCESS -def command_generate(args: Any) -> int: # pylint: disable=too-many-locals +def command_generate(args: Any) -> int: """ (Re-)generate the reStructuredText version of the changelog. @@ -740,9 +738,7 @@ def command_generate(args: Any) -> int: # pylint: disable=too-many-locals if not changes.has_release: print("Cannot create changelog when not at least one release has been added.") return C.RC_COMMAND_FAILED - plugins, fragments = _do_refresh( - args, paths, collection_details, config, changes, None, None - ) + plugins, _ = _do_refresh(args, paths, collection_details, config, changes) if args.reload_plugins and plugins is None: plugins = load_plugins( paths=paths, @@ -769,8 +765,6 @@ def command_generate(args: Any) -> int: # pylint: disable=too-many-locals config, changes, document_format, - plugins=plugins, - fragments=fragments, flatmap=flatmap, changelog_path=output, only_latest=only_latest, diff --git a/src/antsibull_changelog/rendering/changelog.py b/src/antsibull_changelog/rendering/changelog.py index 9ef8df69..86e1a1aa 100644 --- a/src/antsibull_changelog/rendering/changelog.py +++ b/src/antsibull_changelog/rendering/changelog.py @@ -20,7 +20,7 @@ ChangelogGeneratorBase, get_plugin_name, ) -from ..changes import ChangesBase +from ..changes import ChangesData from ..config import ChangelogConfig, PathsConfig, TextFormat from ..fragment import ChangelogFragment from ..logger import LOGGER @@ -60,17 +60,18 @@ class ChangelogGenerator(ChangelogGeneratorBase): def __init__( # pylint: disable=too-many-arguments self, config: ChangelogConfig, - changes: ChangesBase, - plugins: list[PluginDescription] | None = None, - fragments: list[ChangelogFragment] | None = None, + 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, plugins=plugins, fragments=fragments, flatmap=flatmap - ) + super().__init__(config, changes, flatmap=flatmap) def append_changelog_entry( self, @@ -373,7 +374,7 @@ def create_document_renderer( def _create_changelog_path( paths: PathsConfig, config: ChangelogConfig, - changes: ChangesBase, + changes: ChangesData, document_format: TextFormat, ) -> str: major_minor_version = ".".join( @@ -391,11 +392,9 @@ def _create_changelog_path( def generate_changelog( # pylint: disable=too-many-arguments paths: PathsConfig, config: ChangelogConfig, - changes: ChangesBase, + changes: ChangesData, document_format: TextFormat, - /, - plugins: list[PluginDescription] | None = None, - fragments: list[ChangelogFragment] | None = None, + *, flatmap: bool = True, changelog_path: str | None = None, only_latest: bool = False, @@ -403,8 +402,6 @@ def generate_changelog( # pylint: disable=too-many-arguments """ Generate the changelog as reStructuredText. - :kwarg plugins: Will be loaded if necessary. Only provide when you already have them - :kwarg fragments: Will be loaded if necessary. Only provide when you already have them :kwarg flatmap: Whether the collection uses flatmapping or not :kwarg changelog_path: Write the output to this path instead of the default path. :kwarg only_latest: Only write the last changelog entry without any preamble @@ -412,7 +409,7 @@ def generate_changelog( # pylint: disable=too-many-arguments if changelog_path is None: changelog_path = _create_changelog_path(paths, config, changes, document_format) - generator = ChangelogGenerator(config, changes, plugins, fragments, flatmap) + generator = ChangelogGenerator(config, changes, flatmap=flatmap) renderer = create_document_renderer( document_format, start_level=1 if only_latest else 0 ) diff --git a/tests/units/test_changes.py b/tests/units/test_changes.py index 06ce8784..3e66ee7f 100644 --- a/tests/units/test_changes.py +++ b/tests/units/test_changes.py @@ -14,7 +14,7 @@ import pytest -from antsibull_changelog.changes import ChangesBase, ChangesData +from antsibull_changelog.changes import ChangesData from antsibull_changelog.config import ChangelogConfig, CollectionDetails, PathsConfig @@ -76,7 +76,7 @@ def test_changes_data(): changes2 = ChangesData( config, os.path.join(config.paths.changelog_dir, config.changes_file), - data_override=ChangesBase.empty(), + data_override=ChangesData.empty(), ) changes2.ancestor = "1.3.1-alpha" changes2.add_release("1.3.2", None, datetime.date(2020, 3, 10)) @@ -89,7 +89,7 @@ def test_changes_data(): changes3 = ChangesData( config, os.path.join(config.paths.changelog_dir, config.changes_file), - data_override=ChangesBase.empty(), + data_override=ChangesData.empty(), ) changes3.add_release("0.1.0", None, datetime.date(2019, 7, 30)) changes3.add_release("0.2.0", None, datetime.date(2019, 12, 31))