
Houd je van GitLab en haat je fouten? Wil je de kwaliteit van de broncode verbeteren? Dan ben je op de juiste plek. Vandaag vertellen we je hoe je de C# analyzer PVS-Studio kunt instellen voor het controleren van merge requests. Iedereen een eenhoornstemming en veel leesplezier.
is een tool voor het identificeren van fouten en potentiƫle kwetsbaarheden in de broncode van programma's geschreven in C, C++, C# en Java. Werkt op 64-bit systemen met Windows, Linux en macOS. Kan code analyseren die is bedoeld voor 32-bit, 64-bit en embedded ARM-platforms.
Overigens hebben we PVS-Studio 7.08 uitgebracht, waarin we veel gedaan hebben . Bijvoorbeeld:
- C# analyzer voor Linux en macOS;
- plugin voor Rider;
- nieuwe modus voor het controleren van een lijst met bestanden.
Bestandenlijst controlemodus
Eerder moest je een .xml-bestand met een lijst van bestanden aan de analyzer overdragen om bepaalde bestanden te controleren. Maar omdat dat niet erg handig was, hebben we de mogelijkheid toegevoegd om een .txt-bestand door te geven, wat het leven aanzienlijk vergemakkelijkt.
Om bepaalde bestanden te controleren, moet je de vlag opgeven --sourceFiles (-f) en een .txt-bestand met de lijst van bestanden doorgeven. Dit ziet er als volgt uit:
pvs-studio-dotnet -t path/to/solution.sln -f fileList.txt -o project.jsonAls je geĆÆnteresseerd bent in het instellen van de controle van commits of pull requests, kun je dit ook doen met deze modus. Het verschil zal liggen in het verkrijgen van de lijst met bestanden voor analyse en zal afhangen van de systemen die je gebruikt.
Principe van de controle van merge requests
De essentie van de controle is ervoor te zorgen dat de problemen die door de analyzer zijn gevonden, niet in de master branch worden opgenomen bij het mergen. Ook willen we niet elke keer het hele project analyseren. Bovendien hebben we bij het mergen van branches een lijst van gewijzigde bestanden. Daarom stel ik voor om de controle van merge requests toe te voegen.
Zo ziet een merge request eruit voordat de statische analyzer is geĆÆmplementeerd:

Dat wil zeggen, alle fouten die in de branch waren, wijzigingen, zullen naar de master branch overgaan. Omdat we dat niet willen, voegen we de analyse toe, en nu ziet het schema eruit als volgt:

Analyseren we changes2 en als er geen fouten zijn, accepteren we de merge request, anders wijzen we deze af.
Overigens, als je geĆÆnteresseerd bent in de analyse van commits en pull requests voor C/C++, kun je hierover lezen .
GitLab
ā een open-source DevOps lifecycle webtool die een versiebeheersysteem voor Git biedt met een eigen wiki, bugtracking systeem, CI/CD pipeline en andere functies.
Voordat we beginnen met het uitvoeren van de analyse van merge requests, is het nodig om je te registreren en je project te uploaden. Als je niet weet hoe dit moet, stel ik voor van mijn collega.
Opmerking. De methode voor het configureren van de omgeving die hieronder wordt beschreven, is een van de mogelijke manieren. Het doel is om de stappen te laten zien die nodig zijn om de omgeving voor analyse in te stellen en de analyser uit te voeren. Misschien is het in jouw geval efficiƫnter om de fasen van omgeving voorbereiding (toevoegen van repositories, installatie van de analyser) en analyse te splitsen: bijvoorbeeld het voorbereiden van Docker images met de benodigde omgeving en hun gebruik, of een andere manier.
Om beter te begrijpen wat er nu gaat gebeuren, stel ik voor om naar het volgende schema te kijken:

De analyser heeft .NET Core SDK 3 nodig, dus voordat je de analyser installeert, moet je de Microsoft-repositories toevoegen waarvan de benodigde afhankelijkheden voor de analyser worden geĆÆnstalleerd. Het toevoegen van Microsoft-repositories voor verschillende Linux-distributies .
Voor de installatie van PVS-Studio via de pakketbeheerder moet ook de PVS-Studio-repositories worden toegevoegd. Het toevoegen van repositories voor verschillende distributies wordt uitgebreider beschreven in .
Voor het functioneren van de analyser is een licentiesleutel vereist. Een proeflicentie kan worden verkregen op .
Opmerking. Let op dat voor de beschreven werkwijze (analyse van merge requests) een Enterprise-licentie nodig is. Dus, als je deze werkwijze wilt proberen, vergeet dan niet om in het veld "Bericht" aan te geven dat je specifiek een Enterprise-licentie nodig hebt.
Als er een merge request is, moeten we alleen de lijst met gewijzigde bestanden analyseren, anders analyseren we alle bestanden. Na de analyse moeten we de logs converteren naar het gewenste formaat.
Nu we het algoritme van de werkwijze voor ons hebben, kunnen we overgaan tot het schrijven van het script. Om dit te doen, moet je het bestand .gitlab-ci.yml wijzigen of, als het nog niet bestaat, aanmaken. Om dit te doen, klik je op de naam van je project -> Set up CI/CD.

Nu zijn we klaar om het script te schrijven. Laten we eerst de code schrijven die de analyser installeert en de licentie invoert:
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.slnOmdat de installatie en activatie vóór alle andere scripts moet plaatsvinden, gebruiken we een speciaal label. before_script. Laat me dit fragment kort toelichten.
Voorbereiding op de installatie van de analyzer:
- 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 updateToevoegen van PVS-Studio repositories en analyser:
- 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-dotnetLicentie activatie:
- pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY$PVS_NAME ā gebruikersnaam.
$PVS_KEY ā product sleutel.
Herstellen van projectafhankelijkheden, waarbij $CI_PROJECT_DIR ā het volledige pad naar de projectdirectory:
- dotnet restore "$CI_PROJECT_DIR"/Path/To/Solution.slnVoor een correcte analyse moet het project succesvol worden opgebouwd en moeten de afhankelijkheden zijn hersteld (bijvoorbeeld moeten de benodigde NuGet-pakketten zijn gedownload).
Om omgevingsvariabelen in te stellen met licentie-informatie, kunt u klikken op Instellingen, en daarna op CI / CD.

In het geopende venster zoeken we het item Variabelen, rechts klikken we op de knop Uitvouwen en voegen we variabelen toe. Het resultaat zou als volgt moeten zijn:

Nu kunnen we overgaan tot analyse. Laten we eerst het script toevoegen voor een volledige analyse. In de vlag -t geven we het pad naar de oplossing door, in de vlag -o geven we het pad naar het bestand op waarin de analyse resultaten worden vastgelegd. We zijn ook geĆÆnteresseerd in de retourcode. In dit geval willen we dat het proces stopt als de retourcode aangeeft dat er waarschuwingen zijn gegeven tijdens de analyse. Zo ziet dit fragment eruit:
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; fiReturn codes operate on the principle of a bitmask. For example, if warnings are issued as a result of the analysis, the return code will equal 8. If the license expires within a month, the return code will equal 4. If errors are detected during the analysis and the license is also expiring within a month, both values will be recorded in the return code: we add the numbers together and get the final return code ā 8+4=12. Thus, by checking the corresponding bits, you can obtain information about various states during the analysis. Return codes are described in detail in the section "Return codes of pvs-studio-dotnet (Linux / macOS)" of the document.".
In this case, we are interested in all return codes that include 8.
- exit_code=$((($exit_code & 8)/8))We will get 1 when the return code contains the bit of interest to us, otherwise we will get 0.
It's time to add analysis for the merge request. Before doing this, let's prepare a place for the script. We need it to execute only when a merge request occurs. It looks like this:
merge:
script:
only:
- merge_requestsLet's move on to the script itself. I encountered the fact that the virtual machine knows nothing about origin/master. So we help it a bit:
- git fetch originNow we will get the difference between branches and save the result in txt file:
- git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txtWaarbij $CI_COMMIT_SHA ā the hash of the last commit.
Next, we run analysis on the list of files using the flag -f. We pass the previously obtained .txt file to it. And similarly to a full analysis, we check the return codes:
- 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; fiThe complete script for checking the merge request will look like this:
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_requestsIt remains only to add log conversion after all scripts have run. We use the label after_script and the utility plog-converter:
after_script:
- plog-converter -t html -o eLog ./PVS-Studio.jsonHulpprogramma ā is een open source project dat wordt gebruikt om een foutrapport van de parser in verschillende vormen om te zetten, zoals HTML. Een meer gedetailleerde beschrijving van de tool is te vinden in de sectie "Plog Converter Utility" .
Overigens, als je het .json rapport lokaal vanuit een IDE handig wilt bewerken, stel ik onze voor voor IDE Rider. Een uitgebreider gebruik ervan is beschreven in .
Voor de gemak, hier is .gitlab-ci.yml de volledige tekst:
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.jsonZodra alles in het bestand is toegevoegd, klikken we op Commit changes. Om te controleren of alles correct is, gaan we naar CI/CD -> Pipelines -> Running. Er opent een venster van de virtuele machine, waarin aan het eind het volgende moet staan:

We zagen Job succeeded ā dat is een succes, alles werkt perfect. Nu kunnen we ook het gemaakte testen.
Voorbeelden van werk
Om een voorbeeld te maken, creƫren we een eenvoudig project (in master) waarin enkele bestanden zich bevinden. Daarna wijzigen we in een andere branch slechts ƩƩn bestand en proberen we een merge request te doen.
We beschouwen twee situaties: wanneer het gewijzigde bestand een fout bevat en wanneer dat niet zo is. Eerst een voorbeeld met een fout.
Stel dat er in de master branch een bestand is Program.cs, dat geen fouten bevat, en in een andere branch heeft de ontwikkelaar foutieve code toegevoegd en wil hij een merge request doen. Welke fout hij precies heeft gemaakt, is niet zo belangrijk, het belangrijkste is dat dat zo is. Bijvoorbeeld, hij vergat de operator throw (ja, ):
void MyAwesomeMethod(String name)
{
if (name == null)
new ArgumentNullException(....);
// doe iets
....
}Laten we eens kijken naar het resultaat van de analyse van het voorbeeld met een fout. Ook, om te bevestigen dat alleen ƩƩn bestand is geanalyseerd, heb ik de vlag toegevoegd -r aan de opstartregel pvs-studio-dotnet:

We zien dat de analyzer een fout heeft gevonden en het niet mogelijk maakte om de branches samen te voegen.
Laten we het voorbeeld zonder fout controleren. We corrigeren de code:
void MyAwesomeMethod(String name)
{
if (name == null)
throw new ArgumentNullException(....);
// doe iets
....
}Resultaten van de analyse van het merge request:

Zoals we zien, zijn er geen fouten gevonden en is de taak succesvol uitgevoerd, wat we wilden controleren.
Conclusie
Slecht code uitsluiten voor het samenvoegen van branches is zeer handig en prettig. Dus, als je CI/CD gebruikt, probeer dan een statische analyzer te integreren voor controle. Het is bovendien vrij eenvoudig te doen.
Bedankt voor uw aandacht.
Als je dit artikel wilt delen met een Engelstalig publiek, gebruik dan alsjeblieft de link naar de vertaling: Nikolay Mironov. .
Bron: habr.com
