This commit is contained in:
team3
2026-07-27 16:43:11 +02:00
parent 23c908534f
commit 7912eae715
14 changed files with 596 additions and 27 deletions

View File

@@ -18,6 +18,8 @@ from collections import Counter
import agents
import config
import features
import inhalt as inhaltspruefung
import quellcode
import struktur
# projektname -> {"laeuft": bool, "fertig": int, "gesamt": int, "fehler": int,
@@ -70,8 +72,9 @@ NACHBESSERN = """Dein Vorschlag verstößt weiter gegen messbare Vorgaben:
Schreibe die betroffenen Felder erneut. Gleiches Format wie zuvor."""
# Nur hier ist der Text eine Liste — mehrzeilige Vorschläge ergeben nur dort Sinn
ZEILENFELDER = ("regeln", "testen")
# Eine Quelle für „was ist eine Liste" — sonst zerlegt der eine Teil, was der
# andere als Block behandelt, und aus einer Ergänzung wird ein Komplettersatz.
ZEILENFELDER = struktur.ZEILENFELDER
# Felder, die leer bleiben dürfen; ein leerer Vorschlag streicht die Stelle
LEERBAR = ZEILENFELDER + ("ziel",)
# Alles, was es überhaupt gibt; je Bereich gilt eine engere Auswahl
@@ -178,7 +181,7 @@ def status(projekt: str) -> dict:
lauf = _laeufe.get(projekt)
if not lauf:
return {
"laeuft": False, "fertig": 0, "gesamt": 0, "fehler": 0,
"laeuft": False, "art": "", "fertig": 0, "gesamt": 0, "fehler": 0,
"probleme": [], "meldung": "",
}
return lauf
@@ -450,7 +453,33 @@ async def _pruefe(stil: dict, aufgabe: dict) -> list[dict]:
return probleme
async def _lauf(projekt: str, liste: list[dict], stil: dict):
async def _stil_aufgaben(projekt: str):
"""Prüfstellen der Stilprüfung samt der Kataloge, die sie brauchen."""
stil = {b: _stil_lesen(b) for b in BEREICHE}
liste = [a for f in features.liste(projekt) for a in aufgaben(f)]
return liste, lambda a: _pruefe(stil, a)
async def _inhalt_aufgaben(projekt: str):
"""Ein Abgleich über alle Karten — Vollständigkeit ist eine Eigenschaft der
Menge, nicht der einzelnen Karte."""
alle = features.liste(projekt)
quelle = quellcode.dateien()
if not quelle:
raise ValueError("Kein Quelltext gefunden")
text = quellcode.als_text(quelle)
async def abgleich(_):
probleme, _inv = await inhaltspruefung.pruefe(alle, quelle, text)
return probleme
return [{"feature": "", "funktion": ""}], abgleich
ARTEN = {"stil": _stil_aufgaben, "inhalt": _inhalt_aufgaben}
async def _lauf(projekt: str, liste: list[dict], arbeite):
lauf = _laeufe[projekt]
schranke = asyncio.Semaphore(config.PRUEFUNG_PARALLEL)
@@ -459,7 +488,7 @@ async def _lauf(projekt: str, liste: list[dict], stil: dict):
if _laeufe.get(projekt) is not lauf:
return # verworfen (Panel geschlossen) — keine weitere Anfrage
try:
lauf["probleme"].extend(await _pruefe(stil, aufgabe))
lauf["probleme"].extend(await arbeite(aufgabe))
except Exception as e:
# Zählt trotzdem als erledigt, sonst hängt der Fortschritt.
# Die Meldung nennt die Zahl, damit „100 %" nicht vollständig vortäuscht.
@@ -475,22 +504,25 @@ async def _lauf(projekt: str, liste: list[dict], stil: dict):
lauf["laeuft"] = False
async def starte(projekt: str) -> dict:
async def starte(projekt: str, art: str = "stil") -> dict:
"""Startet einen Lauf im Hintergrund; ein laufender wird nicht verdoppelt."""
if art not in ARTEN:
raise ValueError(f"Unbekannte Prüfart „{art}“")
if status(projekt)["laeuft"]:
raise ValueError("Prüfung läuft bereits")
agents.pruefe_konfiguration() # früher Stopp statt halbem Lauf
stil = {b: _stil_lesen(b) for b in BEREICHE} # ebenso: Fehler im Task wäre unsichtbar
liste = [a for f in features.liste(projekt) for a in aufgaben(f)]
# Vorbereiten vor dem Task: ein Fehler darin wäre sonst unsichtbar
liste, arbeite = await ARTEN[art](projekt)
_laeufe[projekt] = {
"laeuft": True,
"art": art,
"fertig": 0,
"gesamt": len(liste),
"fehler": 0,
"probleme": [],
"meldung": "",
}
aufgabe = asyncio.create_task(_lauf(projekt, liste, stil))
aufgabe = asyncio.create_task(_lauf(projekt, liste, arbeite))
_aufgaben.add(aufgabe)
aufgabe.add_done_callback(_aufgaben.discard)
return _laeufe[projekt]