Lesezeit : 12 minutes

Deine Codebasis wächst. Die Abhängigkeiten zwischen Modulen vermehren sich. Die Architektur-Dokumentation wird veraltet, bevor sie überhaupt geschrieben ist. Und was wäre, wenn dein Gradle-Build automatisch aktuelle Diagramme aus der tatsächlichen Code-Struktur generieren könnte? Genau das macht das Graphify + PlantUML Gradle Plugin-Pipeline:`graphify . --no-viz`extrahiert den Knowledge Graph,`./gradlew generateKnowledgeGraphDiagram`Er verwandelt es in PlantUML-Diagramme. Kein LLM, kein Handbuch, 100% deterministisch.

Tic

[]

Das Problem: Diagramme hinken immer dem Code hinterher

Jedes Projekt, das mehrere tausend Zeilen überschreitet, kennt dieses Syndrom:

  1. Man zeichnet ein Architekturdiagramm am Anfang des Projekts

  2. Der Code entwickelt sich, die Abhängigkeiten ändern sich

  3. Das Diagramm wird zu einer dekorativen Lüge.

  4. Niemand aktualisiert es, weil es mühsam ist.

  5. Die Neuanwärter basieren darauf und machen Fehler.

probleme diagrammes obsoletes

Die Frage ist nicht müssen wir Diagramme haben? — jeder weiß, dass ja. Die Frage ist:Wer hält sie auf dem neuesten Stand?

Die Antwort: niemand. Ausser wenn es automatisch ist.

Die Lösung: ein deterministischer Pipeline Knowledge Graph → PlantUML

Das Prinzip ist einfach: Statt die Diagramme von Hand zu zeichnen, zeichnet man siegeneriert aus der tatsächlichen Code-Struktur.

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 8) ]

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

actor Développeur
component "Graphify\n(pip install graphifyy)" as Graphify
collections "graphify-out/graph.json\n(Knowledge Graph)" as KGJSON
component "PlantUML Gradle Plugin
^^^^^
 Syntax Error? (Assumed diagram type: component)

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

actor Développeur
component "Graphify\n(pip install graphifyy)" as Graphify
collections "graphify-out/graph.json\n(Knowledge Graph)" as KGJSON
component "PlantUML Gradle Plugin
(generateKnowledgeGraphDiagram)" as Plugin
component "WissensgraphenParser" as Parser
component "KnowledgeGraphRenderer" as Renderer
component "PlantumlService
(Validierung + PNG-Rendering)" as PS
collections "diagrams/knowledge-graph/\n(.puml + .png)" as Output

Développeur --> Graphify : graphify . --no-viz
Graphify --> KGJSON : extrait la structure\ndu code source
Développeur --> Plugin : ./gradlew generateKnowledgeGraphDiagram
Plugin --> Parser : parse(graph.json)
Parser --> Plugin : KnowledgeGraph\n(noeuds + arêtes + communautés)
Plugin --> Renderer : render(graph, filters)
Renderer --> Plugin : code PlantUML\ndéterministe
Plugin --> PS : validateSyntax + generateImage
PS --> Output : .puml + .png

note bottom of Plugin
  Pipeline DÉTERMINISTE
  Aucun appel LLM
  Résultat reproductible
end note

@enduml

Zwei Befehle. Das ist alles.

# Étape 1 : extraire le Knowledge Graph
graphify . --no-viz

# Étape 2 : générer les diagrammes PlantUML
./gradlew generateKnowledgeGraphDiagram

Das Ergebnis? Dateien`.puml` et .png`in`diagrams/knowledge-graph/, versioniert in Git, immer auf dem neuesten Stand des Codes.

Schritt 1: Graphify installieren und den Knowledge Graph extrahieren

Installation

Graphify ist ein Python-Tool, das Ihre Codebase analysiert und einen strukturierten Wissensgraphen erstellt:

# Méthode recommandée
uv tool install graphifyy && graphify install --platform opencode

# Alternative avec pip
pip install graphifyy && graphify install --platform opencode

Ausnahmen konfigurieren

Eine Datei erstellen`.graphifyignore`im Wurzelverzeichnis des Projekts, um Dateien auszuschließen, die nicht zur Geschäftslogik gehören:

# Secrets — JAMAIS dans le graphe
*-context.yml
*.env

# Fichiers générés
build/
.gradle/

# Tests fonctionnels
src/functionalTest/

Den Knowledge Graph extrahieren

graphify . --no-viz

der Flag`--no-viz`überspringt die HTML-Generierung (unnötig in einem Gradle-Pipeline). Das Ergebnis ist eine Datei`graphify-out/graph.json`enthaltend :

  • Knoten: Klassen, Funktionen, Dateien — mit ihrem Typ und Gemeinschaft

  • GrateBeziehungen zwischen Knoten (EXTRACTED aus dem Code, INFERRED vom LLM)

  • Gemeinschaften: automatische Gruppierungen verbundener Knoten

Beispiel einer Struktur`graph.json`
{
  "nodes": [
    {"id": "0", "label": "LlmService", "file_type": "code", "community": 0},
    {"id": "1", "label": "ApiKeyPool", "file_type": "code", "community": 0},
    {"id": "2", "label": "PlantumlService", "file_type": "code", "community": 1}
  ],
  "links": [
    {"source": "1", "target": "0", "relation": "uses", "confidence": "EXTRACTED", "weight": 0.9},
    {"source": "0", "target": "2", "relation": "calls", "confidence": "INFERRED", "weight": 0.7}
  ]
}

Der Quellcode (.kt, .java) wird lokal von tree-sitter analysiert,unwiderrufliches LLM. Nur die Dokumentationsdateien (.adoc, .md) erfordern einen LLM-Aufruf für die semantische Extraktion. Also`--update`Auf Kotlin-Code ist es quasi sofort.

Schritt 2: Das Gradle-Plugin transformiert den Knowledge Graph in PlantUML

Architektur des Pipelines

Das Plugin`com.cheroliv.plantuml`integriert eine Aufgabe`generateKnowledgeGraphDiagram`der transformiert`graph.json`in PlantUML-Diagrammen auf welche Weisevollständig deterministisch:

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 10) ]

@startuml
skinparam backgroundColor #FEFEFE

participant "Gradle" as G
participant "GenerateKnowledgeGraphDiagramTask" as Task
participant "KnowledgeGraphParser" as Parser
participant "KnowledgeGraphRenderer" as Renderer
participant "PlantumlService" as PS

collections "import sys
^^^^^
 Syntax Error? (Assumed diagram type: sequence)

@startuml
skinparam backgroundColor #FEFEFE

participant "Gradle" as G
participant "GenerateKnowledgeGraphDiagramTask" as Task
participant "KnowledgeGraphParser" as Parser
participant "KnowledgeGraphRenderer" as Renderer
participant "PlantumlService" as PS

collections "import sys
sys.stdout.write(sys.stdin.read())" as JSON

G -> Task : execute
Task -> JSON : read
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph\n(noeuds + arêtes + communautés)
Task -> Renderer : render(graph, filters)
Renderer --> Task : code PlantUML\n(déterministe)
Task -> PS : validateSyntax(plantumlCode)
alt syntaxe valide
    Task -> PS : generateImage → .png
else syntaxe invalide
    Task -> Task : save .puml avec warning
end

@enduml

Die internen Komponenten

Komponente Rolle

KnowledgeGraphParser

parsen`graph.json`— unterstützt 3 Formate: nativer Graphify (nodes+links), legacy (communities), flach. Löst die numerischen IDs in Beschriftungen auf.

KnowledgeGraphRenderer

Transformiert deterministisch ein`KnowledgeGraph`im PlantUML-Code. Gruppen nach Typ, Gemeinschaften in Paketen, automatische Legende.

GenerateKnowledgeGraphDiagramTask

Gradle-Task, die orchestriert: parse → render → validate → PNG. Konfigurierbar über Gradle-Eigenschaften.

kgmodels.kt

Datenmodelle :`KnowledgeGraph`, KnowledgeGraphNode, KnowledgeGraphEdge, KnowledgeGraphCommunity, EdgeType.

PlantumlService

Syntaxprüfung + PNG-Rendering (wiederverwendet von allen Aufgaben des Plugins).

Renderregeln

Der Renderer wendet deterministische visuelle Konventionen an:

Kantentyp PlantUML-Notation Bedeutung

EXTRACTED

-→(durchgezogener Strich, schwarz)

Aus dem Quellcode extrahierte Beziehung (Sicherheit)

geschlossen

..>(punktiert)

Vom LLM abgeleitete Beziehung (Vertrauensscore)

mehrdeutig

--x(rote gepunktete Linie)

Ambigue Beziehung (zu überprüfen)

Die Communities werden als PlantUML-Pakete mit einer automatischen Farbpalette dargestellt.

Schritt 3: Tägliche Nutzung

Vollständiges Diagramm

# Générer le diagramme du Knowledge Graph complet
./gradlew generateKnowledgeGraphDiagram

Ausgabe:`diagrams/knowledge-graph/knowledge-graph-full.puml`+.png

Nach Gemeinschaft filtern

# Une seule communauté
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.community=community_0

# Limiter le nombre de noeuds (lisibilité)
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.community=community_0 \
  -Pplantuml.kg.maxNodes=15

Nach Kantenart filtern

# Uniquement les relations certaines (EXTRACTED)
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.edgeTypes=EXTRACTED

# Relations certaines + inférées
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.edgeTypes=EXTRACTED,INFERRED

Nach Knotentyp und Vertrauen filtern

# Uniquement les classes de code
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.nodeTypes=code

# Seuil de confiance minimum (pour les INFERRED)
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.minConfidence=0.7

Benutzerdefiniertes Ausgabeverzeichnis

./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.outputDir=docs/architecture

Vollständige Referenz der Eigenschaften

Eigenschaft Standard Beschreibung

plantuml.kg.community

(alle)

Gemeinden nach Name filtern (Teilzeichenkette)

plantuml.kg.edgeTypes

(alle)

Kantentypen durch Kommata getrennt:`EXTRACTED`, INFERRED, AMBIGUOUS

plantuml.kg.minConfidence

0.0

Mindestvertrauensschwelle für die Kanten

plantuml.kg.maxNodes

(unbegrenzt)

Maximale Anzahl der anzuzeigenden Knoten

plantuml.kg.nodeTypes

(alle)

Knotentypen durch Kommata getrennt (z.B.class, code)

plantuml.kg.outputDir

diagrams/knowledge-graph

Ausgabeverzeichnis für die Dateien`.puml` et .png

Der vollständige Pipeline in einem Gradle-Workflow

Workflow-Typ

workflow complet

Integration in den Entwicklungszyklus

Die Pipeline integriert sich natürlich in die Schlüsselphasen der Entwicklung:

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 6) ]

@startuml
skinparam backgroundColor #FEFEFE

state "Entwicklung" as dev
state "Extraction\ngraphify . --no-viz" as extract
state "Generierung
^^^^^
 Syntax Error? (Assumed diagram type: state)

@startuml
skinparam backgroundColor #FEFEFE

state "Entwicklung" as dev
state "Extraction\ngraphify . --no-viz" as extract
state "Generierung
./gradlew generateKnowledgeGraphDiagram" as generate
state "Commit
versionierte Diagramme" as commit

[*] --> dev
dev --> extract : Code modifié
extract --> generate : graph.json à jour
generate --> commit : .puml + .png générés
commit --> dev : Diagrammes dans le repo

note right of extract
  Quasi instantané sur du code Kotlin
  (tree-sitter, pas de LLM)
end note

note right of generate
  Déterministe
  Pas de LLM
  Résultat reproductible
end note

@enduml

inkrementelles Update

Wenn der Code sich ändert, bauen wir nicht das gesamte Diagramm von Grund auf neu:

# Mise à jour incrémentale (fichiers modifiés uniquement)
graphify . --update

# Puis régénérer les diagrammes
./gradlew generateKnowledgeGraphDiagram

--update`extrahiert erneut nur die geänderten Dateien (durch SHA256 erkannt in`graphify-out/cache/). Bei Kotlin-Code ist es nahezu sofort, da tree-sitter lokal arbeitet, ohne einen LLM-Aufruf zu tätigen.

Dogfooding: Das Plugin dokumentiert sich selbst

Der PlantUML-Plugin existiert, um Prompts in Diagramme zu verwandeln. Er kann auch den Knowledge Graph seiner eigenen codebase in Dokumentationsdiagramme verwandeln. Das ist dogfooding: Der Plugin verbraucht seinen eigenen Dienst.

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 16) ]

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "Normale Pipeline\n(Benutzer → Diagramme)" as normal {
    [Fichier .prompt] as prompt
    [LlmService\n+ ApiKeyPool] as llm1
    [ProcessPlantumlPromptsTask] as task1
    [Diagramme PNG] as out1

    prompt --> task1
    task1 --> llm1
    llm1 --> out1
}

package "Pipeline Knowledge Graph
^^^^^
 Syntax Error? (Assumed diagram type: component)

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "Normale Pipeline\n(Benutzer → Diagramme)" as normal {
    [Fichier .prompt] as prompt
    [LlmService\n+ ApiKeyPool] as llm1
    [ProcessPlantumlPromptsTask] as task1
    [Diagramme PNG] as out1

    prompt --> task1
    task1 --> llm1
    llm1 --> out1
}

package "Pipeline Knowledge Graph
(deterministischer Ansatz, kein LLM)" as kg {
    [graphify-out/graph.json] as kgjson
    [KnowledgeGraphParser] as parser
    [KnowledgeGraphRenderer] as renderer
    [PlantumlService] as ps
    [Diagramme PNG\n(documentation du plugin)] as out2

    kgjson --> parser
    parser --> renderer
    renderer --> ps
    ps --> out2
}

package "Pipeline Dogfooding\n(LLM → Dokumentation des Plugins)" as dogfood {
    [GraphifyPromptAdapter] as gpa
    [Fichiers .prompt\nauto-générés] as auto_prompt
    [LlmService\n+ ApiKeyPool] as llm2
    [ProcessPlantumlPromptsTask] as task2
    [Diagramme PNG\n(documentation LLM)] as out3

    kgjson --> gpa
    gpa --> auto_prompt
    auto_prompt --> task2
    task2 --> llm2
    llm2 --> out3
}

note "Gleiches LlmService, gleiches ApiKeyPool,
gleiches PlantumlService
— NULL Duplizierung" as N

@enduml

Verknüpfte Gradle-Aufgaben :

Aufgabe LLM ? Beschreibung

generateKnowledgeGraphDiagram

Nein

Transforme`graph.json`in PlantUML (deterministisch)

generateDiagramDocs

Ja

Erzeuge einige`.prompt`von dem Graphen, behandelt sie sie via LLM (dogfooding)

# Documentation déterministe (rapide, pas de LLM)
./gradlew generateKnowledgeGraphDiagram

# Documentation LLM (plus riche, consomme des tokens)
./gradlew generateDiagramDocs

Warum es deterministisch ist (und warum das wichtig ist)

Der Schlüsselpunkt des Pipelines`generateKnowledgeGraphDiagram`(Because the source text is empty, the translation is also empty.)Er ruft kein LLM auf.. Die Transformation`graph.json`→ PlantUML ist eine reine Funktion.

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 6) ]

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

rectangle "Pipeline DETERMINISTISCH
(generateKnowledgeGraphDiagram)" as det {
^^^^^
 Syntax Error? (Assumed diagram type: activity)

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

rectangle "Pipeline DETERMINISTISCH
(generateKnowledgeGraphDiagram)" as det {
    [graph.json] as json
    [KnowledgeGraphParser] as parser
    [KnowledgeGraphRenderer] as renderer
    [PlantUML code] as puml

    json --> parser : parse
    parser --> renderer : KnowledgeGraph
    renderer --> puml : render (fonction pure)
}

rectangle "Pipeline LLM
(processPlantumlPrompts)" as llm {
    [.prompt] as prompt
    [LlmService] as llmSvc
    [ChatModel] as model
    [PlantUML code] as puml2

    prompt --> llmSvc
    llmSvc --> model : API call
    model --> puml2 : réponse non-déterministe
}

note bottom of det
  Même entrée → même sortie
  Pas de latence réseau
  Pas de coût en tokens
  Reproductible en CI
end note

note bottom of llm
  Même entrée → sortie variable
  Latence réseau (1-5s)
  Coût en tokens
  Nécessite une clave API
end note

@enduml

Die konkreten Vorteile:

Vorteil Impact

Reproduzierbarkeit

gleich`graph.json`→ gleiche Abbildung. Genau. Jedes Mal.

Null Kosten

Kein LLM-Aufruf = keine Tokens = keine API-Rechnung.

Null Latenz

Parse + render dauert ~100ms, nicht 1-5 Sekunden.

CI-kompatibel

Es ist kein API-Schlüssel erforderlich. Kein flaky Test aufgrund einer variablen LLM-Antwort.

Versionierbar

Le .puml`generiert ist Text. Man kann es`diff, der Reviewer im PR, in Git versionieren.

Diagramme des Pipelines selbst

Um den Kreis zu schließen, hier ist das Diagramm des Pipelines, wie es vom Plugin generiert würde :

pipeline sequence

Integration in die Projektgovernanz

In unserem Projekt integriert sich diese Pipeline in eine EAGER/LAZY-Kontextverwaltungsstrategie für den KI-Agenten. Der Knowledge Graph ersetzt die manuelle Architektur-Dokumentation durch einen strukturierten, abfragbaren und selbst aktualisierenden Graphen.

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 11) ]

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "EAGER\n(immer geladen)" as eager {
    [PROMPT_REPRISE.adoc\n(contexte session)] as pr
    [INDEX.adoc\n(vue d'ensemble)] as idx
    [GRAPH_REPORT.adoc\n(~50 lignes)] as gr
}

package "LAZY — Strategie
^^^^^
 Syntax Error? (Assumed diagram type: component)

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "EAGER\n(immer geladen)" as eager {
    [PROMPT_REPRISE.adoc\n(contexte session)] as pr
    [INDEX.adoc\n(vue d'ensemble)] as idx
    [GRAPH_REPORT.adoc\n(~50 lignes)] as gr
}

package "LAZY — Strategie
(auf Anfrage)" as lazy_strat {
    [Méthodologies] as meth
    [Archives sessions] as sessions
}

package "LAZY — Graphify\n(zielgerichtete Anfragen)" as lazy_graph {
    [graph.json] as gj
    [Queries\n(query/path/explain)] as queries
}

package "Pipeline PlantUML
(automatisch generiert)" as puml {
    [generateKnowledgeGraphDiagram] as kgTask
    [generateDiagramDocs] as ddTask
    [Diagrammes PNG] as diagrams
}

Agent --> eager : Lit en début de session
Agent ..> lazy_strat : Charge si type détecté
Agent ..> lazy_graph : Query si besoin structurel
kgTask --> diagrams : Déterministe
ddTask --> diagrams : Via LLM

note right of gr
  Condensé du Knowledge Graph
  God nodes + communautés
  Remplace ECOSYSTEM_OVERVIEW
  (225 lignes → 50 lignes)
end note

@enduml

Die Kombination beider Systeme ist komplementär :

  • Die Strategie regelt das WANN und das WIE— Governance, Workflow, Archivierung

  • Graphify verwaltet das WAS und das WO— Struktur des Codes, Beziehungen, gezielte Abfragen

_ Die Sitzungsstrategie verwaltet daswann et le wie(Governance, Workflow, Schwellen), Graphify verwaltet dasWAS et le WO(Struktur des Codes, Beziehungen, gezielte Anfragen). Die Pipeline PlantUML verwaltet dasMit was(deterministische Diagramme, versioniert, stets aktuell). _

Vorbereitung : Checkliste in 5 Minuten

# Schritt Bestellung

1

Graphify installieren

uv tool install graphifyy

2

Ausnahmen konfigurieren

Erstellen`.graphifyignore`

3

Knowledge Graph extrahieren

graphify . --no-viz

4

Die Diagramme generieren

./gradlew generateKnowledgeGraphDiagram

5

Committe die Ergebnisse

git add diagrams/knowledge-graph/

# Script complet en 5 commandes
uv tool install graphifyy
cat > .graphifyignore << 'EOF'
*-context.yml
*.env
build/
.gradle/
EOF
graphify . --no-viz
./gradlew generateKnowledgeGraphDiagram
git add graphify-out/GRAPH_REPORT.adoc graphify-out/graph.json diagrams/knowledge-graph/

Fallstricke und Gegenmaßnahmen

Falle Beschreibung Minderung

zu dichter Graph

Ein großes Projekt erzeugt Hunderte unlesbare Knoten

verwenden`-Pplantuml.kg.maxNodes=30`und nach Community filtern

Zu weite Ausschlüsse

Zu viele Dateien in`.graphifyignore`verringert den Wert des Graphen

Beginnen Sie damit, nur credentials und build zu ausschließen

Richtung der Pfeile

Die INFERRED-Kanten können eine mehrdeutige Richtung haben

Filtern nach`-Pplantuml.kg.edgeTypes=EXTRACTED`nur für bestimmte Beziehungen

veralteter Graph

Der Code ändert sich, aber der Graph wird nicht rekonstruiert

Verwenden`graphify . --update`regelmäßig oder der Git-Hook`graphify hook install`

Aktualisierte Kosten

Inkrementelle Updates sind quasi kostenlos (tree-sitter lokal)

Nur die docs (.adoc) verbrauchen LLM‑Tokens

Was man am Ende erhält

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 10) ]

@startuml
skinparam backgroundColor #FEFEFE

rectangle "VORHER" as avant {
    card "Handgezeichnete Diagramme\nImmer veraltet\nNiemand aktualisiert sie" as av1 #FDEDEC
}

rectangle "nach" as apres {
    card "Automatisch generierte Diagramme
Immer auf dem neuesten Stand mit dem Code
^^^^^
 Syntax Error? (Assumed diagram type: activity)

@startuml
skinparam backgroundColor #FEFEFE

rectangle "VORHER" as avant {
    card "Handgezeichnete Diagramme\nImmer veraltet\nNiemand aktualisiert sie" as av1 #FDEDEC
}

rectangle "nach" as apres {
    card "Automatisch generierte Diagramme
Immer auf dem neuesten Stand mit dem Code
In Git versioniert
Deterministisch und reproduzierbar" as ap1 #E8F8E8
}

avant --> apres : graphify . --no-viz\n+ ./gradlew generateKnowledgeGraphDiagram

@enduml

Die konkreten Vorteile

Vorteil Detail

Immer aktuelle Dokumentation

Die Diagramme spiegeln den aktuellen Code, keinen manuellen Snapshot

Kein Wartungsaufwand

Die Diagramme regenerieren sich bei jedem Build

Reduzierung der technischen Schulden

Es ist nicht mehr nötig, die Diagramme manuell zu pflegen.

Visueller Kontext für die neuen

Ein neuer Entwickler versteht die Architektur, indem er die Diagramme betrachtet.

Feintuning-Potential

Die Paare (Untergraph → Diagramm) sind Beispiele für KI-Training

Automatische Validierung

`PlantumlService.validateSyntax()`Überprüft jedes generierte Diagramm

schnelles Onboarding

5 Diagramme = vollständige Ansicht der Architektur

_ Wer ein Warum hat, kann alle Wie ertragen. _

Das warum : Diagramme stets auf dem neuesten Stand. Das wie : zwei Befehle in einer Gradle-Pipeline.

Verwandte Artikel