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

Commit c96462e

Browse files
author
Thiago C. D'Ávila
authored
Merge pull request #28 from staticdev/nox
nox
2 parents ca209c5 + 2c5b486 commit c96462e

5 files changed

Lines changed: 227 additions & 92 deletions

File tree

.github/workflows/dependabot.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Dependabot
22

33
on:
44
pull_request:
5-
branches: [ master ]
5+
branches: [master]
66

77
jobs:
88
automerge:

.pre-commit-config.yaml

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,3 @@ repos:
66
- id: end-of-file-fixer
77
- id: trailing-whitespace
88
- id: check-added-large-files
9-
- repo: https://github.com/prettier/prettier
10-
rev: 2.0.5
11-
hooks:
12-
- id: prettier
13-
- repo: local
14-
hooks:
15-
- id: black
16-
name: black
17-
entry: poetry run black
18-
language: system
19-
types: [python]
20-
- id: flake8
21-
name: flake8
22-
entry: poetry run flake8
23-
language: system
24-
types: [python]
25-
- id: mypy
26-
name: mypy
27-
entry: poetry run mypy
28-
language: system
29-
types: [python]
30-
require_serial: true

noxfile.py

Lines changed: 113 additions & 68 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 = "toml_validator"
9-
nox.options.sessions = "lint", "safety", "mypy", "tests"
13+
python_versions = ["3.8"]
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-
This function is a wrapper for nox.sessions.Session.install. It
16-
invokes pip to install packages inside of the session's virtualenv.
17-
Additionally, pip is passed a constraints file generated from
18-
Poetry's lock file, to ensure that the packages are pinned to the
19-
versions specified in poetry.lock. This allows you to manage the
20-
packages as Poetry development dependencies.
21-
Arguments:
18+
class Poetry:
19+
"""Helper class for invoking Poetry inside a Nox session.
20+
21+
Attributes:
2222
session: The Session object.
23-
args: Command-line arguments for pip.
24-
kwargs: Additional keyword arguments for Session.install.
2523
"""
26-
with tempfile.NamedTemporaryFile() as requirements:
27-
session.run(
28-
"poetry",
29-
"export",
30-
"--dev",
31-
"--format=requirements.txt",
32-
f"--output={requirements.name}",
33-
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
3459
)
35-
session.install(f"--constraint={requirements.name}", *args, **kwargs)
60+
return cast(str, output).split()[1]
3661

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

4570

46-
@nox.session(python=["3.8", "3.7"])
47-
def lint(session: Session) -> None:
48-
"""Lint using flake8."""
49-
args = session.posargs or locations
50-
install_with_constraints(
51-
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"
5293
)
53-
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)
54118

55119

56120
@nox.session(python="3.8")
57121
def safety(session: Session) -> None:
58122
"""Scan dependencies for insecure packages."""
59-
with tempfile.NamedTemporaryFile() as requirements:
60-
session.run(
61-
"poetry",
62-
"export",
63-
"--dev",
64-
"--format=requirements.txt",
65-
"--without-hashes",
66-
f"--output={requirements.name}",
67-
external=True,
68-
)
69-
install_with_constraints(session, "safety")
70-
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")
71127

72128

73-
@nox.session(python=["3.8", "3.7"])
129+
@nox.session(python=python_versions)
74130
def mypy(session: Session) -> None:
75131
"""Type-check using mypy."""
76132
args = session.posargs or locations
77-
install_with_constraints(session, "mypy")
133+
install(session, "mypy")
78134
session.run("mypy", *args)
79135

80136

81-
@nox.session(python=["3.8", "3.7"])
137+
@nox.session(python=python_versions)
82138
def tests(session: Session) -> None:
83139
"""Run the test suite."""
84-
args = session.posargs or ["--cov", "-m", "not e2e"]
85-
session.run("poetry", "install", "--no-dev", external=True)
86-
install_with_constraints(
87-
session, "coverage[toml]", "pytest", "pytest-cov", "pytest-mock"
88-
)
140+
args = session.posargs or ["--cov"]
141+
install_package(session)
142+
install(session, "coverage[toml]", "pytest", "pytest-cov", "pytest_mock")
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", "pytest-mock", "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)