Nachvollziehbares Code Review mit Doxygen und GitLab

Luca Lattanzio

06/21/2022

Intro

In dem einen oder anderen Blog-Artikel haben wir uns bereits mit Code-Reviews auseinandergesetzt, Wozu also noch ein Artikel zu dem Thema?
Nun: Hier geht es um einen Prozess, der sich bei uns bei der Durchführung von Code-Reviews bewährt hat. Andere Artikel zum Thema Code Review finden Sie hier (2015) und hier (2017).

Warum?

Im Laufe eines Projektes fiel auf, dass das Review eines Moduls bereits erfolgt war. Ein entsprechender Vermerk in einer extra zu diesem Zweck geführten Tabelle war versehentlich geändert worden – mit dem Effekt, dass das Modul nochmal gereviewed wurde (durch später hinzugekommene Projektmitarbeiter, die das natürlich nicht wissen konnten). So etwas passiert unweigerlich dann einmal, wenn der Status eines Items losgelöst vom Item selbst getrackt wird.
Obendrein ist das manuelle Auflisten der Module mit Findings oder noch zu reviewender Module fehlerträchtig und zeitraubend (und eine obendrein langweilige Tätigkeit). Das muss doch besser gehen, ohne dass man jetzt gleich auf möglicherweise teure Tools zurückgreifen muss!

Wohin?

Die Ziele des neuen Prozesses waren schnell definiert:

  • „Single-Source“ – d.h. keine separaten, vom Code losgelösten Dokumente
  • Einfaches Tracking des Review-Status von Source-Modulen
  • Nachverfolgbarkeit von Reviews
  • Möglichst wenige weitere Tools

Womit

Bei MEDtech führen wir Code Reviews mittels Doxygen-Kommentaren direkt im Source-Code durch. GitLab unterstützt dabei das Branching/Merging während des Reviews und die Rückverfolgbarkeit genauso wie die Entwicklung selbst. Will heißen: Git-Abläufe und Doxygen sind in den Projekten bereits etabliert.
Netterweise generiert Doxygen mit Hilfe des Tags „@xrefitem“ selbst definierbare Listen, z.B. im HTML-Format. Dadurch können wir aus dem Source-Code Listen der Module mit ihrem jeweiligen Review-Status (siehe unten) erzeugen. Diese lassen sich z.B. in das Meilenstein-Review-Dokument kopieren (wobei sich dieser Schritt auch noch automatisieren ließe 😉).

Vorbereitung

Um Tippfehler und Schreibarbeit bei den @xrefitem-Kommentaren zu vermeiden, werden in der Doxygen Konfigurationsdatei folgende Aliase definiert:

ALIASES += "review_done=\xrefitem reviews_done \"Code review done\" \"Code Review: Modules done\""
ALIASES += "review_missing=\xrefitem reviews_missing \"Code review missing\" \"Code Review: Modules with without reviews\""
ALIASES += "review_finding=\xrefitem review_findings \"Code review finding\" \"Code Review: Modules with findings\""

Die Tags @review_missing, @review_finding, @review_done werden wie andere Doxygen-Tags verwendet, sollten jedoch im File-Header-Kommentar gesetzt werden. Der Text hinter dem Tag erscheint dann im generierten Dokument (z.B. HTML) unterhalb des Dateinamens:

Mit dieser Konfiguration erstellt Doxygen Einträge in den Listen „Code review: Modules done“, „Code review: Modules missing“ und „Code review: Modules with findings“. Das sollte idealerweise auf Knopfdruck möglich sein (man denke an die Projektleitung) oder zumindest in der CI-Pipeline erfolgen.
Als Schmankerl bekommt das Management auf einfachste Weise noch ein KPI und das Development-Team ein Fleißbildchen 😉

Das Ziel ist also definiert – nun zum Weg dorthin.

Der Prozess

Im Folgenden wollen wir ein Code-Review für ein fiktives Software-Modul durchspielen (wie in der Grafik unten gezeigt). Das Review-Item (=Code) wird im Laufe des Prozesses verschiedene Status durchlaufen, die sich durch die Aktionen der beteiligten Personen „Developer“ und „Reviewer“ ändern. Die Status sind:

  • review missing
  • review findings
  • review done

Start

Eines Vorweg: wir haben eine Grafik erstellt, welche die nachfolgenden Schritte visualisiert. Die Grafik finden Sie am Ende des Blogbeitrags.
Der Code-Review Prozess beginnt mit der Neu-Erstellung bzw. Überarbeitung unseres Software-Moduls im Status „review missing“. Der Developer erstellt dazu ein Review-Ticket (im Folgenden als Issue bezeichnet) in GitLab und weist das dem Reviewer zu. Dabei wird auch ein eigener Git-Branch inkl. Merge Request erstellt (alternativ kann das Review auch direkt auf dem Feature-Entwicklungsbranch erfolgen). Für den Merge Request sollte der WiP („work in progress“) status benutzt werden, damit niemand den Merge Request versehentlich schließen kann. In GitLab erledigt man das alles mit einem Klick („Create branch and merge request“) innerhalb des jeweiligen Issues.

Review

Nun beginnt der Reviewer seine Arbeit, indem er zunächst im Code-Header folgendes Template einfügt (der Übersichtlichkeit halber hier ein reduziertes Template-Beispiel). Es enthält das Status-Alias zusammen mit dem Namenskürzel des letzten Committers, dem Commit-Datum und zum Schluss den Commit-Hash.
Anmerkung: Da Doxygen die Zeilenumbrüche innerhalb eines Kommentarblocks entfernt, sind zwecks besserer Lesbarkeit im Ausgabeformat die manuellen Zeilenumbrüche „@n“ erforderlich.

/**
* @file exempleUnit.c
* @brief example for code review demonstration
*
* @review_finding &ltREVIEWER&gt, &ltDATE&gt, &ltHASH&gt
* @n 1. Completeness of implementation
* @n 2. General code quality
* @n - 2.1 Nullpointer check:
* @n - 2.2 No infinite loops:
* @n - 2.3 No open Todos in code:

In der Kommentarstruktur werden die entsprechenden Findings dokumentiert, z.B.:

* @review_findings RVW, 03.05.2022, &ltHASH&gt
* @n 1. Completeness of implementation: ok
* @n 2. General code quality
* @n - 2.1 Nullpointer check:
* @n RVW finding: Missing Check in foo()
* @n - 2.2 No infinite loops: ok
* @n - 2.3 No open Todos in code: ok


Anmerkung: Die Änderungen am Review-Tag sind in Fettdruck hervorgehoben.
Im unwahrscheinlichen Fall, dass es beim Review keine findings gibt, ändert der Reviewer den Status zu „review done“ (fertig sind wir aber noch nicht). Normalerweise gibt es nach dem ersten Review – wie in diesem Fall – allerdings findings. Dadurch ändert der Reviewer den Status zu „review finding“. Nun committed er die Änderungen und weist das Issue dem Developer zu.

Bearbeitung

Der Developer bearbeitet die Findings. Er kann ein Finding …

  • … zurückweisen (reject): in diesem Falle sind sich Developer und Reviewer uneins. Es sollte diskutiert werden, ob hier ein fix vorgenommen werden muss oder nicht.
  • … reparieren (fix): der Developer stimmt dem Reviewer zu, dass hier nachgearbeitet werden soll und behebt das finding.
  • … akzeptieren (accept): der Developer stimmt zwar dem Reviewer zu, dass nachgearbeitet werden sollte, kann das finding aber nicht beheben (z.B. aus Zeitgründen).

Die Aktionen werden im Review-Tag festgehalten:

* @review_findings RVW, 03.05.2022, &ltHASH&gt
* @n 1. Completeness of implementation: ok
* @n 2. General code quality
* @review_findings RVW, 03.05.2022, &ltHASH&gt
* @n - 2.1 Nullpointer check:
* @n RVW finding: Missing Check in foo()
* @n DVP fix: used semaphore for function foo().

* @n - 2.2 No infinite loops: ok
* @n - 2.3 No open Todos in code: ok

Das Ganze wird daraufhin wieder eingecheckt. Jetzt weist der Developer das Issue erneut dem Reviewer zu.
Hinweis: Der Review-Status wird mit der Überarbeitung durch den Developer nicht geändert!

Re-Review

Die Fixes und Rejects werden in diesem Review-Schritt überprüft und entsprechend kommentiert. Ist der Reviewer mit den Änderungen und/oder den Begründungen der Rejects durch den Developer zufrieden, so bestätigt er dies durch ein einfaches „ok“ im Review-Tag. Diese Kommentar-Änderung wird wieder eingecheckt – denn für das Abschließen des Reviews im nächsten Schritt benötigen wir ja die dazugehörige Revision-Nummer (=Hash) für die erforderliche Nachverfolgbarkeit. Und letztlich soll im Release-Dokument auf die Version verwiesen werden, die den vollständigen Review-Kommentar enthält.

* @review_findings RVW, 03.05.2022, &ltHASH&gt
* @n 1. Completeness of implementation: ok
* @n 2. General code quality
* @n - 2.1 Nullpointer check:
* @n RVW finding: Missing Check in foo()
* @n DVP 2022-06-03: fixed: used semaphore for function foo().
* @n RVW 2022-06-04: confirmed

* @n - 2.2 No infinite loops: ok
* @n - 2.3 No open Todos in code: ok

Bestehen weiterhin Zweifel an der Implementierung bzw. der Entscheidung des Developers, so geht es in eine weitere Überarbeitungsrunde.

Abschluss

Nehmen wir mal an, dass sich Reviewer und Developer einig sind und das Review beendet werden kann. In unserem Beispiel ändern wir schließlich den Review-Status zu „@review_done“, tragen den Git-Hash vom vorausgegangenen Commit ein und räumen die jetzt überflüssig gewordenen Finding-Kommentare auf:

/**
* @file exempleUnit.c
* @brief example for code review demonstration
*
* @review_done RVW, 03.05.2022, 002e9d43bde307687aee6bd8bc3075838645290e
*/

Bleiben Findings bestehen, ändert sich der Status „@review_finding“ auch nach Beenden des Reviews nicht.
Nach dem Commit entfernt der Reviewer den WiP-Status des MRs (=Ändern des MR-Titels) und weist den Merge-Request dem Developer zu, welcher den Merge durchführt. Der erlösende Klick auf den Merge-Button innerhalb des Mergerequests in GitLab schließt nach erfolgreichem Merge des zugehörigen Branches auf den Master-Branch zudem automatisch das zugehörige Issue und den Merge-Request selbst. Das Code-Review unseres Moduls ist damit beendet.

Code Review Prozess (zum Vergrößern anklicken

Resümee

Wir haben in diesem Blogartikel gezeigt, dass nachvollziehbare Code-Reviews mit den anfangs gesteckten Zielen und den Tools GitLab und doxygen machbar und praktikabel sind. Natürlich interessiert uns, was Sie davon halten oder – noch besser – ob Sie selbst „schlichtere“ Prozesse etabliert haben, denn komplizierter geht bekanntlich immer und in der Kürze liegt die Würze

Falls Sie also Anmerkungen, Anregungen oder Fragen haben, zögern Sie nicht uns zu kontaktieren. Hierfür können Sie gerne die Kommentarfunktion benutzen oder uns direkt über E-Mail (info@medtech-ingenieur.de) oder Telefon (09131/691240) kontaktieren.


Geschrieben von Luca Lattanzio

Luca ist studierter Elektrotechnik-Ingenieur und sammelte während seines Studiums sowie in der Zeit danach wertvolle berufliche Erfahrungen bei MEDtech. Obwohl er inzwischen für ein anderes Unternehmen tätig ist, bleibt er bei MEDtech als Autor erhalten und verfasst gelegentlich Beiträge, um seine Expertise und Leidenschaft für seinen Beruf zu teilen. Darüber hinaus zählt er weiterhin zu den engagierten Lesern des Blogs.


Weitere Beiträge

  • 19/03/2025
  • Allgemein, Unternehmen, Veranstaltungen

Wir freuen uns, euch zu einem exklusiven VDI-Event des Netzwerk Systems Engineering einzuladen, das bei uns im Büro stattfindet!Am Freitag, den 28. März 2025, wird sich alles um die ...

Weiterlesen
  • 13/03/2025
  • Allgemein, Unternehmen

MEDtech Ingenieur verstärkt sein Führungsteam: Seit März 2025 übernimmt Daniel Saffer die Rolle des Chief Technical Officers (CTO). Mit seiner langjährigen Erfahrung in der Entwicklung sicherheitskritischer Embedded-Softwarelösungen für die ...

Weiterlesen
  • 29/01/2025
  • Allgemein, Hardware, Testen

EinleitungUm bei der EMV Prüfung für die Zulassung neuer medizintechnischer Geräte das Risiko zu reduzieren machen wir gerne Vortests mit den Geräten in der Prototypen Phase. Aktuell unterstützen wir ...

Weiterlesen
Cookie-Übersicht

Die Internetseiten der MEDtech Ingenieur GmbH verwenden Cookies. Cookies sind Textdateien, welche über einen Internetbrowser auf einem Computersystem abgelegt und gespeichert werden.

Zahlreiche Internetseiten und Server verwenden Cookies. Viele Cookies enthalten eine sogenannte Cookie-ID. Eine Cookie-ID ist eine eindeutige Kennung des Cookies. Sie besteht aus einer Zeichenfolge, durch welche Internetseiten und Server dem konkreten Internetbrowser zugeordnet werden können, in dem das Cookie gespeichert wurde. Dies ermöglicht es den besuchten Internetseiten und Servern, den individuellen Browser der betroffenen Person von anderen Internetbrowsern, die andere Cookies enthalten, zu unterscheiden. Ein bestimmter Internetbrowser kann über die eindeutige Cookie-ID wiedererkannt und identifiziert werden.

Durch den Einsatz von Cookies kann die MEDtech Ingenieur GmbH den Nutzern dieser Internetseite nutzerfreundlichere Services bereitstellen, die ohne die Cookie-Setzung nicht möglich wären.

Mittels eines Cookies können die Informationen und Angebote auf unserer Internetseite im Sinne des Benutzers optimiert werden. Cookies ermöglichen uns, wie bereits erwähnt, die Benutzer unserer Internetseite wiederzuerkennen. Zweck dieser Wiedererkennung ist es, den Nutzern die Verwendung unserer Internetseite zu erleichtern. Der Benutzer einer Internetseite, die Cookies verwendet, muss beispielsweise nicht bei jedem Besuch der Internetseite erneut seine Zugangsdaten eingeben, weil dies von der Internetseite und dem auf dem Computersystem des Benutzers abgelegten Cookie übernommen wird.

Die betroffene Person kann die Setzung von Cookies durch unsere Internetseite jederzeit mittels einer entsprechenden Einstellung des genutzten Internetbrowsers verhindern und damit der Setzung von Cookies dauerhaft widersprechen. Ferner können bereits gesetzte Cookies jederzeit über einen Internetbrowser oder andere Softwareprogramme gelöscht werden. Dies ist in allen gängigen Internetbrowsern möglich. Deaktiviert die betroffene Person die Setzung von Cookies in dem genutzten Internetbrowser, sind unter Umständen nicht alle Funktionen unserer Internetseite vollumfänglich nutzbar.

Weitere Informationen erhalten Sie in unserer Datenschutzerklärung.

Unbedingt notwendige Cookies

Dieses Cookie wird benötigt, um Ihre Cookie-Einstellungen zu merken und weitere Hauptfunktionen zur Verfügung zu stellen

Um Ihnen eine Auskunft über Ihre gespeicherten personenbezogenen Daten hier (https://medtech-ingenieur.de/gespeicherte-daten-2/) geben zu können, benötigen wir einen Cookie, um Sie bei der Datenabfrage identifizieren zu können. Dieser Cookie muss aus Sicherheitsgründen deshalb aktiviert sein. Ein weiterer Cookie wird gesetzt, um diesen Banner nicht erneut anzeigen zu müssen.

Cookie-Name Beschreibung
PHPSESSID Name: PHP session
Anbieter:
Eigentümer der Webseite (MEDtech Ingenieur)
Zweck:
Wir benötigt, um Sie bei der Anfrage von personenbezogenen Daten identifizieren zu können. Das Cookie wird nur gesetzt, wenn Sie eine Anfrage hier (https://medtech-ingenieur.de/gespeicherte-daten-2/) stellen.
Laufzeit: Sitzungsende
Kategorie: Unbedingt notwendige Cookies
moove_gdpr_popup Name: Cookie-Box Einstellungen
Anbieter:
Eigentümer der Webseite (MEDtech Ingenieur)
Zweck:
Wird benötigt, um Ihre Cookie-Einstellungen zu speichern, um den Cookie-Banner nicht erneut anzeigen zu müssen.
Laufzeit: 1 Jahr
Kategorie: Unbedingt notwendige Cookies
comment_author_9c90e388e3e1be4a6c594fa6ac8a3eec
comment_author_email_9c90e388e3e1be4a6c594fa6ac8a3eec
comment_author_url_9c90e388e3e1be4a6c594fa6ac8a3eec
Name: Kommentar Einstellungen
Anbieter:
Eigentümer der Webseite (MEDtech Ingenieur)
Zweck:
Cookie wird angelegt, wenn Sie ein Kommentar auf MEDtech Ingenieur veröffentlichen wollen, um Sie als Autor identifizieren und den aktuellen Status Ihres Kommentars anzeigen zu können. Das Cookie enthält den angegebenen Namen. Das Cookie wird erst gesetzt, wenn Sie der Speicherung Ihrer personenbezogenen Daten zustimmen.
Laufzeit: 1 Jahr
Kategorie: Unbedingt notwendige Cookies
rmp-rate Name: RMP Rate
Anbieter: Eigentümer der Webseite (MEDtech Ingenieur)
Zweck: Cookie wird angelegt, wenn Sie eine Bewertung eines Blogbeitrags mithilfe des Sternebewertungssystems abgeben. Ihnen wird eine anonymisierte ID zugewiesen, um zu erkennen, ob Sie einen Artikel bereits bewertet haben oder nicht. Das Cookie wird nur verwendet, um zu verhindern, dass mehrfache Bewertung abgegeben werden und erst gesetzt, wenn Sie auf einen Stern klicken.
Laufzeit: 1 Jahr
Kategorie: Unbedingt notwendige Cookies
medtech-download-page Name: Download Page
Anbieter: Eigentümer der Webseite (MEDtech Ingenieur)
Zweck: Cookie wird angelegt, wenn Sie den Landing-Page Prozess erfolgreich durchlaufen haben. Dies geschieht nur, wenn Sie einen Content-Download von unserer Website anstreben.
Laufzeit: 1/2 Jahr
Kategorie: Unbedingt notwendige Cookies