summaryrefslogtreecommitdiffstats
path: root/src/ansiblelint/loaders.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/ansiblelint/loaders.py')
-rw-r--r--src/ansiblelint/loaders.py75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/ansiblelint/loaders.py b/src/ansiblelint/loaders.py
new file mode 100644
index 0000000..49e38f1
--- /dev/null
+++ b/src/ansiblelint/loaders.py
@@ -0,0 +1,75 @@
+"""Utilities for loading various files."""
+from __future__ import annotations
+
+import logging
+import os
+from collections import defaultdict, namedtuple
+from functools import partial
+from typing import TYPE_CHECKING, Any
+
+import yaml
+from yaml import YAMLError
+
+try:
+ from yaml import CFullLoader as FullLoader
+ from yaml import CSafeLoader as SafeLoader
+except (ImportError, AttributeError):
+ from yaml import FullLoader, SafeLoader # type: ignore[assignment]
+
+if TYPE_CHECKING:
+ from pathlib import Path
+
+IgnoreFile = namedtuple("IgnoreFile", "default alternative")
+IGNORE_FILE = IgnoreFile(".ansible-lint-ignore", ".config/ansible-lint-ignore.txt")
+
+yaml_load = partial(yaml.load, Loader=FullLoader)
+yaml_load_safe = partial(yaml.load, Loader=SafeLoader)
+_logger = logging.getLogger(__name__)
+
+
+def yaml_from_file(filepath: str | Path) -> Any:
+ """Return a loaded YAML file."""
+ with open(str(filepath), encoding="utf-8") as content:
+ return yaml_load(content)
+
+
+def load_ignore_txt(filepath: Path | None = None) -> dict[str, set[str]]:
+ """Return a list of rules to ignore."""
+ result = defaultdict(set)
+
+ ignore_file = None
+
+ if filepath:
+ if os.path.isfile(filepath):
+ ignore_file = str(filepath)
+ else:
+ _logger.error("Ignore file not found '%s'", ignore_file)
+ elif os.path.isfile(IGNORE_FILE.default):
+ ignore_file = IGNORE_FILE.default
+ elif os.path.isfile(IGNORE_FILE.alternative):
+ ignore_file = IGNORE_FILE.alternative
+
+ if ignore_file:
+ with open(ignore_file, encoding="utf-8") as _ignore_file:
+ _logger.debug("Loading ignores from '%s'", ignore_file)
+ for line in _ignore_file:
+ entry = line.split("#")[0].rstrip()
+ if entry:
+ try:
+ path, rule = entry.split()
+ except ValueError as exc:
+ msg = f"Unable to parse line '{line}' from {ignore_file} file."
+ raise RuntimeError(msg) from exc
+ result[path].add(rule)
+
+ return result
+
+
+__all__ = [
+ "load_ignore_txt",
+ "yaml_from_file",
+ "yaml_load",
+ "yaml_load_safe",
+ "YAMLError",
+ "IGNORE_FILE",
+]