refactor(server): move DLC path resolution to lib/dlc_paths.py (R3 substrate) - #843
Conversation
…bstrate) The keystone for the path-dependent routers (ws_highway, song, audio-local-path, sloppak): the "where do the song files live + safe containment" layer leaves server.py so a router can reach it. - `_resolve_dlc_path` (pure — args only) moves verbatim. - `_get_dlc_dir` reads the env-derived paths through the appstate seam (appstate.dlc_dir/dlc_dir_env/config_dir) instead of module globals, so lib/dlc_paths.py does no import-time IO. - appstate gains `dlc_dir`/`dlc_dir_env` slots (config_dir already there); server.py configures them. All three are env-derived, so a setenv+reimport fixture reconfigures them for free — ZERO setattr retargeting. - server.py RE-EXPORTS both (`from dlc_paths import _get_dlc_dir, _resolve_dlc_path`), so its 24+16 call sites AND the tests that reach `server._get_dlc_dir()` / `server._resolve_dlc_path()` directly (test_dlc_junction, test_highway_ws_*) resolve unchanged — no test edits. server.py: 9,085 -> 9,008. Verified: _resolve_dlc_path byte-identical to origin/main; _get_dlc_dir's only change is the three path identifiers -> appstate.*; pyflakes clean; route table identical (143); pytest 2407 passed (test_dlc_junction + both highway_ws suites green via re-export); packaging guard 52; eslint 0. Boot smoke: library scans (8 songs, _get_dlc_dir), a real song resolves + serves art (_resolve_dlc_path), and the highway WS reaches `ready` with notes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughDLC directory selection and path containment validation moved from ChangesDLC path resolution
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
lib/dlc_paths.py (1)
26-39: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider logging the swallowed config-parse error.
The blind
except Exception: pass(ruff S110/BLE001) silently discards a malformedconfig.json, so a user misconfiguration surfaces only as a mysterious "DLC folder not configured". A debug/warning log would make this diagnosable without changing the fallback behavior.♻️ Log instead of silently passing
if config_file.exists(): try: cfg = json.loads(config_file.read_text(encoding="utf-8")) - except Exception: - pass + except Exception: + logging.warning("Ignoring unreadable/invalid %s", config_file, exc_info=True)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/dlc_paths.py` around lines 26 - 39, Replace the silent `except Exception: pass` in the config-loading logic with a warning or debug log that includes the parsing exception and identifies `config.json`, while preserving the existing fallback behavior of continuing with `cfg` unset.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@lib/dlc_paths.py`:
- Around line 26-39: Replace the silent `except Exception: pass` in the
config-loading logic with a warning or debug log that includes the parsing
exception and identifies `config.json`, while preserving the existing fallback
behavior of continuing with `cfg` unset.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: e1593759-5ee7-43b9-a199-a61e9cfdb601
📒 Files selected for processing (5)
CHANGELOG.mddocs/size-exemptions.mdlib/appstate.pylib/dlc_paths.pyserver.py
…#846) Unblocked by the DLC-path substrate (#843): chart's only server-module deps are now app + meta_db (both seam); _get_dlc_dir/_resolve_dlc_path come from dlc_paths, sloppak/loose detection from the shared lib modules. 4 routes (split/unsplit/ work/fileinfo), meta_db-only otherwise. 0 setattr targets, 0 helpers to relocate. Bodies verbatim; @app -> @router, meta_db -> appstate.meta_db. include_router at the original site; 143-route table identical to origin/main. No test retargeting. server.py: 8,003 -> 7,909. Verified: pyflakes clean on the router; no new undefined/dead in server.py; route table identical; pytest 2401 passed (74 across work_charts/context_menu/ group_filter/packaging); eslint 0. Boot smoke: chart/work 200, chart/fileinfo resolves the real pack path through _resolve_dlc_path. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The keystone for the path-dependent routers (
ws_highway@ 902 lines,song,audio-local-path,sloppak): the "where do the song files live + safe containment" layer leavesserver.pyso a router can reach it.What moves
_resolve_dlc_path(pure — takesdlc+filename, no globals) → verbatim._get_dlc_dirreads the env-derived paths through the appstate seam (appstate.dlc_dir/dlc_dir_env/config_dir) instead of module globals, solib/dlc_paths.pydoes no import-time IO.dlc_dir/dlc_dir_envslots (config_diralready there);server.pyconfigures them. All three are env-derived, so asetenv+reimport fixture reconfigures them for free — zerosetattrretargeting.Zero test churn, via re-export
server.pyre-exports both (from dlc_paths import _get_dlc_dir, _resolve_dlc_path), so its 24+16 call sites and the tests that reachserver._get_dlc_dir()/server._resolve_dlc_path()directly (test_dlc_junction,test_highway_ws_notation,test_highway_ws_authors) resolve unchanged. No test edits.server.py: 9,085 → 9,008.Verification
_resolve_dlc_pathbyte-identical toorigin/main;_get_dlc_dir's only change is the three path identifiers →appstate.*.pyflakesclean; packaging guard 52 (picked updlc_paths);pytest2407 passed (the three direct-caller suites green through the re-export);npm run lint0._get_dlc_dir), a real song resolves and serves art (_resolve_dlc_path), and the highway WS reachesreadywith notes.Next:
ws_highway(902 lines) now needs onlySTATIC_DIR/SLOPPAK_CACHE_DIRin the seam (+ retargeting their ~5setattrsites) and its few remaining helpers, then it can move.🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Documentation