mirror of
https://github.com/enpaul/tox-poetry-installer.git
synced 2024-10-29 19:47:00 +00:00
79 lines
2.4 KiB
Python
79 lines
2.4 KiB
Python
|
from pathlib import Path
|
||
|
import logging
|
||
|
from typing import Dict, List
|
||
|
|
||
|
from poetry.factory import Factory
|
||
|
from poetry.factory import Poetry
|
||
|
from poetry.packages import Package
|
||
|
from poetry.installation.pip_installer import PipInstaller
|
||
|
from poetry.io.null_io import NullIO
|
||
|
from poetry.utils.env import VirtualEnv
|
||
|
|
||
|
from tox.action import Action as ToxAction
|
||
|
from tox.venv import VirtualEnv as ToxVirtualEnv
|
||
|
from tox import hookimpl
|
||
|
|
||
|
|
||
|
__title__ = "tox-poetry-installer"
|
||
|
__summary__ = "Tox plugin to install Tox environment dependencies using the Poetry backend and lockfile"
|
||
|
__version__ = "0.1.0"
|
||
|
__url__ = "https://github.com/enpaul/tox-poetry-installer/"
|
||
|
__license__ = "MIT"
|
||
|
__authors__ = ["Ethan Paul <e@enp.one>"]
|
||
|
|
||
|
|
||
|
def _make_poetry(venv: ToxVirtualEnv) -> Poetry:
|
||
|
return Factory().create_poetry(venv.envconfig.config.toxinidir)
|
||
|
|
||
|
|
||
|
def _find_locked_dependencies(poetry: Poetry, dependency_name: str) -> List[Package]:
|
||
|
packages: Dict[str, Package] = {
|
||
|
package.name: package
|
||
|
for package in poetry.locker.locked_repository(True).packages
|
||
|
}
|
||
|
|
||
|
try:
|
||
|
top_level = packages[dependency_name]
|
||
|
except KeyError:
|
||
|
raise
|
||
|
|
||
|
def find_transients(name: str) -> List[Package]:
|
||
|
transients = [packages[name]]
|
||
|
for dep in packages[name].requires:
|
||
|
transients += find_transients(dep.name)
|
||
|
return transients
|
||
|
|
||
|
return find_transients(top_level.name)
|
||
|
|
||
|
|
||
|
@hookimpl
|
||
|
def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction):
|
||
|
|
||
|
logger = logging.getLogger(__name__)
|
||
|
|
||
|
if action.name == venv.envconfig.config.isolated_build_env:
|
||
|
logger.debug(f"Environment {action.name} is isolated build environment; skipping Poetry-based dependency installation")
|
||
|
return None
|
||
|
|
||
|
poetry = _make_poetry(venv)
|
||
|
|
||
|
logger.debug(f"Loaded project pyproject.toml from {poetry.file}")
|
||
|
|
||
|
dependencies = []
|
||
|
for env_dependency in venv.envconfig.deps:
|
||
|
dependencies += _find_locked_dependencies(poetry, env_dependency.name)
|
||
|
|
||
|
logger.debug(f"Identified {len(dependencies)} dependencies for environment {action.name}")
|
||
|
|
||
|
installer = PipInstaller(
|
||
|
env=VirtualEnv(path=Path(venv.envconfig.envdir)),
|
||
|
io=NullIO(),
|
||
|
pool=poetry.pool
|
||
|
)
|
||
|
|
||
|
for dependency in dependencies:
|
||
|
logger.info(f"Installing environment dependency: {dependency}")
|
||
|
installer.install(dependency)
|
||
|
|
||
|
return dependencies
|