diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 154037b..28049f7 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,7 +4,6 @@ Sebastian.Base Release Notes .. contents:: Topics - v0.4.2 ====== @@ -31,7 +30,6 @@ Release Summary to prevent empty sections, the install and header methods return None if the method would just the scetion header - v0.3.1 ====== diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index 1bfc0a7..7b226e6 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -4,44 +4,56 @@ releases: changes: release_summary: change the module to an ansible module fragments: - - base_release.yml - release_date: '2024-02-11' + - base_release.yml + release_date: "2024-02-11" 0.3.0: changes: release_summary: rewrote the Types helper fragments: - - types.yml - release_date: '2024-02-24' + - types.yml + release_date: "2024-02-24" 0.3.1: changes: release_summary: removed forgotten print calls fragments: - - print_calls.yml - release_date: '2024-02-24' + - print_calls.yml + release_date: "2024-02-24" 0.4.0: changes: - release_summary: 'to prevent empty sections, the install and header methods - return None if the method would just the scetion + release_summary: "to prevent empty sections, the install and header methods return None if the method would just + the scetion header - ' + " fragments: - - sectioning.yml - release_date: '2024-03-08' + - sectioning.yml + release_date: "2024-03-08" 0.4.1: changes: minor_changes: - - added an default Display to the module - - fixed the docification of dictionaries + - added an default Display to the module + - fixed the docification of dictionaries fragments: - - display.yml - - options_fix.yml - release_date: '2024-03-13' + - display.yml + - options_fix.yml + release_date: "2024-03-13" 0.4.2: changes: minor_changes: - - removed the empty options dict + - removed the empty options dict fragments: - - empty_options.yml - release_date: '2024-03-13' + - empty_options.yml + release_date: "2024-03-13" + 0.4.3: + changes: + fragments: + - 0.4.3.yml + release_date: "2024-03-13" + 0.4.4: + changes: + minor_changes: + - removed the empty options dict + fragments: + - 0.4.4.yml + release_date: "2025-03-16" diff --git a/changelogs/fragments/0.4.4.yml b/changelogs/fragments/0.4.4.yml new file mode 100644 index 0000000..7a5990f --- /dev/null +++ b/changelogs/fragments/0.4.4.yml @@ -0,0 +1,3 @@ +--- +major_changes: + - the modules can now accept lists for help. diff --git a/galaxy.yml b/galaxy.yml index 908b75f..059c08d 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,11 +1,10 @@ namespace: sebastian name: base -version: 0.4.3 +version: 0.4.4 readme: README.md authors: - Sebastian Tobie -description: The base of my ansible collections. It provides the nessesary tools for - my modules +description: The base of my ansible collections. It provides the nessesary tools for my modules license_file: LICENSE.txt tags: - linux @@ -15,7 +14,7 @@ repository: https://gitea.sebastian-tobie.de/ansible/ansible-module.git homepage: https://gitea.sebastian-tobie.de/ansible/ansible-module issues: https://gitea.sebastian-tobie.de/ansible/ansible-module/issues build_ignore: - - '*.gz' + - "*.gz" - .* - Makefile - pyproject.toml diff --git a/plugins/module_utils/generic.py b/plugins/module_utils/generic.py index c187eac..6700356 100644 --- a/plugins/module_utils/generic.py +++ b/plugins/module_utils/generic.py @@ -1,6 +1,7 @@ +import builtins import pathlib import warnings -from typing import Any, Callable, Dict, Optional, Sequence, Tuple, Type, Union +from typing import Any, Dict, Optional, Sequence, Tuple, Type, Union __all__ = ( "Types", @@ -46,7 +47,7 @@ GENERIC_DOC = """Returns an dictionary for the Ansible {type} type.""" def default(name: str): def wrapped( required: bool = False, - help: Optional[str] = None, + help: str | list[str] | None = None, choices: Optional[Sequence] = None, default: Optional[Any] = None, ) -> AnsibleParameter: @@ -55,8 +56,10 @@ def default(name: str): option["choices"] = choices if default is not None: option["default"] = default - if help is not None: + if help is not None and isinstance(help, str): option["description"] = help.split("\n") + elif help is not None: + option["description"] = help return option return wrapped @@ -94,7 +97,8 @@ class Types(metaclass=meta): def list( # type: ignore[misc] elements: Union[Type[object], str, AnsibleParameter], required: bool = False, - help: Optional[str] = None, + help: str | list[str] | None = None, + default: list[Any] | None = None, ) -> AnsibleParameter: """Wrapper for the Ansible list type @@ -102,7 +106,10 @@ class Types(metaclass=meta): elements: The type of the elements required: if the item is absolutly required help: an helptext for the ansible-doc + default: an default value. The Value is not converted. """ + if required and default: + raise ValueError("required and default are not allowed") option: AnsibleParameter = dict(type="list", required=required) if not isinstance(elements, (str, dict)): option["elements"] = elements.__name__ @@ -117,12 +124,19 @@ class Types(metaclass=meta): f"helptext of option {name} is unset." " Ansible requires suboptions to have an documentation" ) - if help is not None: + elif elements["type"] == "list": + if "choices" in elements: + option["choices"] = elements["choices"] + if default is not None: + option["default"] = default + if help is not None and isinstance(help, str): option["description"] = help.split("\n") + elif help is not None: + option["description"] = help return option @staticmethod - def dict(required: bool = False, help: Optional[str] = None, **options: AnsibleParameter) -> AnsibleParameter: # type: ignore[misc] + def dict(required: bool = False, help: str | builtins.list[str] | None = None, **options: AnsibleParameter) -> AnsibleParameter: # type: ignore[misc] """Wrapper for the Ansible dict type Args: @@ -132,8 +146,10 @@ class Types(metaclass=meta): """ option: AnsibleParameter = dict(type="dict", required=required) option["options"] = options - if help is not None: + if help is not None and isinstance(help, str): option["description"] = help.split("\n") + elif help is not None: + option["description"] = help return option diff --git a/plugins/module_utils/generic.pyi b/plugins/module_utils/generic.pyi index 0b6baaa..4dae026 100644 --- a/plugins/module_utils/generic.pyi +++ b/plugins/module_utils/generic.pyi @@ -1,5 +1,5 @@ -from typing import Any, Optional, Sequence, Dict, Tuple, Union from pathlib import PosixPath +from typing import Any, Dict, Optional, Sequence, Tuple, Union __all__ = [ 'Types', @@ -22,79 +22,84 @@ class Types(metaclass=meta): @staticmethod def str( required: bool = False, - help: Optional[str] = None, + help: str | list[str] | None = None, choices: Optional[Sequence] = None, default: Optional[Any] = None, ): ... @staticmethod def bool( required: bool = False, - help: Optional[str] = None, + help: str | list[str] | None = None, choices: Optional[Sequence] = None, default: Optional[Any] = None, ): ... @staticmethod def int( required: bool = False, - help: Optional[str] = None, + help: str | list[str] | None = None, choices: Optional[Sequence] = None, default: Optional[Any] = None, ): ... @staticmethod def float( required: bool = False, - help: Optional[str] = None, + help: str | list[str] | None = None, choices: Optional[Sequence] = None, default: Optional[Any] = None, ): ... @staticmethod def path( required: bool = False, - help: Optional[str] = None, + help: str | list[str] | None = None, choices: Optional[Sequence] = None, default: Optional[Any] = None, ): ... @staticmethod def raw( required: bool = False, - help: Optional[str] = None, + help: str | list[str] | None = None, choices: Optional[Sequence] = None, default: Optional[Any] = None, ): ... @staticmethod def jsonarg( required: bool = False, - help: Optional[str] = None, + help: str | list[str] | None = None, choices: Optional[Sequence] = None, default: Optional[Any] = None, ): ... @staticmethod def json( required: bool = False, - help: Optional[str] = None, + help: str | list[str] | None = None, choices: Optional[Sequence] = None, default: Optional[Any] = None, ): ... @staticmethod def bytes( required: bool = False, - help: Optional[str] = None, + help: str | list[str] | None = None, choices: Optional[Sequence] = None, default: Optional[Any] = None, ): ... @staticmethod def bits( required: bool = False, - help: Optional[str] = None, + help: str | list[str] | None = None, choices: Optional[Sequence] = None, default: Optional[Any] = None, ): ... @staticmethod def list( - elements: type[object] | str | AnsibleParameter, required: bool = False, help: str | None = None + elements: type[object] | str | AnsibleParameter, + required: bool = False, + help: str | list[str] | None = None, + default: list[Any] | None = None, ) -> AnsibleParameter: ... @staticmethod - def dict(required: bool = False, help: str | None = None, **options: AnsibleParameter) -> AnsibleParameter: ... + def dict( + required: bool = False, help: str | list[str] | None = None, **options: AnsibleParameter + ) -> AnsibleParameter: ... def systemdbool(b: bool | str) -> str: ... def joindict(*items: dict) -> dict: ... diff --git a/plugins/module_utils/module.py b/plugins/module_utils/module.py index c61f2b8..5d6a6ed 100644 --- a/plugins/module_utils/module.py +++ b/plugins/module_utils/module.py @@ -1,6 +1,7 @@ import pathlib from copy import deepcopy -from typing import Any, Callable, ClassVar, Dict, NoReturn, Optional, Type, TypeVar, Union, overload, TypedDict +from typing import (Any, Callable, ClassVar, Dict, NoReturn, Optional, Type, + TypedDict, TypeVar, Union, overload) import ansible.module_utils.basic as basic