Contributing¶
Prerequisites¶
Development Setup¶
git clone <repo-url>
cd sphinx-need-svg
mise install # installs Python 3.12
uv sync --all-extras # creates .venv, installs all deps
This gives you a working environment with the extension installed in editable mode plus all test, docs, and dev dependencies (ruff, mypy).
Available Tasks¶
All tasks are defined in .mise.toml and run via mise run <task>:
Task |
Description |
|---|---|
|
Run full test suite (unit + e2e) |
|
Run unit/integration tests only |
|
Run e2e docs build test |
|
Run ruff linter |
|
Run ruff linter with auto-fix |
|
Format code with ruff |
|
Check formatting without modifying |
|
Run mypy type checker |
|
Run all checks (lint + format + mypy + test) |
|
Build HTML documentation |
|
Clean and rebuild documentation |
|
Build sdist and wheel with uv |
|
Remove build artifacts |
Before submitting a PR, run the full check suite:
mise run check
This runs ruff lint, ruff format check, mypy, and pytest in sequence.
Pre-commit Hooks¶
Install pre-commit hooks to catch issues before committing:
mise run pre-commit-install
This installs hooks that run on every git commit:
ruff — lint and format checks (auto-fixes lint issues)
detect-secrets — scans for accidentally committed secrets
trailing-whitespace, end-of-file-fixer, check-yaml
Run manually on all files:
mise run pre-commit
Running Tests¶
mise run test # all tests
mise run test-unit # unit/integration tests only
mise run test-e2e # e2e docs build test only
The test suite includes an e2e dogfood test that builds this documentation
project and verifies that needsvg directives produce working SVG output.
If the docs build and the SVG assertions pass, the extension works.
Building Documentation¶
mise run docs # build to docs/_build/html
mise run docs-clean # clean + rebuild
Open docs/_build/html/index.html in a browser to review.
Packaging¶
mise run build # produces dist/*.tar.gz and dist/*.whl
Uses hatchling as the build backend and uv build as the build frontend.
Project Structure¶
sphinx-need-svg/
├── .mise.toml # mise tasks and Python version
├── pyproject.toml # package metadata, deps, tool config
├── uv.lock # reproducible dependency lock
├── LICENSE # MIT license
├── README.md
├── SKILL.md # generated AI agent skill (do not edit)
├── scripts/
│ ├── generate_skill.py # AST-based SKILL.md generator
│ └── skill_template.md.j2 # Jinja2 template for SKILL.md
├── src/sphinx_need_svg/ # extension source
│ ├── __init__.py # Sphinx setup()
│ ├── directives/
│ │ └── needsvg.py # directive, node, processor
│ └── jinja_context.py # Jinja2 context with needs helpers
├── tests/
│ ├── conftest.py # Sphinx testing fixtures
│ ├── test_needsvg.py # unit/integration tests
│ ├── test_docs_build.py # e2e dogfood test
│ └── roots/ # minimal Sphinx test projects
└── docs/ # Sphinx docs (uses needsvg itself)
Code Quality¶
Linting – ruff with rules: E,
F, I, UP, B, SIM, RUF.
Formatting – ruff format (black-compatible).
Type checking – mypy in strict mode.
docutils and sphinx_needs imports have stubs ignored since those
libraries don’t ship type annotations.
Style conventions:
Python 3.9+ compatible syntax
Type hints on all public APIs
from __future__ import annotationsin all modules
Testing Philosophy¶
Tests use Sphinx’s built-in test fixtures (sphinx.testing.fixtures).
Each test builds a small Sphinx project and asserts on the HTML output.
The docs/ directory itself is the main integration test. Every example
on every page exercises the extension. The e2e test
(test_docs_build.py) builds the docs and checks for SVG content
in the output.
AI Agent Skill (SKILL.md)¶
The repository includes a generated SKILL.md at the project root.
This file teaches AI coding agents (Claude Code, OpenCode, Copilot, etc.)
how to use sphinx-need-svg — directive options, Jinja helpers,
configuration, and common patterns like drilldown navigation.
Regenerating the skill file:
uv run python scripts/generate_skill.py
The generator uses AST-based extraction to pull directive options, Jinja
helpers, needs_types, and needs_links from the source code and
docs/conf.py. Static prose (patterns, common mistakes) lives in the
Jinja2 template at scripts/skill_template.md.j2.
The output is deterministic — running the generator twice produces the
same SKILL.md. CI automatically regenerates and commits the file on
pushes to main (the update-skill job in .github/workflows/ci.yml).
When to regenerate manually:
After adding or renaming directive options in
needsvg.pyAfter adding or changing Jinja helpers in
jinja_context.pyAfter modifying
needs_typesorneeds_linksindocs/conf.pyAfter updating the template prose in
scripts/skill_template.md.j2
Adding Features¶
Write a failing test in
tests/test_needsvg.pyImplement the feature
Add an example to
docs/examples.rstthat exercises itRun
mise run checkto verify everything passesRegenerate
SKILL.mdif the change affects the public API (see above)Submit a PR
Reporting Issues¶
Open an issue with:
What you expected
What happened
Minimal RST to reproduce
Sphinx and sphinx-needs versions (
pip list | grep sphinx)