# Contributing

Thanks for your interest in contributing! This guide covers everything you need
to get started.

## Setup

Requires **Python 3.12+** and **bash**.

```bash
git clone <repo-url>
cd <repo>
. .init_venv.sh
```

This creates a virtual environment with [uv](https://docs.astral.sh/uv/),
installs all dependencies (including editable local siblings), and sets up
pre-commit hooks. After the first run you can just activate the existing
environment:

```bash
source .venv/bin/activate
```

To start fresh, delete `.venv/` and re-source `.init_venv.sh`.

## Running Tests

[pytest](https://docs.pytest.org/) with
[pytest-cov](https://pypi.org/project/pytest-cov/) for coverage:

```bash
pytest --cov                    # terminal summary
pytest --cov --cov-report html  # detailed HTML report in .cov_html/
```

CI requires **70% minimum** coverage. Open the HTML report to see exactly which
lines are covered:

```bash
xdg-open .cov_html/index.html  # or: google-chrome, firefox
```

## Linting and Type Checking

### Ruff

[Ruff](https://docs.astral.sh/ruff/) handles both linting and formatting. The
configuration selects **all rules** (`select = ["ALL"]`) with a small ignore
list in `.ruff.toml`.

```bash
ruff check     # lint
ruff format    # format
```

### Pyright

[Pyright](https://microsoft.github.io/pyright/#/) for static type checking:

```bash
pyright
```

### Pre-commit

All of the above run automatically on `git commit` via
[pre-commit](https://pre-commit.com/). If the commit fails, fix the issues,
re-stage, and commit again.

```bash
pre-commit run --all-files  # run manually against everything
```

> **Tip:** To force a commit past hooks (e.g. work-in-progress), use
> `git commit -n`. CI will still enforce the same checks.

## Code Style

- **Docstrings**: [Google convention](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings)
- **Type hints**: Required on all public function signatures
- **Line length**: 88 characters max
- **Formatting**: Let `ruff format` handle it
- **Imports**: All at the top of the file, organized by ruff's isort rules

## Submitting Changes

1. Create a branch from `main`
2. Make your changes with tests
3. Ensure `pytest --cov` passes with >= 70% coverage
4. Ensure `pre-commit run --all-files` passes
5. Open a merge request against `main`

## IDE Setup (VS Code)

Install the [Ruff extension](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff)
by Astral and add to your `settings.json`:

```json
{
  "[python]": {
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "charliermarsh.ruff",
    "editor.codeActionsOnSave": {
      "source.fixAll": "explicit",
      "source.organizeImports.ruff": "explicit"
    }
  },
  "ruff.interpreter": ["${workspaceFolder}/.venv/bin/python"]
}
```

Pyright is included in VS Code's Pylance extension by default.
