antsibull-nox 0.2.0__py3-none-any.whl → 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- antsibull_nox/__init__.py +7 -51
- antsibull_nox/_pydantic.py +98 -0
- antsibull_nox/cli.py +132 -0
- antsibull_nox/collection/__init__.py +2 -2
- antsibull_nox/collection/search.py +8 -4
- antsibull_nox/config.py +48 -2
- antsibull_nox/data/action-groups.py +2 -2
- antsibull_nox/data/antsibull-nox-lint-config.py +29 -0
- antsibull_nox/data/license-check.py +5 -1
- antsibull_nox/data/plugin-yamllint.py +3 -0
- antsibull_nox/init.py +83 -0
- antsibull_nox/interpret_config.py +17 -8
- antsibull_nox/lint_config.py +113 -0
- antsibull_nox/sessions/__init__.py +70 -0
- antsibull_nox/sessions/ansible_lint.py +58 -0
- antsibull_nox/sessions/ansible_test.py +568 -0
- antsibull_nox/sessions/build_import_check.py +147 -0
- antsibull_nox/sessions/collections.py +137 -0
- antsibull_nox/sessions/docs_check.py +78 -0
- antsibull_nox/sessions/extra_checks.py +127 -0
- antsibull_nox/sessions/license_check.py +73 -0
- antsibull_nox/sessions/lint.py +627 -0
- antsibull_nox/sessions/utils.py +206 -0
- {antsibull_nox-0.2.0.dist-info → antsibull_nox-0.3.0.dist-info}/METADATA +2 -2
- antsibull_nox-0.3.0.dist-info/RECORD +40 -0
- antsibull_nox-0.3.0.dist-info/entry_points.txt +2 -0
- antsibull_nox/sessions.py +0 -1712
- antsibull_nox-0.2.0.dist-info/RECORD +0 -25
- {antsibull_nox-0.2.0.dist-info → antsibull_nox-0.3.0.dist-info}/WHEEL +0 -0
- {antsibull_nox-0.2.0.dist-info → antsibull_nox-0.3.0.dist-info}/licenses/LICENSES/GPL-3.0-or-later.txt +0 -0
@@ -0,0 +1,113 @@
|
|
1
|
+
# Author: Felix Fontein <felix@fontein.de>
|
2
|
+
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or
|
3
|
+
# https://www.gnu.org/licenses/gpl-3.0.txt)
|
4
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
5
|
+
# SPDX-FileCopyrightText: 2025, Ansible Project
|
6
|
+
|
7
|
+
"""Lint antsibull-nox config."""
|
8
|
+
|
9
|
+
from __future__ import annotations
|
10
|
+
|
11
|
+
import ast
|
12
|
+
from pathlib import Path
|
13
|
+
|
14
|
+
from .config import lint_config_toml
|
15
|
+
|
16
|
+
NOXFILE_PY = "noxfile.py"
|
17
|
+
|
18
|
+
|
19
|
+
def _is_antsibull_nox_module(module_name: str) -> bool:
|
20
|
+
return module_name == "antsibull_nox" or module_name.startswith("antsibull_nox.")
|
21
|
+
|
22
|
+
|
23
|
+
class _Walker:
|
24
|
+
def __init__(self, path: Path) -> None:
|
25
|
+
self.path = path
|
26
|
+
self.imports: dict[str, str] = {}
|
27
|
+
self.has_config_load = False
|
28
|
+
|
29
|
+
@staticmethod
|
30
|
+
def _get_name(what: ast.expr) -> str | None:
|
31
|
+
if isinstance(what, ast.Name):
|
32
|
+
return what.id
|
33
|
+
if isinstance(what, ast.Attribute):
|
34
|
+
v = _Walker._get_name(what.value)
|
35
|
+
return None if v is None else f"{v}.{what.attr}"
|
36
|
+
return None
|
37
|
+
|
38
|
+
def _check_expression(self, expression: ast.expr) -> None:
|
39
|
+
if isinstance(expression, ast.Call):
|
40
|
+
func = _Walker._get_name(expression.func)
|
41
|
+
if func is not None:
|
42
|
+
func = self.imports.get(func, func)
|
43
|
+
if "." in func:
|
44
|
+
module, module_func = func.rsplit(".", 1)
|
45
|
+
if module in self.imports:
|
46
|
+
func = f"{self.imports[module]}.{module_func}"
|
47
|
+
if func == "antsibull_nox.load_antsibull_nox_toml":
|
48
|
+
self.has_config_load = True
|
49
|
+
|
50
|
+
def _walk(self, statements: list[ast.stmt]) -> None:
|
51
|
+
for statement in statements:
|
52
|
+
# Handle imports
|
53
|
+
if isinstance(statement, ast.Import):
|
54
|
+
for alias in statement.names:
|
55
|
+
if _is_antsibull_nox_module(alias.name):
|
56
|
+
self.imports[alias.asname or alias.name] = alias.name
|
57
|
+
if isinstance(statement, ast.ImportFrom):
|
58
|
+
if statement.level == 0 and _is_antsibull_nox_module(
|
59
|
+
statement.module or ""
|
60
|
+
):
|
61
|
+
for alias in statement.names:
|
62
|
+
self.imports[alias.asname or alias.name] = (
|
63
|
+
f"{statement.module}.{alias.name}"
|
64
|
+
)
|
65
|
+
# Handle try block
|
66
|
+
if isinstance(statement, ast.Try):
|
67
|
+
self._walk(statement.body)
|
68
|
+
# Handle expressions
|
69
|
+
if isinstance(statement, ast.Expr):
|
70
|
+
self._check_expression(statement.value)
|
71
|
+
|
72
|
+
def walk(self, module: ast.Module) -> list[str]:
|
73
|
+
"""
|
74
|
+
Walk the noxfile's module and return a list of errors.
|
75
|
+
"""
|
76
|
+
self._walk(module.body)
|
77
|
+
errors = []
|
78
|
+
if not self.imports:
|
79
|
+
errors.append(f"{self.path}: Found no antsibull_nox import")
|
80
|
+
if not self.has_config_load:
|
81
|
+
errors.append(
|
82
|
+
f"{self.path}: Found no call to antsibull_nox.load_antsibull_nox_toml()"
|
83
|
+
)
|
84
|
+
return errors
|
85
|
+
|
86
|
+
|
87
|
+
def lint_noxfile() -> list[str]:
|
88
|
+
"""
|
89
|
+
Do basic validation for noxfile.py. Return a list of errors.
|
90
|
+
"""
|
91
|
+
path = Path(NOXFILE_PY)
|
92
|
+
try:
|
93
|
+
with open(path, "rt", encoding="utf-8") as f:
|
94
|
+
root = ast.parse(f.read(), filename=path)
|
95
|
+
except FileNotFoundError:
|
96
|
+
return [f"{path}: File does not exist"]
|
97
|
+
except Exception as exc: # pylint: disable=broad-exception-caught
|
98
|
+
return [f"{path}:Error while parsing Python code: {exc}"]
|
99
|
+
|
100
|
+
walker = _Walker(path)
|
101
|
+
return walker.walk(root)
|
102
|
+
|
103
|
+
|
104
|
+
def lint_config() -> list[str]:
|
105
|
+
"""
|
106
|
+
Lint antsibull-nox config file.
|
107
|
+
"""
|
108
|
+
errors = lint_config_toml()
|
109
|
+
errors.extend(lint_noxfile())
|
110
|
+
return sorted(errors)
|
111
|
+
|
112
|
+
|
113
|
+
__all__ = ["lint_config"]
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# Author: Felix Fontein <felix@fontein.de>
|
2
|
+
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or
|
3
|
+
# https://www.gnu.org/licenses/gpl-3.0.txt)
|
4
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
5
|
+
# SPDX-FileCopyrightText: 2025, Ansible Project
|
6
|
+
|
7
|
+
"""
|
8
|
+
Create nox sessions.
|
9
|
+
"""
|
10
|
+
|
11
|
+
from __future__ import annotations
|
12
|
+
|
13
|
+
import json
|
14
|
+
import os
|
15
|
+
import sys
|
16
|
+
|
17
|
+
import nox
|
18
|
+
|
19
|
+
from .collections import ( # Re-export for usage in noxfiles
|
20
|
+
CollectionSetup,
|
21
|
+
prepare_collections,
|
22
|
+
)
|
23
|
+
from .utils import get_registered_sessions
|
24
|
+
|
25
|
+
|
26
|
+
def add_matrix_generator() -> None:
|
27
|
+
"""
|
28
|
+
Add a session that generates matrixes for CI systems.
|
29
|
+
"""
|
30
|
+
|
31
|
+
def matrix_generator(
|
32
|
+
session: nox.Session, # pylint: disable=unused-argument
|
33
|
+
) -> None:
|
34
|
+
registered_sessions = get_registered_sessions()
|
35
|
+
|
36
|
+
json_output = os.environ.get("ANTSIBULL_NOX_MATRIX_JSON")
|
37
|
+
if json_output:
|
38
|
+
print(f"Writing JSON output to {json_output}...")
|
39
|
+
with open(json_output, "wt", encoding="utf-8") as f:
|
40
|
+
f.write(json.dumps(registered_sessions))
|
41
|
+
|
42
|
+
github_output = os.environ.get("GITHUB_OUTPUT")
|
43
|
+
if github_output:
|
44
|
+
print(f"Writing GitHub output to {github_output}...")
|
45
|
+
with open(github_output, "at", encoding="utf-8") as f:
|
46
|
+
for name, sessions in registered_sessions.items():
|
47
|
+
f.write(f"{name}={json.dumps(sessions)}\n")
|
48
|
+
|
49
|
+
for name, sessions in sorted(registered_sessions.items()):
|
50
|
+
print(f"{name} ({len(sessions)}):")
|
51
|
+
for session_data in sessions:
|
52
|
+
data = session_data.copy()
|
53
|
+
session_name = data.pop("name")
|
54
|
+
print(f" {session_name}: {data}")
|
55
|
+
|
56
|
+
sys.stdout.flush()
|
57
|
+
|
58
|
+
matrix_generator.__doc__ = "Generate matrix for CI systems."
|
59
|
+
nox.session(
|
60
|
+
name="matrix-generator",
|
61
|
+
python=False,
|
62
|
+
default=False,
|
63
|
+
)(matrix_generator)
|
64
|
+
|
65
|
+
|
66
|
+
__all__ = [
|
67
|
+
"CollectionSetup",
|
68
|
+
"add_matrix_generator",
|
69
|
+
"prepare_collections",
|
70
|
+
]
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Author: Felix Fontein <felix@fontein.de>
|
2
|
+
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or
|
3
|
+
# https://www.gnu.org/licenses/gpl-3.0.txt)
|
4
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
5
|
+
# SPDX-FileCopyrightText: 2025, Ansible Project
|
6
|
+
|
7
|
+
"""
|
8
|
+
Create nox ansible-lint session.
|
9
|
+
"""
|
10
|
+
|
11
|
+
from __future__ import annotations
|
12
|
+
|
13
|
+
import nox
|
14
|
+
|
15
|
+
from .collections import prepare_collections
|
16
|
+
from .utils import install
|
17
|
+
|
18
|
+
|
19
|
+
def add_ansible_lint(
|
20
|
+
*,
|
21
|
+
make_ansible_lint_default: bool = True,
|
22
|
+
ansible_lint_package: str = "ansible-lint",
|
23
|
+
strict: bool = False,
|
24
|
+
) -> None:
|
25
|
+
"""
|
26
|
+
Add a session that runs ansible-lint.
|
27
|
+
"""
|
28
|
+
|
29
|
+
def compose_dependencies() -> list[str]:
|
30
|
+
return [ansible_lint_package]
|
31
|
+
|
32
|
+
def ansible_lint(session: nox.Session) -> None:
|
33
|
+
install(session, *compose_dependencies())
|
34
|
+
prepared_collections = prepare_collections(
|
35
|
+
session,
|
36
|
+
install_in_site_packages=False,
|
37
|
+
install_out_of_tree=True,
|
38
|
+
extra_deps_files=["tests/integration/requirements.yml"],
|
39
|
+
)
|
40
|
+
if not prepared_collections:
|
41
|
+
session.warn("Skipping ansible-lint...")
|
42
|
+
return
|
43
|
+
env = {"ANSIBLE_COLLECTIONS_PATH": f"{prepared_collections.current_place}"}
|
44
|
+
command = ["ansible-lint", "--offline"]
|
45
|
+
if strict:
|
46
|
+
command.append("--strict")
|
47
|
+
session.run(*command, env=env)
|
48
|
+
|
49
|
+
ansible_lint.__doc__ = "Run ansible-lint."
|
50
|
+
nox.session(
|
51
|
+
name="ansible-lint",
|
52
|
+
default=make_ansible_lint_default,
|
53
|
+
)(ansible_lint)
|
54
|
+
|
55
|
+
|
56
|
+
__all__ = [
|
57
|
+
"add_ansible_lint",
|
58
|
+
]
|