mirror of
				https://github.com/enpaul/tox-poetry-installer.git
				synced 2025-11-04 07:46:06 +00:00 
			
		
		
		
	Add first functional version of the plugin module
This commit is contained in:
		
							
								
								
									
										78
									
								
								tox_poetry_installer.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								tox_poetry_installer.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					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
 | 
				
			||||||
		Reference in New Issue
	
	Block a user