Set up pre-commit hooks
- add pre-commit hooks: + run `nox -s lint` on staged *.py files + run common pre-commit hooks for validations that could not be achieved with tools in the develop environment so easily - add pre-merge hook: + run `nox -s _pre-commit-test-hook` before merges * ignores the paths to staged files passed in by the pre-commit framework * runs all test cases instead
This commit is contained in:
parent
c07a9ed19f
commit
7a5246556a
5 changed files with 196 additions and 2 deletions
48
.pre-commit-config.yaml
Normal file
48
.pre-commit-config.yaml
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
default_stages:
|
||||||
|
- commit
|
||||||
|
fail_fast: true
|
||||||
|
repos:
|
||||||
|
- repo: local
|
||||||
|
hooks:
|
||||||
|
- id: local-lint
|
||||||
|
name: Lint the source files
|
||||||
|
entry: nox -s lint --
|
||||||
|
language: system
|
||||||
|
stages:
|
||||||
|
- commit
|
||||||
|
types:
|
||||||
|
- python
|
||||||
|
verbose: true
|
||||||
|
- id: local-test
|
||||||
|
name: Run the entire test suite
|
||||||
|
entry: nox -s _pre-commit-test-hook --
|
||||||
|
language: system
|
||||||
|
stages:
|
||||||
|
- merge-commit
|
||||||
|
types:
|
||||||
|
- text
|
||||||
|
verbose: true
|
||||||
|
- repo: "https://github.com/pre-commit/pre-commit-hooks"
|
||||||
|
rev: v4.6.0
|
||||||
|
hooks:
|
||||||
|
- id: check-added-large-files
|
||||||
|
args:
|
||||||
|
- "--maxkb=100"
|
||||||
|
- id: check-builtin-literals
|
||||||
|
- id: check-case-conflict
|
||||||
|
- id: check-merge-conflict
|
||||||
|
- id: check-toml
|
||||||
|
- id: check-yaml
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
stages:
|
||||||
|
- commit
|
||||||
|
- id: mixed-line-ending
|
||||||
|
args:
|
||||||
|
- "--fix=no"
|
||||||
|
- id: no-commit-to-branch
|
||||||
|
args:
|
||||||
|
- "--branch"
|
||||||
|
- main
|
||||||
|
- id: trailing-whitespace
|
||||||
|
stages:
|
||||||
|
- commit
|
|
@ -95,6 +95,13 @@ The second task lints all source code files with
|
||||||
[ruff](https://pypi.org/project/ruff/).
|
[ruff](https://pypi.org/project/ruff/).
|
||||||
`flake8` is configured with a couple of plug-ins.
|
`flake8` is configured with a couple of plug-ins.
|
||||||
|
|
||||||
|
You may want to install the [pre-commit](https://pre-commit.com/) hooks
|
||||||
|
that come with the project:
|
||||||
|
|
||||||
|
`nox -s pre-commit-install`
|
||||||
|
|
||||||
|
Then, the linting and testing occurs automatically before every commit.
|
||||||
|
|
||||||
|
|
||||||
#### Test Suite
|
#### Test Suite
|
||||||
|
|
||||||
|
|
38
noxfile.py
38
noxfile.py
|
@ -250,7 +250,10 @@ def test(session: nox.Session) -> None:
|
||||||
install_unpinned(session, "-e", ".") # "-e" makes session reuseable
|
install_unpinned(session, "-e", ".") # "-e" makes session reuseable
|
||||||
install_pinned(session, *TEST_DEPENDENCIES)
|
install_pinned(session, *TEST_DEPENDENCIES)
|
||||||
|
|
||||||
args = session.posargs or (
|
# If this function is run by the `pre-commit` framework, extra
|
||||||
|
# arguments are dropped by the hack inside `pre_commit_test_hook()`
|
||||||
|
posargs = () if session.env.get("_drop_posargs") else session.posargs
|
||||||
|
args = posargs or (
|
||||||
"--cov",
|
"--cov",
|
||||||
"--no-cov-on-fail",
|
"--no-cov-on-fail",
|
||||||
TESTS_LOCATION,
|
TESTS_LOCATION,
|
||||||
|
@ -321,6 +324,39 @@ def test_docstrings(session: nox.Session) -> None:
|
||||||
session.run("xdoctest", "src/lalib")
|
session.run("xdoctest", "src/lalib")
|
||||||
|
|
||||||
|
|
||||||
|
@nox_session(name="pre-commit-install", python=MAIN_PYTHON, venv_backend="none")
|
||||||
|
def pre_commit_install(session: nox.Session) -> None:
|
||||||
|
"""Install `pre-commit` hooks."""
|
||||||
|
for type_ in ("pre-commit", "pre-merge-commit"):
|
||||||
|
session.run(
|
||||||
|
"poetry",
|
||||||
|
"run",
|
||||||
|
"pre-commit",
|
||||||
|
"install",
|
||||||
|
f"--hook-type={type_}",
|
||||||
|
external=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@nox_session(name="_pre-commit-test-hook", python=MAIN_PYTHON, reuse_venv=False)
|
||||||
|
def pre_commit_test_hook(session: nox.Session) -> None:
|
||||||
|
"""`pre-commit` hook to run all tests before merges.
|
||||||
|
|
||||||
|
Ignores the paths to the staged files passed in by the
|
||||||
|
`pre-commit` framework and executes all tests instead. So,
|
||||||
|
`nox -s _pre-commit-test-hook -- FILE1, ...` drops the "FILE1, ...".
|
||||||
|
"""
|
||||||
|
do_not_reuse(session)
|
||||||
|
|
||||||
|
# Little Hack: Create a flag in the env(ironment) ...
|
||||||
|
session.env["_drop_posargs"] = "true"
|
||||||
|
|
||||||
|
# ... and call `test()` directly because `session.notify()`
|
||||||
|
# creates the "test" session as a new `nox.Session` object
|
||||||
|
# that does not have the flag set
|
||||||
|
test(session)
|
||||||
|
|
||||||
|
|
||||||
def do_not_reuse(session: nox.Session, *, raise_error: bool = True) -> None:
|
def do_not_reuse(session: nox.Session, *, raise_error: bool = True) -> None:
|
||||||
"""Do not reuse a session with the "-r" flag."""
|
"""Do not reuse a session with the "-r" flag."""
|
||||||
if session._runner.venv._reused: # noqa:SLF001
|
if session._runner.venv._reused: # noqa:SLF001
|
||||||
|
|
103
poetry.lock
generated
103
poetry.lock
generated
|
@ -149,6 +149,17 @@ files = [
|
||||||
{file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
|
{file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfgv"
|
||||||
|
version = "3.4.0"
|
||||||
|
description = "Validate configuration and produce human readable error messages."
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"},
|
||||||
|
{file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "charset-normalizer"
|
name = "charset-normalizer"
|
||||||
version = "3.3.2"
|
version = "3.3.2"
|
||||||
|
@ -360,6 +371,17 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1
|
||||||
[package.extras]
|
[package.extras]
|
||||||
toml = ["tomli"]
|
toml = ["tomli"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "distlib"
|
||||||
|
version = "0.3.8"
|
||||||
|
description = "Distribution utilities"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
files = [
|
||||||
|
{file = "distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784"},
|
||||||
|
{file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "docstring-parser-fork"
|
name = "docstring-parser-fork"
|
||||||
version = "0.0.9"
|
version = "0.0.9"
|
||||||
|
@ -407,6 +429,22 @@ files = [
|
||||||
[package.extras]
|
[package.extras]
|
||||||
test = ["pytest (>=6)"]
|
test = ["pytest (>=6)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "filelock"
|
||||||
|
version = "3.16.0"
|
||||||
|
description = "A platform independent file lock."
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "filelock-3.16.0-py3-none-any.whl", hash = "sha256:f6ed4c963184f4c84dd5557ce8fece759a3724b37b80c6c4f20a2f63a4dc6609"},
|
||||||
|
{file = "filelock-3.16.0.tar.gz", hash = "sha256:81de9eb8453c769b63369f87f11131a7ab04e367f8d97ad39dc230daa07e3bec"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"]
|
||||||
|
testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.1.1)", "pytest (>=8.3.2)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.3)"]
|
||||||
|
typing = ["typing-extensions (>=4.12.2)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flake8"
|
name = "flake8"
|
||||||
version = "7.1.1"
|
version = "7.1.1"
|
||||||
|
@ -666,6 +704,20 @@ files = [
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
flake8 = "*"
|
flake8 = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "identify"
|
||||||
|
version = "2.6.0"
|
||||||
|
description = "File identification library for Python"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0"},
|
||||||
|
{file = "identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
license = ["ukkonen"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "3.8"
|
version = "3.8"
|
||||||
|
@ -922,6 +974,17 @@ files = [
|
||||||
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nodeenv"
|
||||||
|
version = "1.9.1"
|
||||||
|
description = "Node.js virtual environment builder"
|
||||||
|
optional = false
|
||||||
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||||
|
files = [
|
||||||
|
{file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"},
|
||||||
|
{file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "packaging"
|
name = "packaging"
|
||||||
version = "24.1"
|
version = "24.1"
|
||||||
|
@ -1000,6 +1063,24 @@ files = [
|
||||||
dev = ["pre-commit", "tox"]
|
dev = ["pre-commit", "tox"]
|
||||||
testing = ["pytest", "pytest-benchmark"]
|
testing = ["pytest", "pytest-benchmark"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pre-commit"
|
||||||
|
version = "3.8.0"
|
||||||
|
description = "A framework for managing and maintaining multi-language pre-commit hooks."
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.9"
|
||||||
|
files = [
|
||||||
|
{file = "pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f"},
|
||||||
|
{file = "pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
cfgv = ">=2.0.0"
|
||||||
|
identify = ">=1.0.0"
|
||||||
|
nodeenv = ">=0.11.1"
|
||||||
|
pyyaml = ">=5.1"
|
||||||
|
virtualenv = ">=20.10.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pycodestyle"
|
name = "pycodestyle"
|
||||||
version = "2.12.1"
|
version = "2.12.1"
|
||||||
|
@ -1520,6 +1601,26 @@ h2 = ["h2 (>=4,<5)"]
|
||||||
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||||
zstd = ["zstandard (>=0.18.0)"]
|
zstd = ["zstandard (>=0.18.0)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "virtualenv"
|
||||||
|
version = "20.26.4"
|
||||||
|
description = "Virtual Python Environment builder"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "virtualenv-20.26.4-py3-none-any.whl", hash = "sha256:48f2695d9809277003f30776d155615ffc11328e6a0a8c1f0ec80188d7874a55"},
|
||||||
|
{file = "virtualenv-20.26.4.tar.gz", hash = "sha256:c17f4e0f3e6036e9f26700446f85c76ab11df65ff6d8a9cbfad9f71aabfcf23c"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
distlib = ">=0.3.7,<1"
|
||||||
|
filelock = ">=3.12.2,<4"
|
||||||
|
platformdirs = ">=3.9.1,<5"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
|
||||||
|
test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xdoctest"
|
name = "xdoctest"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -1573,4 +1674,4 @@ type = ["pytest-mypy"]
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.9"
|
python-versions = "^3.9"
|
||||||
content-hash = "cc035dcf07b2024900d20f7e2873c3c4c5497e71fa493bf04a629a087f994ec3"
|
content-hash = "3a34bd29eb4226a6054fe5ddba556605fcd621ceff7661334edf429d715c320f"
|
||||||
|
|
|
@ -32,6 +32,8 @@ python = "^3.9"
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
|
|
||||||
|
pre-commit = "^3.8"
|
||||||
|
|
||||||
# Code formatters
|
# Code formatters
|
||||||
autoflake = "^2.3"
|
autoflake = "^2.3"
|
||||||
black = "^24.8"
|
black = "^24.8"
|
||||||
|
|
Loading…
Reference in a new issue