Development

Developing python projects associated with git-pull.com all use the same structure and workflow. At a later point these will refer to that website for documentation.

Bootstrap the project

Install git and uv (see uv’s installation documentation).

Clone:

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

Install packages:

$ uv sync --all-extras --dev

Development loop

Tests

Tests run on pytest.

Rerun on file change

via pytest-watcher (works out of the box):

$ just start

via entr(1) (requires installation):

$ just watch-test

Manual (just the command, please)

$ uv run py.test

or:

$ just test

Runtime dependency smoke test

Verify that the published wheel runs without dev/test extras:

$ uvx \
    --isolated \
    --no-cache \
    --from . \
    python scripts/runtime_dep_smoketest.py

The script imports every vcspull module and exercises each CLI sub-command with --help. There is also a pytest wrapper guarded by a dedicated marker:

$ uv run pytest \
    -m scripts__runtime_dep_smoketest \
    scripts/test_runtime_dep_smoketest.py

These checks are network-dependent because they rely on uvx to build the package in an isolated environment.

pytest options

PYTEST_ADDOPTS can be set in the commands below. For more information read docs.pytest.com for the latest documentation.

Verbose:

$ env PYTEST_ADDOPTS="-verbose" just start

Drop into pdb on first error:

$ env PYTEST_ADDOPTS="-x -s --pdb" just start

If you have ipython installed:

$ env PYTEST_ADDOPTS="--pdbcls=IPython.terminal.debugger:TerminalPdb" \
    just start

Documentation

sphinx generates the documentation. In the future this may change to docusaurus.

Default preview server: http://localhost:8022

Rerun on file change

sphinx-autobuild will automatically build the docs, it also handles launching a server, rebuilding file changes, and updating content in the browser:

$ cd docs
$ just start

If doing css adjustments:

$ just design

Rebuild docs on file change (requires entr(1)):

$ cd docs
$ just dev

Use two terminals if needed:

$ just watch
$ just serve

Manual (just the command, please)

$ cd docs

Build:

$ just html

Launch server:

$ just serve

Linting

ruff

ruff handles formatting, import sorting, 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 formats the code.

uv:

$ uv run ruff format .

If you setup manually:

$ ruff format .
$ just ruff-format

mypy

mypy checks static types.

uv:

$ uv run mypy .

If you setup manually:

$ mypy .
$ just mypy
$ just watch-mypy

requires entr(1).

See [tool.mypy] in pyproject.toml.

[tool.mypy]
python_version = "3.10"
warn_unused_configs = true
files = [
  "src",
  "tests",
  "docs/_ext",
]
strict = true

Publishing to PyPI

uv handles virtualenv creation, package requirements, versioning, building, and publishing. Therefore there is no setup.py or requirements files.

Update __version__ in __about__.py and pyproject.toml, then commit the bump:

$ git commit -m 'build(vcspull): Tag v0.1.1'

Tag it:

$ git tag v0.1.1

Push the branch and the tag:

$ git push
$ git push --tags

GitHub Actions will detect the new git tag, and in its own workflow run uv build and push to PyPI.