antsibull-nox 0.1.0__py3-none-any.whl → 0.2.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 +48 -1
- antsibull_nox/ansible.py +260 -0
- antsibull_nox/collection/__init__.py +56 -0
- antsibull_nox/collection/data.py +106 -0
- antsibull_nox/collection/extract.py +23 -0
- antsibull_nox/collection/install.py +523 -0
- antsibull_nox/{collection.py → collection/search.py} +164 -253
- antsibull_nox/config.py +332 -0
- antsibull_nox/data/action-groups.py +1 -1
- antsibull_nox/data/antsibull_nox_data_util.py +91 -0
- antsibull_nox/data/license-check.py +1 -1
- antsibull_nox/data/no-unwanted-files.py +5 -1
- antsibull_nox/data/plugin-yamllint.py +244 -0
- antsibull_nox/data_util.py +0 -77
- antsibull_nox/interpret_config.py +235 -0
- antsibull_nox/paths.py +19 -0
- antsibull_nox/python.py +81 -0
- antsibull_nox/sessions.py +898 -26
- antsibull_nox/utils.py +85 -0
- {antsibull_nox-0.1.0.dist-info → antsibull_nox-0.2.0.dist-info}/METADATA +3 -1
- antsibull_nox-0.2.0.dist-info/RECORD +25 -0
- antsibull_nox-0.1.0.dist-info/RECORD +0 -14
- {antsibull_nox-0.1.0.dist-info → antsibull_nox-0.2.0.dist-info}/WHEEL +0 -0
- {antsibull_nox-0.1.0.dist-info → antsibull_nox-0.2.0.dist-info}/licenses/LICENSES/GPL-3.0-or-later.txt +0 -0
antsibull_nox/sessions.py
CHANGED
@@ -10,16 +10,24 @@ Create nox sessions.
|
|
10
10
|
|
11
11
|
from __future__ import annotations
|
12
12
|
|
13
|
+
import json
|
13
14
|
import os
|
14
15
|
import shlex
|
15
16
|
import subprocess
|
16
17
|
import sys
|
17
18
|
import typing as t
|
19
|
+
from contextlib import contextmanager
|
18
20
|
from dataclasses import asdict, dataclass
|
19
21
|
from pathlib import Path
|
20
22
|
|
21
23
|
import nox
|
22
24
|
|
25
|
+
from .ansible import (
|
26
|
+
AnsibleCoreVersion,
|
27
|
+
get_ansible_core_info,
|
28
|
+
get_ansible_core_package_name,
|
29
|
+
get_supported_core_versions,
|
30
|
+
)
|
23
31
|
from .collection import (
|
24
32
|
CollectionData,
|
25
33
|
force_collection_version,
|
@@ -30,17 +38,21 @@ from .collection import (
|
|
30
38
|
from .data_util import prepare_data_script
|
31
39
|
from .paths import (
|
32
40
|
copy_collection,
|
41
|
+
copy_directory_tree_into,
|
33
42
|
create_temp_directory,
|
34
43
|
filter_paths,
|
35
44
|
find_data_directory,
|
36
45
|
list_all_files,
|
37
46
|
remove_path,
|
38
47
|
)
|
48
|
+
from .python import get_installed_python_versions
|
49
|
+
from .utils import Version
|
39
50
|
|
40
51
|
# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables
|
41
52
|
# https://docs.gitlab.com/ci/variables/predefined_variables/#predefined-variables
|
42
53
|
# https://docs.travis-ci.com/user/environment-variables/#default-environment-variables
|
43
54
|
IN_CI = os.environ.get("CI") == "true"
|
55
|
+
IN_GITHUB_ACTIONS = bool(os.environ.get("GITHUB_ACTION"))
|
44
56
|
ALLOW_EDITABLE = os.environ.get("ALLOW_EDITABLE", str(not IN_CI)).lower() in (
|
45
57
|
"1",
|
46
58
|
"true",
|
@@ -60,6 +72,28 @@ MODULE_PATHS = [
|
|
60
72
|
"tests/unit/plugins/module_utils/",
|
61
73
|
]
|
62
74
|
|
75
|
+
_SESSIONS: dict[str, list[dict[str, t.Any]]] = {}
|
76
|
+
|
77
|
+
|
78
|
+
@contextmanager
|
79
|
+
def _ci_group(name: str) -> t.Iterator[None]:
|
80
|
+
"""
|
81
|
+
Try to ensure that the output inside the context is printed in a collapsable group.
|
82
|
+
|
83
|
+
This is highly CI system dependent, and currently only works for GitHub Actions.
|
84
|
+
"""
|
85
|
+
if IN_GITHUB_ACTIONS:
|
86
|
+
print(f"::group::{name}")
|
87
|
+
yield
|
88
|
+
if IN_GITHUB_ACTIONS:
|
89
|
+
print("::endgroup::")
|
90
|
+
|
91
|
+
|
92
|
+
def _register(name: str, data: dict[str, t.Any]) -> None:
|
93
|
+
if name not in _SESSIONS:
|
94
|
+
_SESSIONS[name] = []
|
95
|
+
_SESSIONS[name].append(data)
|
96
|
+
|
63
97
|
|
64
98
|
def install(session: nox.Session, *args: str, editable: bool = False, **kwargs):
|
65
99
|
"""
|
@@ -167,6 +201,7 @@ def prepare_collections(
|
|
167
201
|
extra_deps_files=extra_deps_files,
|
168
202
|
extra_collections=extra_collections,
|
169
203
|
with_current=False,
|
204
|
+
global_cache_dir=session.cache_dir,
|
170
205
|
)
|
171
206
|
current_setup = setup_current_tree(place, setup.current_collection)
|
172
207
|
return CollectionSetup(
|
@@ -179,26 +214,84 @@ def prepare_collections(
|
|
179
214
|
|
180
215
|
|
181
216
|
def _run_bare_script(
|
182
|
-
session: nox.Session,
|
217
|
+
session: nox.Session,
|
218
|
+
/,
|
219
|
+
name: str,
|
220
|
+
*,
|
221
|
+
use_session_python: bool = False,
|
222
|
+
files: list[Path] | None = None,
|
223
|
+
extra_data: dict[str, t.Any] | None = None,
|
183
224
|
) -> None:
|
184
|
-
files
|
225
|
+
if files is None:
|
226
|
+
files = list_all_files()
|
185
227
|
data = prepare_data_script(
|
186
228
|
session,
|
187
229
|
base_name=name,
|
188
230
|
paths=files,
|
189
231
|
extra_data=extra_data,
|
190
232
|
)
|
233
|
+
python = sys.executable
|
234
|
+
env = {}
|
235
|
+
if use_session_python:
|
236
|
+
python = "python"
|
237
|
+
env["PYTHONPATH"] = str(find_data_directory())
|
191
238
|
session.run(
|
192
|
-
|
239
|
+
python,
|
193
240
|
find_data_directory() / f"{name}.py",
|
194
241
|
"--data",
|
195
242
|
data,
|
196
243
|
external=True,
|
244
|
+
env=env,
|
197
245
|
)
|
198
246
|
|
199
247
|
|
248
|
+
def _compose_description(
|
249
|
+
*,
|
250
|
+
prefix: str | dict[t.Literal["one", "other"], str] | None = None,
|
251
|
+
programs: dict[str, str | bool | None],
|
252
|
+
) -> str:
|
253
|
+
parts: list[str] = []
|
254
|
+
|
255
|
+
def add(text: str, *, comma: bool = False) -> None:
|
256
|
+
if parts:
|
257
|
+
if comma:
|
258
|
+
parts.append(", ")
|
259
|
+
else:
|
260
|
+
parts.append(" ")
|
261
|
+
parts.append(text)
|
262
|
+
|
263
|
+
active_programs = [
|
264
|
+
(program, value if isinstance(value, str) else None)
|
265
|
+
for program, value in programs.items()
|
266
|
+
if value not in (False, None)
|
267
|
+
]
|
268
|
+
|
269
|
+
if prefix:
|
270
|
+
if isinstance(prefix, dict):
|
271
|
+
if len(active_programs) == 1 and "one" in prefix:
|
272
|
+
add(prefix["one"])
|
273
|
+
else:
|
274
|
+
add(prefix["other"])
|
275
|
+
else:
|
276
|
+
add(prefix)
|
277
|
+
|
278
|
+
for index, (program, value) in enumerate(active_programs):
|
279
|
+
if index + 1 == len(active_programs) and index > 0:
|
280
|
+
add("and", comma=index > 1)
|
281
|
+
add(program, comma=index > 0 and index + 1 < len(active_programs))
|
282
|
+
if value is not None:
|
283
|
+
add(f"({value})")
|
284
|
+
|
285
|
+
return "".join(parts)
|
286
|
+
|
287
|
+
|
200
288
|
def add_lint(
|
201
|
-
*,
|
289
|
+
*,
|
290
|
+
make_lint_default: bool,
|
291
|
+
has_formatters: bool,
|
292
|
+
has_codeqa: bool,
|
293
|
+
has_yamllint: bool,
|
294
|
+
has_typing: bool,
|
202
295
|
) -> None:
|
203
296
|
"""
|
204
297
|
Add nox meta session for linting.
|
@@ -212,11 +305,28 @@ def add_lint(
|
|
212
305
|
dependent_sessions.append("formatters")
|
213
306
|
if has_codeqa:
|
214
307
|
dependent_sessions.append("codeqa")
|
308
|
+
if has_yamllint:
|
309
|
+
dependent_sessions.append("yamllint")
|
215
310
|
if has_typing:
|
216
311
|
dependent_sessions.append("typing")
|
217
|
-
|
218
|
-
|
312
|
+
|
313
|
+
lint.__doc__ = _compose_description(
|
314
|
+
prefix={
|
315
|
+
"one": "Meta session for triggering the following session:",
|
316
|
+
"other": "Meta session for triggering the following sessions:",
|
317
|
+
},
|
318
|
+
programs={
|
319
|
+
"formatters": has_formatters,
|
320
|
+
"codeqa": has_codeqa,
|
321
|
+
"yamllint": has_yamllint,
|
322
|
+
"typing": has_typing,
|
323
|
+
},
|
219
324
|
)
|
325
|
+
nox.session(
|
326
|
+
name="lint",
|
327
|
+
default=make_lint_default,
|
328
|
+
requires=dependent_sessions,
|
329
|
+
)(lint)
|
220
330
|
|
221
331
|
|
222
332
|
def add_formatters(
|
@@ -299,7 +409,17 @@ def add_formatters(
|
|
299
409
|
if run_black or run_black_modules:
|
300
410
|
execute_black(session)
|
301
411
|
|
302
|
-
|
412
|
+
formatters.__doc__ = _compose_description(
|
413
|
+
prefix={
|
414
|
+
"one": "Run code formatter:",
|
415
|
+
"other": "Run code formatters:",
|
416
|
+
},
|
417
|
+
programs={
|
418
|
+
"isort": run_isort,
|
419
|
+
"black": run_black,
|
420
|
+
},
|
421
|
+
)
|
422
|
+
nox.session(name="formatters", default=False)(formatters)
|
303
423
|
|
304
424
|
|
305
425
|
def add_codeqa( # noqa: C901
|
@@ -412,7 +532,120 @@ def add_codeqa( # noqa: C901
|
|
412
532
|
if run_pylint and prepared_collections:
|
413
533
|
execute_pylint(session, prepared_collections)
|
414
534
|
|
415
|
-
|
535
|
+
codeqa.__doc__ = _compose_description(
|
536
|
+
prefix={
|
537
|
+
"other": "Run code QA:",
|
538
|
+
},
|
539
|
+
programs={
|
540
|
+
"flake8": run_flake8,
|
541
|
+
"pylint": run_pylint,
|
542
|
+
},
|
543
|
+
)
|
544
|
+
nox.session(name="codeqa", default=False)(codeqa)
|
545
|
+
|
546
|
+
|
547
|
+
def add_yamllint(
|
548
|
+
*,
|
549
|
+
run_yamllint: bool,
|
550
|
+
yamllint_config: str | os.PathLike | None,
|
551
|
+
yamllint_config_plugins: str | os.PathLike | None,
|
552
|
+
yamllint_config_plugins_examples: str | os.PathLike | None,
|
553
|
+
yamllint_package: str,
|
554
|
+
) -> None:
|
555
|
+
"""
|
556
|
+
Add yamllint session for linting YAML files and plugin/module docs.
|
557
|
+
"""
|
558
|
+
|
559
|
+
def compose_dependencies() -> list[str]:
|
560
|
+
deps = []
|
561
|
+
if run_yamllint:
|
562
|
+
deps.append(yamllint_package)
|
563
|
+
return deps
|
564
|
+
|
565
|
+
def to_str(config: str | os.PathLike | None) -> str | None:
|
566
|
+
return str(config) if config else None
|
567
|
+
|
568
|
+
def execute_yamllint(session: nox.Session) -> None:
|
569
|
+
# Run yamllint
|
570
|
+
all_files = list_all_files()
|
571
|
+
cwd = Path.cwd()
|
572
|
+
all_yaml_filenames = [
|
573
|
+
str(file.relative_to(cwd))
|
574
|
+
for file in all_files
|
575
|
+
if file.name.lower().endswith((".yml", ".yaml"))
|
576
|
+
]
|
577
|
+
if not all_yaml_filenames:
|
578
|
+
session.warn("Skipping yamllint since no YAML file was found...")
|
579
|
+
return
|
580
|
+
|
581
|
+
command = ["yamllint"]
|
582
|
+
if yamllint_config is not None:
|
583
|
+
command.extend(
|
584
|
+
[
|
585
|
+
"-c",
|
586
|
+
str(yamllint_config),
|
587
|
+
]
|
588
|
+
)
|
589
|
+
command.append("--strict")
|
590
|
+
command.append("--")
|
591
|
+
command.extend(all_yaml_filenames)
|
592
|
+
command.extend(session.posargs)
|
593
|
+
session.run(*command)
|
594
|
+
|
595
|
+
def execute_plugin_yamllint(session: nox.Session) -> None:
|
596
|
+
# Run yamllint
|
597
|
+
all_files = list_all_files()
|
598
|
+
cwd = Path.cwd()
|
599
|
+
plugins_dir = cwd / "plugins"
|
600
|
+
ignore_dirs = [
|
601
|
+
plugins_dir / "action",
|
602
|
+
plugins_dir / "module_utils",
|
603
|
+
plugins_dir / "plugin_utils",
|
604
|
+
]
|
605
|
+
all_plugin_files = [
|
606
|
+
file
|
607
|
+
for file in all_files
|
608
|
+
if file.is_relative_to(plugins_dir)
|
609
|
+
and file.name.lower().endswith((".py", ".yml", ".yaml"))
|
610
|
+
and not any(file.is_relative_to(dir) for dir in ignore_dirs)
|
611
|
+
]
|
612
|
+
if not all_plugin_files:
|
613
|
+
session.warn(
|
614
|
+
"Skipping yamllint for modules/plugins since"
|
615
|
+
" no appropriate Python file was found..."
|
616
|
+
)
|
617
|
+
return
|
618
|
+
_run_bare_script(
|
619
|
+
session,
|
620
|
+
"plugin-yamllint",
|
621
|
+
use_session_python=True,
|
622
|
+
files=all_plugin_files,
|
623
|
+
extra_data={
|
624
|
+
"config": to_str(yamllint_config_plugins or yamllint_config),
|
625
|
+
"config_examples": to_str(
|
626
|
+
yamllint_config_plugins_examples
|
627
|
+
or yamllint_config_plugins
|
628
|
+
or yamllint_config
|
629
|
+
),
|
630
|
+
},
|
631
|
+
)
|
632
|
+
|
633
|
+
def yamllint(session: nox.Session) -> None:
|
634
|
+
install(session, *compose_dependencies())
|
635
|
+
if run_yamllint:
|
636
|
+
execute_yamllint(session)
|
637
|
+
execute_plugin_yamllint(session)
|
638
|
+
|
639
|
+
yamllint.__doc__ = _compose_description(
|
640
|
+
prefix={
|
641
|
+
"one": "Run YAML checker:",
|
642
|
+
"other": "Run YAML checkers:",
|
643
|
+
},
|
644
|
+
programs={
|
645
|
+
"yamllint": run_yamllint,
|
646
|
+
},
|
647
|
+
)
|
648
|
+
nox.session(name="yamllint", default=False)(yamllint)
|
416
649
|
|
417
650
|
|
418
651
|
def add_typing(
|
@@ -479,7 +712,16 @@ def add_typing(
|
|
479
712
|
if run_mypy and prepared_collections:
|
480
713
|
execute_mypy(session, prepared_collections)
|
481
714
|
|
482
|
-
|
715
|
+
typing.__doc__ = _compose_description(
|
716
|
+
prefix={
|
717
|
+
"one": "Run type checker:",
|
718
|
+
"other": "Run type checkers:",
|
719
|
+
},
|
720
|
+
programs={
|
721
|
+
"mypy": run_mypy,
|
722
|
+
},
|
723
|
+
)
|
724
|
+
nox.session(name="typing", default=False)(typing)
|
483
725
|
|
484
726
|
|
485
727
|
def add_lint_sessions(
|
@@ -506,6 +748,12 @@ def add_lint_sessions(
|
|
506
748
|
pylint_package: str = "pylint",
|
507
749
|
pylint_ansible_core_package: str | None = "ansible-core",
|
508
750
|
pylint_extra_deps: list[str] | None = None,
|
751
|
+
# yamllint:
|
752
|
+
run_yamllint: bool = False,
|
753
|
+
yamllint_config: str | os.PathLike | None = None,
|
754
|
+
yamllint_config_plugins: str | os.PathLike | None = None,
|
755
|
+
yamllint_config_plugins_examples: str | os.PathLike | None = None,
|
756
|
+
yamllint_package: str = "yamllint",
|
509
757
|
# mypy:
|
510
758
|
run_mypy: bool = True,
|
511
759
|
mypy_config: str | os.PathLike | None = None,
|
@@ -518,11 +766,13 @@ def add_lint_sessions(
|
|
518
766
|
"""
|
519
767
|
has_formatters = run_isort or run_black or run_black_modules or False
|
520
768
|
has_codeqa = run_flake8 or run_pylint
|
769
|
+
has_yamllint = run_yamllint
|
521
770
|
has_typing = run_mypy
|
522
771
|
|
523
772
|
add_lint(
|
524
773
|
has_formatters=has_formatters,
|
525
774
|
has_codeqa=has_codeqa,
|
775
|
+
has_yamllint=has_yamllint,
|
526
776
|
has_typing=has_typing,
|
527
777
|
make_lint_default=make_lint_default,
|
528
778
|
)
|
@@ -553,6 +803,15 @@ def add_lint_sessions(
|
|
553
803
|
pylint_extra_deps=pylint_extra_deps or [],
|
554
804
|
)
|
555
805
|
|
806
|
+
if has_yamllint:
|
807
|
+
add_yamllint(
|
808
|
+
run_yamllint=run_yamllint,
|
809
|
+
yamllint_config=yamllint_config,
|
810
|
+
yamllint_config_plugins=yamllint_config_plugins,
|
811
|
+
yamllint_config_plugins_examples=yamllint_config_plugins_examples,
|
812
|
+
yamllint_package=yamllint_package,
|
813
|
+
)
|
814
|
+
|
556
815
|
if has_typing:
|
557
816
|
add_typing(
|
558
817
|
extra_code_files=extra_code_files or [],
|
@@ -571,7 +830,7 @@ def add_docs_check(
|
|
571
830
|
ansible_core_package: str = "ansible-core",
|
572
831
|
validate_collection_refs: t.Literal["self", "dependent", "all"] | None = None,
|
573
832
|
extra_collections: list[str] | None = None,
|
574
|
-
):
|
833
|
+
) -> None:
|
575
834
|
"""
|
576
835
|
Add docs-check session for linting.
|
577
836
|
"""
|
@@ -609,9 +868,11 @@ def add_docs_check(
|
|
609
868
|
if prepared_collections:
|
610
869
|
execute_antsibull_docs(session, prepared_collections)
|
611
870
|
|
612
|
-
|
613
|
-
|
614
|
-
|
871
|
+
docs_check.__doc__ = "Run 'antsibull-docs lint-collection-docs'"
|
872
|
+
nox.session(
|
873
|
+
name="docs-check",
|
874
|
+
default=make_docs_check_default,
|
875
|
+
)(docs_check)
|
615
876
|
|
616
877
|
|
617
878
|
def add_license_check(
|
@@ -621,7 +882,7 @@ def add_license_check(
|
|
621
882
|
reuse_package: str = "reuse",
|
622
883
|
run_license_check: bool = True,
|
623
884
|
license_check_extra_ignore_paths: list[str] | None = None,
|
624
|
-
):
|
885
|
+
) -> None:
|
625
886
|
"""
|
626
887
|
Add license-check session for license checks.
|
627
888
|
"""
|
@@ -645,9 +906,22 @@ def add_license_check(
|
|
645
906
|
},
|
646
907
|
)
|
647
908
|
|
648
|
-
|
649
|
-
|
909
|
+
license_check.__doc__ = _compose_description(
|
910
|
+
prefix={
|
911
|
+
"one": "Run license checker:",
|
912
|
+
"other": "Run license checkers:",
|
913
|
+
},
|
914
|
+
programs={
|
915
|
+
"reuse": run_reuse,
|
916
|
+
"license-check": (
|
917
|
+
"ensure GPLv3+ for plugins" if run_license_check else False
|
918
|
+
),
|
919
|
+
},
|
650
920
|
)
|
921
|
+
nox.session(
|
922
|
+
name="license-check",
|
923
|
+
default=make_license_check_default,
|
924
|
+
)(license_check)
|
651
925
|
|
652
926
|
|
653
927
|
@dataclass
|
@@ -688,7 +962,7 @@ def add_extra_checks(
|
|
688
962
|
# action-groups:
|
689
963
|
run_action_groups: bool = False,
|
690
964
|
action_groups_config: list[ActionGroup] | None = None,
|
691
|
-
):
|
965
|
+
) -> None:
|
692
966
|
"""
|
693
967
|
Add extra-checks session for extra checks.
|
694
968
|
"""
|
@@ -730,12 +1004,25 @@ def add_extra_checks(
|
|
730
1004
|
if run_action_groups:
|
731
1005
|
execute_action_groups(session)
|
732
1006
|
|
733
|
-
|
734
|
-
|
1007
|
+
extra_checks.__doc__ = _compose_description(
|
1008
|
+
prefix={
|
1009
|
+
"one": "Run extra checker:",
|
1010
|
+
"other": "Run extra checkers:",
|
1011
|
+
},
|
1012
|
+
programs={
|
1013
|
+
"no-unwanted-files": (
|
1014
|
+
"checks for unwanted files in plugins/"
|
1015
|
+
if run_no_unwanted_files
|
1016
|
+
else False
|
1017
|
+
),
|
1018
|
+
"action-groups": "validate action groups" if run_action_groups else False,
|
1019
|
+
},
|
1020
|
+
)
|
1021
|
+
nox.session(
|
735
1022
|
name="extra-checks",
|
736
1023
|
python=False,
|
737
1024
|
default=make_extra_checks_default,
|
738
|
-
)
|
1025
|
+
)(extra_checks)
|
739
1026
|
|
740
1027
|
|
741
1028
|
def add_build_import_check(
|
@@ -745,9 +1032,9 @@ def add_build_import_check(
|
|
745
1032
|
run_galaxy_importer: bool = True,
|
746
1033
|
galaxy_importer_package: str = "galaxy-importer",
|
747
1034
|
galaxy_importer_config_path: (
|
748
|
-
str | None
|
1035
|
+
str | os.PathLike | None
|
749
1036
|
) = None, # https://github.com/ansible/galaxy-importer#configuration
|
750
|
-
):
|
1037
|
+
) -> None:
|
751
1038
|
"""
|
752
1039
|
Add license-check session for license checks.
|
753
1040
|
"""
|
@@ -793,7 +1080,7 @@ def add_build_import_check(
|
|
793
1080
|
env = {}
|
794
1081
|
if galaxy_importer_config_path:
|
795
1082
|
env["GALAXY_IMPORTER_CONFIG"] = str(
|
796
|
-
Path.
|
1083
|
+
Path(galaxy_importer_config_path).absolute()
|
797
1084
|
)
|
798
1085
|
with session.chdir(collection_dir):
|
799
1086
|
import_log = (
|
@@ -808,7 +1095,8 @@ def add_build_import_check(
|
|
808
1095
|
or ""
|
809
1096
|
)
|
810
1097
|
if import_log:
|
811
|
-
|
1098
|
+
with _ci_group("Run Galaxy importer"):
|
1099
|
+
print(import_log)
|
812
1100
|
error_prefix = "ERROR:"
|
813
1101
|
errors = []
|
814
1102
|
for line in import_log.splitlines():
|
@@ -821,13 +1109,589 @@ def add_build_import_check(
|
|
821
1109
|
f" error{'' if len(errors) == 1 else 's'}:\n{messages}"
|
822
1110
|
)
|
823
1111
|
|
824
|
-
|
825
|
-
|
1112
|
+
build_import_check.__doc__ = _compose_description(
|
1113
|
+
prefix={
|
1114
|
+
"one": "Run build and import checker:",
|
1115
|
+
"other": "Run build and import checkers:",
|
1116
|
+
},
|
1117
|
+
programs={
|
1118
|
+
"build-collection": True,
|
1119
|
+
"galaxy-importer": (
|
1120
|
+
"test whether Galaxy will import built collection"
|
1121
|
+
if run_galaxy_importer
|
1122
|
+
else False
|
1123
|
+
),
|
1124
|
+
},
|
1125
|
+
)
|
1126
|
+
nox.session(
|
826
1127
|
name="build-import-check",
|
827
1128
|
default=make_build_import_check_default,
|
1129
|
+
)(build_import_check)
|
1130
|
+
|
1131
|
+
|
1132
|
+
def _parse_ansible_core_version(
|
1133
|
+
version: str | AnsibleCoreVersion,
|
1134
|
+
) -> AnsibleCoreVersion:
|
1135
|
+
if version in ("devel", "milestone"):
|
1136
|
+
# For some reason mypy doesn't notice that
|
1137
|
+
return t.cast(AnsibleCoreVersion, version)
|
1138
|
+
if isinstance(version, Version):
|
1139
|
+
return version
|
1140
|
+
return Version.parse(version)
|
1141
|
+
|
1142
|
+
|
1143
|
+
def add_ansible_test_session(
|
1144
|
+
*,
|
1145
|
+
name: str,
|
1146
|
+
description: str | None,
|
1147
|
+
extra_deps_files: list[str | os.PathLike] | None = None,
|
1148
|
+
ansible_test_params: list[str],
|
1149
|
+
add_posargs: bool = True,
|
1150
|
+
default: bool,
|
1151
|
+
ansible_core_version: str | AnsibleCoreVersion,
|
1152
|
+
ansible_core_source: t.Literal["git", "pypi"] = "git",
|
1153
|
+
ansible_core_repo_name: str | None = None,
|
1154
|
+
ansible_core_branch_name: str | None = None,
|
1155
|
+
handle_coverage: t.Literal["never", "always", "auto"] = "auto",
|
1156
|
+
register_name: str | None = None,
|
1157
|
+
register_extra_data: dict[str, t.Any] | None = None,
|
1158
|
+
) -> None:
|
1159
|
+
"""
|
1160
|
+
Add generic ansible-test session.
|
1161
|
+
|
1162
|
+
Returns a list of Python versions set for this session.
|
1163
|
+
"""
|
1164
|
+
parsed_ansible_core_version = _parse_ansible_core_version(ansible_core_version)
|
1165
|
+
|
1166
|
+
def compose_dependencies() -> list[str]:
|
1167
|
+
deps = [
|
1168
|
+
get_ansible_core_package_name(
|
1169
|
+
parsed_ansible_core_version,
|
1170
|
+
source=ansible_core_source,
|
1171
|
+
ansible_repo=ansible_core_repo_name,
|
1172
|
+
branch_name=ansible_core_branch_name,
|
1173
|
+
)
|
1174
|
+
]
|
1175
|
+
return deps
|
1176
|
+
|
1177
|
+
def run_ansible_test(session: nox.Session) -> None:
|
1178
|
+
install(session, *compose_dependencies())
|
1179
|
+
prepared_collections = prepare_collections(
|
1180
|
+
session,
|
1181
|
+
install_in_site_packages=False,
|
1182
|
+
extra_deps_files=extra_deps_files,
|
1183
|
+
install_out_of_tree=True,
|
1184
|
+
)
|
1185
|
+
if not prepared_collections:
|
1186
|
+
session.warn("Skipping ansible-test...")
|
1187
|
+
return
|
1188
|
+
cwd = Path.cwd()
|
1189
|
+
with session.chdir(prepared_collections.current_path):
|
1190
|
+
command = ["ansible-test"] + ansible_test_params
|
1191
|
+
if add_posargs and session.posargs:
|
1192
|
+
command.extend(session.posargs)
|
1193
|
+
session.run(*command)
|
1194
|
+
|
1195
|
+
coverage = (handle_coverage == "auto" and "--coverage" in command) or (
|
1196
|
+
handle_coverage == "always"
|
1197
|
+
)
|
1198
|
+
if coverage:
|
1199
|
+
session.run(
|
1200
|
+
"ansible-test",
|
1201
|
+
"coverage",
|
1202
|
+
"xml",
|
1203
|
+
"--color",
|
1204
|
+
"-v",
|
1205
|
+
"--requirements",
|
1206
|
+
"--group-by",
|
1207
|
+
"command",
|
1208
|
+
"--group-by",
|
1209
|
+
"version",
|
1210
|
+
)
|
1211
|
+
|
1212
|
+
copy_directory_tree_into(
|
1213
|
+
prepared_collections.current_path / "tests" / "output",
|
1214
|
+
cwd / "tests" / "output",
|
1215
|
+
)
|
1216
|
+
|
1217
|
+
# Determine Python version(s)
|
1218
|
+
core_info = get_ansible_core_info(parsed_ansible_core_version)
|
1219
|
+
all_versions = get_installed_python_versions()
|
1220
|
+
|
1221
|
+
installed_versions = [
|
1222
|
+
version
|
1223
|
+
for version in core_info.controller_python_versions
|
1224
|
+
if version in all_versions
|
1225
|
+
]
|
1226
|
+
python = max(installed_versions or core_info.controller_python_versions)
|
1227
|
+
python_versions = [python]
|
1228
|
+
|
1229
|
+
run_ansible_test.__doc__ = description
|
1230
|
+
nox.session(
|
1231
|
+
name=name,
|
1232
|
+
default=default,
|
1233
|
+
python=[str(python_version) for python_version in python_versions],
|
1234
|
+
)(run_ansible_test)
|
1235
|
+
|
1236
|
+
if register_name:
|
1237
|
+
data = {
|
1238
|
+
"name": name,
|
1239
|
+
"ansible-core": (
|
1240
|
+
str(ansible_core_branch_name)
|
1241
|
+
if ansible_core_branch_name is not None
|
1242
|
+
else str(parsed_ansible_core_version)
|
1243
|
+
),
|
1244
|
+
"python": " ".join(str(python) for python in python_versions),
|
1245
|
+
}
|
1246
|
+
if register_extra_data:
|
1247
|
+
data.update(register_extra_data)
|
1248
|
+
_register(register_name, data)
|
1249
|
+
|
1250
|
+
|
1251
|
+
def add_ansible_test_sanity_test_session(
|
1252
|
+
*,
|
1253
|
+
name: str,
|
1254
|
+
description: str | None,
|
1255
|
+
default: bool,
|
1256
|
+
ansible_core_version: str | AnsibleCoreVersion,
|
1257
|
+
ansible_core_source: t.Literal["git", "pypi"] = "git",
|
1258
|
+
ansible_core_repo_name: str | None = None,
|
1259
|
+
ansible_core_branch_name: str | None = None,
|
1260
|
+
) -> None:
|
1261
|
+
"""
|
1262
|
+
Add generic ansible-test sanity test session.
|
1263
|
+
"""
|
1264
|
+
add_ansible_test_session(
|
1265
|
+
name=name,
|
1266
|
+
description=description,
|
1267
|
+
ansible_test_params=["sanity", "--docker", "-v", "--color"],
|
1268
|
+
default=default,
|
1269
|
+
ansible_core_version=ansible_core_version,
|
1270
|
+
ansible_core_source=ansible_core_source,
|
1271
|
+
ansible_core_repo_name=ansible_core_repo_name,
|
1272
|
+
ansible_core_branch_name=ansible_core_branch_name,
|
1273
|
+
register_name="sanity",
|
828
1274
|
)
|
829
1275
|
|
830
1276
|
|
1277
|
+
def _parse_min_max_except(
|
1278
|
+
min_version: Version | str | None,
|
1279
|
+
max_version: Version | str | None,
|
1280
|
+
except_versions: list[AnsibleCoreVersion | str] | None,
|
1281
|
+
) -> tuple[Version | None, Version | None, tuple[AnsibleCoreVersion, ...] | None]:
|
1282
|
+
if isinstance(min_version, str):
|
1283
|
+
min_version = Version.parse(min_version)
|
1284
|
+
if isinstance(max_version, str):
|
1285
|
+
max_version = Version.parse(max_version)
|
1286
|
+
if except_versions is None:
|
1287
|
+
return min_version, max_version, None
|
1288
|
+
evs = tuple(_parse_ansible_core_version(version) for version in except_versions)
|
1289
|
+
return min_version, max_version, evs
|
1290
|
+
|
1291
|
+
|
1292
|
+
def add_all_ansible_test_sanity_test_sessions(
|
1293
|
+
*,
|
1294
|
+
default: bool = False,
|
1295
|
+
include_devel: bool = False,
|
1296
|
+
include_milestone: bool = False,
|
1297
|
+
add_devel_like_branches: list[tuple[str | None, str]] | None = None,
|
1298
|
+
min_version: Version | str | None = None,
|
1299
|
+
max_version: Version | str | None = None,
|
1300
|
+
except_versions: list[AnsibleCoreVersion | str] | None = None,
|
1301
|
+
) -> None:
|
1302
|
+
"""
|
1303
|
+
Add ansible-test sanity test meta session that runs ansible-test sanity
|
1304
|
+
for all supported ansible-core versions.
|
1305
|
+
"""
|
1306
|
+
parsed_min_version, parsed_max_version, parsed_except_versions = (
|
1307
|
+
_parse_min_max_except(min_version, max_version, except_versions)
|
1308
|
+
)
|
1309
|
+
|
1310
|
+
sanity_sessions = []
|
1311
|
+
for ansible_core_version in get_supported_core_versions(
|
1312
|
+
include_devel=include_devel,
|
1313
|
+
include_milestone=include_milestone,
|
1314
|
+
min_version=parsed_min_version,
|
1315
|
+
max_version=parsed_max_version,
|
1316
|
+
except_versions=parsed_except_versions,
|
1317
|
+
):
|
1318
|
+
name = f"ansible-test-sanity-{ansible_core_version}"
|
1319
|
+
add_ansible_test_sanity_test_session(
|
1320
|
+
name=name,
|
1321
|
+
description=f"Run sanity tests from ansible-core {ansible_core_version}'s ansible-test",
|
1322
|
+
ansible_core_version=ansible_core_version,
|
1323
|
+
default=False,
|
1324
|
+
)
|
1325
|
+
sanity_sessions.append(name)
|
1326
|
+
if add_devel_like_branches:
|
1327
|
+
for repo_name, branch_name in add_devel_like_branches:
|
1328
|
+
repo_prefix = (
|
1329
|
+
f"{repo_name.replace('/', '-')}-" if repo_name is not None else ""
|
1330
|
+
)
|
1331
|
+
repo_postfix = f", {repo_name} repository" if repo_name is not None else ""
|
1332
|
+
name = f"ansible-test-sanity-{repo_prefix}{branch_name.replace('/', '-')}"
|
1333
|
+
add_ansible_test_sanity_test_session(
|
1334
|
+
name=name,
|
1335
|
+
description=(
|
1336
|
+
"Run sanity tests from ansible-test in ansible-core's"
|
1337
|
+
f" {branch_name} branch{repo_postfix}"
|
1338
|
+
),
|
1339
|
+
ansible_core_version="devel",
|
1340
|
+
ansible_core_repo_name=repo_name,
|
1341
|
+
ansible_core_branch_name=branch_name,
|
1342
|
+
default=False,
|
1343
|
+
)
|
1344
|
+
sanity_sessions.append(name)
|
1345
|
+
|
1346
|
+
def run_all_sanity_tests(
|
1347
|
+
session: nox.Session, # pylint: disable=unused-argument
|
1348
|
+
) -> None:
|
1349
|
+
pass
|
1350
|
+
|
1351
|
+
run_all_sanity_tests.__doc__ = (
|
1352
|
+
"Meta session for running all ansible-test-sanity-* sessions."
|
1353
|
+
)
|
1354
|
+
nox.session(
|
1355
|
+
name="ansible-test-sanity",
|
1356
|
+
default=default,
|
1357
|
+
requires=sanity_sessions,
|
1358
|
+
)(run_all_sanity_tests)
|
1359
|
+
|
1360
|
+
|
1361
|
+
def add_ansible_test_unit_test_session(
|
1362
|
+
*,
|
1363
|
+
name: str,
|
1364
|
+
description: str | None,
|
1365
|
+
default: bool,
|
1366
|
+
ansible_core_version: str | AnsibleCoreVersion,
|
1367
|
+
ansible_core_source: t.Literal["git", "pypi"] = "git",
|
1368
|
+
ansible_core_repo_name: str | None = None,
|
1369
|
+
ansible_core_branch_name: str | None = None,
|
1370
|
+
) -> None:
|
1371
|
+
"""
|
1372
|
+
Add generic ansible-test unit test session.
|
1373
|
+
"""
|
1374
|
+
add_ansible_test_session(
|
1375
|
+
name=name,
|
1376
|
+
description=description,
|
1377
|
+
ansible_test_params=["units", "--docker", "-v", "--color"],
|
1378
|
+
extra_deps_files=["tests/unit/requirements.yml"],
|
1379
|
+
default=default,
|
1380
|
+
ansible_core_version=ansible_core_version,
|
1381
|
+
ansible_core_source=ansible_core_source,
|
1382
|
+
ansible_core_repo_name=ansible_core_repo_name,
|
1383
|
+
ansible_core_branch_name=ansible_core_branch_name,
|
1384
|
+
register_name="units",
|
1385
|
+
)
|
1386
|
+
|
1387
|
+
|
1388
|
+
def add_all_ansible_test_unit_test_sessions(
|
1389
|
+
*,
|
1390
|
+
default: bool = False,
|
1391
|
+
include_devel: bool = False,
|
1392
|
+
include_milestone: bool = False,
|
1393
|
+
add_devel_like_branches: list[tuple[str | None, str]] | None = None,
|
1394
|
+
min_version: Version | str | None = None,
|
1395
|
+
max_version: Version | str | None = None,
|
1396
|
+
except_versions: list[AnsibleCoreVersion | str] | None = None,
|
1397
|
+
) -> None:
|
1398
|
+
"""
|
1399
|
+
Add ansible-test unit test meta session that runs ansible-test units
|
1400
|
+
for all supported ansible-core versions.
|
1401
|
+
"""
|
1402
|
+
parsed_min_version, parsed_max_version, parsed_except_versions = (
|
1403
|
+
_parse_min_max_except(min_version, max_version, except_versions)
|
1404
|
+
)
|
1405
|
+
|
1406
|
+
units_sessions = []
|
1407
|
+
for ansible_core_version in get_supported_core_versions(
|
1408
|
+
include_devel=include_devel,
|
1409
|
+
include_milestone=include_milestone,
|
1410
|
+
min_version=parsed_min_version,
|
1411
|
+
max_version=parsed_max_version,
|
1412
|
+
except_versions=parsed_except_versions,
|
1413
|
+
):
|
1414
|
+
name = f"ansible-test-units-{ansible_core_version}"
|
1415
|
+
add_ansible_test_unit_test_session(
|
1416
|
+
name=name,
|
1417
|
+
description=f"Run unit tests with ansible-core {ansible_core_version}'s ansible-test",
|
1418
|
+
ansible_core_version=ansible_core_version,
|
1419
|
+
default=False,
|
1420
|
+
)
|
1421
|
+
units_sessions.append(name)
|
1422
|
+
if add_devel_like_branches:
|
1423
|
+
for repo_name, branch_name in add_devel_like_branches:
|
1424
|
+
repo_prefix = (
|
1425
|
+
f"{repo_name.replace('/', '-')}-" if repo_name is not None else ""
|
1426
|
+
)
|
1427
|
+
repo_postfix = f", {repo_name} repository" if repo_name is not None else ""
|
1428
|
+
name = f"ansible-test-units-{repo_prefix}{branch_name.replace('/', '-')}"
|
1429
|
+
add_ansible_test_unit_test_session(
|
1430
|
+
name=name,
|
1431
|
+
description=(
|
1432
|
+
"Run unit tests from ansible-test in ansible-core's"
|
1433
|
+
f" {branch_name} branch{repo_postfix}"
|
1434
|
+
),
|
1435
|
+
ansible_core_version="devel",
|
1436
|
+
ansible_core_repo_name=repo_name,
|
1437
|
+
ansible_core_branch_name=branch_name,
|
1438
|
+
default=False,
|
1439
|
+
)
|
1440
|
+
units_sessions.append(name)
|
1441
|
+
|
1442
|
+
def run_all_unit_tests(
|
1443
|
+
session: nox.Session, # pylint: disable=unused-argument
|
1444
|
+
) -> None:
|
1445
|
+
pass
|
1446
|
+
|
1447
|
+
run_all_unit_tests.__doc__ = (
|
1448
|
+
"Meta session for running all ansible-test-units-* sessions."
|
1449
|
+
)
|
1450
|
+
nox.session(
|
1451
|
+
name="ansible-test-units",
|
1452
|
+
default=default,
|
1453
|
+
requires=units_sessions,
|
1454
|
+
)(run_all_unit_tests)
|
1455
|
+
|
1456
|
+
|
1457
|
+
def add_ansible_test_integration_sessions_default_container(
|
1458
|
+
*,
|
1459
|
+
include_devel: bool = False,
|
1460
|
+
include_milestone: bool = False,
|
1461
|
+
add_devel_like_branches: list[tuple[str | None, str]] | None = None,
|
1462
|
+
min_version: Version | str | None = None,
|
1463
|
+
max_version: Version | str | None = None,
|
1464
|
+
except_versions: list[AnsibleCoreVersion | str] | None = None,
|
1465
|
+
core_python_versions: (
|
1466
|
+
dict[str | AnsibleCoreVersion, list[str | Version]] | None
|
1467
|
+
) = None,
|
1468
|
+
controller_python_versions_only: bool = False,
|
1469
|
+
default: bool = False,
|
1470
|
+
) -> None:
|
1471
|
+
"""
|
1472
|
+
Add ansible-test integration tests using the default Docker container.
|
1473
|
+
|
1474
|
+
``core_python_versions`` can be used to restrict the Python versions
|
1475
|
+
to be used for a specific ansible-core version.
|
1476
|
+
|
1477
|
+
``controller_python_versions_only`` can be used to only run against
|
1478
|
+
controller Python versions.
|
1479
|
+
"""
|
1480
|
+
|
1481
|
+
def add_integration_tests(
|
1482
|
+
ansible_core_version: AnsibleCoreVersion,
|
1483
|
+
repo_name: str | None = None,
|
1484
|
+
branch_name: str | None = None,
|
1485
|
+
) -> list[str]:
|
1486
|
+
# Determine Python versions to run tests for
|
1487
|
+
py_versions = (
|
1488
|
+
(core_python_versions.get(branch_name) if branch_name is not None else None)
|
1489
|
+
or core_python_versions.get(ansible_core_version)
|
1490
|
+
or core_python_versions.get(str(ansible_core_version))
|
1491
|
+
if core_python_versions
|
1492
|
+
else None
|
1493
|
+
)
|
1494
|
+
if py_versions is None:
|
1495
|
+
core_info = get_ansible_core_info(ansible_core_version)
|
1496
|
+
py_versions = list(
|
1497
|
+
core_info.controller_python_versions
|
1498
|
+
if controller_python_versions_only
|
1499
|
+
else core_info.remote_python_versions
|
1500
|
+
)
|
1501
|
+
|
1502
|
+
# Add sessions
|
1503
|
+
integration_sessions_core: list[str] = []
|
1504
|
+
if branch_name is None:
|
1505
|
+
base_name = f"ansible-test-integration-{ansible_core_version}-"
|
1506
|
+
else:
|
1507
|
+
repo_prefix = (
|
1508
|
+
f"{repo_name.replace('/', '-')}-" if repo_name is not None else ""
|
1509
|
+
)
|
1510
|
+
base_name = f"ansible-test-integration-{repo_prefix}{branch_name.replace('/', '-')}-"
|
1511
|
+
for py_version in py_versions:
|
1512
|
+
name = f"{base_name}{py_version}"
|
1513
|
+
if branch_name is None:
|
1514
|
+
description = (
|
1515
|
+
f"Run integration tests from ansible-core {ansible_core_version}'s"
|
1516
|
+
f" ansible-test with Python {py_version}"
|
1517
|
+
)
|
1518
|
+
else:
|
1519
|
+
repo_postfix = (
|
1520
|
+
f", {repo_name} repository" if repo_name is not None else ""
|
1521
|
+
)
|
1522
|
+
description = (
|
1523
|
+
f"Run integration tests from ansible-test in ansible-core's {branch_name}"
|
1524
|
+
f" branch{repo_postfix} with Python {py_version}"
|
1525
|
+
)
|
1526
|
+
add_ansible_test_session(
|
1527
|
+
name=name,
|
1528
|
+
description=description,
|
1529
|
+
ansible_test_params=[
|
1530
|
+
"integration",
|
1531
|
+
"--docker",
|
1532
|
+
"default",
|
1533
|
+
"-v",
|
1534
|
+
"--color",
|
1535
|
+
"--python",
|
1536
|
+
str(py_version),
|
1537
|
+
],
|
1538
|
+
extra_deps_files=["tests/integration/requirements.yml"],
|
1539
|
+
ansible_core_version=ansible_core_version,
|
1540
|
+
ansible_core_repo_name=repo_name,
|
1541
|
+
ansible_core_branch_name=branch_name,
|
1542
|
+
default=False,
|
1543
|
+
register_name="integration",
|
1544
|
+
register_extra_data={
|
1545
|
+
"test-container": "default",
|
1546
|
+
"test-python": str(py_version),
|
1547
|
+
},
|
1548
|
+
)
|
1549
|
+
integration_sessions_core.append(name)
|
1550
|
+
return integration_sessions_core
|
1551
|
+
|
1552
|
+
parsed_min_version, parsed_max_version, parsed_except_versions = (
|
1553
|
+
_parse_min_max_except(min_version, max_version, except_versions)
|
1554
|
+
)
|
1555
|
+
integration_sessions: list[str] = []
|
1556
|
+
for ansible_core_version in get_supported_core_versions(
|
1557
|
+
include_devel=include_devel,
|
1558
|
+
include_milestone=include_milestone,
|
1559
|
+
min_version=parsed_min_version,
|
1560
|
+
max_version=parsed_max_version,
|
1561
|
+
except_versions=parsed_except_versions,
|
1562
|
+
):
|
1563
|
+
integration_sessions_core = add_integration_tests(ansible_core_version)
|
1564
|
+
if integration_sessions_core:
|
1565
|
+
name = f"ansible-test-integration-{ansible_core_version}"
|
1566
|
+
integration_sessions.append(name)
|
1567
|
+
|
1568
|
+
def run_integration_tests(
|
1569
|
+
session: nox.Session, # pylint: disable=unused-argument
|
1570
|
+
) -> None:
|
1571
|
+
pass
|
1572
|
+
|
1573
|
+
run_integration_tests.__doc__ = (
|
1574
|
+
f"Meta session for running all {name}-* sessions."
|
1575
|
+
)
|
1576
|
+
nox.session(
|
1577
|
+
name=name,
|
1578
|
+
requires=integration_sessions_core,
|
1579
|
+
default=False,
|
1580
|
+
)(run_integration_tests)
|
1581
|
+
if add_devel_like_branches:
|
1582
|
+
for repo_name, branch_name in add_devel_like_branches:
|
1583
|
+
integration_sessions_core = add_integration_tests(
|
1584
|
+
"devel", repo_name=repo_name, branch_name=branch_name
|
1585
|
+
)
|
1586
|
+
if integration_sessions_core:
|
1587
|
+
repo_prefix = (
|
1588
|
+
f"{repo_name.replace('/', '-')}-" if repo_name is not None else ""
|
1589
|
+
)
|
1590
|
+
name = f"ansible-test-integration-{repo_prefix}{branch_name.replace('/', '-')}"
|
1591
|
+
integration_sessions.append(name)
|
1592
|
+
|
1593
|
+
def run_integration_tests_for_branch(
|
1594
|
+
session: nox.Session, # pylint: disable=unused-argument
|
1595
|
+
) -> None:
|
1596
|
+
pass
|
1597
|
+
|
1598
|
+
run_integration_tests_for_branch.__doc__ = (
|
1599
|
+
f"Meta session for running all {name}-* sessions."
|
1600
|
+
)
|
1601
|
+
nox.session(
|
1602
|
+
name=name,
|
1603
|
+
requires=integration_sessions_core,
|
1604
|
+
default=False,
|
1605
|
+
)(run_integration_tests_for_branch)
|
1606
|
+
|
1607
|
+
def ansible_test_integration(
|
1608
|
+
session: nox.Session, # pylint: disable=unused-argument
|
1609
|
+
) -> None:
|
1610
|
+
pass
|
1611
|
+
|
1612
|
+
ansible_test_integration.__doc__ = (
|
1613
|
+
"Meta session for running all ansible-test-integration-* sessions."
|
1614
|
+
)
|
1615
|
+
nox.session(
|
1616
|
+
name="ansible-test-integration",
|
1617
|
+
requires=integration_sessions,
|
1618
|
+
default=default,
|
1619
|
+
)(ansible_test_integration)
|
1620
|
+
|
1621
|
+
|
1622
|
+
def add_ansible_lint(
|
1623
|
+
*,
|
1624
|
+
make_ansible_lint_default: bool = True,
|
1625
|
+
ansible_lint_package: str = "ansible-lint",
|
1626
|
+
strict: bool = False,
|
1627
|
+
) -> None:
|
1628
|
+
"""
|
1629
|
+
Add a session that runs ansible-lint.
|
1630
|
+
"""
|
1631
|
+
|
1632
|
+
def compose_dependencies() -> list[str]:
|
1633
|
+
return [ansible_lint_package]
|
1634
|
+
|
1635
|
+
def ansible_lint(session: nox.Session) -> None:
|
1636
|
+
install(session, *compose_dependencies())
|
1637
|
+
prepared_collections = prepare_collections(
|
1638
|
+
session,
|
1639
|
+
install_in_site_packages=False,
|
1640
|
+
install_out_of_tree=True,
|
1641
|
+
extra_deps_files=["tests/integration/requirements.yml"],
|
1642
|
+
)
|
1643
|
+
if not prepared_collections:
|
1644
|
+
session.warn("Skipping ansible-lint...")
|
1645
|
+
return
|
1646
|
+
env = {"ANSIBLE_COLLECTIONS_PATH": f"{prepared_collections.current_place}"}
|
1647
|
+
command = ["ansible-lint", "--offline"]
|
1648
|
+
if strict:
|
1649
|
+
command.append("--strict")
|
1650
|
+
session.run(*command, env=env)
|
1651
|
+
|
1652
|
+
ansible_lint.__doc__ = "Run ansible-lint."
|
1653
|
+
nox.session(
|
1654
|
+
name="ansible-lint",
|
1655
|
+
default=make_ansible_lint_default,
|
1656
|
+
)(ansible_lint)
|
1657
|
+
|
1658
|
+
|
1659
|
+
def add_matrix_generator() -> None:
|
1660
|
+
"""
|
1661
|
+
Add a session that generates matrixes for CI systems.
|
1662
|
+
"""
|
1663
|
+
|
1664
|
+
def matrix_generator(
|
1665
|
+
session: nox.Session, # pylint: disable=unused-argument
|
1666
|
+
) -> None:
|
1667
|
+
json_output = os.environ.get("ANTSIBULL_NOX_MATRIX_JSON")
|
1668
|
+
if json_output:
|
1669
|
+
print(f"Writing JSON output to {json_output}...")
|
1670
|
+
with open(json_output, "wt", encoding="utf-8") as f:
|
1671
|
+
f.write(json.dumps(_SESSIONS))
|
1672
|
+
|
1673
|
+
github_output = os.environ.get("GITHUB_OUTPUT")
|
1674
|
+
if github_output:
|
1675
|
+
print(f"Writing GitHub output to {github_output}...")
|
1676
|
+
with open(github_output, "at", encoding="utf-8") as f:
|
1677
|
+
for name, sessions in _SESSIONS.items():
|
1678
|
+
f.write(f"{name}={json.dumps(sessions)}\n")
|
1679
|
+
|
1680
|
+
for name, sessions in sorted(_SESSIONS.items()):
|
1681
|
+
print(f"{name} ({len(sessions)}):")
|
1682
|
+
for session_data in sessions:
|
1683
|
+
data = session_data.copy()
|
1684
|
+
session_name = data.pop("name")
|
1685
|
+
print(f" {session_name}: {data}")
|
1686
|
+
|
1687
|
+
matrix_generator.__doc__ = "Generate matrix for CI systems."
|
1688
|
+
nox.session(
|
1689
|
+
name="matrix-generator",
|
1690
|
+
python=False,
|
1691
|
+
default=False,
|
1692
|
+
)(matrix_generator)
|
1693
|
+
|
1694
|
+
|
831
1695
|
__all__ = [
|
832
1696
|
"ActionGroup",
|
833
1697
|
"add_build_import_check",
|
@@ -835,6 +1699,14 @@ __all__ = [
|
|
835
1699
|
"add_extra_checks",
|
836
1700
|
"add_license_check",
|
837
1701
|
"add_lint_sessions",
|
1702
|
+
"add_ansible_test_session",
|
1703
|
+
"add_ansible_test_sanity_test_session",
|
1704
|
+
"add_all_ansible_test_sanity_test_sessions",
|
1705
|
+
"add_ansible_test_unit_test_session",
|
1706
|
+
"add_all_ansible_test_unit_test_sessions",
|
1707
|
+
"add_ansible_test_integration_sessions_default_container",
|
1708
|
+
"add_ansible_lint",
|
1709
|
+
"add_matrix_generator",
|
838
1710
|
"install",
|
839
1711
|
"prepare_collections",
|
840
1712
|
]
|