Skip to content

Contributing

Bug reports, documentation fixes, examples and code are all welcome. This page summarises CONTRIBUTING.md, which has the full conventions and the release process. Please also read the Code of Conduct.

mapcv is a Python package with a Rust extension built by maturin. You need Python 3.10+, Rust and uv.

  1. Fork and clone the repository, then install the development dependencies and build the extension:

    Terminal window
    uv sync --all-extras
    uv run maturin develop

    Re-run uv run maturin develop after every change to Rust code (src/*.rs). --all-extras installs every optional dependency, so the Sentinel-2, GeoParquet, export and MCP tests run too (the zarr extra installs nothing on Python 3.14). rust-toolchain.toml pins the Rust version CI uses; rustup installs it on first use.

  2. Install the pre-commit hooks (cargo fmt, clippy, ruff, mypy and pytest run before each commit):

    Terminal window
    pip install pre-commit
    pre-commit install
Terminal window
uv run pytest # tests
uv run ruff format . && uv run ruff check .
uv run mypy src tests # strict, configured in pyproject.toml
cargo fmt && cargo clippy --all-targets -- -D warnings && cargo test

The GeoTIFF, KML and tile parsers also have fuzz targets (fuzz/): fuzz/run.sh geotiff_open 60 runs one for a minute (needs the nightly toolchain and cargo install cargo-fuzz). CI runs them on pull requests that touch a parser and every night; a crash is fixed in the parser and pinned with a regression test.

The live Sentinel-2 test is opt-in: set MAPCV_EOPF_URL to a public product and run uv run pytest -m eopf_live.

  • Python: sources in src/mapcv/, tests in tests/test_<module>.py; every file starts with a one-line docstring and from __future__ import annotations; full type annotations with built-in generics and X | None (dict[str, int], list[Path]); plain-prose docstrings; comments explain why; ruff (line length 100) and mypy --strict must pass.
  • Rust: one module per file with a //! header; /// docs on public items with # Errors / # Panics sections; public functions return Result<T, String>; no unwrap()/expect() in public functions; named constants instead of magic numbers.
  • Commits: Conventional Commits (feat:, fix:, perf:, refactor:, docs:, ci:, chore:, test:). They drive the changelog. PRs are squash-merged.
  1. For anything substantial, open an issue first to discuss it.
  2. Create a branch (git checkout -b feat/your-feature-name), commit with the pre-commit checks passing.
  3. Open a pull request against main that explains the problem and the solution and links related issues.

The site is Astro Starlight in website/, deployed to GitHub Pages from main.

Terminal window
cd website
npm ci
npm run dev # http://localhost:4321/mapcv/
npm run build # also fails on broken internal links
  • Pages are MDX files in website/src/content/docs/, organised as Get started, Tutorials, How-to guides (guides/), Reference, Concepts and Project. The sidebar is defined in website/astro.config.mjs.
  • The CLI reference embeds --help snapshots from website/src/cli-help/. After changing the CLI, refresh them with website/scripts/update-cli-help.sh (set MAPCV="uv run mapcv" to use the development build).
  • The Changelog page renders CHANGELOG.md directly; the Migration and Providers pages mirror MIGRATION.md and PROVIDERS.md, so update both places together.
  • Terminal output on the site is real output, trimmed. When behaviour changes, re-run the commands and paste the new output rather than editing it by hand.