antsibull-nox 0.2.0__py3-none-any.whl → 0.4.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.
Files changed (34) hide show
  1. antsibull_nox/__init__.py +7 -51
  2. antsibull_nox/_pydantic.py +98 -0
  3. antsibull_nox/ansible.py +15 -0
  4. antsibull_nox/cli.py +132 -0
  5. antsibull_nox/collection/__init__.py +2 -2
  6. antsibull_nox/collection/data.py +12 -0
  7. antsibull_nox/collection/install.py +194 -79
  8. antsibull_nox/collection/search.py +136 -34
  9. antsibull_nox/config.py +51 -2
  10. antsibull_nox/data/action-groups.py +2 -2
  11. antsibull_nox/data/antsibull-nox-lint-config.py +29 -0
  12. antsibull_nox/data/file-yamllint.py +138 -0
  13. antsibull_nox/data/license-check.py +5 -1
  14. antsibull_nox/data/plugin-yamllint.py +54 -24
  15. antsibull_nox/init.py +83 -0
  16. antsibull_nox/interpret_config.py +29 -8
  17. antsibull_nox/lint_config.py +113 -0
  18. antsibull_nox/sessions/__init__.py +70 -0
  19. antsibull_nox/sessions/ansible_lint.py +60 -0
  20. antsibull_nox/sessions/ansible_test.py +559 -0
  21. antsibull_nox/sessions/build_import_check.py +147 -0
  22. antsibull_nox/sessions/collections.py +145 -0
  23. antsibull_nox/sessions/docs_check.py +78 -0
  24. antsibull_nox/sessions/extra_checks.py +127 -0
  25. antsibull_nox/sessions/license_check.py +73 -0
  26. antsibull_nox/sessions/lint.py +694 -0
  27. antsibull_nox/sessions/utils.py +206 -0
  28. {antsibull_nox-0.2.0.dist-info → antsibull_nox-0.4.0.dist-info}/METADATA +2 -2
  29. antsibull_nox-0.4.0.dist-info/RECORD +41 -0
  30. antsibull_nox-0.4.0.dist-info/entry_points.txt +2 -0
  31. antsibull_nox/sessions.py +0 -1712
  32. antsibull_nox-0.2.0.dist-info/RECORD +0 -25
  33. {antsibull_nox-0.2.0.dist-info → antsibull_nox-0.4.0.dist-info}/WHEEL +0 -0
  34. {antsibull_nox-0.2.0.dist-info → antsibull_nox-0.4.0.dist-info}/licenses/LICENSES/GPL-3.0-or-later.txt +0 -0
@@ -0,0 +1,145 @@
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 os
14
+ import subprocess
15
+ import typing as t
16
+ from dataclasses import dataclass
17
+ from pathlib import Path
18
+
19
+ import nox
20
+
21
+ from ..ansible import AnsibleCoreVersion, parse_ansible_core_version
22
+ from ..collection import (
23
+ CollectionData,
24
+ setup_collections,
25
+ setup_current_tree,
26
+ )
27
+ from ..paths import (
28
+ create_temp_directory,
29
+ )
30
+
31
+
32
+ @dataclass
33
+ class CollectionSetup:
34
+ """
35
+ Information on the setup collections.
36
+ """
37
+
38
+ # The path of the ansible_collections directory where all dependent collections
39
+ # are installed. Is currently identical to current_root, but that might change
40
+ # or depend on options in the future.
41
+ collections_root: Path
42
+
43
+ # The directory in which ansible_collections can be found, as well as
44
+ # ansible_collections/<namespace>/<name> points to a copy of the current collection.
45
+ current_place: Path
46
+
47
+ # The path of the ansible_collections directory that contains the current collection.
48
+ # The following is always true:
49
+ # current_root == current_place / "ansible_collections"
50
+ current_root: Path
51
+
52
+ # Data on the current collection (as in the repository).
53
+ current_collection: CollectionData
54
+
55
+ # The path of the current collection inside the collection tree below current_root.
56
+ # The following is always true:
57
+ # current_path == current_root / current_collection.namespace / current_collection.name
58
+ current_path: Path
59
+
60
+ def prefix_current_paths(self, paths: list[str]) -> list[str]:
61
+ """
62
+ Prefix the list of given paths with ``current_path``.
63
+ """
64
+ result = []
65
+ for path in paths:
66
+ prefixed_path = (self.current_path / path).relative_to(self.current_place)
67
+ if prefixed_path.exists():
68
+ result.append(str(prefixed_path))
69
+ return result
70
+
71
+
72
+ def _run_subprocess(args: list[str]) -> tuple[bytes, bytes]:
73
+ p = subprocess.run(args, check=True, capture_output=True)
74
+ return p.stdout, p.stderr
75
+
76
+
77
+ def prepare_collections(
78
+ session: nox.Session,
79
+ *,
80
+ ansible_core_version: AnsibleCoreVersion | str | None = None,
81
+ install_in_site_packages: bool,
82
+ extra_deps_files: list[str | os.PathLike] | None = None,
83
+ extra_collections: list[str] | None = None,
84
+ install_out_of_tree: bool = False, # can not be used with install_in_site_packages=True
85
+ ) -> CollectionSetup | None:
86
+ """
87
+ Install collections in site-packages.
88
+ """
89
+ parsed_ansible_core_version = (
90
+ parse_ansible_core_version(ansible_core_version)
91
+ if ansible_core_version is not None
92
+ else "devel"
93
+ )
94
+ if install_out_of_tree and install_in_site_packages:
95
+ raise ValueError(
96
+ "install_out_of_tree=True cannot be combined with install_in_site_packages=True"
97
+ )
98
+ if isinstance(session.virtualenv, nox.virtualenv.PassthroughEnv):
99
+ session.warn("No venv. Skip preparing collections...")
100
+ return None
101
+ if install_in_site_packages:
102
+ purelib = (
103
+ session.run(
104
+ "python",
105
+ "-c",
106
+ "import sysconfig; print(sysconfig.get_path('purelib'))",
107
+ silent=True,
108
+ )
109
+ or ""
110
+ ).strip()
111
+ if not purelib:
112
+ session.warn(
113
+ "Cannot find site-packages (probably due to install-only run)."
114
+ " Skip preparing collections..."
115
+ )
116
+ return None
117
+ place = Path(purelib)
118
+ elif install_out_of_tree:
119
+ place = create_temp_directory(f"antsibull-nox-{session.name}-collection-root-")
120
+ else:
121
+ place = Path(session.virtualenv.location) / "collection-root"
122
+ place.mkdir(exist_ok=True)
123
+ setup = setup_collections(
124
+ place,
125
+ _run_subprocess,
126
+ ansible_core_version=parsed_ansible_core_version,
127
+ extra_deps_files=extra_deps_files,
128
+ extra_collections=extra_collections,
129
+ with_current=False,
130
+ global_cache_dir=session.cache_dir,
131
+ )
132
+ current_setup = setup_current_tree(place, setup.current_collection)
133
+ return CollectionSetup(
134
+ collections_root=setup.root,
135
+ current_place=place,
136
+ current_root=current_setup.root,
137
+ current_collection=setup.current_collection,
138
+ current_path=t.cast(Path, current_setup.current_path),
139
+ )
140
+
141
+
142
+ __all__ = [
143
+ "CollectionSetup",
144
+ "prepare_collections",
145
+ ]
@@ -0,0 +1,78 @@
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 docs check session.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import typing as t
14
+
15
+ import nox
16
+
17
+ from .collections import (
18
+ CollectionSetup,
19
+ prepare_collections,
20
+ )
21
+ from .utils import install
22
+
23
+
24
+ def add_docs_check(
25
+ *,
26
+ make_docs_check_default: bool = True,
27
+ antsibull_docs_package: str = "antsibull-docs",
28
+ ansible_core_package: str = "ansible-core",
29
+ validate_collection_refs: t.Literal["self", "dependent", "all"] | None = None,
30
+ extra_collections: list[str] | None = None,
31
+ ) -> None:
32
+ """
33
+ Add docs-check session for linting.
34
+ """
35
+
36
+ def compose_dependencies() -> list[str]:
37
+ deps = [antsibull_docs_package, ansible_core_package]
38
+ return deps
39
+
40
+ def execute_antsibull_docs(
41
+ session: nox.Session, prepared_collections: CollectionSetup
42
+ ) -> None:
43
+ with session.chdir(prepared_collections.current_path):
44
+ collections_path = f"{prepared_collections.current_place}"
45
+ command = [
46
+ "antsibull-docs",
47
+ "lint-collection-docs",
48
+ "--plugin-docs",
49
+ "--skip-rstcheck",
50
+ ".",
51
+ ]
52
+ if validate_collection_refs:
53
+ command.extend(["--validate-collection-refs", validate_collection_refs])
54
+ session.run(*command, env={"ANSIBLE_COLLECTIONS_PATH": collections_path})
55
+
56
+ def docs_check(session: nox.Session) -> None:
57
+ install(session, *compose_dependencies())
58
+ prepared_collections = prepare_collections(
59
+ session,
60
+ install_in_site_packages=False,
61
+ extra_collections=extra_collections,
62
+ install_out_of_tree=True,
63
+ )
64
+ if not prepared_collections:
65
+ session.warn("Skipping antsibull-docs...")
66
+ if prepared_collections:
67
+ execute_antsibull_docs(session, prepared_collections)
68
+
69
+ docs_check.__doc__ = "Run 'antsibull-docs lint-collection-docs'"
70
+ nox.session(
71
+ name="docs-check",
72
+ default=make_docs_check_default,
73
+ )(docs_check)
74
+
75
+
76
+ __all__ = [
77
+ "add_docs_check",
78
+ ]
@@ -0,0 +1,127 @@
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 extra checks session.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from dataclasses import asdict, dataclass
14
+
15
+ import nox
16
+
17
+ from .utils import (
18
+ compose_description,
19
+ run_bare_script,
20
+ )
21
+
22
+
23
+ @dataclass
24
+ class ActionGroup:
25
+ """
26
+ Defines an action group.
27
+ """
28
+
29
+ # Name of the action group.
30
+ name: str
31
+ # Regex pattern to match modules that could belong to this action group.
32
+ pattern: str
33
+ # Doc fragment that members of the action group must have, but no other module
34
+ # must have
35
+ doc_fragment: str
36
+ # Exclusion list of modules that match the regex, but should not be part of the
37
+ # action group. All other modules matching the regex are assumed to be part of
38
+ # the action group.
39
+ exclusions: list[str] | None = None
40
+
41
+
42
+ def add_extra_checks(
43
+ *,
44
+ make_extra_checks_default: bool = True,
45
+ # no-unwanted-files:
46
+ run_no_unwanted_files: bool = True,
47
+ no_unwanted_files_module_extensions: (
48
+ list[str] | None
49
+ ) = None, # default: .cs, .ps1, .psm1, .py
50
+ no_unwanted_files_other_extensions: list[str] | None = None, # default: .py, .pyi
51
+ no_unwanted_files_yaml_extensions: list[str] | None = None, # default: .yml, .yaml
52
+ no_unwanted_files_skip_paths: list[str] | None = None, # default: []
53
+ no_unwanted_files_skip_directories: list[str] | None = None, # default: []
54
+ no_unwanted_files_yaml_directories: (
55
+ list[str] | None
56
+ ) = None, # default: plugins/test/, plugins/filter/
57
+ no_unwanted_files_allow_symlinks: bool = False,
58
+ # action-groups:
59
+ run_action_groups: bool = False,
60
+ action_groups_config: list[ActionGroup] | None = None,
61
+ ) -> None:
62
+ """
63
+ Add extra-checks session for extra checks.
64
+ """
65
+
66
+ def execute_no_unwanted_files(session: nox.Session) -> None:
67
+ run_bare_script(
68
+ session,
69
+ "no-unwanted-files",
70
+ extra_data={
71
+ "module_extensions": no_unwanted_files_module_extensions
72
+ or [".cs", ".ps1", ".psm1", ".py"],
73
+ "other_extensions": no_unwanted_files_other_extensions
74
+ or [".py", ".pyi"],
75
+ "yaml_extensions": no_unwanted_files_yaml_extensions
76
+ or [".yml", ".yaml"],
77
+ "skip_paths": no_unwanted_files_skip_paths or [],
78
+ "skip_directories": no_unwanted_files_skip_directories or [],
79
+ "yaml_directories": no_unwanted_files_yaml_directories
80
+ or ["plugins/test/", "plugins/filter/"],
81
+ "allow_symlinks": no_unwanted_files_allow_symlinks,
82
+ },
83
+ )
84
+
85
+ def execute_action_groups(session: nox.Session) -> None:
86
+ if action_groups_config is None:
87
+ session.warn("Skipping action-groups since config is not provided...")
88
+ return
89
+ run_bare_script(
90
+ session,
91
+ "action-groups",
92
+ extra_data={
93
+ "config": [asdict(cfg) for cfg in action_groups_config],
94
+ },
95
+ )
96
+
97
+ def extra_checks(session: nox.Session) -> None:
98
+ if run_no_unwanted_files:
99
+ execute_no_unwanted_files(session)
100
+ if run_action_groups:
101
+ execute_action_groups(session)
102
+
103
+ extra_checks.__doc__ = compose_description(
104
+ prefix={
105
+ "one": "Run extra checker:",
106
+ "other": "Run extra checkers:",
107
+ },
108
+ programs={
109
+ "no-unwanted-files": (
110
+ "checks for unwanted files in plugins/"
111
+ if run_no_unwanted_files
112
+ else False
113
+ ),
114
+ "action-groups": "validate action groups" if run_action_groups else False,
115
+ },
116
+ )
117
+ nox.session(
118
+ name="extra-checks",
119
+ python=False,
120
+ default=make_extra_checks_default,
121
+ )(extra_checks)
122
+
123
+
124
+ __all__ = [
125
+ "ActionGroup",
126
+ "add_extra_checks",
127
+ ]
@@ -0,0 +1,73 @@
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 license check session.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import nox
14
+
15
+ from .utils import (
16
+ compose_description,
17
+ install,
18
+ run_bare_script,
19
+ )
20
+
21
+
22
+ def add_license_check(
23
+ *,
24
+ make_license_check_default: bool = True,
25
+ run_reuse: bool = True,
26
+ reuse_package: str = "reuse",
27
+ run_license_check: bool = True,
28
+ license_check_extra_ignore_paths: list[str] | None = None,
29
+ ) -> None:
30
+ """
31
+ Add license-check session for license checks.
32
+ """
33
+
34
+ def compose_dependencies() -> list[str]:
35
+ deps = []
36
+ if run_reuse:
37
+ deps.append(reuse_package)
38
+ return deps
39
+
40
+ def license_check(session: nox.Session) -> None:
41
+ install(session, *compose_dependencies())
42
+ if run_reuse:
43
+ session.run("reuse", "lint")
44
+ if run_license_check:
45
+ run_bare_script(
46
+ session,
47
+ "license-check",
48
+ extra_data={
49
+ "extra_ignore_paths": license_check_extra_ignore_paths or [],
50
+ },
51
+ )
52
+
53
+ license_check.__doc__ = compose_description(
54
+ prefix={
55
+ "one": "Run license checker:",
56
+ "other": "Run license checkers:",
57
+ },
58
+ programs={
59
+ "reuse": run_reuse,
60
+ "license-check": (
61
+ "ensure GPLv3+ for plugins" if run_license_check else False
62
+ ),
63
+ },
64
+ )
65
+ nox.session(
66
+ name="license-check",
67
+ default=make_license_check_default,
68
+ )(license_check)
69
+
70
+
71
+ __all__ = [
72
+ "add_license_check",
73
+ ]