otko/CONTRIBUTING.md
smillmorel ba783718d4 chore: adopt remaining local development state
Catch-all for the intermixed residue of the unpushed otko-development
work ported into this tree: combinations/console-dock/quick-guide wiring
across commands, core, services, views and tests; repo-wide ruff-format
normalization; README/CONTRIBUTING updates; and the toolbar default
(both toolbars now open in the top area, quick guide text updated).

Splitting this further would require hunk-level surgery with low
confidence; the preceding commits in this branch isolate the
self-contained features.
2026-09-16 12:03:22 -04:00

3.6 KiB
Raw Permalink Blame History

Contributing

Thanks for helping with OTKO — a SAP2000-style desktop GUI for OpenSeesPy. Early-stage project: the bar is architecture cleanliness, not feature count. If your change breaks a layering rule below, it won't merge — no matter how useful the feature.

Dev setup

python -m venv .venv
source .venv/bin/activate           # Linux / macOS
# .venv\Scripts\activate            # Windows
pip install -e ".[gui,dev]"
pre-commit install

pip install -e ".[gui,dev]" pulls the Qt/PyVista desktop stack plus the dev tools. For a headless checkout (core + services only, no Qt) use pip install -e . instead. Python 3.10+; on Windows use 3.12+.

Launch the GUI with:

python -m otko

pre-commit install wires ruff + mypy into your local git hooks so obvious issues are caught before a commit. Run it once per clone.

Before opening a PR

Run the verify commands in this order and make sure they are all clean:

ruff check src tests
ruff format src tests          # line-length 100, E501 ignored
mypy src/otko/core src/otko/services
pytest -m "not slow"           # CI gate: lint → this, on 3.10/3.11/3.12 × ubuntu/windows/macos

Focused runs are faster while iterating: pytest tests/unit (pure logic, milliseconds), pytest tests/gui -k <name> (pytest-qt, needs a display; Linux GUI tests want xvfb-run -a pytest ...), and pytest tests/integration -k <name> (real OpenSeesPy runs). Single test: pytest tests/unit/test_project.py::test_name -q. Markers: gui, slow.

Architectural rules (enforced in review)

OTKO uses a strict one-way MVVM + service architecture. Dependencies flow outward-in only:

views → viewmodels → services → core

commands sits alongside the bridge and owns every model mutation.

  1. core/ is pure Python — stdlib + numpy + pydantic. It may not import Qt or openseespy. Period.
  2. services/ may use core + h5py + openseespy, but may not import Qt.
  3. views/ (PySide6/pyvistaqt) may not import openseespy directly — go through a service. No business logic in views.
  4. viewmodels/ bridges core ↔ Qt (signals, QUndoStack).
  5. commands/ holds the QUndoCommand subclasses; all model mutations go through commands, not ad-hoc edits in views.
  6. Public functions and methods need type hints and a docstring.
  7. New domain entities go through Pydantic validation.
  8. Long-running operations (>50 ms) run off the GUI thread (AnalysisWorker in a QThread, cancelled via isInterruptionRequested(); results cross threads as a lightweight ResultsHandle written to HDF5).

The full package map and the fixed OpenSeesPy command order the runner emits live in docs/architecture.md. Never reorder the runner's commands.

Branch model

main is the default and integration branch. Work on short-lived topic branches cut from main — feat/<topic>, fix/<topic>, or docs/<topic> — and open a pull request against main. Do not commit directly to main from an agent session. There is no develop branch.

Commit style

Conventional Commits — feat:, fix:, refactor:, docs:, test:, chore:, ci:. Keep each commit focused; a feat: commit should add a feature, not mix one in with unrelated refactors.

Documentation

If your change is user-visible, update docs/QUICK_GUIDE.md and the relevant roadmap or ADR entry. Project model files are .osmodel (Pydantic-validated JSON); regenerate the checked-in examples/*.osmodel from their scripts with python examples/<name>.py rather than hand-editing them.