- ClawdDotNet.Web: Kestrel im Prozess der Anwendung, Token-Absicherung (TokenGate mit FixedTimeEquals), Endpunkte unter /api, Ereignisstrom unter /events (Server-Sent Events) und fortlaufendes Log-Streaming. - Weboberflaeche (wwwroot/): Vollstaendiges Single-Page-Frontend mit nativem HTML5, CSS3 und ES-Modulen ohne Buildschritt (strikt textContent, #-Routing, sofortiger Login-Sprung bei fehlendem Token, Light/Dark-Theme, lokale Barlow-Schriften). - ClawdDotNet.App: Fachlogik aus den Avalonia-ViewModels in Dienste herausgeloest (AgentAdministration, JobAdministration, ServiceAdministration, RunCoordinator) und ueber InstanceChange synchronisiert. - Tests: ClawdDotNet.Web.Tests und ClawdDotNet.App.Tests hinzugefuegt, alle 684 Tests erfolgreich.
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Den erzeugten Zustandsblock in docs/Roadmap.md schreiben und die Prosa
|
||||
abgleichen.
|
||||
|
||||
Das Gegenstueck `php cli/roadmap.php --write` laeuft auf der Maschine des
|
||||
Deploymentcenters und kennt unsere Datei nicht. Der Weg ueber die API ist in
|
||||
ROADMAP_MIGRATION.md, Schritt 5 und 6, beschrieben.
|
||||
|
||||
python roadmap_block.py --write Block holen und zwischen die Marker setzen
|
||||
python roadmap_block.py --check Prosa gegen die Items abgleichen
|
||||
|
||||
Rueckgabewert von --check: 0 in Ordnung (Warnungen erlaubt), 1 bei Fehlern.
|
||||
Damit laesst sich der Aufruf in einen Pre-Commit-Hook haengen.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
|
||||
BASIS = os.environ.get('DC_BASE_URL', 'https://dc.mhdf.de')
|
||||
SLUG = 'clawddotnet'
|
||||
DATEI = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(
|
||||
os.path.abspath(__file__)))), 'docs', 'Roadmap.md')
|
||||
|
||||
ANFANG = '<!-- dc:roadmap'
|
||||
ENDE = '<!-- /dc:roadmap -->'
|
||||
|
||||
|
||||
def ruf(token, methode, query, koerper=None):
|
||||
url = BASIS + '/api/bugtracker/v1/roadmap.php?' + urllib.parse.urlencode(query)
|
||||
daten = json.dumps(koerper).encode('utf-8') if koerper is not None else None
|
||||
anfrage = urllib.request.Request(url, data=daten, method=methode)
|
||||
anfrage.add_header('Authorization', 'Bearer ' + token)
|
||||
anfrage.add_header('Content-Type', 'application/json')
|
||||
with urllib.request.urlopen(anfrage, timeout=30) as antwort:
|
||||
return json.loads(antwort.read().decode('utf-8'))
|
||||
|
||||
|
||||
def grenzen(text):
|
||||
"""Die Marker finden. Fehlen sie, ist das ein Fehler und kein Anhaengen -
|
||||
ein Block am Dateiende waere beim naechsten Lauf ein zweiter."""
|
||||
a = text.find(ANFANG)
|
||||
e = text.find(ENDE)
|
||||
if a < 0 or e < 0 or e < a:
|
||||
raise SystemExit('Marker %s ... %s nicht gefunden in %s' % (ANFANG, ENDE, DATEI))
|
||||
return a, e + len(ENDE)
|
||||
|
||||
|
||||
def main():
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument('--write', action='store_true')
|
||||
p.add_argument('--check', action='store_true')
|
||||
a = p.parse_args()
|
||||
|
||||
token = os.environ.get('DC_TOKEN', '')
|
||||
if not token:
|
||||
raise SystemExit('DC_TOKEN fehlt')
|
||||
|
||||
with open(DATEI, encoding='utf-8') as f:
|
||||
inhalt = f.read()
|
||||
|
||||
if a.write:
|
||||
block = ruf(token, 'GET', {'action': 'render', 'project_slug': SLUG})['markdown']
|
||||
anfang, ende = grenzen(inhalt)
|
||||
neu = inhalt[:anfang] + block.rstrip() + inhalt[ende:]
|
||||
with open(DATEI, 'w', encoding='utf-8', newline='\n') as f:
|
||||
f.write(neu)
|
||||
print('Block geschrieben: %d Zeichen.' % len(block))
|
||||
return
|
||||
|
||||
if a.check:
|
||||
ergebnis = ruf(token, 'POST', {'action': 'check', 'project_slug': SLUG},
|
||||
{'content': inhalt})
|
||||
befunde = ergebnis.get('findings') or ergebnis.get('befunde') or []
|
||||
if not befunde:
|
||||
print('Abgleich ohne Befund.')
|
||||
return
|
||||
fehler = 0
|
||||
for b in befunde:
|
||||
grad = b.get('severity') or b.get('level') or '?'
|
||||
print('%-8s %-24s %s' % (grad, b.get('code', '?'), b.get('message', b)))
|
||||
if grad in ('error', 'fehler'):
|
||||
fehler += 1
|
||||
sys.exit(1 if fehler else 0)
|
||||
|
||||
raise SystemExit('--write oder --check angeben')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user