spiff-arena/spiffworkflow-backend/noxfile.py

229 lines
6.7 KiB
Python
Raw Normal View History

"""Nox sessions."""
import os
import shutil
import sys
from pathlib import Path
from textwrap import dedent
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 = "spiffworkflow_backend"
python_versions = ["3.11", "3.10", "3.9"]
nox.needs_version = ">= 2021.6.6"
nox.options.sessions = (
"pre-commit",
"safety",
"mypy",
"tests",
"typeguard",
"xdoctest",
"docs-build",
)
def setup_database(session: Session) -> None:
"""Run database migrations against the database."""
session.env["FLASK_INSTANCE_PATH"] = os.path.join(os.getcwd(), "instance", "testing")
flask_env_key = "FLASK_SESSION_SECRET_KEY"
2023-03-12 22:20:29 +00:00
session.env[flask_env_key] = "e7711a3ba96c46c68e084a86952de16f"
session.env["FLASK_APP"] = "src/spiffworkflow_backend"
session.env["SPIFFWORKFLOW_BACKEND_ENV"] = "unit_testing"
2023-05-19 11:05:58 +00:00
if os.environ.get("SPIFFWORKFLOW_BACKEND_DATABASE_TYPE") == "sqlite":
# maybe replace this sqlite-specific block with ./bin/recreate_db clean rmall
# (if we can make it work, since it uses poetry),
# which would also remove the migrations folder and re-create things as a single migration
if os.path.exists("migrations"):
import shutil
shutil.rmtree("migrations")
for task in ["init", "migrate"]:
session.run("flask", "db", task)
session.run("flask", "db", "upgrade")
def activate_virtualenv_in_precommit_hooks(session: Session) -> None:
"""Activate virtualenv in hooks installed by pre-commit.
This function patches git hooks installed by pre-commit to activate the
session's virtual environment. This allows pre-commit to locate hooks in
that environment when invoked from git.
Args:
session: The Session object.
"""
assert session.bin is not None # noqa: S101
virtualenv = session.env.get("VIRTUAL_ENV")
if virtualenv is None:
return
hookdir = Path(".git") / "hooks"
if not hookdir.is_dir():
return
for hook in hookdir.iterdir():
if hook.name.endswith(".sample") or not hook.is_file():
continue
text = hook.read_text()
bindir = repr(session.bin)[1:-1] # strip quotes
if not (Path("A") == Path("a") and bindir.lower() in text.lower() or bindir in text):
continue
lines = text.splitlines()
if not (lines[0].startswith("#!") and "python" in lines[0].lower()):
continue
header = dedent(
f"""\
import os
os.environ["VIRTUAL_ENV"] = {virtualenv!r}
os.environ["PATH"] = os.pathsep.join((
{session.bin!r},
os.environ.get("PATH", ""),
))
"""
)
lines.insert(1, header)
hook.write_text("\n".join(lines))
@session(name="pre-commit", python="3.11")
def precommit(session: 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",
)
session.run("pre-commit", *args)
if args and args[0] == "install":
activate_virtualenv_in_precommit_hooks(session)
@session(python="3.11")
def safety(session: Session) -> None:
"""Scan dependencies for insecure packages."""
requirements = session.poetry.export_requirements()
session.install("safety")
session.run("safety", "check", "--full-report", f"--file={requirements}")
@session(python=python_versions)
def mypy(session: Session) -> None:
"""Type-check using mypy."""
args = session.posargs or ["src", "tests", "docs/conf.py"]
session.install(".")
Squashed 'spiffworkflow-backend/' changes from 5225a8b4..1e831706 1e831706 Merge pull request #146 from sartography/test_arena_push df95dccf fixed conflicts and updated usage of active task status w/ burnettk 33b81894 Merge pull request #145 from sartography/feature/remove-task-data-from-active-task 7e1ce35c remove task_data column b9cd1c06 Merge pull request #144 from sartography/feature/lib-updates-and-mypy 5e09e28d fix mypy 68485ab4 use fork of sqlalchemy-stubs 872480db Merge remote-tracking branch 'origin/main' into feature/lib-updates-and-mypy 18a892f6 work in progress 84344d53 Pause/resume process instances (#2) 53652cff Merge commit '4a48d9cccd1ca8619b3dbef3c10bcce667c9d9e0' 9ea3def2 lint c05b5181 Merge remote-tracking branch 'origin/main' into feature/lib-updates-and-mypy b2a75f60 Merge commit 'c661100e03eef762cb51b02be1b309ec47be7002' 3ddaa5d0 lib updates and mypy 30d04282 Merge commit '4fdb0f3ec4b3b6a68cc2e56ed84ffb6dc2743068' a961b2a1 Merge commit '81746ee508f6ab0ffe757856d9a3d5d855db2560' 10651984 Merge commit '8f8b4717990eb86c6bfd2f309ef064152c51b452' 59b90fba Merge branch 'main' of github.com:sartography/spiff-arena 577e0fe3 Merge commit 'a166df83031cb88d223e5c75ae8db8c896622821' 11d40241 Merge commit '106e2ca7214aec4dba965ccb3f94b0658acaa2b2' 1fcc935e Merge commit '9781908243408ed221f2b0131a00b8a9612f81f3' e9734bff Merge commit '64e7049c9a0a4360101a155a41ce64ae692acd3c' 28239aa4 Merge commit 'aa22f4b397a899fa06d06c2e9127ca98d9eb909a' 8b184a5c Merge commit '4f0f5b1ece069ec56f8eb4154d61334a321749a1' bd1effc6 Merge commit 'b4975660431c275ce736e0431b98c39548200af1' eafa4f61 Merge commit 'c9bd62250452403550ae1bf1d27547d4796dd316' 50d9a0c3 Merge commit '9be0517531543655a35023af17b76dbb41eab93e' 34e98b77 Merge commit 'a1a01ad25a1ef60b879dede6f037f0fff3381ae4' c8d0cb8a Merge commit 'bee232a55a82054e629f48f0333495b61a7da7d1' 00478271 Merge commit '71e189afbc127b574cca8d02fc31b2e65aff0d52' 657fbad9 Merge commit 'f21d0ef3a98458deb347fb2a51fab0b5b41f7fe2' c91c279e Merge commit '93dbce681ec89bc45479748aaae06ddd92b64da4' b95a1af9 Merge commit '48918b00428e777ea29d351662467c0ac4e34a36' afea9254 pre-commit updates e3bc3b76 Merge main, resolve conflicts 2e317da8 Updaging the jinja processing so it doesn't leave a bunch of blank lines in the markdown that has strong feelings about white space. Updating the front end to render markdown formatted instructions. And adding a little css love to tables that are generated in Markdown. git-subtree-dir: spiffworkflow-backend git-subtree-split: 1e831706a1f7ed841e343537cfe1dc05d5eedaca
2022-10-21 14:36:41 +00:00
session.install("mypy")
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:
"""Run the test suite."""
session.install(".")
session.install("coverage[toml]", "pytest", "pygments")
try:
setup_database(session)
session.run("coverage", "run", "--parallel", "-m", "pytest", *session.posargs)
finally:
if session.interactive:
session.notify("coverage", posargs=[])
@session
def coverage(session: Session) -> None:
"""Produce the coverage report."""
args = session.posargs or ["report"]
session.install("coverage[toml]")
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:
"""Runtime type checking using Typeguard."""
session.install(".")
session.install("pytest", "typeguard", "pygments")
setup_database(session)
session.env["RUN_TYPEGUARD"] = "true"
session.run("pytest", *session.posargs)
@session(python=python_versions)
def xdoctest(session: Session) -> None:
"""Run examples with xdoctest."""
if session.posargs:
args = [package, *session.posargs]
else:
args = [f"--modname={package}", "--command=all"]
if "FORCE_COLOR" in os.environ:
args.append("--colored=1")
session.install(".")
session.install("xdoctest[colors]")
session.run("python", "-m", "xdoctest", *args)
@session(name="docs-build", python="3.11")
def docs_build(session: Session) -> None:
"""Build the documentation."""
args = session.posargs or ["docs", "docs/_build"]
if not session.posargs and "FORCE_COLOR" in os.environ:
args.insert(0, "--color")
session.install(".")
session.install("sphinx", "sphinx-click", "furo")
build_dir = Path("docs", "_build")
if build_dir.exists():
shutil.rmtree(build_dir)
session.run("sphinx-build", *args)
@session(python="3.11")
def docs(session: 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")
build_dir = Path("docs", "_build")
if build_dir.exists():
shutil.rmtree(build_dir)
session.run("sphinx-autobuild", *args)