summaryrefslogtreecommitdiffstats
path: root/src/ansiblelint/rules/meta_no_info.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/ansiblelint/rules/meta_no_info.py')
-rw-r--r--src/ansiblelint/rules/meta_no_info.py83
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)]