Skip to content

Plugin system, layers refactor, workshop plugin refactor. Refactor of a lot of things. - #44

Merged
PyXiion merged 19 commits into
mainfrom
feat/plugins
Jul 29, 2026
Merged

Plugin system, layers refactor, workshop plugin refactor. Refactor of a lot of things.#44
PyXiion merged 19 commits into
mainfrom
feat/plugins

Conversation

@PyXiion

@PyXiion PyXiion commented Jul 27, 2026

Copy link
Copy Markdown
Owner

Resolves #28. Also refactors code

Extracting Steam integration into a completely independent plugin.

PyXiion added 4 commits July 26, 2026 22:18
…o plugin

- CoreContext stripped of rail_views/add_rail_view (moved to AppContext)
- Plugin base gains dependencies list; register() no-op; setup_all() toposorts
- SteamCmdService paths computed live from ctx.config (no set_prefix/_derive_paths)
- SteamCmdProgress/ItemStatus/Result types moved to download_proto
- save_config deferred until after successful SteamCMD install
- AppContext: owns UI PluginRegistry, rail_views, ui_prefs; sync setup_all/async init_all
- Steam Workshop moved into ui/plugins/steam_workshop/ (self-contained package)
- BaseViewPanel drops ui_prefs param; reads from app_ctx.ui_prefs
- MainWindow drops ui_prefs param; reads from app_ctx
- Tests updated: no set_prefix tests, config-based path tests
@PyXiion PyXiion added this to the 0.7.0 milestone Jul 27, 2026
@PyXiion PyXiion self-assigned this Jul 27, 2026
@codacy-production

codacy-production Bot commented Jul 27, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 426 complexity · -4 duplication

Metric Results
Complexity 426
Duplication -4

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@codacy-production codacy-production Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

While the PR successfully implements a formal plugin system and separates Core/UI layers, the current implementation is not up to standards due to critical gaps in the plugin lifecycle and missing test coverage for the core registry logic. Codacy analysis indicates that coverage requirements are missing, and a significant complexity increase (+246) was detected in the Steam Workshop injection script.

A primary concern is the initialization order in _app.py, which creates a conflict where plugins lack access to mod data during their setup phase, while swapping the order risks UI plugins missing early lifecycle signals. Additionally, the core plugin sorting logic lacks unit tests, and the main entry point still contains hardcoded plugin references, partially undermining the goal of a fully pluggable architecture.

About this PR

  • The core infrastructure for the plugin system (topological sorting and registry lifecycle) in 'core/plugin.py' currently lacks dedicated unit tests. Given this is the foundation for all future extensibility, coverage here is critical.
  • The application entry point in '_app.py' still contains hardcoded logic/imports for specific plugins ('steamcmd', 'steamworkshop'), which partially contradicts the goal of a completely independent/pluggable architecture.

Test suggestions

  • Found: Verify AppContext correctly initializes and manages rail views independently of CoreContext.
  • Found: Verify SteamCmdService still operates correctly as a registered plugin.
  • Missing: Verify PluginRegistry correctly sorts plugins by dependencies during setup_all using a complex graph.
  • Missing: Verify PX_DISABLED_PLUGINS environment variable correctly prevents specified plugins from loading.
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Missing: Verify PluginRegistry correctly sorts plugins by dependencies during setup_all using a complex graph.
2. Missing: Verify PX_DISABLED_PLUGINS environment variable correctly prevents specified plugins from loading.

TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback

Comment thread src/pxmodrim/core/services/startup_impact_service/db.py
Comment thread src/pxmodrim/core/services/steam_cmd_service.py Outdated
Comment thread src/pxmodrim/_app.py Outdated
Comment thread src/pxmodrim/ui/plugins/steam_workshop/inject.js Outdated
Comment thread src/pxmodrim/core/plugin.py
PyXiion and others added 5 commits July 27, 2026 23:22
Co-authored-by: codacy-production[bot] <61871480+codacy-production[bot]@users.noreply.github.com>
…sing

- Extract _parse_disabled_plugins() helper from App._setup()
- Add tests/TestPluginRegistryToposort: complex DAG, missing dep,
  extra_deps, init_all order
- Add tests/TestParseDisabledPlugins: empty, single, multiple, whitespace
- Fix test_persists_prefix patch target (steam_cmd_service -> core.config)
… fail

On Windows the fake_steamcmd fixture creates a .bat script, but
service.executable resolves to steamcmd.exe. Copying batch content
into a .exe file causes ERROR_BAD_EXE_FORMAT because CreateProcess
expects a PE binary. The worker catches the OSError and emits empty
succeeded/failed lists.

Fix: copy to .cmd (executable by CreateProcess via cmd.exe) and mock
the executable property to return the .cmd path.
@PyXiion

PyXiion commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

The Codacy CLI generates a results.sarif with one run per tool.
github/codeql-action/upload-sarif@v4 rejected it because all runs
shared the same category. Split into per-tool files and upload the
directory so each run gets a unique auto-detected category.
@PyXiion

PyXiion commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

Found workaround. QWebChannel is messy, but works fine.

@PyXiion PyXiion changed the title Plugin system + Layers, ownership and connections refactor Plugin system, layers refactor, workshop plugin refactor. Refactor of a lot of things. Jul 28, 2026
PyXiion added 8 commits July 28, 2026 07:32
Replace global config_dir() calls with ConfigService injected via
constructor DI. Tests provide a tmp_path-backed ConfigService so no
test touches the real ~/.config/pxmodrim.

Changes:
- New generic ConfigService in core/config.py with typed load/save
  using msgspec.Struct (FileNotFoundError and corrupt-data handled
  gracefully)
- CoreContext stores ConfigService, forwards to DiagnosticsService
- CommunityRulesService, NoVersionWarningService, UseThisInsteadService
  now take ConfigService via constructor (previously zero-param)
- StartupImpactService reads config_dir from ctx.config_service
- SteamCmdService uses ctx.config_service instead of config_dir()
- ui/config.py delegates to ConfigService (no more direct Path logic)
- tests/conftest.py provides config_service fixture (tmp_path-based)
- main_window.py and mod_info_panel.py pass config_service to
  load/save_ui_prefs
- check-deps.py allows core.sort and core.checker to import core.config
…sService

ModItem no longer stores diagnostic view state (has_error, has_warning,
error_tooltip, warning_tooltip). ModListModel queries DiagnosticsService
via summary_for(uuid) in data() instead, making diagnostic state
independent of load_mods() timing.

- DiagnosticsService: cache _last_summary, add summary_for() API
- ModListModel: remove diagnostic fields from ModItem, pull from service
- ModListPanel: bridge active_mods_changed correctly, skip commitOrder
  when only the checked set changes (not order)
…ates

- Move steam workshop injection from action_handler.py to bridge_obj.py
- Add TypeScript sources for steam workshop webview under ts/
- Add build-inject-js.py script with mtime-based caching
- Update SteamWorkshop.qml, view.py, plugin.py for new bridge
- Update AGENTS.md with build-js workflow and CI matrix details
- Add rimworld-utils build deps to justfile
- Remove action_handler.py (replaced by bridge_obj.py)
- Update tests for plugin interface changes
Merge main's benchmarks & optimisations (PR #45) into feat/plugins, resolving
conflicts in main_window.py and justfile:

- main_window: keep HEAD's simple _auto_sort wrapper around
  CoreContext.auto_sort() over incoming UI-level duplication
- justfile: keep HEAD's build-js recipe + variadic build args, add
  bench recipe from main
- context: log sort time in ms instead of seconds
- packaging/build: add --nofollow-import-to=pytest,pygments
@PyXiion
PyXiion merged commit 456656e into main Jul 29, 2026
4 of 5 checks passed
@PyXiion
PyXiion deleted the feat/plugins branch July 29, 2026 07:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plugin/extension system

1 participant