-
Notifications
You must be signed in to change notification settings - Fork 1
Project Development
This page covers the recommended local development workflow for Hussh contributors. It is based on the repository's GitHub Actions workflows, pyproject.toml, tox.toml, and the test fixtures in tests/.
Hussh is a mixed Rust/Python project built with:
-
maturinfor building and installing the PyO3 extension module -
uvfor managing the local Python environment and editable installs -
toxfor running the supported test and lint environments -
pre-commitfor the same formatting and lint checks that CI runs first
- Install Rust and Cargo.
- Install Python and
uv. - Create a virtual environment and install the development dependencies:
uv venv
source .venv/bin/activate
uv pip install -e .[dev]That editable install gives you the Python dependencies used by local development, including tox, pre-commit, pytest, Docker bindings, and maturin.
For a fast local development loop, reinstall the extension into your active environment after Rust or PyO3-facing changes:
maturin developIf you want to mirror the wheel-building step used in GitHub Actions, build first and then reinstall:
maturin build
pip install .[dev] --find-links dist --force-reinstallIf you want to stay on uv for the reinstall step locally, use:
uv pip install --force-reinstall -e .[dev]CI builds wheels with maturin and then installs the project before running the test suite. Locally, maturin develop is usually the quickest option while iterating, and maturin build is useful when you want to verify the distributable wheel still builds cleanly.
Run the pre-commit hooks manually before pushing changes:
pre-commit run --all-filesThis matches the first CI gate. The configured hooks currently run:
cargo fmtclippyruff-formatruff --fix --exit-non-zero-on-fix
You can also run the same check through tox:
tox -e lintThe project standard is to run tests through tox.
tox -m testThis requires the matching Python interpreters to be available locally. If you only have one interpreter installed, run that specific tox environment instead.
tox -e py312tox -e py312 -- -k proxy_jumpThe tox test environments use uv as the installer and execute:
pytest -v tests/If you specifically need to run pytest directly while debugging, make sure you already refreshed the extension with maturin develop or reinstalled a freshly built wheel first.
Most tests depend on Dockerized SSH test servers. The fixtures in tests/conftest.py will automatically pull and start:
ghcr.io/jacobcallahan/hussh/hussh-test-server:latest
The default tests use Docker ports:
-
8022for the primary SSH test server -
8023for the secondary server used in proxy and copy scenarios
Make sure Docker is running before you start the test suite.
The MultiConnection tests also require local hostnames that resolve to 127.0.0.1. CI adds them automatically; locally you should add them yourself:
echo "127.0.0.1 hussh-server-1.test hussh-server-2.test hussh-server-3.test hussh-server-4.test hussh-server-5.test" | sudo tee -a /etc/hostsIf these hostnames are missing, the MultiConnection tests are skipped.
You can also choose how many multi-host test servers to launch:
tox -e py312 -- --num-servers 5- The extension is built through
maturinwith thepyo3/extension-modulefeature enabled. - Python-only edits do not always require a rebuild, but Rust changes do.
- If imports behave unexpectedly after native changes, rerun
maturin develop. - Build artifacts land under
target/, so stale native artifacts can sometimes explain confusing local behavior.
On Linux and macOS, the CI workflows also install OpenSSL-related system packages before building. If a local native build fails during dependency detection or linking, check that your machine has the equivalent OpenSSL and pkg-config tooling available.
# editable install for development
uv pip install -e .[dev]
# rebuild the extension into the active environment
maturin develop
# verify the wheel build
maturin build
# run the same pre-commit gate used by CI
pre-commit run --all-files
# run lint through tox
tox -e lint
# run tests
tox -e py312
tox -m test