Thanks for your interest in improving DevKit! This guide explains how to set up your environment, make changes safely, and open a clean pull request.
If you’re in a hurry, read AGENTS.md for a concise repository overview and conventions. This doc expands on those details with step‑by‑step instructions.
- Python 3.11+
- Recommended: pyenv to manage Python versions
- Recommended: pipx to install Poetry
- Development: Poetry for dependency management
- Optional (DB features):
psqlandpg_restoreinPATH - Optional (Rails integration):
railsinPATH
# Python 3.11 via pyenv
curl https://pyenv.run | bash
pyenv install 3.11.9
pyenv local 3.11.9
# Tools
python3 -m pip install --user pipx
pipx ensurepath
pipx install poetry
# Project setup
make dev
poetry run devkit --helpUseful make targets
make dev: install dependencies via Poetrymake test: run pytest quietlymake lint: Ruff lint + format checkmake fmt: apply Ruff formattingmake docs/make docs-serve: build or serve docs at http://localhost:8000make build: build the packagemake install: install the built package via pipx
Run the CLI during development
poetry run devkit service list
poetry run devkit db reset myapp --backup /path/to/backup.dump --trace- Create a branch
git checkout -b feat/<slug>
# or fix/<slug>, docs/<slug>- Implement changes (see “Code Organization” and “Style & UX”).
- Keep docs and tests updated as you go.
- Before pushing:
make fmt && make lint && make test && make docs- Open a PR with a clear description, rationale, and screenshots/logs when UX changes.
- Commands (Typer):
devkit/cli.py(sub-apps:service,db,meta) - Domain helpers:
devkit/services.py,devkit/postgres.py,devkit/rails.py,devkit/iofmt.py - Introspection:
devkit/introspect.pyandscripts/generate_reference.py - Docs:
docs/*.md(manual + auto-generatedcommands.md)
Adding or changing commands
- Define parameters and help text in Typer (
devkit/cli.py). - Put logic in small, focused helpers under
devkit/*modules. - For machine-readable output, build payloads with
iofmt.envelope(...)and print viaiofmt.emit(...)when--format json. - Keep command names, flags, and messages consistent with existing commands.
- Python 3.11+, type hints preferred, small functions.
- Ruff controls formatting and lint (100-char lines).
- Naming: modules snake_case, classes PascalCase, functions/vars snake_case.
- CLI output must be predictable:
- Support
--format text|json,--quiet/--verbose,--traceconsistently. - Honor safety:
--yes,--safe, andDEVKIT_SAFE=1(require confirmations for destructive actions unless explicitly allowed). - Use structured error payloads with clear tips when possible.
- Support
- Framework: pytest. Place tests in
tests/astest_*.pywith functionstest_*. - Unit tests over integration: mock external tools (Rails, Postgres) and filesystem.
- Keep tests fast; avoid network or invoking real CLIs.
- Useful patterns:
- Monkeypatch
subprocess.runand environment variables. - Use
tmp_path/tmp_path_factoryfor filesystem isolation. - Provide regression tests for bug fixes.
- Monkeypatch
- Run locally:
make test- Edit
docs/*.mdwhen features or flags change. - Re-generate the command reference after modifying the CLI:
poetry run python scripts/generate_reference.py > docs/commands.md- Build/serve the docs to verify formatting:
make docs
make docs-serve # http://localhost:8000- Conventional Commits:
feat: ...,fix: ...,docs: ...,refactor: ..., etc. - Branches:
feat/<slug>,fix/<slug>,docs/<slug>. - PR checklist:
make fmt,make lint,make test,make docsall pass- Updated docs and regenerated
docs/commands.mdif CLI changed - Clear description, rationale, and screenshots/logs for UX changes
- Do not commit secrets. Use environment variables.
- Treat destructive operations carefully; require
--yeswhen--safe/DEVKIT_SAFE=1is active. - Guard external dependencies (Rails, Postgres) with helpful error messages.
- Include steps to reproduce, expected vs actual, logs, and environment.
- For enhancements, propose the UX (commands/flags) first to align on design.
Open an issue. Thanks for contributing!