
Lieben Sie GitLab und haben eine Abneigung gegen Fehler? Möchten Sie die Qualität Ihres Quellcodes steigern? Dann sind Sie hier genau richtig. Heute zeigen wir Ihnen, wie Sie den C#-Analysator PVS-Studio einrichten, um Merge Requests zu überprüfen. Wir wünschen Ihnen eine kreative Lektüre und viel Spaß!
ist ein Werkzeug zur Aufdeckung von Fehlern und potenziellen Schwachstellen im Quellcode von Programmen, die in den Sprachen C, C++, C# und Java geschrieben sind. Es funktioniert auf 64-Bit-Systemen unter Windows, Linux und macOS. Kann Code analysieren, der für 32-Bit, 64-Bit und eingebettete ARM-Plattformen vorgesehen ist.
Übrigens, wir haben PVS-Studio 7.08 veröffentlicht, in dem wir viele aufregende Neuerungen entwickelt haben. verwendet. Zum Beispiel:
- C#-Analysator für Linux und macOS;
- Plugin für Rider;
- neuer Modus zur Überprüfung einer Dateiliste.
Modus zur Überprüfung einer Dateiliste
Früher mussten Sie zur Überprüfung bestimmter Dateien dem Analysator eine .xml-Datei mit der Liste der Dateien übergeben. Da dies jedoch nicht sehr praktisch war, haben wir die Möglichkeit hinzugefügt, eine .txt-Datei zu übergeben, was das Leben erheblich erleichtert.
Um bestimmte Dateien zu überprüfen, muss das Flag —sourceFiles (-f) angegeben werden, gefolgt von der .txt-Datei mit der Liste der Dateien. Das sieht folgendermaßen aus:
pvs-studio-dotnet -t path/to/solution.sln -f fileList.txt -o project.jsonWenn Sie an der Einrichtung von Commit- oder Pull-Request-Überprüfungen interessiert sind, können Sie dies auch in diesem Modus tun. Der Unterschied liegt darin, dass eine Liste der zu analysierenden Dateien bereitgestellt wird und davon abhängt, welche Systeme Sie verwenden.
Prinzip der Überprüfung von Merge-Requests
Das Hauptziel der Überprüfung besteht darin, sicherzustellen, dass Probleme, die vom Analyzer entdeckt wurden, beim Zusammenführen nicht in den master Branch gelangen. Außerdem möchten wir das gesamte Projekt nicht jedes Mal analysieren. Besonders, da wir beim Zusammenführen von Branches eine Liste der geänderten Dateien haben. Daher schlage ich vor, die Überprüfung von Merge-Requests hinzuzufügen.
So sieht ein Merge-Request vor der Implementierung des statischen Analyzers aus:

Das heißt, alle Fehler, die im Branch changes, vorhanden waren, gelangen in den Master-Branch. Da wir das nicht möchten, fügen wir die Analyse hinzu, und nun sieht das Schema wie folgt aus:

Wir analysieren changes2 und, wenn keine Fehler vorhanden sind, akzeptieren wir den Merge-Request, andernfalls lehnen wir ihn ab.
Übrigens, wenn Sie an der Analyse von Commits und Pull-Requests für C/C++ interessiert sind, können Sie darüber lesen. .
GitLab
— ein webbasiertes Open-Source-Tool für den DevOps-Lebenszyklus, das ein Code-Repository-Management-System für Git mit eigener Wiki, Fehlerverfolgung, CI/CD-Pipeline und weiteren Funktionen bietet.
Bevor Sie mit der Analyse von Merge-Requests beginnen, müssen Sie sich registrieren und Ihr Projekt hochladen. Wenn Sie nicht wissen, wie das funktioniert, empfehle ich meinen Kollegen.
Hinweis. Die im Folgenden beschriebene Methode zur Einrichtung der Umgebung ist eine von vielen möglichen. Ziel ist es, die Schritte zur Einrichtung der für die Analyse benötigten Umgebung und den Start des Analysewerkzeugs zu demonstrieren. Möglicherweise ist es in Ihrem Fall effizienter, die Phasen der Umgebungsbereitstellung (Hinzufügen von Repositories, Installation des Analysewerkzeugs) und der Analyse zu trennen: zum Beispiel durch das Erstellen von Docker-Images mit der erforderlichen Umgebung und deren Verwendung oder auf andere Weise.
Um besser zu verstehen, was jetzt passieren wird, schlage ich vor, einen Blick auf das folgende Diagramm zu werfen:

Für die Arbeit benötigt der Analysator das .NET Core SDK 3. Daher müssen vor der Installation des Analysators die Microsoft-Repositories hinzugefügt werden, aus denen die erforderlichen Abhängigkeiten für den Analysator installiert werden. Die Hinzufügung der Microsoft-Repositories für verschiedene Linux-Distributionen .
Für die Installation von PVS-Studio über den Paketmanager müssen ebenfalls die PVS-Studio-Repositories hinzugefügt werden. Die Hinzufügung der Repositories für verschiedene Distributionen wird detaillierter behandelt in .
Für die Arbeit benötigt der Analysator einen Lizenzschlüssel. Eine Testlizenz kann auf der .
Hinweiserhalten werden. Bitte beachten Sie, dass für den beschriebenen Arbeitsmodus (Analyse von Merge-Requests) eine Enterprise-Lizenz erforderlich ist. Wenn Sie diesen Arbeitsmodus ausprobieren möchten, vergessen Sie nicht, im Feld "Nachricht" anzugeben, dass Sie eine Enterprise-Lizenz benötigen.
Wenn ein Merge-Request erfolgt, müssen wir nur die Liste der geänderten Dateien analysieren; andernfalls analysieren wir alle Dateien. Nach der Analyse müssen die Protokolle in das gewünschte Format konvertiert werden.
Jetzt, da wir den Arbeitsalgorithmus vor uns haben, können wir mit dem Schreiben des Skripts beginnen. Dazu müssen wir die Datei ändern .gitlab-ci.yml oder, falls sie nicht vorhanden ist, erstellen. Zum Erstellen klicken Sie auf den Namen Ihres Projekts -> CI/CD einrichten.

Jetzt sind wir bereit, das Skript zu schreiben. Lassen Sie uns zunächst den Code schreiben, der den Analyzer installiert und die Lizenz eingibt:
before_script:
- apt-get update && apt-get -y install wget gnupg
- apt-get -y install git
- wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
- dpkg -i packages-microsoft-prod.deb
- apt-get update
- apt-get install apt-transport-https
- apt-get update
- wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
- wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
- apt-get update
- apt-get -y install pvs-studio-dotnet
- pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
- dotnet restore "$CI_PROJECT_DIR"/Test/Test.slnDa die Installation und Aktivierung vor allen anderen Skripten erfolgen muss, verwenden wir ein spezielles Label before_script. Ich werde diesen Abschnitt kurz erläutern.
Vorbereitung zur Installation des Analyzers:
- wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
- dpkg -i packages-microsoft-prod.deb
- apt-get update
- apt-get install apt-transport-https
- apt-get updateHinzufügen der PVS-Studio- und Analyzer-Repositories:
- wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
- wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
- apt-get update
- apt-get -y install pvs-studio-dotnetLizenzaktivierung:
- pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY$PVS_NAME — Benutzername.
$PVS_KEY — Produktkey.
Wiederherstellung der Projektabhängigkeiten, wo $CI_PROJECT_DIR – vollständiger Pfad zum Projektverzeichnis:
- dotnet restore "$CI_PROJECT_DIR"/Path/To/Solution.slnFür eine korrekte Analyse muss das Projekt erfolgreich gebaut werden, und seine Abhängigkeiten müssen wiederhergestellt werden (zum Beispiel müssen die erforderlichen NuGet-Pakete heruntergeladen werden).
Um Umgebungsvariablen mit Lizenzinformationen festzulegen, klicken Sie auf Einstellungen, und danach auf CI / CD.

Im geöffneten Fenster suchen wir den Punkt Variablen, rechts klicken wir auf die Schaltfläche Erweitern und fügen die Variablen hinzu. Das Ergebnis sollte wie folgt aussehen:

Jetzt können wir zur Analyse übergehen. Fügen wir zunächst das Skript für die vollständige Analyse hinzu. Im Flag -t übergeben wir den Pfad zur Solution, im Flag -o Wir definieren den Pfad zur Datei, in die die Analyseergebnisse geschrieben werden. Außerdem interessiert uns der Rückgabecode. In diesem Fall ist es wichtig, dass die Ausführung gestoppt wird, wenn der Rückgabecode Informationen über Warnungen während der Analyse enthält. So sieht dieser Abschnitt aus:
job:
script:
- exit_code=0
- pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -o
PVS-Studio.json || exit_code=$?
- exit_code=$((($exit_code & 8)/8))
- if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fiDie Rückgabecodes arbeiten nach dem Prinzip der Bitmaske. Beispielsweise, wenn während der Analyse Warnungen ausgegeben wurden, entspricht der Rückgabecode 8. Wenn die Lizenz innerhalb eines Monats abläuft, beträgt der Rückgabecode 4. Wenn jedoch während der Analyse Fehler gefunden wurden und die Lizenz ebenfalls in einem Monat abläuft, werden beide Werte im Rückgabecode vermerkt: Wir addieren die Zahlen zusammen und erhalten den endgültigen Rückgabecode – 8+4=12. Damit können wir durch Überprüfung der entsprechenden Bits Informationen zu verschiedenen Zuständen während der Analyse erhalten. Rückgabecodes werden ausführlicher im Abschnitt "Rückgabecodes pvs-studio-dotnet (Linux / macOS)" des Dokuments beschrieben.".
In diesem Fall interessieren uns alle Rückgabecodes, in denen die 8 vorkommt.
- exit_code=$((($exit_code & 8)/8))Wir erhalten 1, wenn der Rückgabecode das für uns relevante Bit enthält, ansonsten erhalten wir 0.
Es ist an der Zeit, die Analyse der Merge-Requests hinzuzufügen. Bevor wir das tun, bereiten wir den Platz für das Skript vor. Es muss nur dann ausgeführt werden, wenn ein Merge-Request erfolgt. Das sieht so aus:
merge:
script:
only:
- merge_requestsLass uns zum eigentlichen Skript übergehen. Ich habe festgestellt, dass die virtuelle Maschine nichts über origin/masterweiß. Deshalb helfen wir ihr ein wenig:
- git fetch originNun erhalten wir die Unterschiede zwischen den Branches und speichern das Ergebnis in txt Datei hinzufügen:
- git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txtDabei ist $CI_COMMIT_SHA - der Hash des letzten Commits.
Als Nächstes führen wir die Analyse der Dateiliste durch, indem wir das Flag -fverwenden. Wir übergeben die zuvor erhaltene .txt-Datei. Und analog zur vollständigen Analyse überprüfen wir die Rückgabecodes:
- exit_code=0
- pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
- exit_code=$((($exit_code & 8)/8))
- if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fiDas vollständige Skript zur Überprüfung des Merge-Requests sieht dann so aus:
merge:
script:
- git fetch origin
- git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
- exit_code=0
- pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
- exit_code=$((($exit_code & 8)/8))
- if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
only:
- merge_requestsEs bleibt nur noch die Umwandlung des Logs hinzuzufügen, nachdem alle Skripte ausgeführt wurden. Wir verwenden das Tag after_script und das Dienstprogramm plog-converter:
after_script:
- plog-converter -t html -o eLog ./PVS-Studio.jsonDienstprogramm — ein Open-Source-Projekt, das zur Umwandlung von Fehlerberichten des Analysators in verschiedene Formate wie z.B. HTML verwendet wird. Eine detailliertere Beschreibung des Dienstprogramms finden Sie im Abschnitt "Plog Converter Utility" .
Übrigens, wenn Sie bequem mit dem .json-Bericht lokal aus der IDE arbeiten möchten, empfehle ich unser für die IDE Rider. Eine genauere Beschreibung seiner Verwendung finden Sie im .
Zur Bequemlichkeit hier .gitlab-ci.yml vollständig:
image: debian
before_script:
- apt-get update && apt-get -y install wget gnupg
- apt-get -y install git
- wget https://packages.microsoft.com/config/debian/10/
packages-microsoft-prod.deb -O packages-microsoft-prod.deb
- dpkg -i packages-microsoft-prod.deb
- apt-get update
- apt-get install apt-transport-https
- apt-get update
- wget -q -O - https://files.viva64.com/etc/pubkey.txt | apt-key add -
- wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
- apt-get update
- apt-get -y install pvs-studio-dotnet
- pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY
- dotnet restore "$CI_PROJECT_DIR"/Test/Test.sln
merge:
script:
- git fetch origin
- git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txt
- exit_code=0
- pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -f
pvs-fl.txt -o PVS-Studio.json || exit_code=$?
- exit_code=$((($exit_code & 8)/8))
- if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
only:
- merge_requests
job:
script:
- exit_code=0
- pvs-studio-dotnet -t "$CI_PROJECT_DIR"/Test/Test.sln -o
PVS-Studio.json || exit_code=$?
- exit_code=$((($exit_code & 8)/8))
- if [[ $exit_code == 1 ]]; then exit 1; else exit 0; fi
after_script:
- plog-converter -t html -o eLog ./PVS-Studio.jsonSobald alles in der Datei hinzugefügt ist, klicken wir auf Änderungen bestätigen. Um zu überprüfen, ob alles richtig ist, gehen wir zu CI/CD -> Pipelines -> Running. Ein Fenster der virtuellen Maschine öffnet sich, am Ende davon sollte folgendes sein:

Wir haben gesehen Job erfolgreich – Erfolg, alles ist gut. Jetzt können wir das Erstellen auch testen.
Beispiele für die Arbeit
Um ein Beispiel zu erstellen, erstellen wir ein einfaches Projekt (in master) in dem mehrere Dateien enthalten sein werden. Danach werden wir in einem anderen Branch nur eine Datei ändern und versuchen, einen Merge-Request durchzuführen.
Betrachten wir zwei Fälle: Wenn die geänderte Datei einen Fehler enthält und wenn nicht. Zuerst ein Beispiel mit einem Fehler.
Angenommen, im Master-Branch gibt es die Datei Program.cs, die keine Fehler enthält, aber in einem anderen Branch hat der Entwickler fehlerhaften Code hinzugefügt und möchte einen Merge-Request erstellen. Welche genau der Fehler ist, ist nicht so wichtig, entscheidend ist, dass er vorhanden ist. Zum Beispiel hat er den Operator throw vergessen (ja, ):
void MyAwesomeMethod(String name)
{
if (name == null)
new ArgumentNullException(....);
// etwas tun
....
}Betrachten wir das Ergebnis der Analyse des Beispiels mit dem Fehler. Um sicherzustellen, dass nur eine Datei analysiert wurde, habe ich das Flag -r in der Startzeile von pvs-studio-dotnet hinzugefügt:

Wir sehen, dass der Analyse-Tool einen Fehler gefunden hat und das Mergen der Branches nicht erlaubt hat.
Überprüfen wir das Beispiel ohne Fehler. Den Code korrigieren:
void MyAwesomeMethod(String name)
{
if (name == null)
throw new ArgumentNullException(....);
// etwas tun
....
}Ergebnisse der Analyse des Merge-Requests:

Wie wir sehen, wurden keine Fehler gefunden, und die Aufgabe wurde erfolgreich ausgeführt, was wir überprüfen wollten.
Fazit
Schlechten Code vor dem Mergen von Branches zu filtern, ist äußerst praktisch und angenehm. Wenn Sie also CI/CD nutzen, sollten Sie versuchen, einen statischen Analyzer zur Überprüfung einzubauen. Das ist zudem recht einfach.
Vielen Dank für Ihre Aufmerksamkeit.
Wenn Sie diesen Artikel mit einem englischsprachigen Publikum teilen möchten, nutzen Sie bitte den Link zur Übersetzung: Nikolay Mironov. .
Quelle: habr.com
