Skip to content
This repository was archived by the owner on Feb 13, 2021. It is now read-only.

Commit 5eb9512

Browse files
author
staticdev
committed
New nox config
1 parent 86ef053 commit 5eb9512

1 file changed

Lines changed: 112 additions & 67 deletions

File tree

noxfile.py

Lines changed: 112 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,151 @@
11
"""Nox sessions."""
2+
import contextlib
23
import tempfile
3-
from typing import Any
4+
from pathlib import Path
5+
from typing import cast
6+
from typing import Iterator
47

58
import nox
69
from nox.sessions import Session
710

11+
812
package = "humanizer_portugues"
9-
nox.options.sessions = "lint", "safety", "mypy", "tests"
13+
python_versions = ["3.8", "3.7"]
14+
nox.options.sessions = "pre-commit", "safety", "mypy", "tests"
1015
locations = "src", "tests", "noxfile.py"
1116

1217

13-
def install_with_constraints(session: Session, *args: str, **kwargs: Any) -> None:
14-
"""Install packages constrained by Poetry's lock file.
15-
16-
This function is a wrapper for nox.sessions.Session.install. It
17-
invokes pip to install packages inside of the session's virtualenv.
18-
Additionally, pip is passed a constraints file generated from
19-
Poetry's lock file, to ensure that the packages are pinned to the
20-
versions specified in poetry.lock. This allows you to manage the
21-
packages as Poetry development dependencies.
18+
class Poetry:
19+
"""Helper class for invoking Poetry inside a Nox session.
2220
23-
Arguments:
21+
Attributes:
2422
session: The Session object.
25-
args: Command-line arguments for pip.
26-
kwargs: Additional keyword arguments for Session.install.
2723
"""
28-
with tempfile.NamedTemporaryFile() as requirements:
29-
session.run(
30-
"poetry",
31-
"export",
32-
"--dev",
33-
"--format=requirements.txt",
34-
f"--output={requirements.name}",
35-
external=True,
24+
25+
def __init__(self, session: Session) -> None:
26+
"""Constructor."""
27+
self.session = session
28+
29+
@contextlib.contextmanager
30+
def export(self, *args: str) -> Iterator[Path]:
31+
"""Export the lock file to requirements format.
32+
33+
Args:
34+
args: Command-line arguments for ``poetry export``.
35+
36+
Yields:
37+
The path to the requirements file.
38+
"""
39+
with tempfile.TemporaryDirectory() as directory:
40+
requirements = Path(directory) / "requirements.txt"
41+
self.session.run(
42+
"poetry",
43+
"export",
44+
*args,
45+
"--format=requirements.txt",
46+
f"--output={requirements}",
47+
external=True,
48+
)
49+
yield requirements
50+
51+
def version(self) -> str:
52+
"""Retrieve the package version.
53+
54+
Returns:
55+
The package version.
56+
"""
57+
output = self.session.run(
58+
"poetry", "version", external=True, silent=True, stderr=None
3659
)
37-
session.install(f"--constraint={requirements.name}", *args, **kwargs)
60+
return cast(str, output).split()[1]
3861

62+
def build(self, *args: str) -> None:
63+
"""Build the package.
3964
40-
@nox.session(python="3.8")
41-
def black(session: Session) -> None:
42-
"""Run black code formatter."""
43-
args = session.posargs or locations
44-
install_with_constraints(session, "black")
45-
session.run("black", *args)
65+
Args:
66+
args: Command-line arguments for ``poetry build``.
67+
"""
68+
self.session.run("poetry", "build", *args, external=True)
4669

4770

48-
@nox.session(python=["3.8", "3.7"])
49-
def lint(session: Session) -> None:
50-
"""Lint using flake8."""
51-
args = session.posargs or locations
52-
install_with_constraints(
53-
session, "flake8", "flake8-bandit", "flake8-black", "flake8-bugbear",
71+
def install_package(session: Session) -> None:
72+
"""Build and install the package.
73+
74+
Build a wheel from the package, and install it into the virtual environment
75+
of the specified Nox session.
76+
77+
The package requirements are installed using the versions specified in
78+
Poetry's lock file.
79+
80+
Args:
81+
session: The Session object.
82+
"""
83+
poetry = Poetry(session)
84+
85+
with poetry.export() as requirements:
86+
session.install(f"--requirement={requirements}")
87+
88+
poetry.build("--format=wheel")
89+
90+
version = poetry.version()
91+
session.install(
92+
"--no-deps", "--force-reinstall", f"dist/{package}-{version}-py3-none-any.whl"
5493
)
55-
session.run("flake8", *args)
94+
95+
96+
def install(session: Session, *args: str) -> None:
97+
"""Install development dependencies into the session's virtual environment.
98+
99+
This function is a wrapper for nox.sessions.Session.install.
100+
101+
The packages must be managed as development dependencies in Poetry.
102+
103+
Args:
104+
session: The Session object.
105+
args: Command-line arguments for ``pip install``.
106+
"""
107+
poetry = Poetry(session)
108+
with poetry.export("--dev") as requirements:
109+
session.install(f"--constraint={requirements}", *args)
110+
111+
112+
@nox.session(name="pre-commit", python="3.8")
113+
def precommit(session: Session) -> None:
114+
"""Lint using pre-commit."""
115+
args = session.posargs or ["run", "--all-files", "--show-diff-on-failure"]
116+
install(session, "pre-commit")
117+
session.run("pre-commit", *args)
56118

57119

58120
@nox.session(python="3.8")
59121
def safety(session: Session) -> None:
60122
"""Scan dependencies for insecure packages."""
61-
with tempfile.NamedTemporaryFile() as requirements:
62-
session.run(
63-
"poetry",
64-
"export",
65-
"--dev",
66-
"--format=requirements.txt",
67-
"--without-hashes",
68-
f"--output={requirements.name}",
69-
external=True,
70-
)
71-
install_with_constraints(session, "safety")
72-
session.run("safety", "check", f"--file={requirements.name}", "--full-report")
123+
poetry = Poetry(session)
124+
with poetry.export("--dev", "--without-hashes") as requirements:
125+
install(session, "safety")
126+
session.run("safety", "check", f"--file={requirements}", "--bare")
73127

74128

75-
@nox.session(python=["3.8", "3.7"])
129+
@nox.session(python=python_versions)
76130
def mypy(session: Session) -> None:
77131
"""Type-check using mypy."""
78132
args = session.posargs or locations
79-
install_with_constraints(session, "mypy")
133+
install(session, "mypy")
80134
session.run("mypy", *args)
81135

82136

83-
@nox.session(python=["3.8", "3.7"])
137+
@nox.session(python=python_versions)
84138
def tests(session: Session) -> None:
85139
"""Run the test suite."""
86-
args = session.posargs or ["--cov", "-m", "not e2e"]
87-
session.run("poetry", "install", "--no-dev", external=True)
88-
install_with_constraints(session, "coverage[toml]", "pytest", "pytest-cov")
140+
args = session.posargs or ["--cov"]
141+
install_package(session)
142+
install(session, "coverage[toml]", "pytest", "pytest-cov")
89143
session.run("pytest", *args)
90144

91145

92-
@nox.session(python=["3.8", "3.7"])
146+
@nox.session(python=python_versions)
93147
def typeguard(session: Session) -> None:
94148
"""Runtime type checking using Typeguard."""
95-
args = session.posargs or ["-m", "not e2e"]
96-
session.run("poetry", "install", "--no-dev", external=True)
97-
install_with_constraints(session, "pytest", "typeguard")
98-
session.run("pytest", f"--typeguard-packages={package}", *args)
99-
100-
101-
@nox.session(python="3.8")
102-
def coverage(session: Session) -> None:
103-
"""Upload coverage data."""
104-
install_with_constraints(session, "coverage[toml]", "codecov")
105-
session.run("coverage", "xml", "--fail-under=0")
106-
session.run("codecov", *session.posargs)
149+
install_package(session)
150+
install(session, "pytest", "typeguard")
151+
session.run("pytest", f"--typeguard-packages={package}", *session.posargs)

0 commit comments

Comments
 (0)