
Lieben Sie GitLab und haben keine Lust auf Fehler? Möchten Sie die Qualität Ihres Quellcodes erhöhen? Dann sind Sie hier genau richtig. Heute zeigen wir Ihnen, wie Sie den C#-Analyzer PVS-Studio für die Überprüfung von Merge-Requests einrichten können. Allen einen einhornigen Stimmung und viel Spaß beim Lesen.
— ist ein Werkzeug zur Identifizierung von Fehlern und potenziellen Schwachstellen im Quellcode von Programmen, die in C, C++, C# und Java geschrieben sind. Es läuft auf 64-Bit-Systemen unter Windows, Linux und macOS. Es 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 interessante Dinge gemacht haben. . Zum Beispiel:
- C#-Analyzer unter Linux und macOS;
- Plugin für Rider;
- neuer Modus zur Überprüfung von Dateilisten.
Modus zur Überprüfung von Dateilisten
Früher musste man zur Überprüfung bestimmter Dateien dem Analyzer eine .xml mit einer Liste von Dateien übergeben. Da dies jedoch nicht sehr bequem ist, haben wir die Möglichkeit hinzugefügt, eine .txt zu übergeben, was das Leben erheblich erleichtert.
Um bestimmte Dateien zu überprüfen, muss das Flag angeben werden —sourceFiles (-f) und eine .txt mit der Liste der Dateien übergeben. Das sieht folgendermaßen aus:
pvs-studio-dotnet -t path/to/solution.sln -f fileList.txt -o project.jsonWenn Sie an der Überprüfung von Commits oder Pull Requests interessiert sind, können Sie dies ebenfalls mit diesem Modus tun. Der Unterschied liegt darin, wie die Liste der Dateien für die Analyse abgerufen wird und hängt davon ab, welche Systeme Sie verwenden.
Prinzip der Überprüfung von Merge-Requests
Das Grundprinzip der Überprüfung besteht darin, dass Probleme, die vom Analyzer entdeckt werden, beim Zusammenführen nicht in die master Hauptzweig gelangen. Auch möchten wir nicht jedes Mal das gesamte Projekt analysieren. Zumal wir beim Zusammenführen von Zweigen eine Liste der geänderten Dateien haben. Deshalb 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 Zweig changes, werden in den Master-Zweig übernommen. Da wir das nicht möchten, fügen wir die Analyse hinzu, und jetzt sieht das Schema folgendermaßen aus:

Wir analysieren changes2 und wenn keine Fehler vorhanden sind, akzeptieren wir den Merge-Request, andernfalls lehnen wir ihn ab.
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 DevOps-Lebenszyklus-Tool mit Open-Source-Code, das ein Code-Repository-Management-System für Git mit eigenem Wiki, Fehlerverfolgungssystem, CI/CD-Pipeline und weiteren Funktionen bereitstellt.
Bevor Sie mit der Implementierung der Analyse von Merge Requests beginnen, müssen Sie sich registrieren und Ihr Projekt hochladen. Wenn Sie nicht wissen, wie das geht, empfehle ich meinen Kollegen.
Hinweis. Die nachfolgend beschriebene Methode zur Einrichtung der Umgebung ist eine von mehreren möglichen Methoden. Ziel ist es, die Schritte zur Einrichtung der Umgebung zu zeigen, die für die Analyse und den Start des Analysewerkzeugs erforderlich sind. Möglicherweise ist es in Ihrem Fall optimaler, die Schritte zur Vorbereitung der Umgebung (Hinzufügen von Repositories, Installation des Analysewerkzeugs) und der Analyse zu trennen: beispielsweise das Erstellen von Docker-Images mit der erforderlichen Umgebung und deren Nutzung oder eine andere Methode.
Um besser zu verstehen, was jetzt passieren wird, empfehle ich, sich das folgende Diagramm anzusehen:

Für die Arbeit benötigt der Analyzer das .NET Core SDK 3, daher müssen vor der Installation des Analyzers die Microsoft-Repositories hinzugefügt werden, aus denen die für den Analyzer benötigten Abhängigkeiten installiert werden. Das Hinzufügen von Microsoft-Repositories für verschiedene Linux-Distributionen .
Für die Installation von PVS-Studio über einen Paketmanager müssen zudem die PVS-Studio-Repositories hinzugefügt werden. Das Hinzufügen der Repositories für verschiedene Distributionen wird in .
Für die Arbeit benötigt der Analyzer einen Lizenzschlüssel. Eine Testlizenz kann auf der .
Hinweiserworben werden. Bitte beachten Sie, dass für den beschriebenen Betriebsmodus (Analyse von Merge Requests) eine Enterprise-Lizenz erforderlich ist. Daher sollten Sie, wenn Sie diesen Betriebsmodus ausprobieren möchten, im Feld "Nachricht" angeben, 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.
Nun, da wir den Arbeitsalgorithmus im Blick haben, können wir mit dem Schreiben des Skripts beginnen. Dazu muss die Datei .gitlab-ci.yml oder, falls sie nicht existiert, erstellt werden. Um sie zu 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 einrichtet 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 erkläre diesen Abschnitt etwas näher.
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-Repositorys:
- 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-dotnetAktivierung der Lizenz:
- pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY$PVS_NAME — Benutzername.
$PVS_KEY — Produkt-Schlüssel.
Wiederherstellung der Projektabhängigkeiten, wobei $CI_PROJECT_DIR – der vollständige Pfad zum Projektverzeichnis ist:
- dotnet restore "$CI_PROJECT_DIR"/Path/To/Solution.slnFür eine korrekte Analyse muss das Projekt erfolgreich kompiliert werden, und seine Abhängigkeiten müssen wiederhergestellt werden (z. B. müssen die erforderlichen NuGet-Pakete heruntergeladen werden).
Um Umgebungsvariablen mit Lizenzinformationen einzustellen, klicken Sie auf Einstellungen, und dann auf CI / CD.

Im sich öffnenden Fenster finden wir den Punkt Variablen, auf der rechten Seite klicken wir auf die Schaltfläche Erweitern und fügen die Variablen hinzu. Das Ergebnis sollte wie folgt aussehen:

Jetzt können wir mit der Analyse fortfahren. Zuerst fügen wir das Skript für die vollständige Analyse hinzu. Im Flag -t übergeben wir den Pfad zur Lösung, im Flag -o geben wir den Pfad zur Datei an, in die die Analyseergebnisse geschrieben werden. Außerdem interessiert uns der Rückgabewert. In diesem Fall ist es uns wichtig, dass die Ausführung abgebrochen wird, wenn der Rückgabewert Informationen darüber enthält, dass während der Analyse Warnungen ausgegeben wurden. 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; fiRückgabecodes funktionieren nach dem Prinzip der Bitmaske. Wenn beispielsweise bei der Analyse Warnungen ausgegeben wurden, beträgt der Rückgabecode 8. Wenn die Lizenz innerhalb eines Monats abläuft, beträgt der Rückgabecode 4. Wenn während der Analyse Fehler gefunden werden und die Lizenz auch innerhalb eines Monats abläuft, werden beide Werte im Rückgabecode aufgezeichnet: die Zahlen werden addiert und ergeben den endgültigen Rückgabecode — 8+4=12. Somit kann man durch Überprüfung der entsprechenden Bits Informationen über verschiedene Zustände 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, bei denen die 8 vorkommt.
- exit_code=$((($exit_code & 8)/8))Wir erhalten 1, wenn der Rückgabecode das uns interessierende Bit der Zahl enthält, andernfalls erhalten wir 0.
Es ist an der Zeit, die Analyse des Merge-Requests hinzuzufügen. Bevor wir dies tun, bereiten wir den Platz für das Skript vor. Wir müssen sicherstellen, dass es nur bei einem Merge-Request ausgeführt wird. So sieht das aus:
merge:
script:
only:
- merge_requestsKommen wir zum eigentlichen Skript. Ich bin darauf gestoßen, dass die virtuelle Maschine nichts über origin/masterweiß. Daher helfen wir ihr ein wenig:
- git fetch originJetzt erhalten wir die Differenz der Branches und speichern das Ergebnis in txt Datei hinzufügen:
- git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txtWo $CI_COMMIT_SHA – der Hash des letzten Commits.
Als Nächstes starten wir die Analyse der Dateiliste unter Verwendung des Flags -f. 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 folgendermaßen 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 die Konvertierung des Protokolls 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.jsonDas Tool — dies ist ein Open-Source-Projekt, das verwendet wird, um Fehlerberichte des Parsers in verschiedene Formate zu konvertieren, zum Beispiel HTML. Eine detailliertere Beschreibung des Tools finden Sie im Abschnitt "Plog Converter Utility". .
Übrigens, wenn Sie bequem lokal mit dem .json-Bericht aus Ihrer IDE arbeiten möchten, empfehle ich unser für die IDE Rider. Eine ausführliche Beschreibung seiner Verwendung finden Sie in .
Zur besseren Übersicht hier .gitlab-ci.yml in voller Länge:
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 Sie alles in die Datei hinzugefügt haben, klicken Sie auf Änderungen committen. Um zu überprüfen, ob alles korrekt ist, gehen Sie zu CI/CD -> Pipelines -> Laufend. Es öffnet sich ein Fenster der virtuellen Maschine, am Ende sollte Folgendes angezeigt werden:

Wir haben gesehen Job erfolgreich – Erfolg, alles in Ordnung. Jetzt kann das Erstellte getestet werden.
Beispiele für die Anwendung
Um ein Beispiel zu erstellen, erstellen wir ein einfaches Projekt (in master) in dem es mehrere Dateien geben wird. Danach ändern wir in einem anderen Branch nur eine Datei und versuchen, einen Merge-Request zu erstellen.
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 eine Datei Program.cs, die keine Fehler enthält, und in einem anderen Branch hat der Entwickler fehlerhaften Code hinzugefügt und möchte einen Merge-Request erstellen. Welche Art von Fehler er gemacht hat – das ist nicht so wichtig, entscheidend ist, dass er vorhanden ist. Zum Beispiel hat er den Operator vergessen, throw (ja, ):
void MyAwesomeMethod(String name)
{
if (name == null)
new ArgumentNullException(....);
// do something
....
}Sehen wir uns das Ergebnis der Analyse des Beispiels mit dem Fehler an. Um sicherzustellen, dass nur eine Datei analysiert wurde, habe ich das Flag -r zum Startbefehl von pvs-studio-dotnet hinzugefügt:

Wir sehen, dass der Analyzer einen Fehler gefunden hat und das Zusammenführen der Branches nicht zuließ.
Überprüfen wir das Beispiel ohne Fehler. Korrigieren wir den Code:
void MyAwesomeMethod(String name)
{
if (name == null)
throw new ArgumentNullException(....);
// do something
....
}Analyseergebnisse des Merge-Requests:

Wie wir sehen, wurden keine Fehler gefunden, und die Ausführung der Aufgabe war erfolgreich, was wir überprüfen wollten.
Fazit
Schlechten Code vor dem Zusammenführen der Branches herauszufiltern, ist sehr bequem und erfreulich. Daher, wenn Sie CI/CD verwenden, versuchen Sie, einen statischen Analyzer zur Überprüfung einzubauen. Außerdem ist das relativ einfach zu machen.
Danke für Ihre Aufmerksamkeit.
Wenn Sie diesen Artikel mit einem englischsprachigen Publikum teilen möchten, verwenden Sie bitte den Link zur Übersetzung: Nikolay Mironov. .
Quelle: habr.com
