antsibull-nox 0.1.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.
Files changed (41) hide show
  1. antsibull_nox/__init__.py +17 -14
  2. antsibull_nox/_pydantic.py +98 -0
  3. antsibull_nox/ansible.py +260 -0
  4. antsibull_nox/cli.py +132 -0
  5. antsibull_nox/collection/__init__.py +56 -0
  6. antsibull_nox/collection/data.py +106 -0
  7. antsibull_nox/collection/extract.py +23 -0
  8. antsibull_nox/collection/install.py +523 -0
  9. antsibull_nox/collection/search.py +460 -0
  10. antsibull_nox/config.py +378 -0
  11. antsibull_nox/data/action-groups.py +3 -3
  12. antsibull_nox/data/antsibull-nox-lint-config.py +29 -0
  13. antsibull_nox/data/antsibull_nox_data_util.py +91 -0
  14. antsibull_nox/data/license-check.py +6 -2
  15. antsibull_nox/data/no-unwanted-files.py +5 -1
  16. antsibull_nox/data/plugin-yamllint.py +247 -0
  17. antsibull_nox/data_util.py +0 -77
  18. antsibull_nox/init.py +83 -0
  19. antsibull_nox/interpret_config.py +244 -0
  20. antsibull_nox/lint_config.py +113 -0
  21. antsibull_nox/paths.py +19 -0
  22. antsibull_nox/python.py +81 -0
  23. antsibull_nox/sessions/__init__.py +70 -0
  24. antsibull_nox/sessions/ansible_lint.py +58 -0
  25. antsibull_nox/sessions/ansible_test.py +568 -0
  26. antsibull_nox/sessions/build_import_check.py +147 -0
  27. antsibull_nox/sessions/collections.py +137 -0
  28. antsibull_nox/sessions/docs_check.py +78 -0
  29. antsibull_nox/sessions/extra_checks.py +127 -0
  30. antsibull_nox/sessions/license_check.py +73 -0
  31. antsibull_nox/sessions/lint.py +627 -0
  32. antsibull_nox/sessions/utils.py +206 -0
  33. antsibull_nox/utils.py +85 -0
  34. {antsibull_nox-0.1.0.dist-info → antsibull_nox-0.3.0.dist-info}/METADATA +4 -2
  35. antsibull_nox-0.3.0.dist-info/RECORD +40 -0
  36. antsibull_nox-0.3.0.dist-info/entry_points.txt +2 -0
  37. antsibull_nox/collection.py +0 -545
  38. antsibull_nox/sessions.py +0 -840
  39. antsibull_nox-0.1.0.dist-info/RECORD +0 -14
  40. {antsibull_nox-0.1.0.dist-info → antsibull_nox-0.3.0.dist-info}/WHEEL +0 -0
  41. {antsibull_nox-0.1.0.dist-info → antsibull_nox-0.3.0.dist-info}/licenses/LICENSES/GPL-3.0-or-later.txt +0 -0
@@ -0,0 +1,206 @@
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
+ Utils for creating nox sessions.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import logging
14
+ import os
15
+ import sys
16
+ import typing as t
17
+ from contextlib import contextmanager
18
+ from pathlib import Path
19
+
20
+ import nox
21
+ from nox.logger import OUTPUT as nox_OUTPUT
22
+
23
+ from ..data_util import prepare_data_script
24
+ from ..paths import (
25
+ find_data_directory,
26
+ list_all_files,
27
+ )
28
+
29
+ # https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables
30
+ # https://docs.gitlab.com/ci/variables/predefined_variables/#predefined-variables
31
+ # https://docs.travis-ci.com/user/environment-variables/#default-environment-variables
32
+ IN_CI = os.environ.get("CI") == "true"
33
+ IN_GITHUB_ACTIONS = bool(os.environ.get("GITHUB_ACTION"))
34
+ ALLOW_EDITABLE = os.environ.get("ALLOW_EDITABLE", str(not IN_CI)).lower() in (
35
+ "1",
36
+ "true",
37
+ )
38
+
39
+ _SESSIONS: dict[str, list[dict[str, t.Any]]] = {}
40
+
41
+
42
+ def nox_has_verbosity() -> bool:
43
+ """
44
+ Determine whether nox is run with verbosity enabled.
45
+ """
46
+ logger = logging.getLogger()
47
+ return logger.level <= nox_OUTPUT
48
+
49
+
50
+ @contextmanager
51
+ def silence_run_verbosity() -> t.Iterator[None]:
52
+ """
53
+ When using session.run() with silent=True, nox will log the output
54
+ if -v is used. Using this context manager prevents printing the output.
55
+ """
56
+ logger = logging.getLogger()
57
+ original_level = logger.level
58
+ try:
59
+ logger.setLevel(max(nox_OUTPUT + 1, original_level))
60
+ yield
61
+ finally:
62
+ logger.setLevel(original_level)
63
+
64
+
65
+ @contextmanager
66
+ def ci_group(name: str) -> t.Iterator[tuple[str, bool]]:
67
+ """
68
+ Try to ensure that the output inside the context is printed in a collapsable group.
69
+
70
+ This is highly CI system dependent, and currently only works for GitHub Actions.
71
+ """
72
+ is_collapsing = False
73
+ if IN_GITHUB_ACTIONS:
74
+ print(f"::group::{name}")
75
+ sys.stdout.flush()
76
+ is_collapsing = True
77
+ yield (" " if is_collapsing else "", is_collapsing)
78
+ if IN_GITHUB_ACTIONS:
79
+ print("::endgroup::")
80
+ sys.stdout.flush()
81
+
82
+
83
+ def register(name: str, data: dict[str, t.Any]) -> None:
84
+ """
85
+ Register a session name for matrix generation with additional data.
86
+ """
87
+ if name not in _SESSIONS:
88
+ _SESSIONS[name] = []
89
+ _SESSIONS[name].append(data)
90
+
91
+
92
+ def get_registered_sessions() -> dict[str, list[dict[str, t.Any]]]:
93
+ """
94
+ Return all registered sessions.
95
+ """
96
+ return {
97
+ name: [session.copy() for session in sessions]
98
+ for name, sessions in _SESSIONS.items()
99
+ }
100
+
101
+
102
+ def install(session: nox.Session, *args: str, editable: bool = False, **kwargs):
103
+ """
104
+ Install Python packages.
105
+ """
106
+ if not args:
107
+ return
108
+ # nox --no-venv
109
+ if isinstance(session.virtualenv, nox.virtualenv.PassthroughEnv):
110
+ session.warn(f"No venv. Skipping installation of {args}")
111
+ return
112
+ # Don't install in editable mode in CI or if it's explicitly disabled.
113
+ # This ensures that the wheel contains all of the correct files.
114
+ if editable and ALLOW_EDITABLE:
115
+ args = ("-e", *args)
116
+ session.install(*args, "-U", **kwargs)
117
+
118
+
119
+ def run_bare_script(
120
+ session: nox.Session,
121
+ /,
122
+ name: str,
123
+ *,
124
+ use_session_python: bool = False,
125
+ files: list[Path] | None = None,
126
+ extra_data: dict[str, t.Any] | None = None,
127
+ ) -> None:
128
+ """
129
+ Run a bare script included in antsibull-nox's data directory.
130
+ """
131
+ if files is None:
132
+ files = list_all_files()
133
+ data = prepare_data_script(
134
+ session,
135
+ base_name=name,
136
+ paths=files,
137
+ extra_data=extra_data,
138
+ )
139
+ python = sys.executable
140
+ env = {}
141
+ if use_session_python:
142
+ python = "python"
143
+ env["PYTHONPATH"] = str(find_data_directory())
144
+ session.run(
145
+ python,
146
+ find_data_directory() / f"{name}.py",
147
+ "--data",
148
+ data,
149
+ external=True,
150
+ env=env,
151
+ )
152
+
153
+
154
+ def compose_description(
155
+ *,
156
+ prefix: str | dict[t.Literal["one", "other"], str] | None = None,
157
+ programs: dict[str, str | bool | None],
158
+ ) -> str:
159
+ """
160
+ Compose a description for a nox session from several configurable parts.
161
+ """
162
+ parts: list[str] = []
163
+
164
+ def add(text: str, *, comma: bool = False) -> None:
165
+ if parts:
166
+ if comma:
167
+ parts.append(", ")
168
+ else:
169
+ parts.append(" ")
170
+ parts.append(text)
171
+
172
+ active_programs = [
173
+ (program, value if isinstance(value, str) else None)
174
+ for program, value in programs.items()
175
+ if value not in (False, None)
176
+ ]
177
+
178
+ if prefix:
179
+ if isinstance(prefix, dict):
180
+ if len(active_programs) == 1 and "one" in prefix:
181
+ add(prefix["one"])
182
+ else:
183
+ add(prefix["other"])
184
+ else:
185
+ add(prefix)
186
+
187
+ for index, (program, value) in enumerate(active_programs):
188
+ if index + 1 == len(active_programs) and index > 0:
189
+ add("and", comma=index > 1)
190
+ add(program, comma=index > 0 and index + 1 < len(active_programs))
191
+ if value is not None:
192
+ add(f"({value})")
193
+
194
+ return "".join(parts)
195
+
196
+
197
+ __all__ = [
198
+ "ci_group",
199
+ "compose_description",
200
+ "get_registered_sessions",
201
+ "install",
202
+ "nox_has_verbosity",
203
+ "register",
204
+ "run_bare_script",
205
+ "silence_run_verbosity",
206
+ ]
antsibull_nox/utils.py ADDED
@@ -0,0 +1,85 @@
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
+ General utilities.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import typing as t
14
+ from dataclasses import dataclass
15
+
16
+
17
+ @dataclass(order=True, frozen=True)
18
+ class Version:
19
+ """
20
+ Models a two-part version (major and minor).
21
+ """
22
+
23
+ major: int
24
+ minor: int
25
+
26
+ @classmethod
27
+ def parse(cls, version_string: str) -> Version:
28
+ """
29
+ Given a version string, parses it into a Version object.
30
+ Other components than major and minor version are ignored.
31
+ """
32
+ try:
33
+ major, minor = [int(v) for v in version_string.split(".")[:2]]
34
+ except (AttributeError, ValueError) as exc:
35
+ raise ValueError(
36
+ f"Cannot parse {version_string!r} as version string."
37
+ ) from exc
38
+ return Version(major=major, minor=minor)
39
+
40
+ def __str__(self) -> str:
41
+ return f"{self.major}.{self.minor}"
42
+
43
+ def next_minor_version(self) -> Version:
44
+ """
45
+ Returns the next minor version.
46
+
47
+ The major version stays the same, and the minor version is increased by 1.
48
+ """
49
+ return Version(self.major, self.minor + 1)
50
+
51
+ def previous_minor_version(self) -> Version:
52
+ """
53
+ Returns the previous minor version.
54
+ Raises a ValueError if there is none.
55
+
56
+ The major version stays the same, and the minor version is decreased by 1.
57
+ """
58
+ if self.minor == 0:
59
+ raise ValueError("No previous minor version exists")
60
+ return Version(self.major, self.minor - 1)
61
+
62
+
63
+ def version_range(
64
+ start: Version, end: Version, *, inclusive: bool
65
+ ) -> t.Generator[Version]:
66
+ """
67
+ Enumerate all versions starting at ``start`` until ``end``.
68
+
69
+ Whether ``end`` is included in the range depends on ``inclusive``.
70
+ """
71
+ if start.major != end.major:
72
+ raise ValueError(
73
+ f"Cannot list all versions from {start} to {end}"
74
+ " since they have different major versions"
75
+ )
76
+ version = start
77
+ while (version <= end) if inclusive else (version < end):
78
+ yield version
79
+ version = Version(major=version.major, minor=version.minor + 1)
80
+
81
+
82
+ __all__ = [
83
+ "Version",
84
+ "version_range",
85
+ ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: antsibull-nox
3
- Version: 0.1.0
3
+ Version: 0.3.0
4
4
  Summary: Changelog tool for Ansible-core and Ansible collections
5
5
  Project-URL: Documentation, https://ansible.readthedocs.io/projects/antsibull-nox/
6
6
  Project-URL: Source code, https://github.com/ansible-community/antsibull-nox/
@@ -11,7 +11,7 @@ Author-email: Felix Fontein <felix@fontein.de>, Toshio Kuratomi <a.badger@gmail.
11
11
  Maintainer-email: Felix Fontein <felix@fontein.de>, Maxwell G <maxwell@gtmx.me>
12
12
  License-Expression: GPL-3.0-or-later
13
13
  License-File: LICENSES/GPL-3.0-or-later.txt
14
- Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Development Status :: 4 - Beta
15
15
  Classifier: Framework :: Ansible
16
16
  Classifier: Intended Audience :: Developers
17
17
  Classifier: Programming Language :: Python :: 3
@@ -25,8 +25,10 @@ Requires-Python: >=3.9.0
25
25
  Requires-Dist: antsibull-fileutils<2.0.0,>=1.2.0
26
26
  Requires-Dist: nox>=2025.2.9
27
27
  Requires-Dist: packaging
28
+ Requires-Dist: pydantic~=2.0
28
29
  Requires-Dist: pyyaml
29
30
  Requires-Dist: semantic-version
31
+ Requires-Dist: tomli; python_version < '3.11'
30
32
  Provides-Extra: codeqa
31
33
  Requires-Dist: antsibull-changelog; extra == 'codeqa'
32
34
  Requires-Dist: flake8>=3.8.0; extra == 'codeqa'
@@ -0,0 +1,40 @@
1
+ antsibull_nox/__init__.py,sha256=oivrdT1a_loZAmf254Apt3h5_-Gp1ZnJkOXa40tTEc8,845
2
+ antsibull_nox/_pydantic.py,sha256=VTIh-u0TpWvnY6Dhe4ba8nAmR2tYmz4PXNp2_8Sr9pw,3203
3
+ antsibull_nox/ansible.py,sha256=_PugP3a6JXijptFwuUki5nq_66VA8e9gVZUpA5HewVg,8891
4
+ antsibull_nox/cli.py,sha256=NKeRlWc_0taNRcZcdMv9LHZ5nCz8-DEJxBLPxJ9vFYQ,3358
5
+ antsibull_nox/config.py,sha256=bgvjfB005xS2vXXsGSZPIAs9vxKIg30bleYqm5EwdJM,10916
6
+ antsibull_nox/data_util.py,sha256=7FVoqESEc-_QdqrQ16K1AHRVHEglNbRCH_mNaYDJ7a4,953
7
+ antsibull_nox/init.py,sha256=eRltIrS3AcHqEHk2yNAqJXv7kR6m_ysvFxIHpowd-2M,2259
8
+ antsibull_nox/interpret_config.py,sha256=OjlHtLn22JAZBLycOndIjZVqzx2-bcbJahygJmBg6NQ,10367
9
+ antsibull_nox/lint_config.py,sha256=ZnsUbX6IdQK_IP9nvs8Kk6jb5lPdiREFSHAUuEGGceU,3848
10
+ antsibull_nox/paths.py,sha256=86HOynhCMTVop3ml_77JI06vM9nyK7PHMzLP_4M0V88,6317
11
+ antsibull_nox/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ antsibull_nox/python.py,sha256=0pyGqgwsuyc0BhzoXNZLTLbjaFA4kAYEHrFD6A1o1-o,2113
13
+ antsibull_nox/utils.py,sha256=lgBNuJ67Agl9YpFNWCjr6TBUcbC1LroZrJkv6S5VuxA,2437
14
+ antsibull_nox/collection/__init__.py,sha256=2k6uYdiPjAgJgmz5oviYpu2Sh5ZSKSJEJCR01iz-29A,1494
15
+ antsibull_nox/collection/data.py,sha256=sacVZF517x54B3G6F0hW8fTpEF7zyB8exSQJO9mvhLk,2609
16
+ antsibull_nox/collection/extract.py,sha256=qNVknQRtRrCt10aawuU1Z6NTs16CA1bUEX3WDGBw68g,684
17
+ antsibull_nox/collection/install.py,sha256=DbnXUBzQlzW6TzU_TAszuApix2F2n7w1AcUcPZ4Q4G4,17082
18
+ antsibull_nox/collection/search.py,sha256=peE8JQfHSkHS82NgZfARSF-k_mril_tpwj4QSkdJpOo,15539
19
+ antsibull_nox/data/action-groups.py,sha256=qLuh2YqIpc6i2jpWFzjtFhZhx6_SDbbvJe6VH7EXrqg,6934
20
+ antsibull_nox/data/antsibull-nox-lint-config.py,sha256=tXkKd9AqgfDs5w7S6OaBIt9HnT0KSbiQIU9tFxtYE2U,657
21
+ antsibull_nox/data/antsibull_nox_data_util.py,sha256=D4i_sKxjAeZuDV-z9Ibow0YYIqhXo2V_YC0LONLcEXM,2931
22
+ antsibull_nox/data/license-check.py,sha256=or3GyQC0WWYMxMqL-369krGsHaySH1vX-2fwpRyJGp0,5665
23
+ antsibull_nox/data/license-check.py.license,sha256=iPdFtdkeE3E2nCB-M5KHevbz4d5I-6ymOnKNTc954Dw,218
24
+ antsibull_nox/data/no-unwanted-files.py,sha256=_B3m-XWvWpdzGN-XAP8rLIS_5RMJGntFWL-Jy0WY9Mc,2959
25
+ antsibull_nox/data/plugin-yamllint.py,sha256=zobRajdVAemXbuAzyIjr485T-EzhbzW1JH--UwUswf0,7436
26
+ antsibull_nox/sessions/__init__.py,sha256=4wTTO1E6rdCz4pVMuGUeuXi_vqFaH4whAL9qcjfOqto,2022
27
+ antsibull_nox/sessions/ansible_lint.py,sha256=TzKqxbUHO2nmvJtKqh1hM9HDoCxDr8iNbbSzp8SNkN4,1589
28
+ antsibull_nox/sessions/ansible_test.py,sha256=hR6T-RH2epWAUUsmX3SIzDhdRa5jsVkaH_r_mbaoIAo,20624
29
+ antsibull_nox/sessions/build_import_check.py,sha256=kdr_Cqc0jb8XQQ-2QL-g_X7wgezE04oMVFCPr7a34iA,4719
30
+ antsibull_nox/sessions/collections.py,sha256=t_j1UNgJDvehj7PRQ-67DrmZmauh2uECL8kaRCnKoEY,4324
31
+ antsibull_nox/sessions/docs_check.py,sha256=mVYt278xy5AVwo5rCf6FLZlhqBiEYgJ3mmWsVBShKD0,2344
32
+ antsibull_nox/sessions/extra_checks.py,sha256=sBn0YFD8cM3OqeQ4UgYwD0NAcjKnYoy2zd8q-z4Xl2I,4110
33
+ antsibull_nox/sessions/license_check.py,sha256=t5ut4ZluhFfk-qE6kcU8VNdvIGvzND81N7WCsbA4jLc,1824
34
+ antsibull_nox/sessions/lint.py,sha256=2a2F-Q3VqCUCxEM4r9YFHZTGwe39VxbPJBQO6HX6hQ0,19298
35
+ antsibull_nox/sessions/utils.py,sha256=rrQdzmjdrLQula8t-BCTKbO-tAmzfOKHNn1pN2B1QVc,5632
36
+ antsibull_nox-0.3.0.dist-info/METADATA,sha256=wFsgoXsDAjCLOcSSoPZod69otcwmEnMpsKz5LUn7YUc,7670
37
+ antsibull_nox-0.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
38
+ antsibull_nox-0.3.0.dist-info/entry_points.txt,sha256=solWA9TCB37UlaGk8sHXxJg-k1HWckfKdncHDBsVSsI,57
39
+ antsibull_nox-0.3.0.dist-info/licenses/LICENSES/GPL-3.0-or-later.txt,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
40
+ antsibull_nox-0.3.0.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ antsibull-nox = antsibull_nox.cli:main