Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Poetry dependency groups and drop nox-poetry #679

Draft
wants to merge 81 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
c809df1
update poetry.lock
cjolowicz Nov 13, 2021
e7b6443
pyproject.toml: rename dev-dependencies to group.dev.dependencies
cjolowicz Nov 13, 2021
6f8026a
pyproject.toml: add dependency group for pre-commit
cjolowicz Nov 13, 2021
eb00b25
noxfile: use pre-commit dependency group
cjolowicz Nov 13, 2021
36bcb47
pyproject.toml: add setuptools to pre-commit group (for bandit)
cjolowicz Nov 13, 2021
d62a636
pyproject.toml: add dependency group for safety
cjolowicz Nov 13, 2021
d66427d
noxfile: use safety dependency group
cjolowicz Nov 13, 2021
5b65c32
pyproject.toml: add coverage dependency group
cjolowicz Nov 13, 2021
8b8c1b8
noxfile: use coverage dependency group in coverage session
cjolowicz Nov 13, 2021
c9cc943
pyproject.toml: add tests dependency group
cjolowicz Nov 13, 2021
29545bb
noxfile: install coverage and tests dependencies in tests session
cjolowicz Nov 13, 2021
525afda
pyproject.toml: add mypy dependency group
cjolowicz Nov 13, 2021
ea23366
noxfile: install mypy and test dependency groups in mypy session
cjolowicz Nov 13, 2021
f3e25fb
pyproject.toml: add typeguard dependency group
cjolowicz Nov 13, 2021
e4d49f1
noxfile: install typeguard and tests dependency groups in typeguard s…
cjolowicz Nov 13, 2021
3d87b63
pyproject.toml: add xdoctest dependency group
cjolowicz Nov 13, 2021
5f5e0c8
noxfile: install xdoctest dependency group in xdoctest session
cjolowicz Nov 13, 2021
4b1768b
pyproject.toml: add docs dependency group
cjolowicz Nov 13, 2021
1794d14
noxfile: install docs dependency group in docs and docs-build sessions
cjolowicz Nov 13, 2021
f612fb2
noxfile: use session.run_always for `poetry install`
cjolowicz Nov 13, 2021
8668b02
noxfile: remove unused import for `nox_poetry.session`
cjolowicz Nov 13, 2021
7c385ac
noxfile: extract function `install`
cjolowicz Nov 13, 2021
e8ddad7
noxfile: use qualified name for nox_poetry.Session
cjolowicz Nov 13, 2021
7a3bcd6
noxfile: work around skipped install for coverage on Python 3.10
cjolowicz Nov 13, 2021
98351b8
noxfile: copy nox_poetry.sessions._PoetrySession.installroot
cjolowicz Nov 13, 2021
ed11c0a
noxfile: remove unused parameters from `installroot`
cjolowicz Nov 13, 2021
d16f84e
noxfile: remove dead code for `extras`
cjolowicz Nov 13, 2021
12b5944
noxfile: inline variable `distribution_format`
cjolowicz Nov 13, 2021
634e42c
noxfile: do not pass constraints when installing the root package
cjolowicz Nov 13, 2021
3395350
noxfile: do not uninstall root package before installation
cjolowicz Nov 13, 2021
5c34a99
noxfile: use try...else
cjolowicz Nov 13, 2021
cf5595c
noxfile: inline Session_install
cjolowicz Nov 13, 2021
50d928e
noxfile: use qualified name for `CommandSkippedError`
cjolowicz Nov 13, 2021
77a3125
noxfile: copy nox_poetry.sessions._PoetrySession.build_package
cjolowicz Nov 13, 2021
b643e79
noxfile: remove parameter `distribution_format` from `build_package`
cjolowicz Nov 13, 2021
01731a1
noxfile: inline distributionformat.wheel
cjolowicz Nov 13, 2021
ad261f0
noxfile: copy nox_poetry.poetry.Poetry.build
cjolowicz Nov 13, 2021
6d27700
noxfile: remove parameter `format` from `build`
cjolowicz Nov 13, 2021
b4d1e56
noxfile: inline function `build`
cjolowicz Nov 13, 2021
37bd318
noxfile: pass nox.Session to `build_package`
cjolowicz Nov 13, 2021
44e6a84
noxfile: remove middle man
cjolowicz Nov 13, 2021
07c4b88
noxfile: remove middle man `_PoetrySession`
cjolowicz Nov 13, 2021
58c6441
noxfile: inline function `build_package`
cjolowicz Nov 13, 2021
f392306
noxfile: replace try...except with early return
cjolowicz Nov 13, 2021
f0351cc
noxfile: inline variables `url` and `package`
cjolowicz Nov 13, 2021
254133b
noxfile: document signature of `installroot`
cjolowicz Nov 13, 2021
3115ebe
noxfile: add comment to early return
cjolowicz Nov 13, 2021
693c001
noxfile: do not import internal modules from nox_poetry
cjolowicz Nov 13, 2021
b0c01a1
noxfile: require `only`
cjolowicz Nov 13, 2021
066f1b1
noxfile: replace `only` with `root`
cjolowicz Nov 13, 2021
b2285c5
noxfile: install root by default in `install`
cjolowicz Nov 13, 2021
236ab89
noxfile: use early return
cjolowicz Nov 13, 2021
67fc5e7
noxfile: inline function `installroot`
cjolowicz Nov 13, 2021
a799615
noxfile: update docstring
cjolowicz Nov 13, 2021
d91fc57
noxfile: copy function nox_poetry.sessions._PoetrySession.export_requ…
cjolowicz Nov 13, 2021
104b124
noxfile: do not convert requirements to constraints
cjolowicz Nov 13, 2021
502f870
noxfile: ignore attr-defined due to type stub
cjolowicz Nov 13, 2021
3224128
noxfile: copy function `nox_poetry.poetry.Poetry.export`
cjolowicz Nov 13, 2021
cca9740
noxfile: do not cache requirements files
cjolowicz Nov 13, 2021
3566543
noxfile: inline nox_poetry.poetry.Poetry.config
cjolowicz Nov 13, 2021
6b25054
noxfile: copy nox_poetry.poetry.Config.extras
cjolowicz Nov 13, 2021
8df6bea
noxfile: inline function `extras`
cjolowicz Nov 13, 2021
1222bc5
noxfile: remove redundant copy of extras
cjolowicz Nov 13, 2021
2da3667
noxfile: export requirements without extras because we don't have tom…
cjolowicz Nov 13, 2021
69e5595
noxfile: remove middle man
cjolowicz Nov 13, 2021
796a384
noxfile: inline function `export`
cjolowicz Nov 13, 2021
3398bcd
noxfile: use session.skip instead of raising an exception
cjolowicz Nov 13, 2021
020b075
noxfile: use session.cache_dir for requirements
cjolowicz Nov 13, 2021
5d5c43a
noxfile: slide `path` assignment
cjolowicz Nov 13, 2021
fc6fb7b
noxfile: update docstring for `export_requirements`
cjolowicz Nov 13, 2021
8905d11
noxfile: remove nox_poetry imports
cjolowicz Nov 13, 2021
c7e5399
CONTRIBUTING: remove nox-poetry
cjolowicz Nov 13, 2021
fba6600
noxfile: add extras parameter to export_requirements
cjolowicz Nov 13, 2021
9be145d
CI: bump poetry from 1.1.11 to 1.2.0a2
cjolowicz Nov 13, 2021
dfbb0c2
CI: debug
cjolowicz Nov 13, 2021
942af81
CI: fix
cjolowicz Nov 13, 2021
80f8d61
CI: do not install nox-poetry
cjolowicz Nov 13, 2021
3601ac6
CI: fix project build requirements for RTD
cjolowicz Nov 13, 2021
a665b70
noxfile: remove --dev from poetry export command
cjolowicz Nov 13, 2021
0ecd002
noxfile: replace inline code with `pip install .`
cjolowicz Nov 13, 2021
90e45ce
noxfile: update docstring for `install`
cjolowicz Nov 13, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/constraints.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
pip==21.3.1
nox==2021.10.1
nox-poetry==0.8.6
poetry==1.1.11
virtualenv==20.10.0
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:

- name: Install Poetry
run: |
pip install --constraint=.github/workflows/constraints.txt poetry
pipx install poetry==1.2.0a2
poetry --version

- name: Check if there is a parent commit
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,12 @@ jobs:

- name: Install Poetry
run: |
pipx install --pip-args=--constraint=.github/workflows/constraints.txt poetry
pipx install poetry==1.2.0a2
poetry --version

- name: Install Nox
run: |
pipx install --pip-args=--constraint=.github/workflows/constraints.txt nox
pipx inject --pip-args=--constraint=.github/workflows/constraints.txt nox nox-poetry
nox --version

- name: Compute pre-commit cache key
Expand Down Expand Up @@ -117,13 +116,12 @@ jobs:

- name: Install Poetry
run: |
pipx install --pip-args=--constraint=.github/workflows/constraints.txt poetry
pipx install poetry==1.2.0a2
poetry --version

- name: Install Nox
run: |
pipx install --pip-args=--constraint=.github/workflows/constraints.txt nox
pipx inject --pip-args=--constraint=.github/workflows/constraints.txt nox nox-poetry
nox --version

- name: Download coverage data
Expand Down
2 changes: 0 additions & 2 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ You need Python 3.7+ and the following tools:

- Poetry_
- Nox_
- nox-poetry_

Install the package with development requirements:

Expand All @@ -65,7 +64,6 @@ or the command-line interface:

.. _Poetry: https://python-poetry.org/
.. _Nox: https://nox.thea.codes/
.. _nox-poetry: https://nox-poetry.readthedocs.io/


How to test the project
Expand Down
176 changes: 115 additions & 61 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,15 @@
import sys
from pathlib import Path
from textwrap import dedent
from typing import Iterable
from typing import Iterator

import nox

try:
from nox_poetry import Session
from nox_poetry import session
except ImportError:
message = f"""\
Nox failed to import the 'nox-poetry' package.

Please install it using the following command:

{sys.executable} -m pip install nox-poetry"""
raise SystemExit(dedent(message)) from None


package = "cookiecutter_hypermodern_python_instance"
python_versions = ["3.10", "3.9", "3.8", "3.7"]
nox.needs_version = ">= 2021.6.6"
nox.needs_version = ">= 2021.10.1"
nox.options.sessions = (
"pre-commit",
"safety",
Expand All @@ -33,7 +23,84 @@
)


def activate_virtualenv_in_precommit_hooks(session: Session) -> None:
def install(session: nox.Session, *, groups: Iterable[str], root: bool = True) -> None:
"""Install the dependency groups using Poetry.

This function installs the given dependency groups into the session's
virtual environment. When ``root`` is true (the default), the function
also installs the root package and its default dependencies.

To avoid an editable install, the root package is not installed using
``poetry install``. Instead, the function invokes ``pip install .``
to perform a PEP 517 build.

Args:
session: The Session object.
groups: The dependency groups to install.
root: Install the root package.
"""
session.run_always(
"poetry",
"install",
"--no-root",
"--sync",
"--{}={}".format("only" if not root else "with", ",".join(groups)),
external=True,
)
if root:
session.install(".")


def export_requirements(session: nox.Session, *, extras: Iterable[str] = ()) -> Path:
"""Export a requirements file from Poetry.

This function uses ``poetry export`` to generate a requirements file
containing the default dependencies at the versions specified in
``poetry.lock``.

Args:
session: The Session object.
extras: Extras supported by the project.

Returns:
The path to the requirements file.
"""
# XXX Use poetry-export-plugin with dependency groups
output = session.run_always(
"poetry",
"export",
"--format=requirements.txt",
"--without-hashes",
*[f"--extras={extra}" for extra in extras],
external=True,
silent=True,
stderr=None,
)

if output is None:
session.skip(
"The command `poetry export` was not executed"
" (a possible cause is specifying `--no-install`)"
)

assert isinstance(output, str) # noqa: S101

def _stripwarnings(lines: Iterable[str]) -> Iterator[str]:
for line in lines:
if line.startswith("Warning:"):
print(line, file=sys.stderr)
continue
yield line

text = "".join(_stripwarnings(output.splitlines(keepends=True)))

path = session.cache_dir / "requirements.txt"
path.write_text(text)

return path


def activate_virtualenv_in_precommit_hooks(session: nox.Session) -> None:
"""Activate virtualenv in hooks installed by pre-commit.

This function patches git hooks installed by pre-commit to activate the
Expand Down Expand Up @@ -83,96 +150,84 @@ def activate_virtualenv_in_precommit_hooks(session: Session) -> None:
hook.write_text("\n".join(lines))


@session(name="pre-commit", python="3.10")
def precommit(session: Session) -> None:
@nox.session(name="pre-commit", python="3.10")
def precommit(session: nox.Session) -> None:
"""Lint using pre-commit."""
args = session.posargs or ["run", "--all-files", "--show-diff-on-failure"]
session.install(
"black",
"darglint",
"flake8",
"flake8-bandit",
"flake8-bugbear",
"flake8-docstrings",
"flake8-rst-docstrings",
"pep8-naming",
"pre-commit",
"pre-commit-hooks",
"pyupgrade",
"reorder-python-imports",
)
install(session, groups=["pre-commit"], root=False)
session.run("pre-commit", *args)
if args and args[0] == "install":
activate_virtualenv_in_precommit_hooks(session)


@session(python="3.10")
def safety(session: Session) -> None:
@nox.session(python="3.10")
def safety(session: nox.Session) -> None:
"""Scan dependencies for insecure packages."""
requirements = session.poetry.export_requirements()
session.install("safety")
# NOTE: Pass `extras` to `export_requirements` if the project supports any.
requirements = export_requirements(session)
install(session, groups=["safety"], root=False)
session.run("safety", "check", "--full-report", f"--file={requirements}")


@session(python=python_versions)
def mypy(session: Session) -> None:
@nox.session(python=python_versions)
def mypy(session: nox.Session) -> None:
"""Type-check using mypy."""
args = session.posargs or ["src", "tests", "docs/conf.py"]
session.install(".")
session.install("mypy", "pytest")
install(session, groups=["mypy", "tests"])
session.run("mypy", *args)
if not session.posargs:
session.run("mypy", f"--python-executable={sys.executable}", "noxfile.py")


@session(python=python_versions)
def tests(session: Session) -> None:
@nox.session(python=python_versions)
def tests(session: nox.Session) -> None:
"""Run the test suite."""
session.install(".")
session.install("coverage[toml]", "pytest", "pygments")
install(session, groups=["coverage", "tests"])

if session.python == "3.10":
# Workaround an unidentified issue in Poetry 1.2.0a2.
session.install("coverage[toml]==6.1.2")

try:
session.run("coverage", "run", "--parallel", "-m", "pytest", *session.posargs)
finally:
if session.interactive:
session.notify("coverage", posargs=[])


@session
def coverage(session: Session) -> None:
@nox.session
def coverage(session: nox.Session) -> None:
"""Produce the coverage report."""
args = session.posargs or ["report"]

session.install("coverage[toml]")
install(session, groups=["coverage"], root=False)

if not session.posargs and any(Path().glob(".coverage.*")):
session.run("coverage", "combine")

session.run("coverage", *args)


@session(python=python_versions)
def typeguard(session: Session) -> None:
@nox.session(python=python_versions)
def typeguard(session: nox.Session) -> None:
"""Runtime type checking using Typeguard."""
session.install(".")
session.install("pytest", "typeguard", "pygments")
install(session, groups=["typeguard", "tests"])
session.run("pytest", f"--typeguard-packages={package}", *session.posargs)


@session(python=python_versions)
def xdoctest(session: Session) -> None:
@nox.session(python=python_versions)
def xdoctest(session: nox.Session) -> None:
"""Run examples with xdoctest."""
args = session.posargs or ["all"]
session.install(".")
session.install("xdoctest[colors]")
install(session, groups=["xdoctest"])
session.run("python", "-m", "xdoctest", package, *args)


@session(name="docs-build", python="3.10")
def docs_build(session: Session) -> None:
@nox.session(name="docs-build", python="3.10")
def docs_build(session: nox.Session) -> None:
"""Build the documentation."""
args = session.posargs or ["docs", "docs/_build"]
session.install(".")
session.install("sphinx", "sphinx-click", "furo")
install(session, groups=["docs"])

build_dir = Path("docs", "_build")
if build_dir.exists():
Expand All @@ -181,12 +236,11 @@ def docs_build(session: Session) -> None:
session.run("sphinx-build", *args)


@session(python="3.10")
def docs(session: Session) -> None:
@nox.session(python="3.10")
def docs(session: nox.Session) -> None:
"""Build and serve the documentation with live reloading on file changes."""
args = session.posargs or ["--open-browser", "docs", "docs/_build"]
session.install(".")
session.install("sphinx", "sphinx-autobuild", "sphinx-click", "furo")
install(session, groups=["docs"])

build_dir = Path("docs", "_build")
if build_dir.exists():
Expand Down
Loading