Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add script that checks dependency conflicts #218

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions komodo/check_conflicts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import argparse
import pathlib
import subprocess
import sys
import tempfile
import platform
import venv
import contextlib

import yaml

from komodo.check_up_to_date_pypi import get_pypi_packages
from komodo.package_version import strip_version


@contextlib.contextmanager
def temporary_environment():
class EnvBuilder(venv.EnvBuilder):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.context = None

def post_setup(self, context):
self.context = context

with tempfile.TemporaryDirectory() as tmp_dir:
builder = EnvBuilder(with_pip=True)
builder.create(str(tmp_dir))
context = builder.context
yield context.env_exe


def main():
parser = argparse.ArgumentParser(
description="Checks if pypi packages are compatible"
)
parser.add_argument(
"release_file",
type=lambda arg: arg
if pathlib.Path(arg).is_file()
else parser.error("{} is not a file".format(arg)),
help="Release file you would like to check dependencies on.",
)
parser.add_argument(
"repository_file",
type=lambda arg: arg
if pathlib.Path(arg).is_file()
else parser.error("{} is not a file".format(arg)),
help="Repository file where the source of the packages is found",
)
parser.add_argument(
"--output-file",
type=str,
default=False,
help="Output file where requirements are written",
)
parser.add_argument(
"--try-pip",
action="store_true",
help="If given, will try to install packages and check validity. Note that "
"creates a virtual environment and is quite slow",
)
Comment on lines +57 to +62
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I need to pass --try-pip to actually have anything checked? What happens if this is not provided?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either way, I think invoking this program like so

komodo-check-conflicts bleeding.yml repository.yml

should

  1. if it finds conflict, exit with a non-zero exit code and output these to stdout;
  2. if no conflict, exit with 0 without any output.

The parser is called "Checks if pypi packages are compatible" and the command is called "komodo-check-conflicts", so introducing "output", "requirements", and "try-pip" as default false is a bit unexpected.

Maybe remove --try-pip, rename --output-file to --generate-requirements. The latter should also

  1. have help text explaining that the program will "Output installed packages in pip requirements format.";
  2. not require a file, but generate the requirements on stdout. If the user needs something in a file, the unix philosophy warrants:

komodo-check-conflicts --generate-requirements > requirements.txt

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes you do, will remove that option so it always checks.


args = parser.parse_args()
with open(args.release_file) as fin:
releases = yaml.safe_load(fin)
with open(args.repository_file) as fin:
repository = yaml.safe_load(fin)

pypi_packages = get_pypi_packages(releases, repository)

requirements = []
for package in pypi_packages:
if package == "opm" and platform.system() == "Darwin":
print("Found opm, which has no osx source (as of 08.2021)")
continue
version = strip_version(releases[package])
requirements.append(f"{package}=={version}")

if args.output_file:
with open(args.output_file, "w") as fout:
fout.write("\n".join(requirements) + "\n")

if args.try_pip:
print("Checking dependencies, this is usually slow")
with temporary_environment() as current_python:
upgrade_pip = subprocess.run(
[
current_python,
"-m",
"pip",
"install",
"pip",
"-U",
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
jondequinor marked this conversation as resolved.
Show resolved Hide resolved
if upgrade_pip.returncode == 1:
sys.exit(
upgrade_pip.stderr.decode("utf-8")
+ "\n Upgrading pip failed"
)
install = subprocess.run(
[
current_python,
"-m",
"pip",
"install",
*requirements,
"--no-deps",
"--force-reinstall", # Probably not needed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed

],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
if install.returncode == 1:
sys.exit(
install.stderr.decode("utf-8")
+ "\n Installation of packages failed"
)
result = subprocess.run(
[current_python, "-m", "pip", "check"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
if result.returncode == 1:
sys.exit(result.stdout.decode("utf-8"))
else:
print("Everything is awesome!")
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
'komodo-reverse-deps = komodo.reverse_dep_graph:main',
'komodo-insert-proposals = komodo.insert_proposals:main',
'komodo-check-pypi = komodo.check_up_to_date_pypi:main',
'komodo-check-conflicts = komodo.check_conflicts:main',
]
},
)