Skip to content

Commit a902c2f

Browse files
authored
Restore pre ansible-lint 25.8.1 behavior for compatibility (#520)
- Add ansible-lint version detection via importlib.metadata - Auto-enable plugin loader for ansible-lint < 25.8.1 to preserve old behavior - Create compatibility module for backward compatibility logic - Add utils module for version detection functions - Add comprehensive parametrized tests for compatibility logic - Maintain new gated behavior for ansible-lint >= 25.8.1 This change resolves compatibility issues reported by users with older ansible-lint versions while preserving the improved collection discovery behavior for newer versions.
1 parent 74c522b commit a902c2f

5 files changed

Lines changed: 113 additions & 0 deletions

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""Compatibility functions for ansible_compat.
2+
3+
This module contains functions that handle backward compatibility
4+
with different versions of ansible-lint and other tools.
5+
"""
6+
7+
from __future__ import annotations
8+
9+
from packaging.version import Version
10+
11+
from ansible_compat.constants import ANSIBLE_LINT_MIN_VERSION_EARLY_LOADER
12+
from ansible_compat.utils import ansible_lint_version
13+
14+
15+
def should_auto_enable_plugin_loader() -> bool:
16+
"""Check if plugin loader should be auto-enabled for backwards compatibility.
17+
18+
Returns True if ansible-lint version is < ANSIBLE_LINT_MIN_VERSION_EARLY_LOADER.
19+
20+
Returns:
21+
True if plugin loader should be auto-enabled, False otherwise.
22+
"""
23+
# Check ansible-lint version
24+
lint_version = ansible_lint_version()
25+
return lint_version is not None and lint_version < Version(
26+
ANSIBLE_LINT_MIN_VERSION_EARLY_LOADER,
27+
)

src/ansible_compat/constants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
# Minimal version of Ansible we support for runtime
1717
ANSIBLE_MIN_VERSION = "2.16"
1818

19+
# ansible-lint version below which we auto-enable plugin loader for backwards compatibility
20+
ANSIBLE_LINT_MIN_VERSION_EARLY_LOADER = "25.8.1"
21+
1922
# Based on https://docs.ansible.com/ansible/latest/reference_appendices/config.html
2023
ANSIBLE_DEFAULT_ROLES_PATH = (
2124
"~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles"

src/ansible_compat/runtime.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import subprocess_tee
2424
from packaging.version import Version
2525

26+
from ansible_compat.compatibility import should_auto_enable_plugin_loader
2627
from ansible_compat.config import (
2728
AnsibleConfig,
2829
parse_ansible_version,
@@ -252,6 +253,10 @@ def __init__(
252253
self.require_module = True
253254
self._ensure_module_available()
254255

256+
# For backwards compatibility with ansible-lint < 25.8.1
257+
if should_auto_enable_plugin_loader():
258+
self.enable_plugin_loader()
259+
255260
# pylint: disable=import-outside-toplevel
256261
from ansible.utils.display import Display
257262

src/ansible_compat/utils.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""Utility functions for ansible_compat."""
2+
3+
from __future__ import annotations
4+
5+
from importlib.metadata import PackageNotFoundError, version
6+
7+
from packaging.version import Version
8+
9+
from ansible_compat.ports import cache
10+
11+
12+
@cache
13+
def ansible_lint_version() -> Version | None:
14+
"""Return current Version object for ansible-lint if available.
15+
16+
Returns:
17+
Version object for ansible-lint or None if not found.
18+
"""
19+
try:
20+
return Version(version("ansible-lint"))
21+
except (ImportError, PackageNotFoundError):
22+
return None

test/test_compatibility.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""Test compatibility functions."""
2+
3+
from __future__ import annotations
4+
5+
import pytest
6+
from packaging.version import Version
7+
8+
from ansible_compat.compatibility import should_auto_enable_plugin_loader
9+
10+
11+
@pytest.mark.parametrize(
12+
("ansible_lint_version", "expected"),
13+
(
14+
# ansible-lint < 25.8.1 should auto-enable
15+
("25.8.0", True),
16+
("25.7.9", True),
17+
("25.0.0", True),
18+
("24.9.9", True),
19+
("6.22.2", True),
20+
# ansible-lint >= 25.8.1 should not auto-enable
21+
("25.8.1", False),
22+
("25.8.2", False),
23+
("25.9.0", False),
24+
("26.0.0", False),
25+
("30.0.0", False),
26+
# No ansible-lint should not auto-enable
27+
(None, False),
28+
),
29+
)
30+
def test_should_auto_enable_plugin_loader(
31+
ansible_lint_version: str | None,
32+
expected: bool,
33+
monkeypatch: pytest.MonkeyPatch,
34+
) -> None:
35+
"""Test should_auto_enable_plugin_loader with different ansible-lint versions.
36+
37+
Args:
38+
ansible_lint_version: The ansible-lint version to mock, or None for no ansible-lint.
39+
expected: The expected result from should_auto_enable_plugin_loader().
40+
monkeypatch: Pytest fixture for mocking.
41+
"""
42+
43+
def mock_ansible_lint_version() -> Version | None:
44+
if ansible_lint_version is None:
45+
return None
46+
return Version(ansible_lint_version)
47+
48+
monkeypatch.setattr(
49+
"ansible_compat.compatibility.ansible_lint_version",
50+
mock_ansible_lint_version,
51+
)
52+
53+
result = should_auto_enable_plugin_loader()
54+
assert (
55+
result is expected
56+
), f"Expected {expected} for ansible-lint {ansible_lint_version}, got {result}"

0 commit comments

Comments
 (0)