Skip to content

Commit

Permalink
Merge branch 'release-0.0.4' into releases-0.0.x
Browse files Browse the repository at this point in the history
  • Loading branch information
sinoroc committed Oct 13, 2020
2 parents ca53fcf + 08b730e commit 502b0a5
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 56 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# Python
/*.egg
/.eggs/
/.mypy_cache/
/.pytest_cache/
/.tox/
/.venv/
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@

.. Keep the current version number on line number 6
0.0.4
=====

*2020-10-13*

* Rename setting ``add_poetry_dev_dependencies`` to ``poetry_add_dev_dependencies``.
* Add the ``poetry_experimental_add_locked_dependencies`` setting to let Tox add Poetry's locked dependencies from Poetry's lockfile (experimental feature).
* Remove the *PEP 396* ``__version__``. This also allows getting rid of the dependency on `importlib-metadata``.


0.0.3
=====

Expand Down
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ source_dir := ./src
tests_dir := ./test


.DEFAULT_GOAL := refresh
.DEFAULT_GOAL := all


.PHONY: all
all: develop review package


.PHONY: refresh
refresh: clean develop review package
refresh: clean all


.PHONY: develop
Expand Down Expand Up @@ -91,6 +95,7 @@ review: check
.PHONY: clean
clean:
$(RM) --recursive ./.eggs/
$(RM) --recursive ./.mypy_cache/
$(RM) --recursive ./.pytest_cache/
$(RM) --recursive ./build/
$(RM) --recursive ./dist/
Expand Down
59 changes: 44 additions & 15 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
..

.. contents::
:backlinks: none


Introduction
============

Tox plugin to let Tox know about Poetry's development dependencies.
Tox plugin to help working with Poetry-based projects.


Repositories
Expand All @@ -24,35 +28,33 @@ Source code:
Usage
=====

Installation
------------
By default the plugin does not do anything. Use one of the following settings to activate the corresponding features.

It is a plugin for Tox and it is available on PyPI, install it however best fits the workflow. A useful thing to know though, is that starting with Tox version *3.8* it is possible to enforce the installation (in an isolated environment) of the plugin directly from within the ``tox.ini`` file, thanks to the ``requires`` setting (Tox *3.2*) and the *auto-provisioning* feature (Tox *3.8*):

.. code::
``poetry_experimental_add_locked_dependencies``
-----------------------------------------------

[tox]
requires =
tox-poetry-dev-dependencies
Set the ``testenv`` setting ``poetry_experimental_add_locked_dependencies`` to ``True`` to let Tox add Poetry's locked dependencies from the *lockfile* to the ``deps`` list in the test environment.

.. code::
* https://tox.readthedocs.io/en/latest/config.html#conf-requires
* https://tox.readthedocs.io/en/latest/example/basic.html#tox-auto-provisioning
[testenv:example]
# ...
poetry_experimental_add_locked_dependencies = True
By default the plugin does not do anything. Use one of the following settings to activate the corresponding features.
If ``poetry_add_dev_dependencies`` is set as well then the development dependencies are added with the version from the *lockfile*.


``add_poetry_dev_dependencies``
``poetry_add_dev_dependencies``
-------------------------------

Set the ``testenv`` setting ``add_poetry_dev_dependencies`` to ``True`` to let Tox install Poetry's development dependencies in the test environment.
Set the ``testenv`` setting ``poetry_add_dev_dependencies`` to ``True`` to let Tox add Poetry's development dependencies to the ``deps`` list in the test environment.

.. code::
[testenv:example]
# ...
add_poetry_dev_dependencies = True
poetry_add_dev_dependencies = True
``poetry_use_source_repos``
Expand Down Expand Up @@ -122,4 +124,31 @@ This might be useful in cases where all the required dependencies and tools are

For such environments it might be best to skip the installation of the project (``skip_install``) as well as keeping the list of dependencies empty (``deps``).


Appendix
========

Installation
------------

It is a plugin for Tox and it is available on PyPI, install it however best fits the workflow. A useful thing to know though, is that starting with Tox version *3.8* it is possible to enforce the installation (in an isolated environment) of the plugin directly from within the ``tox.ini`` file, thanks to the ``requires`` setting (Tox *3.2*) and the *auto-provisioning* feature (Tox *3.8*):

.. code::
[tox]
requires =
tox-poetry-dev-dependencies
* https://tox.readthedocs.io/en/latest/config.html#conf-requires
* https://tox.readthedocs.io/en/latest/example/basic.html#tox-auto-provisioning


Similar projects
----------------

* https://pypi.org/project/tox-poetry-installer/
* https://pypi.org/project/tox-poetry/


.. EOF
6 changes: 3 additions & 3 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ warn_unreachable = True
warn_unused_configs = True
warn_unused_ignores = True

[mypy-importlib_metadata.*]
ignore_missing_imports = True

[mypy-poetry.*]
ignore_missing_imports = True

[mypy-setuptools.*]
ignore_missing_imports = True

[mypy-tomlkit.*]
ignore_missing_imports = True

[mypy-tox.*]
ignore_missing_imports = True

Expand Down
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ classifiers =
Programming Language :: Python :: 3.8
Topic :: Software Development :: Testing
Typing :: Typed
description = Let Tox know about Poetry's development dependencies
description = Tox plugin to help working with Poetry-based projects
license = Apache-2.0
license_file = LICENSE.txt
long_description = file: README.rst
Expand All @@ -33,8 +33,8 @@ url = https://pypi.org/project/tox-poetry-dev-dependencies/

[options]
install_requires =
importlib-metadata
poetry-core ~= 1.0
tomlkit
tox
package_dir =
= src
Expand Down
6 changes: 1 addition & 5 deletions src/tox_poetry_dev_dependencies/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
#

"""tox-poetry-dev-dependencies."""

from . import _meta

__version__ = _meta.VERSION # PEP 396
"""Tox plugin to help working with Poetry-based projects."""

# EOF
93 changes: 83 additions & 10 deletions src/tox_poetry_dev_dependencies/_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import typing

import poetry.core.factory
import tomlkit
import tox

if typing.TYPE_CHECKING:
Expand All @@ -17,6 +18,8 @@
PIP_DEFAULT_INDEX_SERVER_URL = 'https://pypi.org/simple'
PIP_DEFAULT_INDEX_SERVER_NAME = 'pypi'

POETRY_LOCKFILE_FILE_NAME = 'poetry.lock'


class _Exception(Exception):
"""Base exception."""
Expand All @@ -38,7 +41,7 @@ class CanNotHaveMultipleDefaultSourceRepositories(_Exception):
def tox_addoption(parser: tox.config.Parser) -> None:
"""Set hook."""
parser.add_testenv_attribute(
'add_poetry_dev_dependencies',
'poetry_add_dev_dependencies',
'bool',
"Add Poetry's 'dev-dependencies' to the test environment.",
default=False,
Expand All @@ -47,20 +50,41 @@ def tox_addoption(parser: tox.config.Parser) -> None:
'poetry_use_source_repos',
'string',
(
"Use Poetry's source repositories. Set 'pip_env_vars' to set as "
"Pip environment variables ('PIP_INDEX_URL', and "
"'PIP_EXTRA_INDEX_URL')."
"Use Poetry's source repositories. Set 'pip_env_vars' to set as"
" Pip environment variables ('PIP_INDEX_URL' and"
" 'PIP_EXTRA_INDEX_URL')."
),
)
parser.add_testenv_attribute(
'poetry_experimental_no_virtual_env',
'bool',
"Do not create a virtual environment.",
"(EXPERIMENTAL) Do not create a virtual environment.",
default=False,
)
parser.add_testenv_attribute(
'poetry_experimental_add_locked_dependencies',
'bool',
(
"(EXPERIMENTAL) Add Poetry's locked dependencies from the lockfile"
" to 'deps' in the test environment."
),
default=False,
)


def _is_test_env(env_config: tox.config.TestenvConfig) -> bool:
"""Check if it is a test environment.
Tox creates environments for provisioning (`.tox`) and for isolated build
(`.packaging`) in addition to the usual test environments. And in hooks
such as `tox_testenv_create` it is not clear if the environment is a test
environment or one of those environments used for tox's own purposes.
So we start by excluding the provisioning environment named after
`provision_tox_env` and the build isolation environment named after
`isolated_build_env`. Then we keep only the environments listed in
`envlist`.
"""
#
is_test_env = False
#
Expand All @@ -87,11 +111,18 @@ def _is_test_env(env_config: tox.config.TestenvConfig) -> bool:
@tox.hookimpl # type: ignore[misc]
def tox_configure(config: tox.config.Config) -> None:
"""Set hook."""
#
project_dir_path = pathlib.Path(config.setupdir)
#
try:
poetry_ = _get_poetry(config.setupdir)
poetry_ = _get_poetry(project_dir_path)
except (NoPoetryFound, NoPyprojectTomlFound):
pass
else:
#
locked_deps = _get_locked_deps(project_dir_path)
_add_locked_dependencies(config, locked_deps)
#
dev_deps = _get_dev_requirements(poetry_)
_add_dev_dependencies(config, dev_deps)
#
Expand Down Expand Up @@ -132,10 +163,11 @@ def _add_dev_dependencies(
) -> None:
#
for env_config in tox_config.envconfigs.values():
if _is_test_env(env_config):
if env_config.add_poetry_dev_dependencies is True:
for dep_config in dev_dep_configs:
env_config.deps.append(dep_config)
if env_config.poetry_experimental_add_locked_dependencies is not True:
if _is_test_env(env_config):
if env_config.poetry_add_dev_dependencies is True:
for dep_config in dev_dep_configs:
env_config.deps.append(dep_config)


def _add_index_servers(
Expand Down Expand Up @@ -167,6 +199,21 @@ def _add_index_servers_as_pip_env_vars(
)


def _add_locked_dependencies(
tox_config: tox.config.Config,
locked_deps: typing.Mapping[str, typing.List[tox.config.DepConfig]],
) -> None:
#
for env_config in tox_config.envconfigs.values():
if _is_test_env(env_config):
if env_config.poetry_experimental_add_locked_dependencies is True:
for dep_config in locked_deps['main']:
env_config.deps.append(dep_config)
if env_config.poetry_add_dev_dependencies is True:
for dep_config in locked_deps['dev']:
env_config.deps.append(dep_config)


def _get_poetry(project_root_path: pathlib.Path) -> poetry.core.poetry.Poetry:
poetry_factory = poetry.core.factory.Factory()
try:
Expand Down Expand Up @@ -245,4 +292,30 @@ def _get_index_servers(
return index_servers


def _get_locked_deps(
project_root_path: pathlib.Path,
) -> typing.Dict[str, typing.List[tox.config.DepConfig]]:
#
locked_deps: typing.Dict[str, typing.List[tox.config.DepConfig]] = {}
#
lock_file_path = project_root_path.joinpath(POETRY_LOCKFILE_FILE_NAME)
if lock_file_path.is_file():
#
lock_str = lock_file_path.read_text()
lock_document = tomlkit.parse(lock_str)
#
for dependency in lock_document['package']:
#
dep_name = dependency['name']
dep_version = dependency['version']
#
dep_pep_508 = f'{dep_name}=={dep_version}'
#
dep_category = dependency['category']
dep_config = tox.config.DepConfig(dep_pep_508)
locked_deps.setdefault(dep_category, []).append(dep_config)
#
return locked_deps


# EOF
13 changes: 0 additions & 13 deletions src/tox_poetry_dev_dependencies/_meta.py

This file was deleted.

12 changes: 6 additions & 6 deletions test/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

"""Unit tests."""

import types
import unittest

import tox_poetry_dev_dependencies


class TestProjectVersion(unittest.TestCase):
"""Project version string."""
class TestDummy(unittest.TestCase):
"""Dummy."""

def test_project_has_version_string(self) -> None:
"""Project should have a vesion string."""
self.assertIn('__version__', dir(tox_poetry_dev_dependencies))
self.assertIsInstance(tox_poetry_dev_dependencies.__version__, str)
def test_dummy(self) -> None:
"""Dummy test."""
self.assertIsInstance(tox_poetry_dev_dependencies, types.ModuleType)


# EOF

0 comments on commit 502b0a5

Please sign in to comment.