mirror of
				https://github.com/enpaul/tox-poetry-installer.git
				synced 2025-11-04 07:46:06 +00:00 
			
		
		
		
	Merge pull request #11 from enpaul/enp/extras
Add support for the extras option
This commit is contained in:
		@@ -249,10 +249,6 @@ Tox installation backend.
 | 
				
			|||||||
  * [`indexserver`](https://tox.readthedocs.io/en/latest/config.html#conf-indexserver)
 | 
					  * [`indexserver`](https://tox.readthedocs.io/en/latest/config.html#conf-indexserver)
 | 
				
			||||||
  * [`usedevelop`](https://tox.readthedocs.io/en/latest/config.html#conf-indexserver)
 | 
					  * [`usedevelop`](https://tox.readthedocs.io/en/latest/config.html#conf-indexserver)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* The [`extras`](https://tox.readthedocs.io/en/latest/config.html#conf-extras) setting in `tox.ini`
 | 
					 | 
				
			||||||
  does not work. Optional dependencies of the project package will not be installed to Tox
 | 
					 | 
				
			||||||
  environments. (See the [road map](#roadmap))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* Tox environments automatically inherit their settings from the main `testenv` environment. This
 | 
					* Tox environments automatically inherit their settings from the main `testenv` environment. This
 | 
				
			||||||
  means that if the `require_locked_deps = true` is specified for the `testenv` environment then
 | 
					  means that if the `require_locked_deps = true` is specified for the `testenv` environment then
 | 
				
			||||||
  all environments will also require locked dependencies. This can be overwritten by explicitly
 | 
					  all environments will also require locked dependencies. This can be overwritten by explicitly
 | 
				
			||||||
@@ -443,7 +439,7 @@ for usage in production environments.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
- [X] Verify that primary package dependencies (from the `.package` env) are installed
 | 
					- [X] Verify that primary package dependencies (from the `.package` env) are installed
 | 
				
			||||||
      correctly using the Poetry backend.
 | 
					      correctly using the Poetry backend.
 | 
				
			||||||
- [ ] Support the [`extras`](https://tox.readthedocs.io/en/latest/config.html#conf-extras)
 | 
					- [X] Support the [`extras`](https://tox.readthedocs.io/en/latest/config.html#conf-extras)
 | 
				
			||||||
      Tox configuration option ([#4](https://github.com/enpaul/tox-poetry-installer/issues/4))
 | 
					      Tox configuration option ([#4](https://github.com/enpaul/tox-poetry-installer/issues/4))
 | 
				
			||||||
- [X] Add per-environment Tox configuration option to fall back to default installation
 | 
					- [X] Add per-environment Tox configuration option to fall back to default installation
 | 
				
			||||||
      backend.
 | 
					      backend.
 | 
				
			||||||
@@ -464,6 +460,6 @@ Everything in Beta plus...
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
- [ ] Add tests for each feature version of Tox between 2.3 and 3.20
 | 
					- [ ] Add tests for each feature version of Tox between 2.3 and 3.20
 | 
				
			||||||
- [ ] Add tests for Python-3.6, 3.7, and 3.8
 | 
					- [ ] Add tests for Python-3.6, 3.7, and 3.8
 | 
				
			||||||
- [ ] Add Github Actions based CI
 | 
					- [X] Add Github Actions based CI
 | 
				
			||||||
- [ ] Add CI for CPython, PyPy, and Conda
 | 
					- [ ] Add CI for CPython, PyPy, and Conda
 | 
				
			||||||
- [ ] Add CI for Linux and Windows
 | 
					- [ ] Add CI for Linux and Windows
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										785
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										785
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,6 +1,6 @@
 | 
				
			|||||||
[tool.poetry]
 | 
					[tool.poetry]
 | 
				
			||||||
name = "tox-poetry-installer"
 | 
					name = "tox-poetry-installer"
 | 
				
			||||||
version = "0.2.4"
 | 
					version = "0.3.0"
 | 
				
			||||||
license = "MIT"
 | 
					license = "MIT"
 | 
				
			||||||
authors = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
 | 
					authors = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
 | 
				
			||||||
description = "Tox plugin to install Tox environment dependencies using the Poetry backend and lockfile"
 | 
					description = "Tox plugin to install Tox environment dependencies using the Poetry backend and lockfile"
 | 
				
			||||||
@@ -31,6 +31,7 @@ poetry_installer = "tox_poetry_installer"
 | 
				
			|||||||
[tool.poetry.dependencies]
 | 
					[tool.poetry.dependencies]
 | 
				
			||||||
python = "^3.6"
 | 
					python = "^3.6"
 | 
				
			||||||
poetry = "^1.0.0"
 | 
					poetry = "^1.0.0"
 | 
				
			||||||
 | 
					poetry-core = "^1.0.0"
 | 
				
			||||||
tox = "^2.3.0 || ^3.0.0"
 | 
					tox = "^2.3.0 || ^3.0.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[tool.poetry.dev-dependencies]
 | 
					[tool.poetry.dev-dependencies]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@ from tox.venv import VirtualEnv as ToxVirtualEnv
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
__title__ = "tox-poetry-installer"
 | 
					__title__ = "tox-poetry-installer"
 | 
				
			||||||
__summary__ = "Tox plugin to install Tox environment dependencies using the Poetry backend and lockfile"
 | 
					__summary__ = "Tox plugin to install Tox environment dependencies using the Poetry backend and lockfile"
 | 
				
			||||||
__version__ = "0.2.4"
 | 
					__version__ = "0.3.0"
 | 
				
			||||||
__url__ = "https://github.com/enpaul/tox-poetry-installer/"
 | 
					__url__ = "https://github.com/enpaul/tox-poetry-installer/"
 | 
				
			||||||
__license__ = "MIT"
 | 
					__license__ = "MIT"
 | 
				
			||||||
__authors__ = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
 | 
					__authors__ = ["Ethan Paul <24588726+enpaul@users.noreply.github.com>"]
 | 
				
			||||||
@@ -52,6 +52,9 @@ _REPORTER_PREFIX = f"[{__title__}]:"
 | 
				
			|||||||
_MAGIC_SUFFIX_MARKER = "@poetry"
 | 
					_MAGIC_SUFFIX_MARKER = "@poetry"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PackageMap = Dict[str, PoetryPackage]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _SortedEnvDeps(NamedTuple):
 | 
					class _SortedEnvDeps(NamedTuple):
 | 
				
			||||||
    unlocked_deps: List[ToxDepConfig]
 | 
					    unlocked_deps: List[ToxDepConfig]
 | 
				
			||||||
    locked_deps: List[ToxDepConfig]
 | 
					    locked_deps: List[ToxDepConfig]
 | 
				
			||||||
@@ -69,6 +72,10 @@ class LockedDepNotFoundError(ToxPoetryInstallerException):
 | 
				
			|||||||
    """Locked dependency was not found in the lockfile"""
 | 
					    """Locked dependency was not found in the lockfile"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ExtraNotFoundError(ToxPoetryInstallerException):
 | 
				
			||||||
 | 
					    """Project package extra not defined in project's pyproject.toml"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _sort_env_deps(venv: ToxVirtualEnv) -> _SortedEnvDeps:
 | 
					def _sort_env_deps(venv: ToxVirtualEnv) -> _SortedEnvDeps:
 | 
				
			||||||
    """Sorts the environment dependencies by lock status
 | 
					    """Sorts the environment dependencies by lock status
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -140,7 +147,7 @@ def _install_to_venv(
 | 
				
			|||||||
        installer.install(dependency)
 | 
					        installer.install(dependency)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _find_transients(poetry: Poetry, dependency_name: str) -> Set[PoetryPackage]:
 | 
					def _find_transients(packages: PackageMap, dependency_name: str) -> Set[PoetryPackage]:
 | 
				
			||||||
    """Using a poetry object identify all dependencies of a specific dependency
 | 
					    """Using a poetry object identify all dependencies of a specific dependency
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    :param poetry: Populated poetry object which can be used to build a populated locked
 | 
					    :param poetry: Populated poetry object which can be used to build a populated locked
 | 
				
			||||||
@@ -152,10 +159,6 @@ def _find_transients(poetry: Poetry, dependency_name: str) -> Set[PoetryPackage]
 | 
				
			|||||||
    .. note:: The package corresponding to the dependency named by ``dependency_name`` is included
 | 
					    .. note:: The package corresponding to the dependency named by ``dependency_name`` is included
 | 
				
			||||||
              in the list of returned packages.
 | 
					              in the list of returned packages.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    packages: Dict[str, PoetryPackage] = {
 | 
					 | 
				
			||||||
        package.name: package
 | 
					 | 
				
			||||||
        for package in poetry.locker.locked_repository(True).packages
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        top_level = packages[dependency_name]
 | 
					        top_level = packages[dependency_name]
 | 
				
			||||||
@@ -185,13 +188,15 @@ def _find_transients(poetry: Poetry, dependency_name: str) -> Set[PoetryPackage]
 | 
				
			|||||||
        ) from None
 | 
					        ) from None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _install_env_dependencies(venv: ToxVirtualEnv, poetry: Poetry):
 | 
					def _install_env_dependencies(
 | 
				
			||||||
 | 
					    venv: ToxVirtualEnv, poetry: Poetry, packages: PackageMap
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
    env_deps = _sort_env_deps(venv)
 | 
					    env_deps = _sort_env_deps(venv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dependencies: List[PoetryPackage] = []
 | 
					    dependencies: List[PoetryPackage] = []
 | 
				
			||||||
    for dep in env_deps.locked_deps:
 | 
					    for dep in env_deps.locked_deps:
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            dependencies += _find_transients(poetry, dep.name.lower())
 | 
					            dependencies += _find_transients(packages, dep.name.lower())
 | 
				
			||||||
        except ToxPoetryInstallerException as err:
 | 
					        except ToxPoetryInstallerException as err:
 | 
				
			||||||
            venv.status = "lockfile installation failed"
 | 
					            venv.status = "lockfile installation failed"
 | 
				
			||||||
            reporter.error(f"{_REPORTER_PREFIX} {err}")
 | 
					            reporter.error(f"{_REPORTER_PREFIX} {err}")
 | 
				
			||||||
@@ -212,21 +217,44 @@ def _install_env_dependencies(venv: ToxVirtualEnv, poetry: Poetry):
 | 
				
			|||||||
    _install_to_venv(poetry, venv, dependencies)
 | 
					    _install_to_venv(poetry, venv, dependencies)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _install_package_dependencies(venv: ToxVirtualEnv, poetry: Poetry):
 | 
					def _install_package_dependencies(
 | 
				
			||||||
 | 
					    venv: ToxVirtualEnv, poetry: Poetry, packages: PackageMap
 | 
				
			||||||
 | 
					):
 | 
				
			||||||
    reporter.verbosity1(
 | 
					    reporter.verbosity1(
 | 
				
			||||||
        f"{_REPORTER_PREFIX} performing installation of project dependencies"
 | 
					        f"{_REPORTER_PREFIX} performing installation of project dependencies"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    primary_dependencies = poetry.locker.locked_repository(False).packages
 | 
					    base_dependencies = [
 | 
				
			||||||
 | 
					        packages[item.name] for item in poetry.package.requires if not item.is_optional
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for extra in venv.envconfig.extras:
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            extra_dependencies = [
 | 
				
			||||||
 | 
					                packages[item.name] for item in poetry.package.extras[extra]
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        except KeyError:
 | 
				
			||||||
 | 
					            raise ExtraNotFoundError(
 | 
				
			||||||
 | 
					                f"Environment '{venv.name}' specifies project extra '{extra}' which was not found in the lockfile"
 | 
				
			||||||
 | 
					            ) from None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies: List[PoetryPackage] = []
 | 
				
			||||||
 | 
					    for dep in base_dependencies + extra_dependencies:
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            dependencies += _find_transients(packages, dep.name.lower())
 | 
				
			||||||
 | 
					        except ToxPoetryInstallerException as err:
 | 
				
			||||||
 | 
					            venv.status = "lockfile installation failed"
 | 
				
			||||||
 | 
					            reporter.error(f"{_REPORTER_PREFIX} {err}")
 | 
				
			||||||
 | 
					            raise err
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    reporter.verbosity1(
 | 
					    reporter.verbosity1(
 | 
				
			||||||
        f"{_REPORTER_PREFIX} identified {len(primary_dependencies)} dependencies of project '{poetry.package.name}'"
 | 
					        f"{_REPORTER_PREFIX} identified {len(dependencies)} dependencies of project '{poetry.package.name}'"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    reporter.verbosity0(
 | 
					    reporter.verbosity0(
 | 
				
			||||||
        f"{_REPORTER_PREFIX} ({venv.name}) installing {len(primary_dependencies)} project dependencies from lockfile"
 | 
					        f"{_REPORTER_PREFIX} ({venv.name}) installing {len(dependencies)} project dependencies from lockfile"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    _install_to_venv(poetry, venv, primary_dependencies)
 | 
					    _install_to_venv(poetry, venv, dependencies)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@hookimpl
 | 
					@hookimpl
 | 
				
			||||||
@@ -283,19 +311,26 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction):
 | 
				
			|||||||
        f"{_REPORTER_PREFIX} loaded project pyproject.toml from {poetry.file}"
 | 
					        f"{_REPORTER_PREFIX} loaded project pyproject.toml from {poetry.file}"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    package_map: PackageMap = {
 | 
				
			||||||
 | 
					        package.name: package
 | 
				
			||||||
 | 
					        for package in poetry.locker.locked_repository(True).packages
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Handle the installation of any locked env dependencies from the lockfile
 | 
					    # Handle the installation of any locked env dependencies from the lockfile
 | 
				
			||||||
    _install_env_dependencies(venv, poetry)
 | 
					    _install_env_dependencies(venv, poetry, package_map)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Handle the installation of the package dependencies from the lockfile if the package is
 | 
					    # Handle the installation of the package dependencies from the lockfile if the package is
 | 
				
			||||||
    # being installed to this venv; otherwise skip installing the package dependencies
 | 
					    # being installed to this venv; otherwise skip installing the package dependencies
 | 
				
			||||||
    if not venv.envconfig.skip_install and not venv.envconfig.config.skipsdist:
 | 
					 | 
				
			||||||
        _install_package_dependencies(venv, poetry)
 | 
					 | 
				
			||||||
    else:
 | 
					 | 
				
			||||||
    if venv.envconfig.skip_install:
 | 
					    if venv.envconfig.skip_install:
 | 
				
			||||||
        reporter.verbosity1(
 | 
					        reporter.verbosity1(
 | 
				
			||||||
            f"{_REPORTER_PREFIX} env specifies 'skip_install = true', skipping installation of project package"
 | 
					            f"{_REPORTER_PREFIX} env specifies 'skip_install = true', skipping installation of project package"
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        elif venv.envconfig.config.skipsdist:
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if venv.envconfig.config.skipsdist:
 | 
				
			||||||
        reporter.verbosity1(
 | 
					        reporter.verbosity1(
 | 
				
			||||||
            f"{_REPORTER_PREFIX} config specifies 'skipsdist = true', skipping installation of project package"
 | 
					            f"{_REPORTER_PREFIX} config specifies 'skipsdist = true', skipping installation of project package"
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _install_package_dependencies(venv, poetry, package_map)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user