diff options
Diffstat (limited to 'src/ansiblelint/rules/meta_no_info.py')
-rw-r--r-- | src/ansiblelint/rules/meta_no_info.py | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/ansiblelint/rules/meta_no_info.py b/src/ansiblelint/rules/meta_no_info.py new file mode 100644 index 0000000..0e3c046 --- /dev/null +++ b/src/ansiblelint/rules/meta_no_info.py @@ -0,0 +1,83 @@ +"""Implementation of meta-no-info rule.""" +# Copyright (c) 2016, Will Thames and contributors +# Copyright (c) 2018, Ansible Project +from __future__ import annotations + +from typing import TYPE_CHECKING, Generator + +from ansiblelint.errors import MatchError +from ansiblelint.file_utils import Lintable +from ansiblelint.rules import AnsibleLintRule + +if TYPE_CHECKING: + from typing import Any, Tuple + + +META_STR_INFO = ("author", "description") +META_INFO = tuple( + list(META_STR_INFO) + + [ + "license", + "min_ansible_version", + "platforms", + ] +) + + +def _platform_info_errors_itr( + platforms: list[dict[str, str]], +) -> Generator[str, None, None]: + if not isinstance(platforms, list): + yield "Platforms should be a list of dictionaries" + return + + for platform in platforms: + if not isinstance(platform, dict): + yield "Platforms should be a list of dictionaries" + elif "name" not in platform: + yield "Platform should contain name" + + +def _galaxy_info_errors_itr( + galaxy_info: dict[str, Any], + info_list: tuple[str, ...] = META_INFO, + str_info_list: tuple[str, ...] = META_STR_INFO, +) -> Generator[str, None, None]: + for info in info_list: + g_info = galaxy_info.get(info, False) + if g_info: + if info in str_info_list and not isinstance(g_info, str): + yield f"{info} should be a string" + elif info == "platforms": + yield from _platform_info_errors_itr(g_info) + else: + yield f"Role info should contain {info}" + + +class MetaMainHasInfoRule(AnsibleLintRule): + """meta/main.yml should contain relevant info.""" + + id = "meta-no-info" + str_info = META_STR_INFO + info = META_INFO + description = f"meta/main.yml should contain: {', '.join(info)}" + severity = "HIGH" + tags = ["metadata"] + version_added = "v4.0.0" + + def matchplay(self, file: Lintable, data: dict[str, Any]) -> list[MatchError]: + if file.kind != "meta": + return [] + + # since Ansible 2.10 we can add a meta/requirements.yml but + # we only want to match on meta/main.yml + if file.path.name != "main.yml": + return [] + + galaxy_info = data.get("galaxy_info", False) + if galaxy_info: + return [ + self.create_matcherror(message=err, filename=file) + for err in _galaxy_info_errors_itr(galaxy_info) + ] + return [self.create_matcherror(message="No 'galaxy_info' found", filename=file)] |