feedBack/.dockerignore
Byron Gamatos b3215694e7
fix(build): move appstate.py + routers/ under lib/ so the desktop app ships them (#836)
The packaged desktop app died at startup:

    File ".../Resources/slopsmith/server.py", line 71, in <module>
        import appstate
    ModuleNotFoundError: No module named 'appstate'

feedback-desktop's scripts/bundle-slopsmith.sh copies a HARDCODED list of core
files into the bundle -- server.py, VERSION, lib/, data/, static/,
plugins/__init__.py. The root-level appstate.py (#833) and routers/ (#834)
shipped fine in Docker, passed every test, and were silently dropped from the
packaged app.

Both now live under lib/, the one core directory every packaging path already
copies wholesale -- Dockerfile `COPY lib/`, docker-compose.yml, and the desktop
bundler's `cp -r lib` -- and that all three put on sys.path (on Windows via the
embeddable-Python ._pth, where PYTHONPATH is ignored: build-windows.sh writes
`../slopsmith` and `../slopsmith/lib`). No feedback-desktop change and no new
release are needed for this to take effect.

lib/ is also the CORRECT home under Principle V, and always was once the design
settled: with the injection seam, appstate.py constructs nothing and does no
import-time IO, and a route module only builds an APIRouter. The premise that
forced root placement -- "appstate opens sqlite at import" -- stopped being true
when configure() replaced ownership. The Dockerfile / .dockerignore /
docker-compose.yml entries added for the root layout are reverted; nothing else
in core changes (git mv, so --follow survives).

tests/test_packaging.py is the guard: it walks server.py's module-level imports,
keeps the ones resolving inside this repo, and fails if any lives outside a
directory the packagers copy -- with the ModuleNotFoundError spelled out. So the
next root-level core module can't ship broken. Negative-checked: restoring
appstate.py to the root fails it; the message names the file and the four
packaging files a root module would have to teach.
(It also has to skip `origin in {"built-in","frozen"}` -- on 3.14 the frozen
stdlib reports origin="frozen", and Path("frozen").resolve() lands inside the
repo, which flagged `os` and `stat` as first-party.)

Verified: the bundler's copy replicated exactly into a temp dir and booted with
PYTHONPATH=<bundle>:<bundle>/lib -- `import server`, `import appstate`,
`import routers.audio_effects` all resolve, appstate.meta_db is server.meta_db,
143 routes. The same simulation against origin/main reproduces the production
ModuleNotFoundError. pytest 2398 passed (2348 + 50 new); route table still
identical to origin/main (paths, methods, order); docker build context reaches
lib/appstate.py and lib/routers/ with no __pycache__; native uvicorn boot smoke
serves /api/version, /api/library, the moved audio-effects router, and all three
migrated plugins' src/ graphs; eslint 0 errors.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 17:16:34 +02:00

80 lines
1.9 KiB
Plaintext

*
!.dockerignore
!Dockerfile
!dockerfile
!requirements.txt
!server.py
!main.py
!VERSION
!tailwind.config.js
!lib/
!lib/**
# Mirror the static/* policy from .gitignore: ship the static tree, but not
# the cached audio/art artifacts a developer's runtime would generate
# (static/*.ogg, *.mp3, *.wav, art/, audio_*/). Those bloat the image and
# make builds non-reproducible across machines.
!static/
!static/**
static/*.ogg
static/*.mp3
static/*.wav
static/art/
static/audio_*/
static/sloppak_cache/
# note-detection tuning flow auto-writes WAVs and JSONL captures here.
# Not in .gitignore yet — see docs/note-detect-tuning.md — but still a
# generated-at-runtime directory that shouldn't bake into the image.
static/note_detect_recordings/
# All in-tree core plugins ship in the image. Each plugin directory must be
# explicitly re-allowed after the blanket `plugins/*/` exclusion below.
!plugins/
plugins/*/
!plugins/__init__.py
!plugins/app_tour_library/
!plugins/app_tour_library/**
!plugins/app_tour_settings/
!plugins/app_tour_settings/**
!plugins/capability_inspector/
!plugins/capability_inspector/**
!plugins/highway_3d/
!plugins/highway_3d/**
!plugins/minigames/
!plugins/minigames/**
!plugins/tuner/
!plugins/tuner/**
!data/
!data/**
# Ship only the built-in diagnostic sloppak artifacts (seeded into
# DLC_DIR/diagnostics-builtin/ at scan time). The builder script + README
# under docs/diagnostics/ are dev-only and stay out of the image.
!docs/
docs/*/
!docs/diagnostics/
docs/diagnostics/*
!docs/diagnostics/*.sloppak
# Exclude common developer artifacts even inside the whitelisted trees so a
# venv / cache / build output never gets baked into the image.
**/__pycache__/
**/*.pyc
**/.pytest_cache/
**/.mypy_cache/
**/.ruff_cache/
**/node_modules/
**/.venv/
**/venv/
**/.env
# (the Dockerfile builder stage rebuilds from source). A contributor
# into the build context.
**/bin/
**/obj/
**/.env.*
**/.DS_Store