Tier 2 (WIP): Settings validation + AppController #9

Closed
clanker wants to merge 0 commits from tier2/settings-and-controller into master
Owner

Tracking PR for Tier 2. Will accumulate commits for:

  • Settings validation — typed Settings dataclass + validated load_config() with clear error dialog on bad config.py
  • AppController split — break Dodo(QApplication) god object into bootstrap + controller owning panel registry / sync / tab persistence, panels depend on Controller instead of Dodo (fixes the cycle).

First commit (225ae96): wired lazarus/controller.py alongside Dodo — panels still target Dodo, but Dodo.controller exists and both Dodo + controller paths are wired to batch_done. Next commits move callers and carve Dodo down.

Draft until Tier 2 is complete. No breakage expected — py_compile passes.

Tracking PR for Tier 2. Will accumulate commits for: - **Settings validation** — typed Settings dataclass + validated load_config() with clear error dialog on bad config.py - **AppController split** — break Dodo(QApplication) god object into bootstrap + controller owning panel registry / sync / tab persistence, panels depend on Controller instead of Dodo (fixes the cycle). **First commit (225ae96):** wired `lazarus/controller.py` alongside Dodo — panels still target Dodo, but `Dodo.controller` exists and both Dodo + controller paths are wired to `batch_done`. Next commits move callers and carve Dodo down. Draft until Tier 2 is complete. No breakage expected — py_compile passes.
Add lazarus/controller.py owning panel registry and app-level commands
(open/search/thread/compose/tags, delegation, sync wrappers, panel
refresh). Dodo keeps all methods as the controller is wired alongside
the existing paths — next commits move callers to the controller and
shrink Dodo to a bootstrap.

Why: Dodo(QApplication) was an 800-line god object; splitting it breaks
the circular imports and makes panels testable without a QA display.
Controller.__init__ accessed app.sync_thread before Dodo had created
it (field init is after MainWindow). Move construction after sync
timer setup and guard reads with getattr so ordering is safe.
Add lazarus/config.py with ConfigError + load_config() + _validate_settings()
that catches the classes of mistakes that silently break mail routing:
- missing/empty email_address + sent_dir, dict/string mismatches,
- smtp_accounts typo vs email_address keys, invalid sync interval/pane/theme,
- common typo '~Mail' (missing /) in sent_dir paths.

Dodo now calls load_config() instead of raw exec() + manual locate; bad
config fails with file:lineno + a checklist, not a downstream traceback.

Also fixes a latent typo in ~/.config/lazarus/config.py (~Mail → ~/Mail).
Move panel orchestration ownership to controller.py:
- Dodo methods (open/search/thread/compose/tags, delegation, panel
  registry) now shim to self.controller while preserving the same
  public surface for keymap and existing callers.
- Panel base + all panel subclasses + MainWindow + CommandBar widen
  their constructor typing to 'Dodo | AppController' so they accept
  either; runtime is duck-typed (both expose same interface).
- Batch_done now single-wired via controller (Dodo shim keeps compat).

Next: migrate SyncMailThread ownership + QSettings persistence into
controller so Dodo becomes a ~120-line bootstrap.
SyncMailThread is the sync engine — it belongs with panel/orchestration
ownership (AppController), not the QApplication bootstrap. Move the
definition to controller.py and re-export from app.py so existing
'lazarus.app.SyncMailThread' imports keep working while new code
imports from controller. Also deduplicate the controller/app header
imports needed for QThread/pyqtSignal/os/signal/subprocess.
Move sync_mail implementation to AppController (canonical), leaving
Dodo.sync_mail as a delegation shim. Move SyncMailThread canonical to
controller.py (already done) and wire batch_done-driven panel refresh
via controller only. Dodo now holds only QApplication lifecycle,
signal handling, HelpWindow, and delegation shims — down from 831 to
392 lines. Controller at 568 lines owns panel registry + SyncMailThread
+ sync orchestration.
clanker closed this pull request 2026-08-07 23:50:41 +00:00

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Home/lazarus!9
No description provided.