mirror of
https://github.com/enpaul/tox-poetry-installer.git
synced 2025-01-15 08:43:29 +00:00
[WIP] Make plugin compatible with tox v4
This commit is contained in:
parent
c55ba474c7
commit
a94933e7ef
@ -6,7 +6,7 @@ import poetry.factory
|
|||||||
import poetry.installation.pip_installer
|
import poetry.installation.pip_installer
|
||||||
import poetry.utils.env
|
import poetry.utils.env
|
||||||
import pytest
|
import pytest
|
||||||
import tox
|
import tox.tox_env.python.virtual_env.runner
|
||||||
from poetry.core.packages.package import Package as PoetryPackage
|
from poetry.core.packages.package import Package as PoetryPackage
|
||||||
|
|
||||||
from tox_poetry_installer import utilities
|
from tox_poetry_installer import utilities
|
||||||
@ -20,11 +20,8 @@ FAKE_VENV_PATH = Path("nowhere")
|
|||||||
class MockVirtualEnv:
|
class MockVirtualEnv:
|
||||||
"""Mock class for the :class:`poetry.utils.env.VirtualEnv` and :class:`tox.venv.VirtualEnv`"""
|
"""Mock class for the :class:`poetry.utils.env.VirtualEnv` and :class:`tox.venv.VirtualEnv`"""
|
||||||
|
|
||||||
class MockTestenvConfig: # pylint: disable=missing-class-docstring
|
|
||||||
envdir = FAKE_VENV_PATH
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.envconfig = self.MockTestenvConfig()
|
self.env_dir = FAKE_VENV_PATH
|
||||||
self.installed = []
|
self.installed = []
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -53,7 +50,9 @@ def mock_venv(monkeypatch):
|
|||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
poetry.installation.pip_installer, "PipInstaller", MockPipInstaller
|
poetry.installation.pip_installer, "PipInstaller", MockPipInstaller
|
||||||
)
|
)
|
||||||
monkeypatch.setattr(tox.venv, "VirtualEnv", MockVirtualEnv)
|
monkeypatch.setattr(
|
||||||
|
tox.tox_env.python.virtual_env.runner, "VirtualEnvRunner", MockVirtualEnv
|
||||||
|
)
|
||||||
monkeypatch.setattr(poetry.utils.env, "VirtualEnv", MockVirtualEnv)
|
monkeypatch.setattr(poetry.utils.env, "VirtualEnv", MockVirtualEnv)
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import time
|
|||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import tox.venv
|
import tox.tox_env.python.virtual_env.runner
|
||||||
from poetry.factory import Factory
|
from poetry.factory import Factory
|
||||||
|
|
||||||
from .fixtures import mock_poetry_factory
|
from .fixtures import mock_poetry_factory
|
||||||
@ -19,7 +19,7 @@ def test_deduplication(mock_venv, mock_poetry_factory):
|
|||||||
item.name: item for item in poetry.locker.locked_repository().packages
|
item.name: item for item in poetry.locker.locked_repository().packages
|
||||||
}
|
}
|
||||||
|
|
||||||
venv = tox.venv.VirtualEnv()
|
venv = tox.tox_env.python.virtual_env.runner.VirtualEnvRunner()
|
||||||
to_install = [packages["toml"], packages["toml"]]
|
to_install = [packages["toml"], packages["toml"]]
|
||||||
|
|
||||||
installer.install(poetry, venv, to_install)
|
installer.install(poetry, venv, to_install)
|
||||||
@ -43,12 +43,12 @@ def test_parallelization(mock_venv, mock_poetry_factory):
|
|||||||
packages["attrs"],
|
packages["attrs"],
|
||||||
]
|
]
|
||||||
|
|
||||||
venv_sequential = tox.venv.VirtualEnv()
|
venv_sequential = tox.tox_env.python.virtual_env.runner.VirtualEnvRunner()
|
||||||
start_sequential = time.time()
|
start_sequential = time.time()
|
||||||
installer.install(poetry, venv_sequential, to_install, 0)
|
installer.install(poetry, venv_sequential, to_install, 0)
|
||||||
sequential = time.time() - start_sequential
|
sequential = time.time() - start_sequential
|
||||||
|
|
||||||
venv_parallel = tox.venv.VirtualEnv()
|
venv_parallel = tox.tox_env.python.virtual_env.runner.VirtualEnvRunner()
|
||||||
start_parallel = time.time()
|
start_parallel = time.time()
|
||||||
installer.install(poetry, venv_parallel, to_install, 5)
|
installer.install(poetry, venv_parallel, to_install, 5)
|
||||||
parallel = time.time() - start_parallel
|
parallel = time.time() - start_parallel
|
||||||
@ -76,7 +76,7 @@ def test_propagates_exceptions_during_installation(
|
|||||||
item.name: item for item in poetry.locker.locked_repository().packages
|
item.name: item for item in poetry.locker.locked_repository().packages
|
||||||
}
|
}
|
||||||
to_install = [packages["toml"]]
|
to_install = [packages["toml"]]
|
||||||
venv = tox.venv.VirtualEnv()
|
venv = tox.tox_env.python.virtual_env.runner.VirtualEnvRunner()
|
||||||
fake_exception = ValueError("my testing exception")
|
fake_exception = ValueError("my testing exception")
|
||||||
|
|
||||||
with mock.patch.object(
|
with mock.patch.object(
|
||||||
|
7
tox.ini
7
tox.ini
@ -1,6 +1,5 @@
|
|||||||
[tox]
|
[tox]
|
||||||
envlist = py37, py38, py39, py310, py311, static, static-tests, security
|
envlist = py37, py38, py39, py310, py311, static, static-tests, security
|
||||||
isolated_build = true
|
|
||||||
skip_missing_interpreters = true
|
skip_missing_interpreters = true
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
@ -21,7 +20,7 @@ commands =
|
|||||||
|
|
||||||
[testenv:static]
|
[testenv:static]
|
||||||
description = Static formatting and quality enforcement
|
description = Static formatting and quality enforcement
|
||||||
basepython = python3.10
|
basepython = py3.10
|
||||||
platform = linux
|
platform = linux
|
||||||
ignore_errors = true
|
ignore_errors = true
|
||||||
locked_deps =
|
locked_deps =
|
||||||
@ -46,7 +45,7 @@ commands =
|
|||||||
|
|
||||||
[testenv:static-tests]
|
[testenv:static-tests]
|
||||||
description = Static formatting and quality enforcement for the tests
|
description = Static formatting and quality enforcement for the tests
|
||||||
basepython = python3.10
|
basepython = py3.10
|
||||||
platform = linux
|
platform = linux
|
||||||
ignore_errors = true
|
ignore_errors = true
|
||||||
locked_deps =
|
locked_deps =
|
||||||
@ -63,7 +62,7 @@ commands =
|
|||||||
|
|
||||||
[testenv:security]
|
[testenv:security]
|
||||||
description = Security checks
|
description = Security checks
|
||||||
basepython = python3.10
|
basepython = py3.10
|
||||||
platform = linux
|
platform = linux
|
||||||
ignore_errors = true
|
ignore_errors = true
|
||||||
skip_install = true
|
skip_install = true
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
# pylint: disable=missing-docstring
|
# pylint: disable=missing-docstring
|
||||||
from tox_poetry_installer.hooks import tox_addoption
|
from tox_poetry_installer.hooks import tox_add_core_config
|
||||||
from tox_poetry_installer.hooks import tox_testenv_install_deps
|
from tox_poetry_installer.hooks import tox_add_env_config
|
||||||
|
from tox_poetry_installer.hooks import tox_on_install
|
||||||
|
@ -5,14 +5,13 @@ specifically related to implementing the hooks (to keep the size/readability of
|
|||||||
themselves manageable).
|
themselves manageable).
|
||||||
"""
|
"""
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from typing import Optional
|
from typing import List
|
||||||
|
|
||||||
import tox
|
from tox.config.sets import ConfigSet
|
||||||
from tox.action import Action as ToxAction
|
from tox.config.sets import EnvConfigSet
|
||||||
from tox.config import Parser as ToxParser
|
from tox.plugin import impl
|
||||||
from tox.venv import VirtualEnv as ToxVirtualEnv
|
from tox.tox_env.api import ToxEnv as ToxVirtualEnv
|
||||||
|
|
||||||
from tox_poetry_installer import __about__
|
|
||||||
from tox_poetry_installer import constants
|
from tox_poetry_installer import constants
|
||||||
from tox_poetry_installer import exceptions
|
from tox_poetry_installer import exceptions
|
||||||
from tox_poetry_installer import installer
|
from tox_poetry_installer import installer
|
||||||
@ -20,142 +19,61 @@ from tox_poetry_installer import logger
|
|||||||
from tox_poetry_installer import utilities
|
from tox_poetry_installer import utilities
|
||||||
|
|
||||||
|
|
||||||
def _postprocess_install_project_deps(
|
@impl
|
||||||
testenv_config, value: Optional[str] # pylint: disable=unused-argument
|
def tox_add_core_config(core_conf: ConfigSet):
|
||||||
) -> Optional[bool]:
|
"""Add required core configuration options to the tox INI file"""
|
||||||
"""An awful hack to patch on three-state boolean logic to a config parameter
|
|
||||||
|
|
||||||
.. warning: This logic should 100% be removed in the next feature release. It's here to work
|
core_conf.add_config(
|
||||||
around a bad design for now but should not persist.
|
"parallel_install_threads",
|
||||||
|
of_type=int,
|
||||||
The bug filed in `#61`_ is caused by a combination of poor design and attempted cleverness. The
|
|
||||||
name of the ``install_project_deps`` config option implies that it has ultimate control over
|
|
||||||
whether the project dependencies are installed to the testenv, but this is not actually correct.
|
|
||||||
What it actually allows the user to do is force the project dependencies to not be installed to
|
|
||||||
an environment that would otherwise install them. This was intended behavior, however the
|
|
||||||
intention was wrong.
|
|
||||||
|
|
||||||
.. _`#61`: https://github.com/enpaul/tox-poetry-installer/issues/61
|
|
||||||
|
|
||||||
In an effort to be clever the plugin automatically skips installing project dependencies when
|
|
||||||
the project package is not installed to the testenv (``skip_install = true``) or if packaging
|
|
||||||
as a whole is disabled (``skipsdist = true``). The intention of this behavior is to install only
|
|
||||||
the expected dependencies to a testenv and no more. However, this conflicts with the
|
|
||||||
``install_project_deps`` config option, which cannot override this behavior because it defaults
|
|
||||||
to ``True``. In effect, ``install_project_deps = true`` in fact means "automatically
|
|
||||||
determine whether to install project dependencies" and ``install_project_deps = false`` means
|
|
||||||
"never install the project dependencies". This is not ideal and unintuitive.
|
|
||||||
|
|
||||||
To avoid having to make a breaking change this workaround has been added to support three-state
|
|
||||||
logic between ``True``, ``False``, and ``None``. The ``install_project_deps`` option is now
|
|
||||||
parsed by Tox as a string with a default value of ``None``. If the value is not ``None`` then
|
|
||||||
this post processing function will try to convert it to a boolean the same way that Tox's
|
|
||||||
`SectionReader.getbool()`_ method does, raising an error to mimic the default behavior if it
|
|
||||||
can't.
|
|
||||||
|
|
||||||
.. _`SectionReader.getbool()`: https://github.com/tox-dev/tox/blob/f8459218ee5ab5753321b3eb989b7beee5b391ad/src/tox/config/__init__.py#L1724
|
|
||||||
|
|
||||||
The three states for the ``install_project_deps`` setting are:
|
|
||||||
* ``None`` - User did not configure the setting, package dependency installation is
|
|
||||||
determined automatically
|
|
||||||
* ``True`` - User configured the setting to ``True``, package dependencies will be installed
|
|
||||||
* ``False`` - User configured the setting to ``False``, package dependencies will not be
|
|
||||||
installed
|
|
||||||
|
|
||||||
This config option should be deprecated with the 1.0.0 release and instead an option like
|
|
||||||
``always_install_project_deps`` should be added which overrides the default determination and
|
|
||||||
just installs the project dependencies. The counterpart (``never_install_project_deps``)
|
|
||||||
shouldn't be needed, since I don't think there's a real use case for that.
|
|
||||||
"""
|
|
||||||
if value is None:
|
|
||||||
return value
|
|
||||||
|
|
||||||
if value.lower() == "true":
|
|
||||||
return True
|
|
||||||
if value.lower() == "false":
|
|
||||||
return False
|
|
||||||
|
|
||||||
raise tox.exception.ConfigError(
|
|
||||||
f"install_project_deps: boolean value '{value}' needs to be 'True' or 'False'"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@tox.hookimpl
|
|
||||||
def tox_addoption(parser: ToxParser):
|
|
||||||
"""Add required configuration options to the tox INI file
|
|
||||||
|
|
||||||
Adds the ``require_locked_deps`` configuration option to the venv to check whether all
|
|
||||||
dependencies should be treated as locked or not.
|
|
||||||
"""
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"--require-poetry",
|
|
||||||
action="store_true",
|
|
||||||
dest="require_poetry",
|
|
||||||
help="(deprecated) Trigger a failure if Poetry is not available to Tox",
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"--parallelize-locked-install",
|
|
||||||
type=int,
|
|
||||||
dest="parallelize_locked_install",
|
|
||||||
default=None,
|
|
||||||
help="(deprecated) Number of worker threads to use for installing dependencies from the Poetry lockfile in parallel",
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_argument(
|
|
||||||
"--parallel-install-threads",
|
|
||||||
type=int,
|
|
||||||
dest="parallel_install_threads",
|
|
||||||
default=constants.DEFAULT_INSTALL_THREADS,
|
default=constants.DEFAULT_INSTALL_THREADS,
|
||||||
help="Number of locked dependencies to install simultaneously; set to 0 to disable parallel installation",
|
desc="Number of locked dependencies to install simultaneously; set to 0 to disable parallel installation",
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.add_testenv_attribute(
|
|
||||||
name="install_dev_deps",
|
|
||||||
type="bool",
|
|
||||||
default=False,
|
|
||||||
help="(deprecated) Automatically install all Poetry development dependencies to the environment",
|
|
||||||
)
|
|
||||||
|
|
||||||
parser.add_testenv_attribute(
|
@impl
|
||||||
name="poetry_dep_groups",
|
def tox_add_env_config(env_conf: EnvConfigSet):
|
||||||
type="line-list",
|
"""Add required env configuration options to the tox INI file"""
|
||||||
|
env_conf.add_config(
|
||||||
|
"poetry_dep_groups",
|
||||||
|
of_type=List[str],
|
||||||
default=[],
|
default=[],
|
||||||
help="List of Poetry dependency groups to install to the environment",
|
desc="List of Poetry dependency groups to install to the environment",
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.add_testenv_attribute(
|
env_conf.add_config(
|
||||||
name="install_project_deps",
|
"install_project_deps",
|
||||||
type="string",
|
of_type=bool,
|
||||||
default=None,
|
default=True,
|
||||||
help="Automatically install all Poetry primary dependencies to the environment",
|
desc="Automatically install all Poetry primary dependencies to the environment",
|
||||||
postprocess=_postprocess_install_project_deps,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.add_testenv_attribute(
|
env_conf.add_config(
|
||||||
name="require_locked_deps",
|
"require_locked_deps",
|
||||||
type="bool",
|
of_type=bool,
|
||||||
default=False,
|
default=False,
|
||||||
help="Require all dependencies in the environment be installed using the Poetry lockfile",
|
desc="Require all dependencies in the environment be installed using the Poetry lockfile",
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.add_testenv_attribute(
|
env_conf.add_config(
|
||||||
name="require_poetry",
|
"require_poetry",
|
||||||
type="bool",
|
of_type=bool,
|
||||||
default=False,
|
default=False,
|
||||||
help="Trigger a failure if Poetry is not available to Tox",
|
desc="Trigger a failure if Poetry is not available to Tox",
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.add_testenv_attribute(
|
env_conf.add_config(
|
||||||
name="locked_deps",
|
"locked_deps",
|
||||||
type="line-list",
|
of_type=List[str],
|
||||||
help="List of locked dependencies to install to the environment using the Poetry lockfile",
|
default=[],
|
||||||
|
desc="List of locked dependencies to install to the environment using the Poetry lockfile",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@tox.hookimpl
|
@impl
|
||||||
def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional[bool]:
|
def tox_on_install(
|
||||||
|
tox_env: ToxVirtualEnv, section: str # pylint: disable=unused-argument
|
||||||
|
) -> None:
|
||||||
"""Install the dependencies for the current environment
|
"""Install the dependencies for the current environment
|
||||||
|
|
||||||
Loads the local Poetry environment and the corresponding lockfile then pulls the dependencies
|
Loads the local Poetry environment and the corresponding lockfile then pulls the dependencies
|
||||||
@ -165,22 +83,20 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional
|
|||||||
:param venv: Tox virtual environment object with configuration for the local Tox environment.
|
:param venv: Tox virtual environment object with configuration for the local Tox environment.
|
||||||
:param action: Tox action object
|
:param action: Tox action object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
poetry = utilities.check_preconditions(venv, action)
|
poetry = utilities.check_preconditions(tox_env)
|
||||||
except exceptions.SkipEnvironment as err:
|
except exceptions.SkipEnvironment as err:
|
||||||
if isinstance(err, exceptions.PoetryNotInstalledError) and (
|
if isinstance(err, exceptions.PoetryNotInstalledError) and (
|
||||||
venv.envconfig.config.option.require_poetry or venv.envconfig.require_poetry
|
tox_env.core["require_poetry"] or tox_env.conf["require_poetry"]
|
||||||
):
|
):
|
||||||
venv.status = err.__class__.__name__
|
|
||||||
logger.error(str(err))
|
logger.error(str(err))
|
||||||
return False
|
raise err
|
||||||
logger.info(str(err))
|
logger.info(str(err))
|
||||||
return None
|
return
|
||||||
|
|
||||||
logger.info(f"Loaded project pyproject.toml from {poetry.file}")
|
logger.info(f"Loaded project pyproject.toml from {poetry.file}")
|
||||||
|
|
||||||
virtualenv = utilities.convert_virtualenv(venv)
|
virtualenv = utilities.convert_virtualenv(tox_env)
|
||||||
|
|
||||||
if not poetry.locker.is_fresh():
|
if not poetry.locker.is_fresh():
|
||||||
logger.warning(
|
logger.warning(
|
||||||
@ -188,28 +104,19 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional
|
|||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if venv.envconfig.require_locked_deps and venv.envconfig.deps:
|
if tox_env.conf["require_locked_deps"] and tox_env.conf["deps"].lines():
|
||||||
raise exceptions.LockedDepsRequiredError(
|
raise exceptions.LockedDepsRequiredError(
|
||||||
f"Unlocked dependencies '{venv.envconfig.deps}' specified for environment '{venv.name}' which requires locked dependencies"
|
f"Unlocked dependencies '{tox_env.conf['deps']}' specified for environment '{tox_env.name}' which requires locked dependencies"
|
||||||
)
|
)
|
||||||
|
|
||||||
packages = utilities.build_package_map(poetry)
|
packages = utilities.build_package_map(poetry)
|
||||||
|
|
||||||
if venv.envconfig.install_dev_deps:
|
|
||||||
dev_deps = utilities.find_dev_deps(packages, virtualenv, poetry)
|
|
||||||
logger.info(
|
|
||||||
f"Identified {len(dev_deps)} development dependencies to install to env"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
dev_deps = []
|
|
||||||
logger.info("Env does not install development dependencies, skipping")
|
|
||||||
|
|
||||||
group_deps = utilities.dedupe_packages(
|
group_deps = utilities.dedupe_packages(
|
||||||
list(
|
list(
|
||||||
chain(
|
chain(
|
||||||
*[
|
*[
|
||||||
utilities.find_group_deps(group, packages, virtualenv, poetry)
|
utilities.find_group_deps(group, packages, virtualenv, poetry)
|
||||||
for group in venv.envconfig.poetry_dep_groups
|
for group in tox_env.conf["poetry_dep_groups"]
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -219,7 +126,7 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional
|
|||||||
)
|
)
|
||||||
|
|
||||||
env_deps = utilities.find_additional_deps(
|
env_deps = utilities.find_additional_deps(
|
||||||
packages, virtualenv, poetry, venv.envconfig.locked_deps
|
packages, virtualenv, poetry, tox_env.conf["locked_deps"]
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
@ -227,16 +134,20 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional
|
|||||||
)
|
)
|
||||||
|
|
||||||
install_project_deps = (
|
install_project_deps = (
|
||||||
venv.envconfig.install_project_deps
|
tox_env.conf["install_project_deps"]
|
||||||
if venv.envconfig.install_project_deps is not None
|
if tox_env.conf["install_project_deps"] is not None
|
||||||
else (
|
else (not tox_env.conf["skip_install"] and not tox_env.core["no_package"])
|
||||||
not venv.envconfig.skip_install and not venv.envconfig.config.skipsdist
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# extras are not set in a testenv if skip_install=true
|
||||||
|
try:
|
||||||
|
extras = tox_env.conf["extras"]
|
||||||
|
except KeyError:
|
||||||
|
extras = []
|
||||||
|
|
||||||
if install_project_deps:
|
if install_project_deps:
|
||||||
project_deps = utilities.find_project_deps(
|
project_deps = utilities.find_project_deps(
|
||||||
packages, virtualenv, poetry, venv.envconfig.extras
|
packages, virtualenv, poetry, extras
|
||||||
)
|
)
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Identified {len(project_deps)} project dependencies to install to env"
|
f"Identified {len(project_deps)} project dependencies to install to env"
|
||||||
@ -245,39 +156,18 @@ def tox_testenv_install_deps(venv: ToxVirtualEnv, action: ToxAction) -> Optional
|
|||||||
project_deps = []
|
project_deps = []
|
||||||
logger.info("Env does not install project package dependencies, skipping")
|
logger.info("Env does not install project package dependencies, skipping")
|
||||||
except exceptions.ToxPoetryInstallerException as err:
|
except exceptions.ToxPoetryInstallerException as err:
|
||||||
venv.status = err.__class__.__name__
|
|
||||||
logger.error(str(err))
|
logger.error(str(err))
|
||||||
return False
|
raise err
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
venv.status = "InternalError"
|
# tox_env.status = "InternalError"
|
||||||
logger.error(f"Internal plugin error: {err}")
|
logger.error(f"Internal plugin error: {err}")
|
||||||
raise err
|
raise err
|
||||||
|
|
||||||
dependencies = utilities.dedupe_packages(
|
dependencies = utilities.dedupe_packages(group_deps + env_deps + project_deps)
|
||||||
dev_deps + group_deps + env_deps + project_deps
|
|
||||||
)
|
|
||||||
if (
|
|
||||||
venv.envconfig.config.option.parallel_install_threads
|
|
||||||
!= constants.DEFAULT_INSTALL_THREADS
|
|
||||||
):
|
|
||||||
parallel_threads = venv.envconfig.config.option.parallel_install_threads
|
|
||||||
else:
|
|
||||||
parallel_threads = (
|
|
||||||
venv.envconfig.config.option.parallelize_locked_install
|
|
||||||
if venv.envconfig.config.option.parallelize_locked_install is not None
|
|
||||||
else constants.DEFAULT_INSTALL_THREADS
|
|
||||||
)
|
|
||||||
log_parallel = f" (using {parallel_threads} threads)" if parallel_threads else ""
|
|
||||||
|
|
||||||
action.setactivity(
|
|
||||||
__about__.__title__,
|
|
||||||
f"Installing {len(dependencies)} dependencies from Poetry lock file{log_parallel}",
|
|
||||||
)
|
|
||||||
installer.install(
|
installer.install(
|
||||||
poetry,
|
poetry,
|
||||||
venv,
|
tox_env,
|
||||||
dependencies,
|
dependencies,
|
||||||
parallel_threads,
|
tox_env.core["parallel_install_threads"],
|
||||||
)
|
)
|
||||||
|
|
||||||
return venv.envconfig.require_locked_deps or None
|
|
||||||
|
@ -10,7 +10,7 @@ from typing import Collection
|
|||||||
from typing import Set
|
from typing import Set
|
||||||
|
|
||||||
from poetry.core.packages.package import Package as PoetryPackage
|
from poetry.core.packages.package import Package as PoetryPackage
|
||||||
from tox.venv import VirtualEnv as ToxVirtualEnv
|
from tox.tox_env.api import ToxEnv as ToxVirtualEnv
|
||||||
|
|
||||||
from tox_poetry_installer import logger
|
from tox_poetry_installer import logger
|
||||||
from tox_poetry_installer import utilities
|
from tox_poetry_installer import utilities
|
||||||
@ -35,9 +35,7 @@ def install(
|
|||||||
"""
|
"""
|
||||||
from tox_poetry_installer import _poetry
|
from tox_poetry_installer import _poetry
|
||||||
|
|
||||||
logger.info(
|
logger.info(f"Installing {len(packages)} packages to environment at {venv.env_dir}")
|
||||||
f"Installing {len(packages)} packages to environment at {venv.envconfig.envdir}"
|
|
||||||
)
|
|
||||||
|
|
||||||
pip = _poetry.PipInstaller(
|
pip = _poetry.PipInstaller(
|
||||||
env=utilities.convert_virtualenv(venv),
|
env=utilities.convert_virtualenv(venv),
|
||||||
|
@ -4,26 +4,26 @@ Calling ``tox.reporter.something()`` and having to format a string with the pref
|
|||||||
gets really old fast, but more importantly it also makes the flow of the main code
|
gets really old fast, but more importantly it also makes the flow of the main code
|
||||||
more difficult to follow because of the added complexity.
|
more difficult to follow because of the added complexity.
|
||||||
"""
|
"""
|
||||||
import tox
|
import logging
|
||||||
|
|
||||||
from tox_poetry_installer import constants
|
from tox_poetry_installer import constants
|
||||||
|
|
||||||
|
|
||||||
def error(message: str):
|
def error(message: str):
|
||||||
"""Wrapper around :func:`tox.reporter.error`"""
|
"""Wrapper around :func:`logging.error` that prefixes the reporter prefix onto the message"""
|
||||||
tox.reporter.error(f"{constants.REPORTER_PREFIX} {message}")
|
logging.error(f"{constants.REPORTER_PREFIX} {message}")
|
||||||
|
|
||||||
|
|
||||||
def warning(message: str):
|
def warning(message: str):
|
||||||
"""Wrapper around :func:`tox.reporter.warning`"""
|
"""Wrapper around :func:`logging.warning`"""
|
||||||
tox.reporter.warning(f"{constants.REPORTER_PREFIX} {message}")
|
logging.warning(f"{constants.REPORTER_PREFIX} {message}")
|
||||||
|
|
||||||
|
|
||||||
def info(message: str):
|
def info(message: str):
|
||||||
"""Wrapper around :func:`tox.reporter.verbosity1`"""
|
"""Wrapper around :func:`logging.info`"""
|
||||||
tox.reporter.verbosity1(f"{constants.REPORTER_PREFIX} {message}")
|
logging.info(f"{constants.REPORTER_PREFIX} {message}")
|
||||||
|
|
||||||
|
|
||||||
def debug(message: str):
|
def debug(message: str):
|
||||||
"""Wrapper around :func:`tox.reporter.verbosity2`"""
|
"""Wrapper around :func:`logging.debug`"""
|
||||||
tox.reporter.verbosity2(f"{constants.REPORTER_PREFIX} {message}")
|
logging.debug(f"{constants.REPORTER_PREFIX} {message}")
|
||||||
|
@ -12,8 +12,8 @@ from typing import Set
|
|||||||
|
|
||||||
from poetry.core.packages.dependency import Dependency as PoetryDependency
|
from poetry.core.packages.dependency import Dependency as PoetryDependency
|
||||||
from poetry.core.packages.package import Package as PoetryPackage
|
from poetry.core.packages.package import Package as PoetryPackage
|
||||||
from tox.action import Action as ToxAction
|
from tox.tox_env.api import ToxEnv as ToxVirtualEnv
|
||||||
from tox.venv import VirtualEnv as ToxVirtualEnv
|
from tox.tox_env.package import PackageToxEnv
|
||||||
|
|
||||||
from tox_poetry_installer import constants
|
from tox_poetry_installer import constants
|
||||||
from tox_poetry_installer import exceptions
|
from tox_poetry_installer import exceptions
|
||||||
@ -26,50 +26,28 @@ if typing.TYPE_CHECKING:
|
|||||||
PackageMap = Dict[str, List[PoetryPackage]]
|
PackageMap = Dict[str, List[PoetryPackage]]
|
||||||
|
|
||||||
|
|
||||||
def check_preconditions(venv: ToxVirtualEnv, action: ToxAction) -> "_poetry.Poetry":
|
def check_preconditions(venv: ToxVirtualEnv) -> "_poetry.Poetry":
|
||||||
"""Check that the local project environment meets expectations"""
|
"""Check that the local project environment meets expectations"""
|
||||||
|
|
||||||
# Skip running the plugin for the provisioning environment. The provisioned environment,
|
# Skip running the plugin for the provisioning environment. The provisioned environment,
|
||||||
# for alternative Tox versions and/or the ``requires`` meta dependencies is specially
|
# for alternative Tox versions and/or the ``requires`` meta dependencies is specially
|
||||||
# handled by Tox and is out of scope for this plugin. Since one of the ways to install this
|
# handled by Tox and is out of scope for this plugin. Since one of the ways to install this
|
||||||
# plugin in the first place is via the Tox provisioning environment, it quickly becomes a
|
# plugin in the first place is via the Tox provisioning environment, it quickly becomes a
|
||||||
# chicken-and-egg problem.
|
# chicken-and-egg problem.
|
||||||
if action.name == venv.envconfig.config.provision_tox_env:
|
if isinstance(venv, PackageToxEnv):
|
||||||
raise exceptions.SkipEnvironment(
|
raise exceptions.SkipEnvironment(f"Skipping Tox provisioning env '{venv.name}'")
|
||||||
f"Skipping Tox provisioning env '{action.name}'"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Skip running the plugin for the packaging environment. PEP-517 front ends can handle
|
if venv.conf["require_poetry"]:
|
||||||
# that better than we can, so let them do their thing. More to the point: if you're having
|
|
||||||
# problems in the packaging env that this plugin would solve, god help you.
|
|
||||||
if action.name == venv.envconfig.config.isolated_build_env:
|
|
||||||
raise exceptions.SkipEnvironment(
|
|
||||||
f"Skipping isolated packaging build env '{action.name}'"
|
|
||||||
)
|
|
||||||
|
|
||||||
if venv.envconfig.config.option.require_poetry:
|
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"DEPRECATION: The '--require-poetry' runtime option is deprecated and will be "
|
"DEPRECATION: The '--require-poetry' runtime option is deprecated and will be "
|
||||||
"removed in version 1.0.0. Please update test environments that require Poetry to "
|
"removed in version 1.0.0. Please update test environments that require Poetry to "
|
||||||
"set the 'require_poetry = true' option in tox.ini"
|
"set the 'require_poetry = true' option in tox.ini"
|
||||||
)
|
)
|
||||||
|
|
||||||
if venv.envconfig.config.option.parallelize_locked_install is not None:
|
|
||||||
logger.warning(
|
|
||||||
"DEPRECATION: The '--parallelize-locked-install' option is deprecated and will "
|
|
||||||
"be removed in version 1.0.0. Please use the '--parallel-install-threads' option."
|
|
||||||
)
|
|
||||||
|
|
||||||
if venv.envconfig.install_dev_deps:
|
|
||||||
logger.warning(
|
|
||||||
"DEPRECATION: The 'install_dev_deps' option is deprecated and will be removed in "
|
|
||||||
"version 1.0.0. Please update test environments that install development dependencies "
|
|
||||||
"to set the 'poetry_dev_groups = [dev]' option in tox.ini"
|
|
||||||
)
|
|
||||||
|
|
||||||
from tox_poetry_installer import _poetry
|
from tox_poetry_installer import _poetry
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return _poetry.Factory().create_poetry(venv.envconfig.config.toxinidir)
|
return _poetry.Factory().create_poetry(venv.core["tox_root"])
|
||||||
# Support running the plugin when the current tox project does not use Poetry for its
|
# Support running the plugin when the current tox project does not use Poetry for its
|
||||||
# environment/dependency management.
|
# environment/dependency management.
|
||||||
#
|
#
|
||||||
@ -89,7 +67,7 @@ def convert_virtualenv(venv: ToxVirtualEnv) -> "_poetry.VirtualEnv":
|
|||||||
"""
|
"""
|
||||||
from tox_poetry_installer import _poetry
|
from tox_poetry_installer import _poetry
|
||||||
|
|
||||||
return _poetry.VirtualEnv(path=Path(venv.envconfig.envdir))
|
return _poetry.VirtualEnv(path=Path(venv.env_dir))
|
||||||
|
|
||||||
|
|
||||||
def build_package_map(poetry: "_poetry.Poetry") -> PackageMap:
|
def build_package_map(poetry: "_poetry.Poetry") -> PackageMap:
|
||||||
|
Loading…
Reference in New Issue
Block a user