1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
"""PyTest fixtures for testing the project."""
from __future__ import annotations
import os
import shutil
import subprocess
from contextlib import contextmanager
from pathlib import Path
from typing import TYPE_CHECKING, Iterator
import pytest
# pylint: disable=wildcard-import,unused-wildcard-import
from ansiblelint.testing.fixtures import * # noqa: F403
from ansiblelint.yaml_utils import FormattedYAML
if TYPE_CHECKING:
from typing import List # pylint: disable=ungrouped-imports
from _pytest import nodes
from _pytest.config import Config
from _pytest.config.argparsing import Parser
@contextmanager
def cwd(path: str) -> Iterator[None]:
"""Context manager for chdir."""
old_pwd = os.getcwd()
os.chdir(path)
try:
yield
finally:
os.chdir(old_pwd)
def pytest_addoption(parser: Parser) -> None:
"""Add --regenerate-formatting-fixtures option to pytest."""
parser.addoption(
"--regenerate-formatting-fixtures",
action="store_true",
default=False,
help="Regenerate formatting fixtures with prettier and internal formatter",
)
def pytest_collection_modifyitems(items: list[nodes.Item], config: Config) -> None:
"""Skip tests based on --regenerate-formatting-fixtures option."""
do_regenerate = config.getoption("--regenerate-formatting-fixtures")
skip_other = pytest.mark.skip(
reason="not a formatting_fixture test and "
"--regenerate-formatting-fixtures was specified"
)
skip_formatting_fixture = pytest.mark.skip(
reason="specify --regenerate-formatting-fixtures to "
"only run formatting_fixtures test"
)
for item in items:
if do_regenerate and "formatting_fixtures" not in item.keywords:
item.add_marker(skip_other)
elif not do_regenerate and "formatting_fixtures" in item.keywords:
item.add_marker(skip_formatting_fixture)
def pytest_configure(config: Config) -> None:
"""Register custom markers."""
if config.getoption("--regenerate-formatting-fixtures"):
regenerate_formatting_fixtures()
def regenerate_formatting_fixtures() -> None:
"""Re-generate formatting fixtures with prettier and internal formatter.
Pass ``--regenerate-formatting-fixtures`` to run this and skip all other tests.
This is a "test" because once fixtures are regenerated,
we run prettier again to make sure it does not change files formatted
with our internal formatting code.
"""
subprocess.check_call(["which", "prettier"])
yaml = FormattedYAML()
fixtures_dir = Path("test/fixtures/")
fixtures_dir_before = fixtures_dir / "formatting-before"
fixtures_dir_prettier = fixtures_dir / "formatting-prettier"
fixtures_dir_after = fixtures_dir / "formatting-after"
fixtures_dir_prettier.mkdir(exist_ok=True)
fixtures_dir_after.mkdir(exist_ok=True)
# Copying before fixtures...
for fixture in fixtures_dir_before.glob("fmt-[0-9].yml"):
shutil.copy(str(fixture), str(fixtures_dir_prettier / fixture.name))
shutil.copy(str(fixture), str(fixtures_dir_after / fixture.name))
# Writing fixtures with prettier...
subprocess.check_call(["prettier", "-w", str(fixtures_dir_prettier)])
# NB: pre-commit end-of-file-fixer can also modify files.
# Writing fixtures with ansiblelint.yaml_utils.FormattedYAML()
for fixture in fixtures_dir_after.glob("fmt-[0-9].yml"):
data = yaml.loads(fixture.read_text())
output = yaml.dumps(data)
fixture.write_text(output)
# Make sure prettier won't make changes in {fixtures_dir_after}
subprocess.check_call(["prettier", "-c", str(fixtures_dir_after)])
|