11 Commits
0.3.0 ... 0.4.0

Author SHA1 Message Date
3a262d718c Merge pull request #19 from enpaul/enp/install-dev-deps
Add config option for installing dev dependencies to testenv
2020-10-29 17:28:39 -04:00
5979ec7a8a Add documentation for new config option 2020-10-28 16:26:31 -04:00
c7bb3d35ea Bump feature version 2020-10-24 12:10:07 -04:00
961e6f6acd Add support for installing all dev dependencies to a testenv 2020-10-24 12:09:42 -04:00
ed039de674 Merge pull request #16 from enpaul/enp/fix
Fix support for extras installation
2020-10-24 11:55:35 -04:00
db0cf6ce0c Bump patch version 2020-10-24 11:53:38 -04:00
e8d3f4fcac Fix support for non-single extra dependency installation 2020-10-24 11:53:38 -04:00
653622fd35 Merge pull request #15 from enpaul/enp/housekeeping
Some housekeeping changes
2020-10-23 10:02:45 -04:00
de4c3515ec Refactor to maintain consistent terminology
With a dozen different "dependency" types, consistent naming is critical
2020-10-23 00:59:43 -04:00
01bfdd74bd Add missing documentation for internal functions/constants 2020-10-23 00:43:11 -04:00
3e98ec81eb Update beta roadmap features list 2020-10-22 21:16:32 -04:00
3 changed files with 84 additions and 14 deletions

View File

@@ -96,6 +96,10 @@ deps =
commands = ... commands = ...
``` ```
Alternatively, to quickly install all Poetry dev-dependencies to a Tox environment, add the
`install_dev_deps = true` option to the environment configuration. This option can be used either
with the `require_locked_deps = true` option or without it
**Note:** Regardless of the settings outlined above, all dependencies of the project package (the **Note:** Regardless of the settings outlined above, all dependencies of the project package (the
one Tox is testing) will always be installed from the lockfile. one Tox is testing) will always be installed from the lockfile.
@@ -452,7 +456,8 @@ for usage in production environments.
to avoid potentially breaking API changes in upstream packages. ([#2](https://github.com/enpaul/tox-poetry-installer/issues/2)) to avoid potentially breaking API changes in upstream packages. ([#2](https://github.com/enpaul/tox-poetry-installer/issues/2))
- [ ] Find and implement a way to mitigate the [UNSAFE_DEPENDENCIES issue](https://github.com/python-poetry/poetry/issues/1584) in Poetry. - [ ] Find and implement a way to mitigate the [UNSAFE_DEPENDENCIES issue](https://github.com/python-poetry/poetry/issues/1584) in Poetry.
([#6](https://github.com/enpaul/tox-poetry-installer/issues/6)) ([#6](https://github.com/enpaul/tox-poetry-installer/issues/6))
- [ ] Fix logging to make proper use of Tox's logging reporter infrastructure - [ ] Fix logging to make proper use of Tox's logging reporter infrastructure ([#3](https://github.com/enpaul/tox-poetry-installer/issues/3))
- [ ] Add configuration option for installing all dev-dependencies to a testenv ([#14](https://github.com/enpaul/tox-poetry-installer/issues/14))
### Path to Stable ### Path to Stable

View File

@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "tox-poetry-installer" name = "tox-poetry-installer"
version = "0.3.0" version = "0.4.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"

View File

@@ -1,9 +1,24 @@
"""Tox plugin for installing environments using Poetry """Tox plugin for installing environments using Poetry
This plugin makes use of the ``tox_testenv_install_deps`` Tox plugin hook to replace the default This plugin makes use of the ``tox_testenv_install_deps`` Tox plugin hook to augment the default
installation functionality to install dependencies from the Poetry lockfile for the project. It installation functionality to install dependencies from the Poetry lockfile for the project. It
does this by using ``poetry`` to read in the lockfile, identify necessary dependencies, and then does this by using ``poetry`` to read in the lockfile, identify necessary dependencies, and then
use Poetry's ``PipInstaller`` class to install those packages into the Tox environment. use Poetry's ``PipInstaller`` class to install those packages into the Tox environment.
Quick definition of terminology:
* "project package" - the package that Tox is testing, usually the one the current project is
is developing; definitionally, this is the package that is built by Tox in the ``.package`` env.
* "project package dependency" or "project dependency" - a dependency required by the project
package for installation; i.e. a package that would be installed when running
``pip install <project package>``.
* "environment dependency" - a dependency specified for a given testenv in the Tox configuration.
* "locked dependency" - a package that is present in the Poetry lockfile and will be installed
according to the metadata in the lockfile.
* "unlocked dependency" - a package that is either not present in the Poetry lockfile or is not
specified to be installed according to the metadata in the lockfile.
* "transiety dependency" - a package not explicitly specified for installation, but required by a
package that is explicitly specified.
""" """
from pathlib import Path from pathlib import Path
from typing import Dict from typing import Dict
@@ -30,7 +45,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.3.0" __version__ = "0.4.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 +67,7 @@ _REPORTER_PREFIX = f"[{__title__}]:"
_MAGIC_SUFFIX_MARKER = "@poetry" _MAGIC_SUFFIX_MARKER = "@poetry"
# Map of package names to the package object
PackageMap = Dict[str, PoetryPackage] PackageMap = Dict[str, PoetryPackage]
@@ -118,10 +134,10 @@ def _sort_env_deps(venv: ToxVirtualEnv) -> _SortedEnvDeps:
unlocked_deps.append(dep) unlocked_deps.append(dep)
reporter.verbosity1( reporter.verbosity1(
f"{_REPORTER_PREFIX} identified {len(locked_deps)} locked env dependencies for installation from poetry lockfile: {[item.name for item in locked_deps]}" f"{_REPORTER_PREFIX} identified {len(locked_deps)} locked env dependencies: {[item.name for item in locked_deps]}"
) )
reporter.verbosity1( reporter.verbosity1(
f"{_REPORTER_PREFIX} identified {len(unlocked_deps)} unlocked env dependencies for installation using default backend: {[item.name for item in unlocked_deps]}" f"{_REPORTER_PREFIX} identified {len(unlocked_deps)} unlocked env dependencies: {[item.name for item in unlocked_deps]}"
) )
return _SortedEnvDeps(locked_deps=locked_deps, unlocked_deps=unlocked_deps) return _SortedEnvDeps(locked_deps=locked_deps, unlocked_deps=unlocked_deps)
@@ -136,6 +152,11 @@ def _install_to_venv(
:param venv: Tox virtual environment to install the packages to :param venv: Tox virtual environment to install the packages to
:param packages: List of packages to install to the virtual environment :param packages: List of packages to install to the virtual environment
""" """
reporter.verbosity1(
f"{_REPORTER_PREFIX} Installing {len(packages)} packages to environment at {venv.envconfig.envdir}"
)
installer = PoetryPipInstaller( installer = PoetryPipInstaller(
env=PoetryVirtualEnv(path=Path(venv.envconfig.envdir)), env=PoetryVirtualEnv(path=Path(venv.envconfig.envdir)),
io=PoetryNullIO(), io=PoetryNullIO(),
@@ -166,7 +187,7 @@ def _find_transients(packages: PackageMap, dependency_name: str) -> Set[PoetryPa
def find_deps_of_deps(name: str) -> List[PoetryPackage]: def find_deps_of_deps(name: str) -> List[PoetryPackage]:
if name in PoetryProvider.UNSAFE_PACKAGES: if name in PoetryProvider.UNSAFE_PACKAGES:
reporter.warning( reporter.warning(
f"{_REPORTER_PREFIX} installing '{name}' using Poetry is not supported; skipping" f"{_REPORTER_PREFIX} installing package '{name}' using Poetry is not supported; skipping installation of package '{name}'"
) )
return [] return []
transients = [packages[name]] transients = [packages[name]]
@@ -191,6 +212,15 @@ def _find_transients(packages: PackageMap, dependency_name: str) -> Set[PoetryPa
def _install_env_dependencies( def _install_env_dependencies(
venv: ToxVirtualEnv, poetry: Poetry, packages: PackageMap venv: ToxVirtualEnv, poetry: Poetry, packages: PackageMap
): ):
"""Install the packages for a specified testenv
Processes the tox environment config, identifies any locked environment dependencies, pulls
them from the lockfile, and installs them to the virtual environment.
:param venv: Tox virtual environment to install the packages to
:param poetry: Poetry object the packages were sourced from
:param packages: Mapping of package names to the corresponding package object
"""
env_deps = _sort_env_deps(venv) env_deps = _sort_env_deps(venv)
dependencies: List[PoetryPackage] = [] dependencies: List[PoetryPackage] = []
@@ -202,8 +232,25 @@ def _install_env_dependencies(
reporter.error(f"{_REPORTER_PREFIX} {err}") reporter.error(f"{_REPORTER_PREFIX} {err}")
raise err raise err
if venv.envconfig.install_dev_deps:
reporter.verbosity1(
f"{_REPORTER_PREFIX} env specifies 'install_env_deps = true', including Poetry dev dependencies"
)
dev_dependencies = [
dep
for dep in poetry.locker.locked_repository(True).packages
if dep not in poetry.locker.locked_repository(False).packages
]
reporter.verbosity1(
f"{_REPORTER_PREFIX} identified {len(dev_dependencies)} Poetry dev dependencies"
)
dependencies = list(set(dev_dependencies + dependencies))
reporter.verbosity1( reporter.verbosity1(
f"{_REPORTER_PREFIX} identified {len(dependencies)} actual dependencies from {len(venv.envconfig.deps)} specified env dependencies" f"{_REPORTER_PREFIX} identified {len(dependencies)} total dependencies from {len(env_deps.locked_deps)} locked env dependencies"
) )
reporter.verbosity1( reporter.verbosity1(
@@ -217,20 +264,31 @@ def _install_env_dependencies(
_install_to_venv(poetry, venv, dependencies) _install_to_venv(poetry, venv, dependencies)
def _install_package_dependencies( def _install_project_dependencies(
venv: ToxVirtualEnv, poetry: Poetry, packages: PackageMap venv: ToxVirtualEnv, poetry: Poetry, packages: PackageMap
): ):
"""Install the dependencies of the project package
Install all primary dependencies of the project package.
:param venv: Tox virtual environment to install the packages to
:param poetry: Poetry object the packages were sourced from
:param packages: Mapping of package names to the corresponding package object
"""
reporter.verbosity1( reporter.verbosity1(
f"{_REPORTER_PREFIX} performing installation of project dependencies" f"{_REPORTER_PREFIX} performing installation of project dependencies"
) )
base_dependencies = [ base_dependencies: List[PoetryPackage] = [
packages[item.name] for item in poetry.package.requires if not item.is_optional packages[item.name]
for item in poetry.package.requires
if not item.is_optional()
] ]
extra_dependencies: List[PoetryPackage] = []
for extra in venv.envconfig.extras: for extra in venv.envconfig.extras:
try: try:
extra_dependencies = [ extra_dependencies += [
packages[item.name] for item in poetry.package.extras[extra] packages[item.name] for item in poetry.package.extras[extra]
] ]
except KeyError: except KeyError:
@@ -248,7 +306,7 @@ def _install_package_dependencies(
raise err raise err
reporter.verbosity1( reporter.verbosity1(
f"{_REPORTER_PREFIX} identified {len(dependencies)} dependencies of project '{poetry.package.name}'" f"{_REPORTER_PREFIX} identified {len(dependencies)} total dependencies from {len(poetry.package.requires)} project dependencies"
) )
reporter.verbosity0( reporter.verbosity0(
@@ -265,6 +323,13 @@ def tox_addoption(parser: ToxParser):
dependencies should be treated as locked or not. dependencies should be treated as locked or not.
""" """
parser.add_testenv_attribute(
name="install_dev_deps",
type="bool",
default=False,
help="Automatically install all Poetry development dependencies to the environment",
)
parser.add_testenv_attribute( parser.add_testenv_attribute(
name="require_locked_deps", name="require_locked_deps",
type="bool", type="bool",
@@ -333,4 +398,4 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction):
) )
return return
_install_package_dependencies(venv, poetry, package_map) _install_project_dependencies(venv, poetry, package_map)