Skip to content

Contributing

Thanks for your interest in improving cgt-calc — contributions of all kinds are welcome! If you find a bug or have feature ideas, please open an issue or pull request.

Getting started

This project uses uv for dependency management, testing, and builds.

1. Install uv

Follow uv’s installation guide:

curl -LsSf https://astral.sh/uv/install.sh | sh

2. Clone the repository

git clone https://github.com/KapJI/capital-gains-calculator.git
cd capital-gains-calculator

3. Set up the environment

uv sync

This command creates a virtual environment and installs all project and development dependencies into it. Run it again after pulling new changes to update dependencies.

Code style

All checks in CI must pass before merging changes.

We use:

  • ruff — for Python linting and formatting
  • mypy — for static type checking
  • pytest — for running tests
  • dprint — for formatting Markdown, YAML, TOML, JSON, and Dockerfiles
  • shfmt - for formatting shell scripts
  • markdown-link-check - for checking links in Markdown
  • codespell - for catching common misspellings
  • Harper - for grammar and spell checking of comments, docstrings, and Markdown docs

prek can be used to run all checks with one command (see below).

The project uses Python 3.12 as the minimum supported version.

Prek

prek is fully compatible with pre-commit, so pre-commit can be used as well.

Install prek first, e.g. using uv or pipx:

uv tool install prek

Installing it globally avoids issues when prek invokes uv inside hooks.

Activate the prek hook:

prek install

This will automatically check code style, linting, and types before each commit.

You can also run all checks on the repository manually:

prek run --all-files

Or you can run single hook:

prek run mypy --all-files
prek run pytest
prek run --hook-stage manual python-typing-update --all-files

Harper runs as a regular hook via uv (the harper-cli dev dependency), so no separate installation is needed. Project vocabulary (tickers, broker names, identifiers) lives in .harper-dictionary.txt; the Harper editor extension picks it up automatically. Words that the dictionary cannot whitelist — Harper dialect-gates US spellings such as product names — are accepted via regexes in .harper-ignore.txt.

Running linters and tests manually

You can also run linters and tests directly:

uv run pytest
uv run pytest -k <expr> -q # run subset
uv run ruff check .
uv run mypy cgt_calc

Managing dependencies

You can manage dependencies either with uv commands or by editing pyproject.toml directly.

Add a new runtime dependency

uv add <package-name>

Add a development dependency

uv add --group dev <package-name>

Upgrade existing dependencies

uv lock --upgrade
uv sync

Manual changes

If you edit pyproject.toml manually (for example, to bump a version), run uv sync afterwards to apply the changes and update uv.lock.

Updating the example report

To regenerate the example PDF report used in the docs, run:

./scripts/generate_example_report.sh

This writes docs/assets/example_report.pdf. Commit the updated file if your changes affect report generation.