Ampel / ampel (push) Failing after 55s
Commander: "Unterbinde das CMD Fenster was sich beim oeffnen mitoeffnet."
Mein erster Anlauf wollte die Konsole VERSTECKEN und war falsch, aus zwei
Gruenden:
* Eine Onefile-EXE ist ZWEI Prozesse (gemessen: PID 33172 mit 8 MB, PID
33580 mit 103 MB, beide Rippy.exe). Die Pruefung "haengt genau EIN Prozess
an der Konsole" war damit nie wahr, das Fenster blieb einfach stehen.
* Selbst wenn sie ginge, waere das Fenster erst nach ein bis zwei Sekunden
weg. Ein Aufblitzen ist kein "unterbunden".
Jetzt wird die Konsole gar nicht erst erzeugt: --windowed statt --console.
Nachgemessen am fertigen Bau -- PE-Subsystem 2 (GUI) statt 3 (Konsole), und
beim Klick auf die Desktop-Verknuepfung ist genau EIN sichtbares Fenster da:
die WinForms-Oberflaeche. Kein ConsoleWindowClass-Fenster von Rippy, weder
sichtbar noch unsichtbar.
Was dazugehoert, damit daraus kein stiller Fehlschlag wird:
* Ohne Konsole ist sys.stdout None. uvicorn schreibt auf stderr und waere
mitten im Start gestorben, ohne dass irgendwo etwas stuende. einstieg.py
haengt sich deshalb an die Konsole des Aufrufers (--status in PowerShell
schreibt weiter dorthin) oder leitet nach %LOCALAPPDATA%\Rippy\rippy.log um.
* Der Installer meldet sein Ergebnis in einem Fenster, wenn keine Konsole da
ist -- sonst saehe ein gescheiterter Doppelklick aus wie einer, der nichts
tut. Bei --still und mit Konsole bleibt es bei der Textzeile.
Gegengeprueft am laufenden Programm: /api/health, / und /api/capabilities
antworten mit 200, und rippy.log faengt auf, was vorher ins Leere ging.
fix(drives): linux.py reicht die detection-Funktionen wieder durch
Die Ampel war seit Lauf 181 rot -- vier Commits lang, und ich hatte es
uebersehen. Ursache:
docker/api/main.py:54
AttributeError: module 'rippy.drives.linux' has no attribute 'drive_status'
main.py holt sich beim Import device_discovery.drive_status. Der
Windows-Treiber hat die Funktion; linux.py hatte sie nicht mehr, seit
detection (und damit fcntl) bewusst nicht mehr oben importiert wird -- sonst
waere main.py unter Windows nicht ladbar. Unter Windows lief also alles, auf
Linux waere der API-Container gar nicht hochgekommen.
Behoben mit PEP 562 (__getattr__), demselben Kniff wie in store/__init__.py:
Der Import bleibt ohne fcntl moeglich, wer die Funktionen BENUTZT bekommt sie.
Dazu drei weitere Fehler, die nur auf Linux auftraten:
* katalog.py baute Windows-Pfade mit os.path.join. Auf dem Linux-Runner wurde
daraus C:\Program Files (x86)\MakeMKV/makemkvcon64.exe. Jetzt entscheidet
der Pfad selbst ueber den Trenner, nicht die rechnende Maschine.
* verknuepfungen.py nahm os.path.dirname fuer den Arbeitsordner einer .lnk.
Eine .lnk zeigt IMMER auf einen Windows-Pfad -- also ntpath.
* waechter.py las 0.0 als Zeitpunkt statt als "noch nie geprueft". Auf einer
frisch gestarteten Maschine ist time.monotonic() klein, also fiel die erste
Laufwerks-Abfrage aus. None statt 0.0.
Alle vier haben jetzt Tests, die auf JEDER Plattform laufen -- der
Treiber-Test schiebt eine detection-Attrappe unter, der Waechter-Test stellt
eine Uhr bei 0,5 s nach, die Pfad-Tests pruefen beide Zweige. Beim
Wegnehmen der Durchreiche rot gesehen (5 Fehlschlaege), danach wieder gruen.
Damit faengt die Ampel so etwas kuenftig, ohne dass es eine Linux-Umgebung
auf dem Entwicklungsrechner braucht.
Ampel lokal: 582 gruen, ruff sauber.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
62 lines
2.1 KiB
Python
62 lines
2.1 KiB
Python
"""Einstiegspunkt der gebuendelten RippySetup.exe.
|
|
|
|
Bewusst winzig: PyInstaller braucht EINE Datei als Startpunkt, und alles
|
|
Weitere gehoert ins Paket `rippy`, wo es getestet werden kann. Was hier
|
|
steht, laesst sich nicht testen — also steht hier so wenig wie moeglich.
|
|
|
|
## Warum hier trotzdem etwas zur Ausgabe steht
|
|
|
|
Die EXE ist als Fenster-Programm gebaut (`--windowed`), damit beim Start
|
|
KEINE Konsole aufgeht — ausdruecklicher Wunsch des Commanders am 28.08.2026:
|
|
„Unterbinde das CMD Fenster was sich beim Oeffnen mitoeffnet."
|
|
|
|
Der Preis: `sys.stdout` ist dann `None`. Jede Bibliothek, die auf `stderr`
|
|
schreibt — uvicorn tut das —, wuerde mit
|
|
`AttributeError: 'NoneType' object has no attribute 'write'` sterben, und
|
|
zwar mitten im Start, ohne dass irgendwo etwas stuende.
|
|
|
|
Deshalb ganz zu Anfang, VOR allen anderen Importen aus `rippy`:
|
|
|
|
1. In einem Terminal gestartet? -> dort hineinschreiben
|
|
2. Sonst -> in %LOCALAPPDATA%\\Rippy\\rippy.log
|
|
"""
|
|
|
|
import multiprocessing
|
|
import sys
|
|
|
|
|
|
def _ausgabe_richten() -> None:
|
|
"""Dafuer sorgen, dass es eine Ausgabe GIBT — Konsole oder Datei."""
|
|
from rippy.platform import winlauf
|
|
|
|
if not winlauf.ohne_konsole():
|
|
return # aus dem Quellcode gestartet
|
|
if winlauf.an_elternkonsole_haengen():
|
|
# Ein Terminal ist da. Die Stroeme neu oeffnen, sonst bleibt
|
|
# sys.stdout trotz Konsole None.
|
|
try:
|
|
sys.stdout = open("CONOUT$", "w", encoding="utf-8", errors="replace",
|
|
buffering=1)
|
|
sys.stderr = sys.stdout
|
|
return
|
|
except OSError:
|
|
pass
|
|
winlauf.ausgabe_umleiten()
|
|
|
|
|
|
def main() -> int:
|
|
# Pflicht in gebuendelten Programmen: Ohne diesen Aufruf startet ein
|
|
# Kindprozess unter Windows die ganze EXE erneut — eine Startschleife,
|
|
# die sich als "das Programm oeffnet sich immer wieder" zeigt.
|
|
multiprocessing.freeze_support()
|
|
|
|
_ausgabe_richten()
|
|
|
|
from rippy.windows_app import main as rippy_main
|
|
|
|
return rippy_main()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|