Workflow¶

Use this page for the day-to-day development loop: install the environment, run the tests, preview docs, and run the project checks. For the rationale behind order-independent and opt-in parallel tests, see ADR 0002: Order-independent tests with opt-in parallelism.

Development environment¶

Development requires uv.

$ git clone https://github.com/vcs-python/libvcs.git
$ cd libvcs

Install the project and its development dependency groups:

$ uv sync

Justfile commands prefixed with watch- will watch files and rerun.

Tests¶

$ uv run py.test

Helper: just test. Rerun tests on file change: just watch-test (requires entr(1)).

Running tests in parallel¶

The suite spawns real git, hg, and svn processes, so on a multi-core machine it runs faster across workers with pytest-xdist (a dev dependency):

$ just test-parallel

This runs uv run py.test -n auto, where auto sizes the worker pool to the machine’s cores. Parallelism is opt-in — just test and uv run py.test stay serial by default.

Order independence¶

Tests must pass regardless of the order they run in. Parallel and shuffled runs spread tests across workers, so any hidden coupling — shared global state, or a fixture that leaks into a later test — surfaces as a failure. Keep fixtures self-contained and reset any global state in teardown. Check locally with a shuffled run:

$ uv run --with pytest-randomly py.test -p randomly

Documentation¶

Default preview server: http://localhost:8068

sphinx-autobuild will automatically build the docs, watch for file changes and launch a server.

From the project root: just start-docs. From inside docs/: just start.

Manual documentation (the hard way)¶

cd docs/ and just html to build. just serve to start http server.

Helpers: just build-docs, just serve-docs

Rebuild docs on file change: just watch-docs (requires entr(1))

Rebuild docs and run server via one terminal: just dev-docs

Formatting / linting¶

ruff¶

The project uses ruff to handle formatting, sorting imports and linting.

uv:

$ uv run ruff check .

If you setup manually:

$ ruff check .
$ just ruff
$ just watch-ruff

requires entr(1).

uv:

$ uv run ruff check . --fix

If you setup manually:

$ ruff check . --fix

ruff format¶

ruff format is used for formatting.

uv:

$ uv run ruff format .

If you setup manually:

$ ruff format .
$ just ruff-format

mypy¶

mypy is used for static type checking.

uv:

$ uv run mypy .

If you setup manually:

$ mypy .
$ just mypy
$ just watch-mypy

requires entr(1).

Releasing¶

See Releasing for the version policy and release checklist.