forked from frequenz-floss/frequenz-sdk-python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnoxfile.py
162 lines (127 loc) · 4.94 KB
/
noxfile.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
from typing import List
import nox
FMT_DEPS = ["black", "isort"]
LINT_DEPS = ["mypy", "pylint"]
DOCSTRING_DEPS = ["pydocstyle", "darglint"]
PYTEST_DEPS = ["pytest", "pytest-cov", "pytest-mock", "pytest-asyncio"]
def source_file_paths(session: nox.Session) -> List[str]:
"""Return the file paths to run the checks on.
If positional arguments are present, we use those as the file paths, and if
not, we use all source files."""
if session.posargs:
return session.posargs
return ["src", "tests", "examples", "benchmarks"]
# Run all checks except `ci_checks` by default. When running locally with just
# `nox` or `nox -R`, these are the checks that will run.
nox.options.sessions = [
"formatting",
"mypy",
"pylint",
"docstrings",
"pytest_min",
"pytest_max",
]
@nox.session
def ci_checks_max(session: nox.Session) -> None:
"""Run all checks with max dependencies in a single session.
This is faster than running the checks separately, so it is suitable for CI.
This does NOT run pytest_min, so that needs to be run separately as well.
"""
session.install(".", *PYTEST_DEPS, *FMT_DEPS, *LINT_DEPS, *DOCSTRING_DEPS)
formatting(session, False)
mypy(session, False)
pylint(session, False)
docstrings(session, False)
pytest_max(session, False)
@nox.session
def formatting(session: nox.Session, install_deps: bool = True) -> None:
"""Check code formatting with black and isort."""
if install_deps:
session.install(*FMT_DEPS)
session.run("black", "--check", *source_file_paths(session))
session.run("isort", "--check", *source_file_paths(session))
@nox.session
def mypy(session: nox.Session, install_deps: bool = True) -> None:
"""Check type hints with mypy."""
if install_deps:
# install the package itself as editable, so that it is possible to do
# fast local tests with `nox -R -e mypy`.
session.install("-e", ".", "mypy", *PYTEST_DEPS)
# Since we use other packages in the frequenz namespace, we need to run the
# checks for frequenz.sdk from the installed package instead of the src
# directory.
mypy_paths = [path for path in source_file_paths(session)
if not path.startswith("src")]
mypy_cmd = [
"mypy",
"--ignore-missing-imports",
"--install-types",
"--namespace-packages",
"--non-interactive",
"--explicit-package-bases",
"--follow-imports=silent",
"--strict",
]
# Runs on the installed package
session.run(*mypy_cmd, "-p", "frequenz.sdk")
# Runs on the rest of the source folders
session.run(*mypy_cmd, *mypy_paths)
@nox.session
def pylint(session: nox.Session, install_deps: bool = True) -> None:
"""Check for code smells with pylint."""
if install_deps:
# install the package itself as editable, so that it is possible to do
# fast local tests with `nox -R -e pylint`.
session.install("-e", ".", "pylint", *PYTEST_DEPS)
session.run(
"pylint",
"--extension-pkg-whitelist=pydantic",
*source_file_paths(session),
)
@nox.session
def docstrings(session: nox.Session, install_deps: bool = True) -> None:
"""Check docstring tone with pydocstyle and param descriptions with darglint."""
if install_deps:
session.install(*DOCSTRING_DEPS, "toml")
session.run("pydocstyle", *source_file_paths(session))
# Darglint checks that function argument and return values are documented.
# This is needed only for the `src` dir, so we exclude the other top level
# dirs that contain code.
darglint_paths = filter(
lambda path: not (
path.startswith("tests")
or path.startswith("benchmarks")
),
source_file_paths(session),
)
session.run(
"darglint",
*darglint_paths,
)
@nox.session
def pytest_max(session: nox.Session, install_deps: bool = True) -> None:
"""Test the code against max dependency versions with pytest."""
if install_deps:
# install the package itself as editable, so that it is possible to do
# fast local tests with `nox -R -e pytest_max`.
session.install("-e", ".", *PYTEST_DEPS)
_pytest_impl(session, "max", install_deps)
@nox.session
def pytest_min(session: nox.Session, install_deps: bool = True) -> None:
"""Test the code against min dependency versions with pytest."""
if install_deps:
# install the package itself as editable, so that it is possible to do
# fast local tests with `nox -R -e pytest_min`.
session.install("-e", ".", *PYTEST_DEPS, "-r", "minimum-requirements-ci.txt")
_pytest_impl(session, "min", install_deps)
def _pytest_impl(
session: nox.Session, max_or_min_deps: str, install_deps: bool
) -> None:
session.run(
"pytest",
"-W=all",
"-vv",
"--cov=frequenz.sdk",
"--cov-report=term",
f"--cov-report=html:.htmlcov-{max_or_min_deps}",
)