Skip to content

Latest commit

 

History

History
27 lines (18 loc) · 2.97 KB

File metadata and controls

27 lines (18 loc) · 2.97 KB

Design choices

  • a Makefile to use as a task runner during development/CI.
  • the makefile uses uv to create a virtualenv and install dependencies. uv is faster than pip at dependency resolution and installation.
  • ruff for linting, formatting similar to black, import sorting, and auto fixing (eg: removing unused imports) because its the fastest and most feature complete linter
  • enforced type hints for non-test code because "explicit is better than implicit"
  • pyright to check those type hints because it's more accurate and faster than mypy
  • pytest for tests because it doesn't require classes unlike unittest
  • setuptools for building wheels because its the most popular build backend and does the job. Source dists (sdists) aren't built because they aren't useful.
  • pyproject.toml for describing requirements and python versions as per PEP 621 (ie: no requirements.txt)

Pre-commit

pre-commit is used for linting, formatting, type checking and testing using the tools above. pre-commit is particularly useful in remote environments without an IDE, or for projects without CI.

Tools are configured as a git push hook instead of git commit to minimise interruptions. They can also be run on-demand via the Makefile. The Makefile uses pre-commit, instead of directly running the tools, because pre-commit will nicely collapse output on success and continue running subsequent tools when a previous one fails.

The version of pre-commit is major-version constrained to avoid breaking changes (see this example). The version is specified as a dev dependency, rather than in the makefile, so that dependabot can bump it. This has the slight disadvantage of polluting the dependency tree, which must now satisfy pre-commit's dependencies.

Project structure

A single virtualenv is assumed with requirements for all packages, rather than a monorepo with multiple projects that have different requirements. The directory structure prescribes packages at the top-level for convenience rather than under src/.

Cruft

Cruft uses cookiecutter under the hood to bake a cookie. But unlike cookiecutter, cruft creates a .cruft.json file which records the commit hash of the template used and the prompt values provided by the user at the time of baking. Projects baked using cruft can be aligned with future versions of the template by running cruft update. This does a 3-way merge to apply template changes made since baking.