Skip to content

v2.14.0 — Cleanup pass · CI linter · dep refresh

Latest

Choose a tag to compare

@gfargo gfargo released this 18 May 15:28
· 4 commits to main since this release
b080b56

v2.14.0 — Cleanup pass · CI linter · dep refresh

First minor bump since v2.13. No new features — a foundation pass that pays down accumulated debt, adds a Python linter to CI, refreshes dependencies, and quietens a cosmetic startup warning. The path is clear for the feature backlog (#24#37) to land cleanly on top of this.

🧹 Code cleanup (PR #44)

  • switchTab consolidation — was three nested function-replace wrappers stacked at parse time (base → currentTab tracking → chat-render hook). Collapsed into one function with a doc-block listing all five responsibilities. ~30 lines shorter, much easier to follow.
  • Dead JS removedloadPersistedHistory (defined but never called) and updateSliderByAbsAddr (3-line alias wrapper with no callers).
  • New tests (+31):
    • tests/test_xml_escape.py — 10 tests covering all 5 XML entities, ordering rule (& substituted first or & would re-escape), unicode passthrough, realistic mixed content with quotes/apostrophes/ampersands. Matters because scene XML injection corrupts .qxw files if entities are wrong.
    • tests/test_absolute_channel.py — 11 tests covering universe-boundary math (channel 512 vs 513), the +1 1-based-vs-0-based conversion, plus rig-specific pinning for the Riversway SlimPAR Pro + SlimPAR 56 addressing.

✅ Ruff linter + CI gate (PR #45)

New fourth CI job catches style drift, dead imports, deprecated typing, and small footguns at PR time.

  • Config in repo-root pyproject.toml: line-length 120, target Python 3.11, rules E F W I B UP (pycodestyle + pyflakes + isort + bugbear + pyupgrade)
  • 67 violations fixed: 35 auto-fixed (import sorting, Dictdict, Optional[X]X | None, unused emit import), 6 E701 split, 4 B904 (exception chains preserved via from e/from None in AI provider wrappers), 2 E402, 2 W293, 18 E501 (long tool-registry descriptions wrapped using paren-grouped string concat)
  • CI step runs once across both servers (~150ms) — slots in before pytest

📦 Dependency refresh (PR #46)

All five runtime deps were pinned to versions ~6 months old.

Package From To
Flask 3.0.0 3.1.3
flask-cors 4.0.0 6.0.2
flask-socketio 5.3.5 5.6.1
requests 2.31.0 2.34.2
websockets 12.0 15.0.1

Tested in a fresh venv against the full pytest suite. Notable: requests 2.34 includes security fixes for PoolManager-related CVEs. Websockets kept one minor back from latest 16.0 for stability.

🤫 Silence Werkzeug dev-server warning (PR #48)

Werkzeug's "WARNING: This is a development server" line in journalctl is cosmetic noise for the single-user studio LAN deploy. Silenced via a targeted logging.Filter on the werkzeug logger — other startup output (request access logs, * Running on http://... banner) is preserved.

The proper production-WSGI migration (gunicorn + eventlet/gevent worker) is queued as #47. That migration needs Pi-side testing because of the persistent QLC+ asyncio loop in a dedicated thread — out of scope for a cleanup pass.

Numbers

  • Tests: 195 → 226 (+31)
  • CI jobs: 3 → 4 (added ruff)
  • Lint violations: 67 → 0
  • Dead code removed: ~40 lines of JS
  • Switch-tab layers: 3 → 1

Upgrade

From your Mac:

git pull origin main
bash scripts/deploy.sh

Then on the Pi (one-time, to pick up dep bumps):

ssh lights.local
cd ~/lights-pi/control-server
source ~/venv/bin/activate    # wherever the venv lives
pip install --upgrade -r requirements.txt
sudo systemctl restart lighting-control.service
journalctl -u lighting-control.service -f    # watch startup

You should no longer see "WARNING: This is a development server" in the log.

What's next

Foundation pass is wrapped. The feature backlog (#24#37) is the main thrust from here. MIDI controller input (#26) is still the one I'd cut next — the single biggest UX upgrade for daily use, and ~$40 of hardware + a couple days of code.