Test Failed
Push — main ( 4e8f49...433afe )
by John Patrick
01:43
created

noxfile   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 237
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 143
dl 0
loc 237
rs 9.68
c 0
b 0
f 0
wmc 34

10 Functions

Rating   Name   Duplication   Size   Complexity  
A mypy() 0 9 2
A coverage() 0 11 3
A safety() 0 6 1
A typeguard() 0 6 1
A xdoctest() 0 13 3
D activate_virtualenv_in_precommit_hooks() 0 72 13
A docs() 0 12 2
A tests() 0 10 2
A precommit() 0 26 3
A docs_build() 0 15 4
1
"""Nox sessions."""
2
import os
3
import shlex
4
import shutil
5
import sys
6
from pathlib import Path
7
from textwrap import dedent
8
9
import nox
10
11
12
try:
13
    from nox_poetry import Session
14
    from nox_poetry import session
15
except ImportError:
16
    message = f"""\
17
    Nox failed to import the 'nox-poetry' package.
18
19
    Please install it using the following command:
20
21
    {sys.executable} -m pip install nox-poetry"""
22
    raise SystemExit(dedent(message)) from None
23
24
25
package = "trending_homebrew"
26
python_versions = ["3.10", "3.9", "3.8", "3.7"]
27
nox.needs_version = ">= 2021.6.6"
28
nox.options.sessions = (
29
    "pre-commit",
30
    "safety",
31
    "mypy",
32
    "tests",
33
    "typeguard",
34
    "xdoctest",
35
    "docs-build",
36
)
37
38
39
def activate_virtualenv_in_precommit_hooks(session: Session) -> None:
40
    """Activate virtualenv in hooks installed by pre-commit.
41
42
    This function patches git hooks installed by pre-commit to activate the
43
    session's virtual environment. This allows pre-commit to locate hooks in
44
    that environment when invoked from git.
45
46
    Args:
47
        session: The Session object.
48
    """
49
    assert session.bin is not None  # noqa: S101
50
51
    # Only patch hooks containing a reference to this session's bindir. Support
52
    # quoting rules for Python and bash, but strip the outermost quotes so we
53
    # can detect paths within the bindir, like <bindir>/python.
54
    bindirs = [
55
        bindir[1:-1] if bindir[0] in "'\"" else bindir
56
        for bindir in (repr(session.bin), shlex.quote(session.bin))
57
    ]
58
59
    virtualenv = session.env.get("VIRTUAL_ENV")
60
    if virtualenv is None:
61
        return
62
63
    headers = {
64
        # pre-commit < 2.16.0
65
        "python": f"""\
66
            import os
67
            os.environ["VIRTUAL_ENV"] = {virtualenv!r}
68
            os.environ["PATH"] = os.pathsep.join((
69
                {session.bin!r},
70
                os.environ.get("PATH", ""),
71
            ))
72
            """,
73
        # pre-commit >= 2.16.0
74
        "bash": f"""\
75
            VIRTUAL_ENV={shlex.quote(virtualenv)}
76
            PATH={shlex.quote(session.bin)}"{os.pathsep}$PATH"
77
            """,
78
        # pre-commit >= 2.17.0 on Windows forces sh shebang
79
        "/bin/sh": f"""\
80
            VIRTUAL_ENV={shlex.quote(virtualenv)}
81
            PATH={shlex.quote(session.bin)}"{os.pathsep}$PATH"
82
            """,
83
    }
84
85
    hookdir = Path(".git") / "hooks"
86
    if not hookdir.is_dir():
87
        return
88
89
    for hook in hookdir.iterdir():
90
        if hook.name.endswith(".sample") or not hook.is_file():
91
            continue
92
93
        if not hook.read_bytes().startswith(b"#!"):
94
            continue
95
96
        text = hook.read_text()
97
98
        if not any(
99
            Path("A") == Path("a") and bindir.lower() in text.lower() or bindir in text
100
            for bindir in bindirs
101
        ):
102
            continue
103
104
        lines = text.splitlines()
105
106
        for executable, header in headers.items():
107
            if executable in lines[0].lower():
108
                lines.insert(1, dedent(header))
109
                hook.write_text("\n".join(lines))
110
                break
111
112
113
@session(name="pre-commit", python=python_versions[0])
114
def precommit(session: Session) -> None:
115
    """Lint using pre-commit."""
116
    args = session.posargs or [
117
        "run",
118
        "--all-files",
119
        "--hook-stage=manual",
120
        "--show-diff-on-failure",
121
    ]
122
    session.install(
123
        "black",
124
        "darglint",
125
        "flake8",
126
        "flake8-bandit",
127
        "flake8-bugbear",
128
        "flake8-docstrings",
129
        "flake8-rst-docstrings",
130
        "isort",
131
        "pep8-naming",
132
        "pre-commit",
133
        "pre-commit-hooks",
134
        "pyupgrade",
135
    )
136
    session.run("pre-commit", *args)
137
    if args and args[0] == "install":
138
        activate_virtualenv_in_precommit_hooks(session)
139
140
141
@session(python=python_versions[0])
142
def safety(session: Session) -> None:
143
    """Scan dependencies for insecure packages."""
144
    requirements = session.poetry.export_requirements()
145
    session.install("safety")
146
    session.run("safety", "check", "--full-report", f"--file={requirements}")
147
148
149
@session(python=python_versions)
150
def mypy(session: Session) -> None:
151
    """Type-check using mypy."""
152
    args = session.posargs or ["src", "tests", "docs/conf.py"]
153
    session.install(".")
154
    session.install("mypy", "pytest")
155
    session.run("mypy", *args)
156
    if not session.posargs:
157
        session.run("mypy", f"--python-executable={sys.executable}", "noxfile.py")
158
159
160
@session(python=python_versions)
161
def tests(session: Session) -> None:
162
    """Run the test suite."""
163
    session.install(".")
164
    session.install("coverage[toml]", "pytest", "pygments")
165
    try:
166
        session.run("coverage", "run", "--parallel", "-m", "pytest", *session.posargs)
167
    finally:
168
        if session.interactive:
169
            session.notify("coverage", posargs=[])
170
171
172
@session(python=python_versions[0])
173
def coverage(session: Session) -> None:
174
    """Produce the coverage report."""
175
    args = session.posargs or ["report"]
176
177
    session.install("coverage[toml]")
178
179
    if not session.posargs and any(Path().glob(".coverage.*")):
180
        session.run("coverage", "combine")
181
182
    session.run("coverage", *args)
183
184
185
@session(python=python_versions[0])
186
def typeguard(session: Session) -> None:
187
    """Runtime type checking using Typeguard."""
188
    session.install(".")
189
    session.install("pytest", "typeguard", "pygments")
190
    session.run("pytest", f"--typeguard-packages={package}", *session.posargs)
191
192
193
@session(python=python_versions)
194
def xdoctest(session: Session) -> None:
195
    """Run examples with xdoctest."""
196
    if session.posargs:
197
        args = [package, *session.posargs]
198
    else:
199
        args = [f"--modname={package}", "--command=all"]
200
        if "FORCE_COLOR" in os.environ:
201
            args.append("--colored=1")
202
203
    session.install(".")
204
    session.install("xdoctest[colors]")
205
    session.run("python", "-m", "xdoctest", *args)
206
207
208
@session(name="docs-build", python=python_versions[0])
209
def docs_build(session: Session) -> None:
210
    """Build the documentation."""
211
    args = session.posargs or ["docs", "docs/_build"]
212
    if not session.posargs and "FORCE_COLOR" in os.environ:
213
        args.insert(0, "--color")
214
215
    session.install(".")
216
    session.install("sphinx", "sphinx-click", "furo", "myst-parser")
217
218
    build_dir = Path("docs", "_build")
219
    if build_dir.exists():
220
        shutil.rmtree(build_dir)
221
222
    session.run("sphinx-build", *args)
223
224
225
@session(python=python_versions[0])
226
def docs(session: Session) -> None:
227
    """Build and serve the documentation with live reloading on file changes."""
228
    args = session.posargs or ["--open-browser", "docs", "docs/_build"]
229
    session.install(".")
230
    session.install("sphinx", "sphinx-autobuild", "sphinx-click", "furo", "myst-parser")
231
232
    build_dir = Path("docs", "_build")
233
    if build_dir.exists():
234
        shutil.rmtree(build_dir)
235
236
    session.run("sphinx-autobuild", *args)
237