From dcc9a7c8470a62b615a24341331e9455fadbfd65 Mon Sep 17 00:00:00 2001 From: Dorian Turba <froggit.commit.z3jqj@simplelogin.com> Date: Sun, 10 Sep 2023 14:05:33 +0200 Subject: [PATCH] use requirement-compare --- .../depandabot/compare.py | 150 ------------------ .../depandabot/depandabot.yml | 4 +- 2 files changed, 2 insertions(+), 152 deletions(-) delete mode 100644 templates/python/dependency_management/depandabot/compare.py diff --git a/templates/python/dependency_management/depandabot/compare.py b/templates/python/dependency_management/depandabot/compare.py deleted file mode 100644 index 22462d2..0000000 --- a/templates/python/dependency_management/depandabot/compare.py +++ /dev/null @@ -1,150 +0,0 @@ -import packaging.requirements -import packaging.specifiers -import pathlib -import io -import subprocess -import argparse -import typing - - -class OldNewRequirements(typing.NamedTuple): - old: packaging.requirements.Requirement - new: packaging.requirements.Requirement - - -def clean_lines(f: io.TextIOWrapper) -> typing.Generator[str, None, None]: - for line in f: - # remove comments and hashes - # because packaging.requirements.Requirement can't read hashes - # and comments are useless here - if not line.lstrip().startswith(("#", "--hash")): - yield line.rstrip("\n").rstrip("\\") - - -def retrieve_equal_version( - specifier: packaging.specifiers.SpecifierSet, -) -> packaging.specifiers.Specifier: - """ - :raises ValueError: if no equal version is found - """ - for s in specifier: - if s.operator == "==": - return s - raise ValueError("No equal version found") - - -def retrieve_requirements(file: pathlib.Path) -> io.StringIO: - p = subprocess.run( - ["git", "show", f"HEAD:{file.name}"], - stdout=subprocess.PIPE, - ) - content = io.StringIO(p.stdout.decode()) - return content - - -def compare_requirements( - requirements: pathlib.Path, -) -> tuple[ - set[packaging.requirements.Requirement], - set[ - OldNewRequirements[ - packaging.requirements.Requirement, packaging.requirements.Requirement - ] - ], - set[packaging.requirements.Requirement], -]: - with requirements.open() as file: - set_after = { - packaging.requirements.Requirement(line) for line in clean_lines(file) - } - - set_before = { - packaging.requirements.Requirement(line) - for line in clean_lines(retrieve_requirements(requirements)) - } - - new_requirements = { - requirement.name: requirement - for requirement in set_after.difference(set_before) - } - old_requirements = { - requirement.name: requirement - for requirement in set_before.difference(set_after) - } - - added_requirements = { - requirement - for package_name, requirement in new_requirements.items() - if package_name not in old_requirements - } - updated_requirements = { - OldNewRequirements(old_requirements[package_name], requirement) - for package_name, requirement in new_requirements.items() - if package_name in old_requirements - } - removed_requirements = { - requirement - for package_name, requirement in old_requirements.items() - if package_name not in new_requirements - } - - return added_requirements, updated_requirements, removed_requirements - - -def parser() -> argparse.ArgumentParser: - parser = argparse.ArgumentParser() - parser.add_argument( - "requirements_file", - nargs="?", - default=pathlib.Path("requirements.txt"), - type=pathlib.Path, - ) - parser.add_argument( - "-o", - nargs="?", - default=pathlib.Path("description.md"), - type=pathlib.Path, - required=False, - ) - return parser - - -def generate_changes( - added_requirements: set[packaging.requirements.Requirement], - updated: set[ - OldNewRequirements[ - packaging.requirements.Requirement, - packaging.requirements.Requirement, - ] - ], - removed: set[packaging.requirements.Requirement], -) -> str: - description = ( - [ - f"- Added `{requirement.name}` version " - f"`{retrieve_equal_version(requirement.specifier).version}`" - for requirement in added_requirements - ] - + [ - f"- Bump `{requirements.old.name}` from " - f"`{retrieve_equal_version(requirements.old.specifier).version}` to " - f"`{retrieve_equal_version(requirements.new.specifier).version}`" - for requirements in updated - ] - + [ - f"- Removed `{requirement.name}` version " - f"`{retrieve_equal_version(requirement.specifier).version}`" - for requirement in removed - ] - ) - return "\r\n".join(description) - - -def main(): - args = parser().parse_args() - added, updated, removed = compare_requirements(args.requirements_file) - args.o.write_text(generate_changes(added, updated, removed)) - - -if __name__ == "__main__": - main() diff --git a/templates/python/dependency_management/depandabot/depandabot.yml b/templates/python/dependency_management/depandabot/depandabot.yml index b4c6f91..756baff 100644 --- a/templates/python/dependency_management/depandabot/depandabot.yml +++ b/templates/python/dependency_management/depandabot/depandabot.yml @@ -8,7 +8,7 @@ depandabot: image: python:${IMAGE_TAG} variables: - PYTHON_SETUP: pip install pip-tools + PYTHON_SETUP: pip install pip-tools requirement-compare GITLAB_API_URL: "${CI_SERVER_HOST}" REQUIREMENTS_FILE_PATH: "${PROJECT_PATH}/requirements.in" OUTPUT_FILE_PATH: "${PROJECT_PATH}/requirements${IMAGE_TAG}.txt" @@ -34,7 +34,7 @@ depandabot: --form "actions[][file_path]=${OUTPUT_FILE_PATH}" \ --form "actions[][content]=<${OUTPUT_FILE_PATH}" \ "https://${GITLAB_API_URL}/api/v4/projects/${CI_PROJECT_ID}/repository/commits" - - python compare.py -o description.md ${OUTPUT_FILE_PATH} + - requirement-compare ${REQUIREMENTS_FILE_PATH} ${OUTPUT_FILE_PATH} - | curl --header "Authorization: Bearer ${DEPANDABOT_TOKEN}" \ --form "source_branch=$DEPS_BRANCH" \ -- GitLab