diff options
author | Matt Clay <matt@mystile.com> | 2023-07-19 03:17:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-19 03:17:48 +0200 |
commit | e964078a83af240b103e34eafca9162deff0e16f (patch) | |
tree | e76f897ce6437efb27c6b7af357e2d7ffbaff42b /hacking | |
parent | Disable cron integration test on Alpine (#81301) (diff) | |
download | ansible-e964078a83af240b103e34eafca9162deff0e16f.tar.xz ansible-e964078a83af240b103e34eafca9162deff0e16f.zip |
ansible-test - Pre-build PyYAML wheels (#81300)
This works around Cython failures when attempting to install PyYAML >= 5.4 <= 6.0.
Diffstat (limited to 'hacking')
-rwxr-xr-x | hacking/update-sanity-requirements.py | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/hacking/update-sanity-requirements.py b/hacking/update-sanity-requirements.py index 63eaec786a..5861590bea 100755 --- a/hacking/update-sanity-requirements.py +++ b/hacking/update-sanity-requirements.py @@ -7,11 +7,15 @@ from __future__ import annotations import argparse import dataclasses import pathlib +import re import subprocess import tempfile import typing as t import venv +import packaging.version +import packaging.specifiers + try: import argcomplete except ImportError: @@ -59,7 +63,22 @@ class SanityTest: pip_freeze = subprocess.run(pip + ['freeze'] + freeze_options, 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}' + self.write_requirements(pip_freeze.stdout) + + def update_pre_build(self) -> None: + """Update requirements in place with current pre-build instructions.""" + requirements = pathlib.Path(self.requirements_path).read_text() + lines = requirements.splitlines(keepends=True) + lines = [line for line in lines if not line.startswith('#')] + requirements = ''.join(lines) + + self.write_requirements(requirements) + + def write_requirements(self, requirements: str) -> None: + """Write the given test requirements to the requirements file for this test.""" + pre_build = pre_build_instructions(requirements) + + requirements = f'# edit "{self.source_path.name}" and generate with: {SELF} --test {self.name}\n{pre_build}{requirements}' with open(self.requirements_path, 'w') as requirement_file: requirement_file.write(requirements) @@ -73,6 +92,38 @@ class SanityTest: ) +def pre_build_instructions(requirements: str) -> str: + """Parse the given requirements and return any applicable pre-build instructions.""" + parsed_requirements = requirements.splitlines() + + package_versions = { + match.group('package').lower(): match.group('version') for match + in (re.search('^(?P<package>.*)==(?P<version>.*)$', requirement) for requirement in parsed_requirements) + if match + } + + instructions: list[str] = [] + + build_constraints = ( + ('pyyaml', '>= 5.4, <= 6.0', ('Cython < 3.0',)), + ) + + for package, specifier, constraints in build_constraints: + version_string = package_versions.get(package) + + if version_string: + version = packaging.version.Version(version_string) + specifier_set = packaging.specifiers.SpecifierSet(specifier) + + if specifier_set.contains(version): + instructions.append(f'# pre-build requirement: {package} == {version}\n') + + for constraint in constraints: + instructions.append(f'# pre-build constraint: {constraint}\n') + + return ''.join(instructions) + + def main() -> None: tests = find_tests() @@ -86,6 +137,12 @@ def main() -> None: help='test requirements to update' ) + parser.add_argument( + '--pre-build-only', + action='store_true', + help='apply pre-build instructions to existing requirements', + ) + if argcomplete: argcomplete.autocomplete(parser) @@ -96,7 +153,11 @@ def main() -> None: for test in tests: print(f'===[ {test.name} ]===', flush=True) - test.freeze_requirements() + + if args.pre_build_only: + test.update_pre_build() + else: + test.freeze_requirements() def find_tests() -> t.List[SanityTest]: |