Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=white)](https://conventionalcommits.org)
[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)

A minimal, opinionated template for modern Python projects -- featuring Poetry packaging, Ruff for linting and formatting, pytest testing with code coverage upload to codecov, MkDocs documentation with configuration for Read The Docs, pre-commit hooks, GitHub Actions CI, GitHub issue and pull request templates and automated semantic releases.
A minimal, opinionated template for modern Python projects -- featuring Poetry packaging, Ruff for linting and formatting, justfile, pytest testing with code coverage upload to codecov, MkDocs documentation with configuration for Read The Docs, pre-commit hooks, GitHub Actions CI, GitHub issue and pull request templates and automated semantic releases.

The goal is to help you start writing code immediately without having to spend time deciding what tools or conventions to use.

Expand Down Expand Up @@ -70,30 +70,31 @@ print(say_hello("World"))

## 🧪 Common Tasks

Several common tasks have been added as recipes to a [justfile](justfile) in the root of the repository.
[Installing just](https://just.systems/man/en/packages.html) allows you to run the following:

```bash
poetry run pytest # full test suite
poetry run pytest -m "not slow" # quick (mirrors pre-push)
poetry run ruff format # format
poetry run ruff check # lint
poetry run mkdocs serve # live docs
poetry run mkdocs build --strict # build docs (CI parity)
poetry run python -m doctest package_name/greet.py
just install # poetry install
just test # full test suite
just lint # ruff check
just format # ruff format
just docs-serve # live docs
just pre-commit # run all pre-commit hooks
just clean # remove generated files and folders
```

## 🪝 Pre-commit / Pre-push

Install hooks once:

```bash
poetry run pre-commit install # installs default (commit-stage) hooks
poetry run pre-commit install --hook-type pre-push
pre-commit install --hook-type commit-msg # for conventional commits
just pre-commit-install # installs default (commit-stage) hooks
```

Run on all files (CI equivalent):

```bash
poetry run pre-commit run --all-files --hook-stage push
just pre-commit
```

Hook definitions: [.pre-commit-config.yaml](.pre-commit-config.yaml)
Expand Down Expand Up @@ -152,6 +153,7 @@ Managed by release-please: ([conventional commits](https://www.conventionalcommi
├── .release-please-manifest.json # Release-please state
├── release-please-config.json # Release-please configuration
├── .python-version # pyenv version pin
├── justfile # justfile containing recipes for common tasks
└── .gitignore
```

Expand Down
75 changes: 75 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# -----------------------------------------------------------------------------
# 🧰 Python Project Template — Justfile
# -----------------------------------------------------------------------------
# Common developer commands for Poetry-based projects.
# Run `just <command>` (e.g., `just test`).
# -----------------------------------------------------------------------------

# Always use bash for consistency across OSes
set shell := ["bash", "-cu"]

# Default recipe (shown when running plain `just`)
default:
@just --list

# Install dependencies (create/update virtualenv)
install:
poetry install

# Update dependencies to latest allowed versions
update:
poetry update

# Regenerate lock file
lock:
poetry lock

# Lint (Ruff check)
lint:
poetry run ruff check .

# Format (Ruff format)
format:
poetry run ruff format .

# Type checking (Pyright)
type-check:
poetry run pyright

# Run quick tests (exclude slow)
test:
poetry run pytest -q -m "not slow" --doctest-modules --doctest-glob="*.py" --maxfail=1 --disable-warnings

# Run tests with verbose output (exclude slow)
test-vv:
poetry run pytest -vv -m "not slow" --doctest-modules --doctest-glob="*.py" --maxfail=1 --disable-warnings

# Run full test suite with coverage
coverage:
poetry run pytest --cov --cov-report=term-missing

# Build docs (MkDocs strict)
docs-build:
poetry run mkdocs build --strict

# Serve docs locally
docs-serve:
poetry run mkdocs serve -a localhost:8000

# Install pre-commit hooks
pre-commit-install:
poetry run pre-commit install \
&& poetry run pre-commit install -t pre-push \
&& poetry run pre-commit install --hook-type commit-msg

# Run all pre-commit hooks
pre-commit:
poetry run pre-commit run --all-files --hook-stage push

# Clean generated artifacts
clean:
rm -rf .pytest_cache dist build .ruff_cache .mypy_cache site

# Build distribution (wheel + sdist)
build:
poetry build
1 change: 0 additions & 1 deletion tests/unit/test_greet.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,3 @@ def test_say_hello(input_name, expected_output):
def test_say_goodbye(input_name, expected_output):
"""Test the say_goodbye function."""
assert say_goodbye(input_name) == expected_output
"input_name,expected_output", [("Alice", "Hello, Alice!"), ("Bob", "Hello, Bob!")]