Skip to content

Commit

Permalink
Allow running with incompatible yamllint config
Browse files Browse the repository at this point in the history
Fixes: #4152
  • Loading branch information
ssbarnea committed May 13, 2024
1 parent 6fb75a4 commit ef8a647
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 16 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ repos:
- pytest-mock
- pytest>=7.2.2
- rich>=13.2.0
- ruamel-yaml-clib>=0.2.7
- ruamel-yaml>=0.18.2
- ruamel-yaml-clib>=0.2.8
- ruamel-yaml>=0.18.6
- subprocess-tee
- types-PyYAML
- types-jsonschema>=4.20.0.0
Expand Down
8 changes: 8 additions & 0 deletions src/ansiblelint/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,15 @@ def main(argv: list[str] | None = None) -> int:
match.ignored = True
_logger.debug("Ignored: %s", match)

if app.yamllint_config.incompatible:
logging.log(
level=logging.ERROR if options.write_list else logging.WARNING,
msg=app.yamllint_config.incompatible,
)

if options.write_list:
if app.yamllint_config.incompatible:
sys.exit(RC.INVALID_CONFIG)
fix(runtime_options=options, result=result, rules=rules)

app.render_matches(result.matches)
Expand Down
6 changes: 6 additions & 0 deletions src/ansiblelint/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ def __init__(self, options: Options):
verbosity=options.verbosity,
)

# if "ansiblelint.yaml_utils" not in sys.modules:
# pylint: disable=import-outside-toplevel
from ansiblelint.yaml_utils import load_yamllint_config # noqa: 811,I001

self.yamllint_config = load_yamllint_config()

def render_matches(self, matches: list[MatchError]) -> None:
"""Display given matches (if they are not fixed)."""
matches = [match for match in matches if not match.fixed]
Expand Down
27 changes: 19 additions & 8 deletions src/ansiblelint/yaml_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import logging
import os
import re
import sys
from collections.abc import Callable, Iterator, Sequence
from io import StringIO
from pathlib import Path
Expand All @@ -31,7 +30,6 @@
ANNOTATION_KEYS,
NESTED_TASK_KEYS,
PLAYBOOK_TASK_KEYWORDS,
RC,
)
from ansiblelint.utils import Task

Expand All @@ -48,6 +46,19 @@
_logger = logging.getLogger(__name__)


class CustomYamlLintConfig(YamlLintConfig): # type: ignore[misc]
"""Extension of YamlLintConfig."""

def __init__(
self,
content: str | None = None,
file: str | Path | None = None,
) -> None:
"""Initialize config."""
super().__init__(content, file)
self.incompatible = ""


def deannotate(data: Any) -> Any:
"""Remove our annotations like __file__ and __line__ and return a JSON serializable object."""
if isinstance(data, dict):
Expand All @@ -63,9 +74,10 @@ def deannotate(data: Any) -> Any:
return data


def load_yamllint_config() -> YamlLintConfig:
def load_yamllint_config() -> CustomYamlLintConfig:
"""Load our default yamllint config and any customized override file."""
config = YamlLintConfig(file=Path(__file__).parent / "data" / ".yamllint")
config = CustomYamlLintConfig(file=Path(__file__).parent / "data" / ".yamllint")
config.incompatible = ""
# if we detect local yamllint config we use it but raise a warning
# as this is likely to get out of sync with our internal config.
for path in [
Expand All @@ -82,7 +94,7 @@ def load_yamllint_config() -> YamlLintConfig:
"internal yamllint config.",
file,
)
custom_config = YamlLintConfig(file=str(file))
custom_config = CustomYamlLintConfig(file=str(file))
custom_config.extend(config)
config = custom_config
break
Expand Down Expand Up @@ -138,9 +150,8 @@ def load_yamllint_config() -> YamlLintConfig:
errors.append(msg)
if errors:
nl = "\n"
msg = f"Found incompatible custom yamllint configuration ({file}), please either remove the file or edit it to comply with:{nl} - {nl + ' - '.join(errors)}.{nl}{nl}Read https://ansible.readthedocs.io/projects/lint/rules/yaml/ for more details regarding why we have these requirements."
logging.fatal(msg)
sys.exit(RC.INVALID_CONFIG)
msg = f"Found incompatible custom yamllint configuration ({file}), please either remove the file or edit it to comply with:{nl} - {(nl + ' - ').join(errors)}.{nl}{nl}Read https://ansible.readthedocs.io/projects/lint/rules/yaml/ for more details regarding why we have these requirements. Fix mode will not be available."
config.incompatible = msg

_logger.debug("Effective yamllint rules used: %s", config.rules)
return config
Expand Down
9 changes: 3 additions & 6 deletions test/test_yaml_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from yamllint.linter import run as run_yamllint

import ansiblelint.yaml_utils
from ansiblelint.constants import RC
from ansiblelint.file_utils import Lintable, cwd
from ansiblelint.utils import task_in_list

Expand Down Expand Up @@ -996,8 +995,6 @@ def test_deannotate(

def test_yamllint_incompatible_config() -> None:
"""Ensure we can detect incompatible yamllint settings."""
with (
cwd(Path("examples/yamllint/incompatible-config")),
pytest.raises(SystemExit, match=f"^{RC.INVALID_CONFIG}$"),
):
ansiblelint.yaml_utils.load_yamllint_config()
with (cwd(Path("examples/yamllint/incompatible-config")),):
config = ansiblelint.yaml_utils.load_yamllint_config()
assert config.incompatible

0 comments on commit ef8a647

Please sign in to comment.