Pour tout problème contactez-nous par mail : support@froggit.fr | La FAQ :grey_question: | Rejoignez-nous sur le Chat :speech_balloon:

Skip to content
Snippets Groups Projects
Commit dcc9a7c8 authored by Dorian Turba's avatar Dorian Turba
Browse files

use requirement-compare

parent 7ba8e3de
No related branches found
No related tags found
1 merge request!1feat: add depandabot template
Pipeline #24096 failed
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()
......@@ -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" \
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment