diff --git a/pyproject.toml b/pyproject.toml index 06a5188..a13b9de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tox-poetry-installer" -version = "0.6.0" +version = "0.6.1" license = "MIT" authors = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"] description = "Tox plugin to install Tox environment dependencies using the Poetry backend and lockfile" diff --git a/tox_poetry_installer/__about__.py b/tox_poetry_installer/__about__.py index af40cd6..594f2c6 100644 --- a/tox_poetry_installer/__about__.py +++ b/tox_poetry_installer/__about__.py @@ -1,7 +1,7 @@ # pylint: disable=missing-docstring __title__ = "tox-poetry-installer" __summary__ = "Tox plugin to install Tox environment dependencies using the Poetry backend and lockfile" -__version__ = "0.6.0" +__version__ = "0.6.1" __url__ = "https://github.com/enpaul/tox-poetry-installer/" __license__ = "MIT" __authors__ = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"] diff --git a/tox_poetry_installer/utilities.py b/tox_poetry_installer/utilities.py index c753a75..d2d84c9 100644 --- a/tox_poetry_installer/utilities.py +++ b/tox_poetry_installer/utilities.py @@ -62,44 +62,60 @@ def find_transients(packages: PackageMap, dependency_name: str) -> Set[PoetryPac """ from tox_poetry_installer import _poetry + def find_deps_of_deps(name: str, searched: Set[str]) -> PackageMap: + searched.add(name) + + if name in _poetry.Provider.UNSAFE_PACKAGES: + reporter.warning( + f"{constants.REPORTER_PREFIX} Installing package '{name}' using Poetry is not supported and will be skipped" + ) + reporter.verbosity2( + f"{constants.REPORTER_PREFIX} Skip {name}: designated unsafe by Poetry" + ) + return dict() + + transients: PackageMap = {} + package = packages[name] + + if not package.python_constraint.allows(constants.PLATFORM_VERSION): + reporter.verbosity2( + f"{constants.REPORTER_PREFIX} Skip {package}: incompatible Python requirement '{package.python_constraint}' for current version '{constants.PLATFORM_VERSION}'" + ) + elif package.platform is not None and package.platform != sys.platform: + reporter.verbosity2( + f"{constants.REPORTER_PREFIX} Skip {package}: incompatible platform requirement '{package.platform}' for current platform '{sys.platform}'" + ) + else: + reporter.verbosity2( + f"{constants.REPORTER_PREFIX} Including {package} for installation" + ) + transients[name] = package + for index, dep in enumerate(package.requires): + reporter.verbosity2( + f"{constants.REPORTER_PREFIX} Processing dependency {index + 1}/{len(package.requires)} for {package}: {dep.name}" + ) + if dep.name not in searched: + transients.update(find_deps_of_deps(dep.name, searched)) + else: + reporter.verbosity2( + f"{constants.REPORTER_PREFIX} Package with name '{dep.name}' has already been processed, skipping" + ) + + return transients + + searched: Set[str] = set() + try: - - def find_deps_of_deps(name: str, searched: Set[str]) -> PackageMap: - package = packages[name] - transients: PackageMap = {} - searched.update([name]) - - if name in _poetry.Provider.UNSAFE_PACKAGES: - reporter.warning( - f"{constants.REPORTER_PREFIX} Installing package '{name}' using Poetry is not supported; skipping installation of package '{name}'" - ) - reporter.verbosity2( - f"{constants.REPORTER_PREFIX} Skip {package}: designated unsafe by Poetry" - ) - elif not package.python_constraint.allows(constants.PLATFORM_VERSION): - reporter.verbosity2( - f"{constants.REPORTER_PREFIX} Skip {package}: incompatible Python requirement '{package.python_constraint}' for current version '{constants.PLATFORM_VERSION}'" - ) - elif package.platform is not None and package.platform != sys.platform: - reporter.verbosity2( - f"{constants.REPORTER_PREFIX} Skip {package}: incompatible platform requirement '{package.platform}' for current platform '{sys.platform}'" - ) - else: - reporter.verbosity2(f"{constants.REPORTER_PREFIX} Include {package}") - transients[name] = package - for dep in package.requires: - if dep.name not in searched: - transients.update(find_deps_of_deps(dep.name, searched)) - - return transients - - searched: Set[str] = set() transients: PackageMap = find_deps_of_deps( packages[dependency_name].name, searched ) - - return set(transients.values()) except KeyError: + if dependency_name in _poetry.Provider.UNSAFE_PACKAGES: + reporter.warning( + f"{constants.REPORTER_PREFIX} Installing package '{dependency_name}' using Poetry is not supported and will be skipped" + ) + return set() + if any( delimiter in dependency_name for delimiter in constants.PEP508_VERSION_DELIMITERS @@ -107,10 +123,13 @@ def find_transients(packages: PackageMap, dependency_name: str) -> Set[PoetryPac raise exceptions.LockedDepVersionConflictError( f"Locked dependency '{dependency_name}' cannot include version specifier" ) from None + raise exceptions.LockedDepNotFoundError( f"No version of locked dependency '{dependency_name}' found in the project lockfile" ) from None + return set(transients.values()) + def check_preconditions(venv: ToxVirtualEnv, action: ToxAction) -> "_poetry.Poetry": """Check that the local project environment meets expectations"""