In der Softwareentwicklung ist die Software Dokumentation ein essenzieller Baustein, um Wissen zu konservieren und Transparenz zu schaffen. Im Gegensatz zu Source Code kann eine Dokumentation Hinweise liefern, warum bestimmte Architekturentscheide getroffen wurden, anders als beim Quellcode selbst, der nur das Wie beantwortet.
”Code tells you how, comments tell you why
Jeff AtwoodGründer von Stack Overflow
Des Weiteren kann in einer Dokumentation der Fokus und Abstraktionsgrad sowie die Perspektive bewusst gewählt werden, was bei Source Code nicht möglich ist.
Die Software Dokumentation als Utopie
Die Software Dokumentation ist jedoch das Stiefkind der meisten Entwickler*innen. Vielfach ist aus Sicht der Entwickler*innen ein rudimentäres Readme ausreichend (GitHub best practices). Das Readme scheint der ideale Kompromiss zwischen keiner Software Dokumentation und dem Benutzerhandbuch zu sein. Es erfüllt folgende Zwecke:
- Kurzbeschreibung mit Technologieübersicht
- (Lokaler) Set-up
- Wartbarkeit durch geringen Umfang
Ein Vorwurf, den sich jede Software Dokumentation gefallen lassen muss, ist, dass sie tatsächlich schnell veraltet und oft schlecht getestet ist. Ein Grund dafür ist folgender: Die Dokumentation ist zumeist eine statische Projektion eines Software-Systems, und Software ist volatil. Das heisst, da sich Software ständig verändert, entsteht eine Lücke zwischen dem Ist-Zustand der Dokumentation und dem Soll, jenem Zustand, in dem sich das Software-System im Augenblick befindet. Je nach Auflösung und Detailgrad der Dokumentation kann diese Lücke zu gross sein, welches die Dokumentation ohne ständiges Updaten schnell unbrauchbar machen kann.
Zusätzlich schafft sie keinen direkten Mehrwert für Entwickler*innen, die bereits alles Relevante verinnerlicht haben. Die dokumentarische Nacharbeit mag vielen Entwickler*innen im Eifer des Gefechts als sinnlose Fleissarbeit erscheinen, deren Nutzen sich erst dann zeigt, wenn nach monatelanger Pause ein altes Projekt wieder entstaubt wird und neu angestossen werden soll. Alle «Trivialitäten», die nicht würdig waren, zu automatisieren oder zu dokumentieren, müssen nun wieder mühsam aufgearbeitet werden. Oft hört man dann die nachträgliche Rationalisierung, dass der Nutzen, nicht zu dokumentieren, die Kosten überwiegt.
Doch diese Wahrnehmung ist möglicherweise falsch und sofern die richtige Detail-Auflösung gewählt wird, kann auch eine umfangreichere Software Dokumentation ohne ständiges Nachbessern immer noch brauchbar sein.
Problemstellung der Software Dokumentation
In einem Kundenprojekt hatten wir eine ähnliche Problemstellung, nämlich die nachträgliche Software Dokumentation dieser Trivialitäten, ein historisch gewachsenes System unterschiedlicher Softwarekomponenten nachträglich zu dokumentieren. Nachträglich bedeutet hier, dass die meisten am Systemaufbau ursächlich beteiligten Entwickler*innen nicht mehr verfügbar waren. Wir betraten eine über Jahrzehnte gewachsene Systemlandschaft und die Entwicklerkultur förderte Spezialisierung auf wenige Projekte und nicht Universalisten. Dies führte zu den erwähnten Readmes.
Als Quellen also nur Git Repositories, Log Archive verwenden und den geschulten Blick jahrzehntelanger Erfahrung als Softwarentwickler*in bemühen. Diese Einschränkung wirkt erst einmal dramatisch, doch aus den genannten Quellen lässt sich erstaunlich viel ableiten und in geeigneter Form darstellen, wie später noch demonstriert wird.
Ziel unserer Anstrengungen waren im Wesentlichen zwei Aspekte: Dokumentieren der Systemlandschaft und Softwarekomponenten, genannt Services. Der Kunde erwartet durch die Software Dokumentation ein einfacheres Onboarding neuer Mitarbeiter und eine bessere Übersicht über die Zusammenhänge der Systeme, Komplexität und Kritikalität.
Hier ein kurzer Ausflug in die wesentlichen Eigenheiten der beiden Perspektiven.
Systemlandschaft in der Software Dokumentation
Die Software Dokumentation der Systemlandschaft bietet einen umfassenden Überblick über die technologische Infrastruktur eines Projekts oder einer Organisation. Sie bietet einen nützlichen Rahmen für Architekt*innen und Manager*innen, um ein gemeinsames Verständnis der systemischen Abhängigkeiten und Zusammenhänge zu entwickeln. Die Abstraktion hier ist relativ hoch und der technische Detaillierungsgrad niedrig.
Interaktionsdiagramme: Diagramme, die die Interaktionen zwischen den verschiedenen Systemkomponenten darstellen, einschliesslich externer Schnittstellen und Dienste.
Architekturdiagramme: Grafische Darstellungen der Systemarchitektur, die die Komponenten, ihre Abhängigkeiten und ihre Bereitstellung in der Infrastruktur veranschaulichen.
Abhängigkeiten und Integrationen: Beschreibungen der Abhängigkeiten zwischen verschiedenen Systemkomponenten sowie Integrationen mit externen Diensten oder Systemen.
Bereitstellungsarchitektur: Informationen über die Bereitstellungsumgebung, einschliesslich Cloud-Plattformen, Serverkonfigurationen und Netzwerktopologien.
Softwarekomponenten (Services)
Die Dokumentation der Softwarekomponenten konzentriert sich auf die Beschreibung einer spezifischen Komponente oder Module innerhalb eines Softwareprojekts. Diese Dokumentation bietet detaillierte Einblicke in die Funktionalität, Technologiewahl, Struktur und Schnittstellen einer einzelnen Einheit des Systems. Typischer Inhalt ist das oben erwähnte Readme. Die Zielgruppe für dieses Artefakt sind technisch versierte Personen, in der Regel Softwareentwickler*innen.
Die Dokumentation der Softwarekomponente bietet Entwickler*innen ein umfassendes Verständnis der internen Arbeitsweise einer bestimmten Einheit des Systems, was die Entwicklung, Wartung und Fehlerbehebung erleichtert.
Theorie der Software Dokumentation
Erfreulicherweise hat sich trotz der grossen Anzahl von über 50 Projekten eine homogene Struktur der Git-Repositories und der verwendeten Technologien etabliert. Ziel war es, möglichst viel Dokumentation automatisch zu generieren. Es wurde jedoch schnell klar, dass Daten manuell nachgeliefert werden mussten, um die Semantik, die Service-Gruppierungen und die Beschreibungen auf den gewünschten Standard zu bringen. Im Folgenden wird skizziert, welche Informationen aus welchen Quellen automatisch extrahiert werden konnten.
Technologie Stack
Maven, Gradle, npm: Der Technologie-Stack eines Projekts gibt Einblick in die Werkzeuge und Frameworks, die für die Entwicklung und den Build-Prozess verwendet werden.
Modul Abhängigkeiten
Maven, Gradle: Diese Build-Management-Tools ermöglichen die Definition und Verwaltung von Modulabhängigkeiten, die die Struktur und Komposition des Projekts beeinflussen.
Library Abhängigkeiten
Maven, Gradle, npm: Informationen über externe und interne Bibliotheken und ihre Abhängigkeiten sind entscheidend, um die Funktionalität und Integration des Codes zu verstehen.
Runtime/Service Abhängigkeiten
Die Analyse von Access Logs, Spring Boot Application Properties und Kubernetes YAMLs liefert Einblicke in die Laufzeitabhängigkeiten der Komponente.
Releases
Tags aus Git, Maven, Nexus: Die Identifizierung von Releases und Versionen ermöglicht es, wichtige Meilensteine und den Verlauf des Projekts zu dokumentieren.
Deployments
Kubernetes und Deploy-Scripts: Die Bereitstellung von Anwendungen auf Produktionsumgebungen erfordert die Verwendung von Tools wie Kubernetes und spezifischen Bereitstellungsskripten.
Runtimes
Dockerfile und Pipeline Specification: Durch Docker-Files und Pipeline-Spezifikationen wird der Build- und Bereitstellungsprozess eines Projekts definiert und dokumentiert.
Contributors
Git Commits: Die Analyse von Git-Commits ermöglicht es, die Beteiligung der Entwickler*innen am Projekt im Zeitverlauf zu verfolgen und ihre Beiträge zu würdigen.
Project Status
Git Activity, Jira: Die Aktivitäten in Git und in Jira-Tickets geben Einblicke in den aktuellen Stand und den Fortschritt des Projekts.
Umsetzung der Software Dokumentation
Der gesamte Quellcode war auf GitLab verfügbar. Unter Verwendung der GitLab API können alle Projekte ausgelesen und lokal geklont werden. GitLab liefert auch einige Metadaten, die für die Servicedokumentation relevant waren. Mit Grafana Queries konnten die effektiven Serviceabhängigkeiten live aufgelöst werden, da ausgehende und eingehende Requests in Prometheus geloggt wurden.
Analyse der Software Dokumentation
Mithilfe von speziellen Scannern wurde der Source Code analysiert und die Daten in einer Postgres Datenbank abgelegt. Diese Scanner sind in TypeScript geschriebene Programme, um die oben genannten Informationen zu analysieren. Diese Scanner laufen in einer GitLab Pipeline, als Cron Job, und generieren eine weitestgehend aktuelle Dokumentation. Die Dokumentation wird in GitLab CI/CD Pipelines veröffentlicht.
Nach Abschluss der Analysephase konnten die serviceabhängigen und logischen Gruppierungen (siehe Abbildung 1) visualisiert und Markdown Dateien (siehe Abbildung 2) generiert werden. Dazu mussten alle Datenfragmente logisch miteinander verknüpft werden. Die Visualisierungen wurden mit PlantUML in Markdown erstellt.
Zusammenfassung
Eine gute Dokumentation kann das Leben von Entwickler*innen und Manager*innen erheblich vereinfachen und für mehr Planungssicherheit sorgen. Mangelndes Systemverständnis kann bremsend und wie Sand im Getriebe wirken. Eine generierte Software Dokumentation, wie hier gezeigt, kann dem entgegenwirken. Durch die Aggregation bzw. Automatisierung konnten wesentliche Kritikpunkte wie Kosten/Nutzen und Aktualität deutlich entschärft werden.