Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 31 additions & 7 deletions .github/workflows/module-collisions.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
name: Module Collisions
name: Plugin Structure

# Fails when a plugin's deferred import (subpackage file or function-scoped
# import) targets a sibling top-level module whose name is also shipped by
# another plugin. The core loads plugin modules by bare name on sys.path and
# isolates them after the entry point loads, so such a deferred import can bind
# a different plugin's same-named module and fail to load. Scans ALL plugins
# because a newly added plugin can collide with an existing one.
# Two structural checks that both scan ALL plugins, because either problem can
# arrive with a newly added plugin rather than a changed one.
#
# 1. Module collisions — fails when a plugin's deferred import (subpackage file
# or function-scoped import) targets a sibling top-level module whose name is
# also shipped by another plugin. The core loads plugin modules by bare name
# on sys.path and isolates them after the entry point loads, so such a
# deferred import can bind a different plugin's same-named module and fail
# to load.
#
# 2. Scroll adoption — fails when a plugin's scroll_display.py also defines the
# fallback implementation it is supposed to import from
# scroll_display_legacy.py. Three plugins shipped as those two files
# concatenated, carrying ~2,000 lines nothing referenced, and that dead copy
# is what hid the missing separator-icon constants that broke scroll mode.

on:
pull_request:
paths:
- 'plugins/**'
- 'scripts/check_module_collisions.py'
- 'scripts/check_scroll_adoption.py'
Comment thread
coderabbitai[bot] marked this conversation as resolved.
- 'scripts/test_check_scroll_adoption.py'
# Without this, a PR that only edits this workflow matches no path and
# the workflow never runs against its own change.
- '.github/workflows/module-collisions.yml'
workflow_dispatch:

jobs:
Expand All @@ -24,3 +38,13 @@ jobs:
python-version: '3.12'
- name: Check for cross-plugin module collisions
run: python scripts/check_module_collisions.py
# Runs even when the collision check fails, so one PR surfaces both.
- name: Check scroll adoption does not inline the fallback
if: always()
run: python scripts/check_scroll_adoption.py
# The gate's own regression suite. It reports by absence -- "no legacy
# classes found" and "could not look" would otherwise be the same
# answer -- so a gate that quietly stopped detecting still exits 0.
- name: Test the scroll-adoption gate
if: always()
run: python scripts/test_check_scroll_adoption.py
12 changes: 6 additions & 6 deletions plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@
"plugin_path": "plugins/basketball-scoreboard",
"stars": 0,
"downloads": 0,
"last_updated": "2026-07-31",
"last_updated": "2026-08-05",
"verified": true,
"screenshot": "",
"latest_version": "1.10.1"
"latest_version": "1.10.2"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
},
{
"id": "calendar",
Expand Down Expand Up @@ -332,10 +332,10 @@
"plugin_path": "plugins/hockey-scoreboard",
"stars": 0,
"downloads": 0,
"last_updated": "2026-07-31",
"last_updated": "2026-08-05",
"verified": true,
"screenshot": "",
"latest_version": "1.7.1",
"latest_version": "1.7.2",
"icon": "fas fa-hockey-puck"
},
{
Expand All @@ -356,10 +356,10 @@
"plugin_path": "plugins/lacrosse-scoreboard",
"stars": 0,
"downloads": 0,
"last_updated": "2026-07-31",
"last_updated": "2026-08-05",
"verified": true,
"screenshot": "",
"latest_version": "1.7.1",
"latest_version": "1.7.2",
"icon": "fas fa-baseball-ball"
},
{
Expand Down
10 changes: 8 additions & 2 deletions plugins/basketball-scoreboard/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "basketball-scoreboard",
"name": "Basketball Scoreboard",
"version": "1.10.1",
"version": "1.10.2",
"description": "Live, recent, and upcoming basketball games across NBA, NCAA Men's, NCAA Women's, and WNBA with real-time scores, schedules, and March Madness tournament support",
"author": "ChuckBuilds",
"category": "sports",
Expand All @@ -18,6 +18,12 @@
"branch": "main",
"plugin_path": "plugins/basketball-scoreboard",
"versions": [
{
"version": "1.10.2",
"released": "2026-08-05",
"notes": "Housekeeping, no behaviour change: scroll_display.py carried a second, unreferenced copy of the bundled fallback classes at module level -- the file was the pre-adoption and adopted versions concatenated rather than one replacing the other. The live fallback in scroll_display_legacy.py is untouched. Removing the dead copy is what makes a missing constant visible instead of appearing defined; that dead block is where the ones that broke scroll mode were hiding.",
"ledmatrix_min_version": "2.0.0"
},
{
"version": "1.10.1",
"released": "2026-08-05",
Expand Down Expand Up @@ -138,7 +144,7 @@
],
"stars": 0,
"downloads": 0,
"last_updated": "2026-07-31",
"last_updated": "2026-08-05",
"verified": true,
"screenshot": "",
"display_modes": [
Expand Down
Loading
Loading