mirror of
https://github.com/ansible/ansible.git
synced 2025-12-01 07:26:10 +07:00
ansible-test - Update import test and sanity requirements. (#76308)
* Add script to freeze sanity requirements. * Declare sanity test requirements and freeze * Use pinned requirements for import.plugin test. * Expand scope of import test for ansible-core. * Add ignores for galaxy import errors. * Update test-constraints sanity test.
This commit is contained in:
@@ -29,10 +29,10 @@ recursive-include packaging *
|
|||||||
recursive-include test/ansible_test *.py Makefile
|
recursive-include test/ansible_test *.py Makefile
|
||||||
recursive-include test/integration *
|
recursive-include test/integration *
|
||||||
recursive-include test/lib/ansible_test/config *.yml *.template
|
recursive-include test/lib/ansible_test/config *.yml *.template
|
||||||
recursive-include test/lib/ansible_test/_data *.cfg *.ini *.ps1 *.txt *.yml coveragerc
|
recursive-include test/lib/ansible_test/_data *.cfg *.in *.ini *.ps1 *.txt *.yml coveragerc
|
||||||
recursive-include test/lib/ansible_test/_util *.cfg *.json *.ps1 *.psd1 *.py *.sh *.txt *.yml
|
recursive-include test/lib/ansible_test/_util *.cfg *.json *.ps1 *.psd1 *.py *.sh *.txt *.yml
|
||||||
recursive-include test/lib/ansible_test/_util/controller/sanity/validate-modules validate-modules
|
recursive-include test/lib/ansible_test/_util/controller/sanity/validate-modules validate-modules
|
||||||
recursive-include test/sanity *.json *.py *.txt
|
recursive-include test/sanity *.in *.json *.py *.txt
|
||||||
recursive-include test/support *.py *.ps1 *.psm1 *.cs
|
recursive-include test/support *.py *.ps1 *.psm1 *.cs
|
||||||
exclude test/sanity/code-smell/botmeta.*
|
exclude test/sanity/code-smell/botmeta.*
|
||||||
exclude test/sanity/code-smell/release-names.*
|
exclude test/sanity/code-smell/release-names.*
|
||||||
@@ -46,4 +46,5 @@ include changelogs/changelog.yaml
|
|||||||
recursive-include hacking/build_library *.py
|
recursive-include hacking/build_library *.py
|
||||||
include hacking/build-ansible.py
|
include hacking/build-ansible.py
|
||||||
include hacking/test-module.py
|
include hacking/test-module.py
|
||||||
|
include hacking/update-sanity-requirements.py
|
||||||
include bin/*
|
include bin/*
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
minor_changes:
|
||||||
|
- ansible-test - Declare public dependencies of ansible-core and use to limit unguarded imports in plugins.
|
||||||
|
- ansible-test - Requirements for the plugin import test are now frozen.
|
||||||
|
- ansible-test - Update sanity test requirements.
|
||||||
@@ -60,9 +60,15 @@ Ansible allows the following unchecked imports from these specific directories:
|
|||||||
* ansible-core:
|
* ansible-core:
|
||||||
|
|
||||||
* For ``lib/ansible/modules/`` and ``lib/ansible/module_utils/``, unchecked imports are only allowed from the Python standard library;
|
* For ``lib/ansible/modules/`` and ``lib/ansible/module_utils/``, unchecked imports are only allowed from the Python standard library;
|
||||||
* For ``lib/ansible/plugins/``, unchecked imports are only allowed from the Python standard library, from dependencies of ansible-core, and from ansible-core itself;
|
* For ``lib/ansible/plugins/``, unchecked imports are only allowed from the Python standard library, from public dependencies of ansible-core, and from ansible-core itself;
|
||||||
|
|
||||||
* collections:
|
* collections:
|
||||||
|
|
||||||
* For ``plugins/modules/`` and ``plugins/module_utils/``, unchecked imports are only allowed from the Python standard library;
|
* For ``plugins/modules/`` and ``plugins/module_utils/``, unchecked imports are only allowed from the Python standard library;
|
||||||
* For other directories in ``plugins/`` (see `the community collection requirements <https://github.com/ansible-collections/overview/blob/main/collection_requirements.rst#modules-plugins>`_ for a list), unchecked imports are only allowed from the Python standard library, from dependencies of ansible-core, and from ansible-core itself.
|
* For other directories in ``plugins/`` (see `the community collection requirements <https://github.com/ansible-collections/overview/blob/main/collection_requirements.rst#modules-plugins>`_ for a list), unchecked imports are only allowed from the Python standard library, from public dependencies of ansible-core, and from ansible-core itself.
|
||||||
|
|
||||||
|
Public dependencies of ansible-core are:
|
||||||
|
|
||||||
|
* Jinja2
|
||||||
|
* PyYAML
|
||||||
|
* MarkupSafe (as a dependency of Jinja2)
|
||||||
|
|||||||
112
hacking/update-sanity-requirements.py
Executable file
112
hacking/update-sanity-requirements.py
Executable file
@@ -0,0 +1,112 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# PYTHON_ARGCOMPLETE_OK
|
||||||
|
"""Generate frozen sanity test requirements from source requirements files."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import dataclasses
|
||||||
|
import pathlib
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
import typing as t
|
||||||
|
import venv
|
||||||
|
|
||||||
|
try:
|
||||||
|
import argcomplete
|
||||||
|
except ImportError:
|
||||||
|
argcomplete = None
|
||||||
|
|
||||||
|
|
||||||
|
FILE = pathlib.Path(__file__).resolve()
|
||||||
|
ROOT = FILE.parent.parent
|
||||||
|
SELF = FILE.relative_to(ROOT)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass(frozen=True)
|
||||||
|
class SanityTest:
|
||||||
|
name: str
|
||||||
|
requirements_path: pathlib.Path
|
||||||
|
source_path: pathlib.Path
|
||||||
|
|
||||||
|
def freeze_requirements(self) -> None:
|
||||||
|
with tempfile.TemporaryDirectory() as venv_dir:
|
||||||
|
venv.create(venv_dir, with_pip=True)
|
||||||
|
|
||||||
|
python = pathlib.Path(venv_dir, 'bin', 'python')
|
||||||
|
pip = [python, '-m', 'pip', '--disable-pip-version-check']
|
||||||
|
env = dict()
|
||||||
|
|
||||||
|
pip_freeze = subprocess.run(pip + ['freeze'], env=env, check=True, capture_output=True, text=True)
|
||||||
|
|
||||||
|
if pip_freeze.stdout:
|
||||||
|
raise Exception(f'Initial virtual environment is not empty:\n{pip_freeze.stdout}')
|
||||||
|
|
||||||
|
subprocess.run(pip + ['install', 'wheel'], env=env, check=True) # make bdist_wheel available during pip install
|
||||||
|
subprocess.run(pip + ['install', '-r', self.source_path], env=env, check=True)
|
||||||
|
|
||||||
|
pip_freeze = subprocess.run(pip + ['freeze'], env=env, check=True, capture_output=True, text=True)
|
||||||
|
|
||||||
|
requirements = f'# edit "{self.source_path.name}" and generate with: {SELF} --test {self.name}\n{pip_freeze.stdout}'
|
||||||
|
|
||||||
|
with open(self.requirements_path, 'w') as requirement_file:
|
||||||
|
requirement_file.write(requirements)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create(path: pathlib.Path) -> SanityTest:
|
||||||
|
return SanityTest(
|
||||||
|
name=path.stem.replace('sanity.', '').replace('.requirements', ''),
|
||||||
|
requirements_path=path,
|
||||||
|
source_path=path.with_suffix('.in'),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
tests = find_tests()
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument(
|
||||||
|
'--test',
|
||||||
|
metavar='TEST',
|
||||||
|
dest='test_names',
|
||||||
|
action='append',
|
||||||
|
choices=[test.name for test in tests],
|
||||||
|
help='test requirements to update'
|
||||||
|
)
|
||||||
|
|
||||||
|
if argcomplete:
|
||||||
|
argcomplete.autocomplete(parser)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
test_names: set[str] = set(args.test_names or [])
|
||||||
|
|
||||||
|
tests = [test for test in tests if test.name in test_names] if test_names else tests
|
||||||
|
|
||||||
|
for test in tests:
|
||||||
|
print(f'===[ {test.name} ]===')
|
||||||
|
test.freeze_requirements()
|
||||||
|
|
||||||
|
|
||||||
|
def find_tests() -> t.List[SanityTest]:
|
||||||
|
globs = (
|
||||||
|
'test/lib/ansible_test/_data/requirements/sanity.*.txt',
|
||||||
|
'test/sanity/code-smell/*.requirements.txt',
|
||||||
|
)
|
||||||
|
|
||||||
|
tests: t.List[SanityTest] = []
|
||||||
|
|
||||||
|
for glob in globs:
|
||||||
|
tests.extend(get_tests(pathlib.Path(glob)))
|
||||||
|
|
||||||
|
return sorted(tests, key=lambda test: test.name)
|
||||||
|
|
||||||
|
|
||||||
|
def get_tests(glob: pathlib.Path) -> t.List[SanityTest]:
|
||||||
|
path = pathlib.Path(ROOT, glob.parent)
|
||||||
|
pattern = glob.name
|
||||||
|
|
||||||
|
return [SanityTest.create(item) for item in path.glob(pattern)]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
jinja2 # ansible-core requirement
|
||||||
|
packaging # ansible-core requirement
|
||||||
|
pyyaml # ansible-core requirement
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
jinja2 == 3.0.1 # ansible-core requirement
|
# edit "sanity.ansible-doc.in" and generate with: hacking/update-sanity-requirements.py --test ansible-doc
|
||||||
pyyaml == 5.4.1 # ansible-core requirement
|
Jinja2==3.0.3
|
||||||
packaging == 21.0 # ansible-doc requirement
|
MarkupSafe==2.0.1
|
||||||
|
packaging==21.2
|
||||||
# dependencies
|
pyparsing==2.4.7
|
||||||
MarkupSafe == 2.0.1
|
PyYAML==6.0
|
||||||
pyparsing == 2.4.7
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
antsibull-changelog
|
||||||
|
docutils < 0.18 # match version required by sphinx in the docs-build sanity test
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
antsibull-changelog == 0.9.0
|
# edit "sanity.changelog.in" and generate with: hacking/update-sanity-requirements.py --test changelog
|
||||||
|
antsibull-changelog==0.12.0
|
||||||
# dependencies
|
docutils==0.17.1
|
||||||
pyyaml == 5.4.1
|
packaging==21.2
|
||||||
docutils == 0.17.1
|
pyparsing==2.4.7
|
||||||
packaging == 21.0
|
PyYAML==6.0
|
||||||
pyparsing == 2.4.7
|
rstcheck==3.3.1
|
||||||
rstcheck == 3.3.1
|
semantic-version==2.8.5
|
||||||
semantic-version == 2.8.5
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
pyyaml # needed for yaml_to_json.py
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
jinja2 # ansible-core requirement
|
||||||
|
pyyaml # ansible-core requirement
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# edit "sanity.import.plugin.in" and generate with: hacking/update-sanity-requirements.py --test import.plugin
|
||||||
|
Jinja2==3.0.3
|
||||||
|
MarkupSafe==2.0.1
|
||||||
|
PyYAML==6.0
|
||||||
@@ -1 +1,2 @@
|
|||||||
pyyaml == 5.4.1 # needed for yaml_to_json.py
|
# edit "sanity.import.in" and generate with: hacking/update-sanity-requirements.py --test import
|
||||||
|
PyYAML==6.0
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
pyyaml
|
||||||
@@ -1 +1,2 @@
|
|||||||
pyyaml == 5.4.1
|
# edit "sanity.integration-aliases.in" and generate with: hacking/update-sanity-requirements.py --test integration-aliases
|
||||||
|
PyYAML==6.0
|
||||||
|
|||||||
1
test/lib/ansible_test/_data/requirements/sanity.pep8.in
Normal file
1
test/lib/ansible_test/_data/requirements/sanity.pep8.in
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pycodestyle
|
||||||
@@ -1 +1,2 @@
|
|||||||
pycodestyle == 2.6.0
|
# edit "sanity.pep8.in" and generate with: hacking/update-sanity-requirements.py --test pep8
|
||||||
|
pycodestyle==2.8.0
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
pylint == 2.9.3 # currently vetted version
|
||||||
|
pyyaml # needed for collection_detail.py
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
pylint == 2.9.3
|
# edit "sanity.pylint.in" and generate with: hacking/update-sanity-requirements.py --test pylint
|
||||||
pyyaml == 5.4.1 # needed for collection_detail.py
|
astroid==2.6.6
|
||||||
|
isort==5.10.1
|
||||||
# dependencies
|
lazy-object-proxy==1.6.0
|
||||||
astroid == 2.6.6
|
mccabe==0.6.1
|
||||||
isort == 5.9.3
|
pylint==2.9.3
|
||||||
lazy-object-proxy == 1.6.0
|
PyYAML==6.0
|
||||||
mccabe == 0.6.1
|
toml==0.10.2
|
||||||
toml == 0.10.2
|
wrapt==1.12.1
|
||||||
wrapt == 1.12.1
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
pyyaml
|
||||||
|
voluptuous
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
pyyaml == 5.4.1
|
# edit "sanity.runtime-metadata.in" and generate with: hacking/update-sanity-requirements.py --test runtime-metadata
|
||||||
voluptuous == 0.12.1
|
PyYAML==6.0
|
||||||
|
voluptuous==0.12.2
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
jinja2 # ansible-core requirement
|
||||||
|
pyyaml # needed for collection_detail.py
|
||||||
|
voluptuous
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
jinja2 == 3.0.1 # ansible-core requirement
|
# edit "sanity.validate-modules.in" and generate with: hacking/update-sanity-requirements.py --test validate-modules
|
||||||
pyyaml == 5.4.1 # needed for collection_detail.py
|
Jinja2==3.0.3
|
||||||
voluptuous == 0.12.1
|
MarkupSafe==2.0.1
|
||||||
|
PyYAML==6.0
|
||||||
# dependencies
|
voluptuous==0.12.2
|
||||||
MarkupSafe == 2.0.1
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
yamllint
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
yamllint == 1.26.0
|
# edit "sanity.yamllint.in" and generate with: hacking/update-sanity-requirements.py --test yamllint
|
||||||
|
pathspec==0.9.0
|
||||||
# dependencies
|
PyYAML==6.0
|
||||||
pathspec == 0.9.0
|
yamllint==1.26.3
|
||||||
pyyaml == 5.4.1
|
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ def command_sanity(args): # type: (SanityConfig) -> None
|
|||||||
elif isinstance(test, SanitySingleVersion):
|
elif isinstance(test, SanitySingleVersion):
|
||||||
# single version sanity tests use the controller python
|
# single version sanity tests use the controller python
|
||||||
test_profile = host_state.controller_profile
|
test_profile = host_state.controller_profile
|
||||||
virtualenv_python = create_sanity_virtualenv(args, test_profile.python, test.name, context=test.name)
|
virtualenv_python = create_sanity_virtualenv(args, test_profile.python, test.name)
|
||||||
|
|
||||||
if virtualenv_python:
|
if virtualenv_python:
|
||||||
virtualenv_yaml = check_sanity_virtualenv_yaml(virtualenv_python)
|
virtualenv_yaml = check_sanity_virtualenv_yaml(virtualenv_python)
|
||||||
@@ -1077,10 +1077,8 @@ def create_sanity_virtualenv(
|
|||||||
args, # type: SanityConfig
|
args, # type: SanityConfig
|
||||||
python, # type: PythonConfig
|
python, # type: PythonConfig
|
||||||
name, # type: str
|
name, # type: str
|
||||||
ansible=False, # type: bool
|
|
||||||
coverage=False, # type: bool
|
coverage=False, # type: bool
|
||||||
minimize=False, # type: bool
|
minimize=False, # type: bool
|
||||||
context=None, # type: t.Optional[str]
|
|
||||||
): # type: (...) -> t.Optional[VirtualPythonConfig]
|
): # type: (...) -> t.Optional[VirtualPythonConfig]
|
||||||
"""Return an existing sanity virtual environment matching the requested parameters or create a new one."""
|
"""Return an existing sanity virtual environment matching the requested parameters or create a new one."""
|
||||||
commands = collect_requirements( # create_sanity_virtualenv()
|
commands = collect_requirements( # create_sanity_virtualenv()
|
||||||
@@ -1088,13 +1086,11 @@ def create_sanity_virtualenv(
|
|||||||
controller=True,
|
controller=True,
|
||||||
virtualenv=False,
|
virtualenv=False,
|
||||||
command=None,
|
command=None,
|
||||||
# used by import tests
|
ansible=False,
|
||||||
ansible=ansible,
|
cryptography=False,
|
||||||
cryptography=ansible,
|
|
||||||
coverage=coverage,
|
coverage=coverage,
|
||||||
minimize=minimize,
|
minimize=minimize,
|
||||||
# used by non-import tests
|
sanity=name,
|
||||||
sanity=context,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if commands:
|
if commands:
|
||||||
|
|||||||
@@ -87,8 +87,17 @@ class ImportTest(SanityMultipleVersion):
|
|||||||
"""Sanity test for proper import exception handling."""
|
"""Sanity test for proper import exception handling."""
|
||||||
def filter_targets(self, targets): # type: (t.List[TestTarget]) -> t.List[TestTarget]
|
def filter_targets(self, targets): # type: (t.List[TestTarget]) -> t.List[TestTarget]
|
||||||
"""Return the given list of test targets, filtered to include only those relevant for the test."""
|
"""Return the given list of test targets, filtered to include only those relevant for the test."""
|
||||||
|
if data_context().content.is_ansible:
|
||||||
|
# all of ansible-core must pass the import test, not just plugins/modules
|
||||||
|
# modules/module_utils will be tested using the module context
|
||||||
|
# everything else will be tested using the plugin context
|
||||||
|
paths = ['lib/ansible']
|
||||||
|
else:
|
||||||
|
# only plugins/modules must pass the import test for collections
|
||||||
|
paths = list(data_context().content.plugin_paths.values())
|
||||||
|
|
||||||
return [target for target in targets if os.path.splitext(target.path)[1] == '.py' and
|
return [target for target in targets if os.path.splitext(target.path)[1] == '.py' and
|
||||||
any(is_subdir(target.path, path) for path in data_context().content.plugin_paths.values())]
|
any(is_subdir(target.path, path) for path in paths)]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def needs_pypi(self): # type: () -> bool
|
def needs_pypi(self): # type: () -> bool
|
||||||
@@ -112,9 +121,9 @@ class ImportTest(SanityMultipleVersion):
|
|||||||
|
|
||||||
messages = []
|
messages = []
|
||||||
|
|
||||||
for import_type, test, controller in (
|
for import_type, test in (
|
||||||
('module', _get_module_test(True), False),
|
('module', _get_module_test(True)),
|
||||||
('plugin', _get_module_test(False), True),
|
('plugin', _get_module_test(False)),
|
||||||
):
|
):
|
||||||
if import_type == 'plugin' and python.version in REMOTE_ONLY_PYTHON_VERSIONS:
|
if import_type == 'plugin' and python.version in REMOTE_ONLY_PYTHON_VERSIONS:
|
||||||
continue
|
continue
|
||||||
@@ -124,7 +133,7 @@ class ImportTest(SanityMultipleVersion):
|
|||||||
if not data and not args.prime_venvs:
|
if not data and not args.prime_venvs:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
virtualenv_python = create_sanity_virtualenv(args, python, f'{self.name}.{import_type}', ansible=controller, coverage=args.coverage, minimize=True)
|
virtualenv_python = create_sanity_virtualenv(args, python, f'{self.name}.{import_type}', coverage=args.coverage, minimize=True)
|
||||||
|
|
||||||
if not virtualenv_python:
|
if not virtualenv_python:
|
||||||
display.warning(f'Skipping sanity test "{self.name}" on Python {python.version} due to missing virtual environment support.')
|
display.warning(f'Skipping sanity test "{self.name}" on Python {python.version} due to missing virtual environment support.')
|
||||||
@@ -143,7 +152,7 @@ class ImportTest(SanityMultipleVersion):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if data_context().content.collection:
|
if data_context().content.collection:
|
||||||
external_python = create_sanity_virtualenv(args, args.controller_python, self.name, context=self.name)
|
external_python = create_sanity_virtualenv(args, args.controller_python, self.name)
|
||||||
|
|
||||||
env.update(
|
env.update(
|
||||||
SANITY_COLLECTION_FULL_NAME=data_context().content.collection.full_name,
|
SANITY_COLLECTION_FULL_NAME=data_context().content.collection.full_name,
|
||||||
|
|||||||
2
test/sanity/code-smell/botmeta.requirements.in
Normal file
2
test/sanity/code-smell/botmeta.requirements.in
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
pyyaml
|
||||||
|
voluptuous
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
pyyaml == 5.4.1
|
# edit "botmeta.requirements.in" and generate with: hacking/update-sanity-requirements.py --test botmeta
|
||||||
voluptuous == 0.12.1
|
PyYAML==6.0
|
||||||
|
voluptuous==0.12.2
|
||||||
|
|||||||
2
test/sanity/code-smell/deprecated-config.requirements.in
Normal file
2
test/sanity/code-smell/deprecated-config.requirements.in
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
jinja2 # ansible-core requirement
|
||||||
|
pyyaml
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
jinja2 == 3.0.1 # ansible-core requirement
|
# edit "deprecated-config.requirements.in" and generate with: hacking/update-sanity-requirements.py --test deprecated-config
|
||||||
pyyaml == 5.4.1
|
Jinja2==3.0.3
|
||||||
|
MarkupSafe==2.0.1
|
||||||
# dependencies
|
PyYAML==6.0
|
||||||
MarkupSafe == 2.0.1
|
|
||||||
|
|||||||
8
test/sanity/code-smell/docs-build.requirements.in
Normal file
8
test/sanity/code-smell/docs-build.requirements.in
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
jinja2
|
||||||
|
pyyaml
|
||||||
|
resolvelib < 0.6.0
|
||||||
|
sphinx == 4.2.0
|
||||||
|
sphinx-notfound-page
|
||||||
|
sphinx-ansible-theme
|
||||||
|
straight.plugin
|
||||||
|
antsibull
|
||||||
@@ -1,50 +1,50 @@
|
|||||||
jinja2 == 3.0.1
|
# edit "docs-build.requirements.in" and generate with: hacking/update-sanity-requirements.py --test docs-build
|
||||||
pyyaml == 5.4.1
|
aiofiles==0.7.0
|
||||||
resolvelib == 0.5.4
|
aiohttp==3.8.0
|
||||||
sphinx == 2.1.2
|
aiosignal==1.2.0
|
||||||
sphinx-notfound-page == 0.7.1
|
alabaster==0.7.12
|
||||||
sphinx-ansible-theme == 0.8.0
|
ansible-pygments==0.1.0
|
||||||
straight.plugin == 1.5.0
|
antsibull==0.39.2
|
||||||
antsibull == 0.26.0
|
antsibull-changelog==0.12.0
|
||||||
|
async-timeout==4.0.1
|
||||||
# dependencies
|
asyncio-pool==0.5.2
|
||||||
MarkupSafe == 2.0.1
|
attrs==21.2.0
|
||||||
aiofiles == 0.7.0
|
Babel==2.9.1
|
||||||
aiohttp == 3.7.4.post0
|
certifi==2021.10.8
|
||||||
alabaster == 0.7.12
|
charset-normalizer==2.0.7
|
||||||
ansible-pygments == 0.1.0
|
docutils==0.17.1
|
||||||
antsibull-changelog == 0.9.0
|
frozenlist==1.2.0
|
||||||
async-timeout == 3.0.1
|
idna==3.3
|
||||||
asyncio-pool == 0.5.2
|
imagesize==1.3.0
|
||||||
attrs == 21.2.0
|
Jinja2==3.0.3
|
||||||
babel == 2.9.1
|
MarkupSafe==2.0.1
|
||||||
certifi == 2021.5.30
|
multidict==5.2.0
|
||||||
chardet == 4.0.0
|
packaging==21.2
|
||||||
charset-normalizer == 2.0.5
|
perky==0.5.5
|
||||||
docutils == 0.17.1
|
pydantic==1.8.2
|
||||||
idna == 2.5
|
Pygments==2.10.0
|
||||||
imagesize == 1.2.0
|
pyparsing==2.4.7
|
||||||
multidict == 5.1.0
|
pytz==2021.3
|
||||||
packaging == 21.0
|
PyYAML==6.0
|
||||||
perky == 0.5.5
|
requests==2.26.0
|
||||||
pydantic == 1.8.2
|
resolvelib==0.5.4
|
||||||
pygments == 2.10.0
|
rstcheck==3.3.1
|
||||||
pyparsing == 2.4.7
|
semantic-version==2.8.5
|
||||||
pytz == 2021.1
|
sh==1.14.2
|
||||||
requests == 2.26.0
|
six==1.16.0
|
||||||
rstcheck == 3.3.1
|
snowballstemmer==2.1.0
|
||||||
semantic-version == 2.8.5
|
Sphinx==4.2.0
|
||||||
sh == 1.14.2
|
sphinx-ansible-theme==0.8.0
|
||||||
six == 1.16.0
|
sphinx-notfound-page==0.8
|
||||||
snowballstemmer == 2.1.0
|
sphinx-rtd-theme==1.0.0
|
||||||
sphinx-rtd-theme == 1.0.0
|
sphinxcontrib-applehelp==1.0.2
|
||||||
sphinxcontrib-applehelp == 1.0.2
|
sphinxcontrib-devhelp==1.0.2
|
||||||
sphinxcontrib-devhelp == 1.0.2
|
sphinxcontrib-htmlhelp==2.0.0
|
||||||
sphinxcontrib-htmlhelp == 2.0.0
|
sphinxcontrib-jsmath==1.0.1
|
||||||
sphinxcontrib-jsmath == 1.0.1
|
sphinxcontrib-qthelp==1.0.3
|
||||||
sphinxcontrib-qthelp == 1.0.3
|
sphinxcontrib-serializinghtml==1.1.5
|
||||||
sphinxcontrib-serializinghtml == 1.1.5
|
straight.plugin==1.5.0
|
||||||
twiggy == 0.5.1
|
Twiggy==0.5.1
|
||||||
typing-extensions == 3.10.0.2
|
typing-extensions==3.10.0.2
|
||||||
urllib3 == 1.26.6
|
urllib3==1.26.7
|
||||||
yarl == 1.6.3
|
yarl==1.7.2
|
||||||
|
|||||||
7
test/sanity/code-smell/package-data.requirements.in
Normal file
7
test/sanity/code-smell/package-data.requirements.in
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
docutils < 0.18 # match version required by sphinx in the docs-build sanity test
|
||||||
|
jinja2
|
||||||
|
pyyaml # ansible-core requirement
|
||||||
|
resolvelib < 0.6.0
|
||||||
|
rstcheck
|
||||||
|
straight.plugin
|
||||||
|
antsibull-changelog
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
docutils == 0.17.1
|
# edit "package-data.requirements.in" and generate with: hacking/update-sanity-requirements.py --test package-data
|
||||||
jinja2 == 3.0.1
|
antsibull-changelog==0.12.0
|
||||||
packaging == 21.0
|
docutils==0.17.1
|
||||||
pyyaml == 5.4.1 # ansible-core requirement
|
Jinja2==3.0.3
|
||||||
resolvelib == 0.5.4 # ansible-core requirement
|
MarkupSafe==2.0.1
|
||||||
rstcheck == 3.3.1
|
packaging==21.2
|
||||||
straight.plugin == 1.5.0
|
pyparsing==2.4.7
|
||||||
antsibull-changelog == 0.9.0
|
PyYAML==6.0
|
||||||
|
resolvelib==0.5.4
|
||||||
# dependencies
|
rstcheck==3.3.1
|
||||||
MarkupSafe == 2.0.1
|
semantic-version==2.8.5
|
||||||
pyparsing == 2.4.7
|
straight.plugin==1.5.0
|
||||||
semantic-version == 2.8.5
|
|
||||||
|
|||||||
1
test/sanity/code-smell/release-names.requirements.in
Normal file
1
test/sanity/code-smell/release-names.requirements.in
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pyyaml
|
||||||
@@ -1 +1,2 @@
|
|||||||
pyyaml == 5.4.1
|
# edit "release-names.requirements.in" and generate with: hacking/update-sanity-requirements.py --test release-names
|
||||||
|
PyYAML==6.0
|
||||||
|
|||||||
3
test/sanity/code-smell/rstcheck.requirements.in
Normal file
3
test/sanity/code-smell/rstcheck.requirements.in
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
sphinx == 4.2.0 # required for full rstcheck functionality, installed first to get the correct docutils version
|
||||||
|
rstcheck
|
||||||
|
jinja2 # ansible-core requirement
|
||||||
@@ -1,27 +1,25 @@
|
|||||||
rstcheck == 3.3.1
|
# edit "rstcheck.requirements.in" and generate with: hacking/update-sanity-requirements.py --test rstcheck
|
||||||
sphinx == 2.1.2 # required for full functionality
|
alabaster==0.7.12
|
||||||
|
Babel==2.9.1
|
||||||
# dependencies
|
certifi==2021.10.8
|
||||||
Jinja2 == 3.0.1
|
charset-normalizer==2.0.7
|
||||||
MarkupSafe == 2.0.1
|
docutils==0.17.1
|
||||||
Pygments == 2.10.0
|
idna==3.3
|
||||||
alabaster == 0.7.12
|
imagesize==1.3.0
|
||||||
babel == 2.9.1
|
Jinja2==3.0.3
|
||||||
certifi == 2021.5.30
|
MarkupSafe==2.0.1
|
||||||
charset-normalizer == 2.0.5
|
packaging==21.2
|
||||||
docutils == 0.17.1
|
Pygments==2.10.0
|
||||||
idna == 2.5
|
pyparsing==2.4.7
|
||||||
imagesize == 1.2.0
|
pytz==2021.3
|
||||||
packaging == 21.0
|
requests==2.26.0
|
||||||
pyparsing == 2.4.7
|
rstcheck==3.3.1
|
||||||
pytz == 2021.1
|
snowballstemmer==2.1.0
|
||||||
requests == 2.26.0
|
Sphinx==4.2.0
|
||||||
rstcheck == 3.3.1
|
sphinxcontrib-applehelp==1.0.2
|
||||||
snowballstemmer == 2.1.0
|
sphinxcontrib-devhelp==1.0.2
|
||||||
sphinxcontrib-applehelp == 1.0.2
|
sphinxcontrib-htmlhelp==2.0.0
|
||||||
sphinxcontrib-devhelp == 1.0.2
|
sphinxcontrib-jsmath==1.0.1
|
||||||
sphinxcontrib-htmlhelp == 2.0.0
|
sphinxcontrib-qthelp==1.0.3
|
||||||
sphinxcontrib-jsmath == 1.0.1
|
sphinxcontrib-serializinghtml==1.1.5
|
||||||
sphinxcontrib-qthelp == 1.0.3
|
urllib3==1.26.7
|
||||||
sphinxcontrib-serializinghtml == 1.1.5
|
|
||||||
urllib3 == 1.26.6
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@@ -21,6 +22,11 @@ def main():
|
|||||||
non_sanity_requirements = set()
|
non_sanity_requirements = set()
|
||||||
|
|
||||||
for path, requirements in requirements.items():
|
for path, requirements in requirements.items():
|
||||||
|
filename = os.path.basename(path)
|
||||||
|
|
||||||
|
is_sanity = filename.startswith('sanity.') or filename.endswith('.requirements.txt')
|
||||||
|
is_constraints = path == constraints_path
|
||||||
|
|
||||||
for lineno, line, requirement in requirements:
|
for lineno, line, requirement in requirements:
|
||||||
if not requirement:
|
if not requirement:
|
||||||
print('%s:%d:%d: cannot parse requirement: %s' % (path, lineno, 1, line))
|
print('%s:%d:%d: cannot parse requirement: %s' % (path, lineno, 1, line))
|
||||||
@@ -28,14 +34,10 @@ def main():
|
|||||||
|
|
||||||
name = requirement.group('name').lower()
|
name = requirement.group('name').lower()
|
||||||
raw_constraints = requirement.group('constraints')
|
raw_constraints = requirement.group('constraints')
|
||||||
raw_markers = requirement.group('markers')
|
|
||||||
constraints = raw_constraints.strip()
|
constraints = raw_constraints.strip()
|
||||||
markers = raw_markers.strip()
|
|
||||||
comment = requirement.group('comment')
|
comment = requirement.group('comment')
|
||||||
|
|
||||||
is_sanity = path.startswith('test/lib/ansible_test/_data/requirements/sanity.') or path.startswith('test/sanity/code-smell/')
|
|
||||||
is_pinned = re.search('^ *== *[0-9.]+(\\.post[0-9]+)?$', constraints)
|
is_pinned = re.search('^ *== *[0-9.]+(\\.post[0-9]+)?$', constraints)
|
||||||
is_constraints = path == constraints_path
|
|
||||||
|
|
||||||
if is_sanity:
|
if is_sanity:
|
||||||
sanity = frozen_sanity.setdefault(name, [])
|
sanity = frozen_sanity.setdefault(name, [])
|
||||||
@@ -43,20 +45,19 @@ def main():
|
|||||||
elif not is_constraints:
|
elif not is_constraints:
|
||||||
non_sanity_requirements.add(name)
|
non_sanity_requirements.add(name)
|
||||||
|
|
||||||
|
if is_sanity:
|
||||||
|
if not is_pinned:
|
||||||
|
# sanity test requirements must be pinned
|
||||||
|
print('%s:%d:%d: sanity test requirement (%s%s) must be frozen (use `==`)' % (path, lineno, 1, name, raw_constraints))
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
if constraints and not is_constraints:
|
if constraints and not is_constraints:
|
||||||
allow_constraints = 'sanity_ok' in comment
|
allow_constraints = 'sanity_ok' in comment
|
||||||
|
|
||||||
if is_sanity and is_pinned and not markers:
|
|
||||||
allow_constraints = True # sanity tests can use frozen requirements without markers
|
|
||||||
|
|
||||||
if not allow_constraints:
|
if not allow_constraints:
|
||||||
if is_sanity:
|
# keeping constraints for tests other than sanity tests in one file helps avoid conflicts
|
||||||
# sanity test requirements which need constraints should be frozen to maintain consistent test results
|
print('%s:%d:%d: put the constraint (%s%s) in `%s`' % (path, lineno, 1, name, raw_constraints, constraints_path))
|
||||||
# use of anything other than frozen constraints will make evaluation of conflicts extremely difficult
|
|
||||||
print('%s:%d:%d: sanity test constraint (%s%s) must be frozen (use `==`)' % (path, lineno, 1, name, raw_constraints))
|
|
||||||
else:
|
|
||||||
# keeping constraints for tests other than sanity tests in one file helps avoid conflicts
|
|
||||||
print('%s:%d:%d: put the constraint (%s%s) in `%s`' % (path, lineno, 1, name, raw_constraints, constraints_path))
|
|
||||||
|
|
||||||
for name, requirements in frozen_sanity.items():
|
for name, requirements in frozen_sanity.items():
|
||||||
if len(set(req[3].group('constraints').strip() for req in requirements)) != 1:
|
if len(set(req[3].group('constraints').strip() for req in requirements)) != 1:
|
||||||
|
|||||||
1
test/sanity/code-smell/update-bundled.requirements.in
Normal file
1
test/sanity/code-smell/update-bundled.requirements.in
Normal file
@@ -0,0 +1 @@
|
|||||||
|
packaging
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
packaging == 21.0
|
# edit "update-bundled.requirements.in" and generate with: hacking/update-sanity-requirements.py --test update-bundled
|
||||||
|
packaging==21.2
|
||||||
# dependencies
|
pyparsing==2.4.7
|
||||||
pyparsing == 2.4.7
|
|
||||||
|
|||||||
@@ -4,6 +4,39 @@ docs/docsite/rst/locales/ja/LC_MESSAGES/dev_guide.po no-smart-quotes # Translat
|
|||||||
examples/scripts/ConfigureRemotingForAnsible.ps1 pslint:PSCustomUseLiteralPath
|
examples/scripts/ConfigureRemotingForAnsible.ps1 pslint:PSCustomUseLiteralPath
|
||||||
examples/scripts/upgrade_to_ps3.ps1 pslint:PSCustomUseLiteralPath
|
examples/scripts/upgrade_to_ps3.ps1 pslint:PSCustomUseLiteralPath
|
||||||
examples/scripts/upgrade_to_ps3.ps1 pslint:PSUseApprovedVerbs
|
examples/scripts/upgrade_to_ps3.ps1 pslint:PSUseApprovedVerbs
|
||||||
|
lib/ansible/cli/galaxy.py import-3.8 # unguarded indirect resolvelib import
|
||||||
|
lib/ansible/galaxy/collection/__init__.py import-3.8 # unguarded resolvelib import
|
||||||
|
lib/ansible/galaxy/collection/concrete_artifact_manager.py import-3.8 # unguarded resolvelib import
|
||||||
|
lib/ansible/galaxy/collection/galaxy_api_proxy.py import-3.8 # unguarded resolvelib imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/__init__.py import-3.8 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/dataclasses.py import-3.8 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/errors.py import-3.8 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/providers.py import-3.8 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/reporters.py import-3.8 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/resolvers.py import-3.8 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/versioning.py import-3.8 # circular imports
|
||||||
|
lib/ansible/cli/galaxy.py import-3.9 # unguarded indirect resolvelib import
|
||||||
|
lib/ansible/galaxy/collection/__init__.py import-3.9 # unguarded resolvelib import
|
||||||
|
lib/ansible/galaxy/collection/concrete_artifact_manager.py import-3.9 # unguarded resolvelib import
|
||||||
|
lib/ansible/galaxy/collection/galaxy_api_proxy.py import-3.9 # unguarded resolvelib imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/__init__.py import-3.9 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/dataclasses.py import-3.9 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/errors.py import-3.9 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/providers.py import-3.9 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/reporters.py import-3.9 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/resolvers.py import-3.9 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/versioning.py import-3.9 # circular imports
|
||||||
|
lib/ansible/cli/galaxy.py import-3.10 # unguarded indirect resolvelib import
|
||||||
|
lib/ansible/galaxy/collection/__init__.py import-3.10 # unguarded resolvelib import
|
||||||
|
lib/ansible/galaxy/collection/concrete_artifact_manager.py import-3.10 # unguarded resolvelib import
|
||||||
|
lib/ansible/galaxy/collection/galaxy_api_proxy.py import-3.10 # unguarded resolvelib imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/__init__.py import-3.10 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/dataclasses.py import-3.10 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/errors.py import-3.10 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/providers.py import-3.10 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/reporters.py import-3.10 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/resolvers.py import-3.10 # circular imports
|
||||||
|
lib/ansible/galaxy/dependency_resolution/versioning.py import-3.10 # circular imports
|
||||||
lib/ansible/cli/scripts/ansible_connection_cli_stub.py shebang
|
lib/ansible/cli/scripts/ansible_connection_cli_stub.py shebang
|
||||||
lib/ansible/config/base.yml no-unwanted-files
|
lib/ansible/config/base.yml no-unwanted-files
|
||||||
lib/ansible/executor/playbook_executor.py pylint:disallowed-name
|
lib/ansible/executor/playbook_executor.py pylint:disallowed-name
|
||||||
|
|||||||
Reference in New Issue
Block a user