
Milujete GitLab a nemáte radi chyby? Chcete zvýšiť kvalitu zdrojového kódu? Potom ste na správnom mieste. Dnes vám ukážeme, ako nastaviť C# analyzátor PVS-Studio na kontrolu merge requestov. Prajeme vám všem jednorohým náladu a príjemné čítanie.
je nástroj na odhaľovanie chýb a potenciálnych zraniteľností v zdrojovom kóde programov napísaných v jazykoch C, C++, C# a Java. Funguje na 64-bitových systémoch na Windows, Linux a macOS. Môže analyzovať kód, určený pre 32-bitové, 64-bitové a integrované ARM platformy.
Mimochodom, vydali sme PVS-Studio 7.08, v ktorom sme urobili množstvo zmien . Napríklad:
- analyzátor C# pod Linux a macOS;
- plugin pre Rider;
- nový režim kontroly zoznamu súborov.
Režim kontroly zoznamu súborov
Predtým bolo potrebné na kontrolu konkrétnych súborov odovzdať analyzátorovi .xml so zoznamom súborov. Ale pretože to nebolo veľmi pohodlné, pridali sme možnosť odovzdať .txt, čo veľmi uľahčuje život.
Na kontrolu konkrétnych súborov je potrebné uviesť príznak --sourceFiles (-f) a odovzdať .txt so zoznamom súborov. Vyzerá to nasledovne:
pvs-studio-dotnet -t path/to/solution.sln -f fileList.txt -o project.jsonAk vás zaujíma nastavenie kontroly commitov alebo pull requestov, môžete to tiež urobiť pomocou tohto režimu. Rozdiel bude v získavaní zoznamu súborov na analýzu a bude závisieť od toho, aké systémy používate.
Zásada kontroly merge requestov
Hlavný zmysel kontroly spočíva v tom, aby problémy, ktoré analyzátor odhalí, sa pri zlúčení nedostali do master vetvy. Taktiež nechceme zakaždým analyzovať projekt celý. O to viac, keď pri zlúčení vetiev máme zoznam zmenených súborov. Preto navrhujem pridať kontrolu merge requestov.
Takto vyzerá merge request pred zavedením statického analyzátora:

To znamená, že všetky chyby, ktoré boli vo vetve changes, prejdú do master vetvy. Pretože by sme to nechceli, pridávame analýzu, a teraz schéma vyzerá nasledovne:

Analizujeme changes2 a ak nie sú žiadne chyby, prijmeme merge request, inak ho zamietneme.
Mimochodom, ak vás zaujíma analýza commitov a pull requestov pre C/C++, môžete si o tom prečítať tu .
GitLab
— webový nástroj DevOps životného cyklu s otvoreným zdrojovým kódom, predstavujúci systém správy repozitárov kódu pre Git s vlastnou wikipédiou, systémom sledovania chýb, CI/CD pipeline a inými funkciami.
Predtým, ako začnete implementovať analýzu merge requestov, je potrebné sa zaregistrovať a nahrať svoj projekt. Ak neviete, ako to urobiť, navrhujem môjho kolegu.
Poznámka. Opisovaný spôsob nastavenia prostredia je jedným z možných. Cieľom je ukázať kroky nastavenia potrebného pre analýzu prostredia a spustenie analyzátora. Možno, v vašom prípade bude optimálnejšie rozdelenie etáp prípravy prostredia (pridanie repozitárov, inštalácia analyzátora) a analýzy: napríklad príprava Docker obrazov s potrebným prostredím a ich použitie alebo iný spôsob.
Aby ste lepšie pochopili, čo sa teraz bude diať, navrhujem pozrieť sa na nasledujúcu schému:

Pre prácu analyzátora je potrebný .NET Core SDK 3, preto pred inštaláciou analyzátora treba pridať repozitáre Microsoft, z ktorých budú nainštalované potrebné závislosti. Pridanie repozitárov Microsoft pre rôzne distribúcie Linux .
Pre inštaláciu PVS-Studio cez balíčkový manažér bude tiež potrebné pridať repozitáre PVS-Studio. Pridanie repozitárov pre rôzne distribúcie je podrobne opísané v .
Pre prácu analyzátora je potrebný licenčný kľúč. Získať skúšobnú licenciu môžete na .
Poznámka. Upozorňujeme, že pre opisovaný režim práce (analýza merge requests) je potrebná licencie Enterprise. Preto, ak chcete vyskúšať tento režim, v poli "Správa" nezabudnite uviesť, že potrebujete práve licenciu Enterprise.
Ak dôjde k merge requestu, musíme analyzovať len zoznam zmenených súborov, inak analyzujeme všetky súbory. Po analýze je potrebné konvertovať logy do požadovaného formátu.
Teraz, keď máme pred očami algoritmus práce, môžeme prejsť k napísaniu skriptu. Aby sme to urobili, je potrebné zmeniť súbor .gitlab-ci.yml alebo, ak neexistuje, vytvoriť. Na jeho vytvorenie je potrebné kliknúť na názov vášho projektu -> Nastaviť CI/CD.

Teraz sme pripravení napísať skript. Poďme najprv napísať kód, ktorý nainštaluje analyzer a zadá licenciu:
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.slnKeďže inštalácia a aktivácia sa musia uskutočniť pred všetkými ostatnými skriptami, použijeme špeciálnu značku before_script. Trochu vysvetlím tento fragment.
Príprava na inštaláciu analyzátora:
- 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 updatePridanie repozitárov PVS-Studio a analyzátora:
- 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-dotnetAktivácia licencie:
- pvs-studio-analyzer credentials $PVS_NAME $PVS_KEY$PVS_NAME — používateľské meno.
$PVS_KEY — produktový kľúč.
Obnovenie závislostí projektu, kde $CI_PROJECT_DIR – úplná cesta do adresára projektu:
- dotnet restore "$CI_PROJECT_DIR"/Path/To/Solution.slnPre správnu analýzu musí byť projekt úspešne zostavený a jeho závislosti musia byť obnovené (napríklad musia byť načítané potrebné NuGet balíčky).
Premenné prostredia obsahujúce licenčné informácie môžete nastaviť kliknutím na Nastavenie, a potom na CI / CD.

V otvorenom okne nájdeme položku Premenné, vpravo klikneme na tlačidlo Rozbalit a pridáme premenné. Výsledok by mal vyzerať nasledovne:

Teraz môžeme prejsť na analýzu. Najprv pridáme skript na úplnú analýzu. V príznaku -t poskytujeme cestu k riešeniu, v príznaku -o uvádzame cestu k súboru, do ktorého budú zapísané výsledky analýzy. Zaujíma nás aj návratový kód. V tomto prípade nás zaujíma, aby práca skončila, keď návratový kód indikuje, že počas analýzy boli vydané varovania. Takto vyzerá tento fragment:
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; fiNávratové kódy fungujú na princípe bitovej masky. Napríklad, ak boli v dôsledku analýzy vydané varovania, návratový kód bude 8. Ak licencia vyprší v priebehu mesiaca, návratový kód bude 4. Ak sa počas analýzy zistili chyby a licencia vyprší v priebehu mesiaca, do návratového kódu sa zapíšu obe hodnoty: spočítame čísla a dostaneme konečný návratový kód — 8+4=12. Takto môžeme overiť príslušné bity a získať informácie o rôznych stave počas analýzy. O návratových kódoch je podrobnejšie popísané v časti "Návratové kódy pvs-studio-dotnet (Linux / macOS)" dokumentu.".
V tomto prípade nás zaujímajú všetky návratové kódy, kde figuruje 8.
- exit_code=$((($exit_code & 8)/8))Dostaneme 1, ak návratový kód obsahuje nás zaujímajúci bit čísla, inak dostaneme 0.
Nastal čas pridať analýzu merge request. Predtým, ako to urobíme, pripravíme miesto pre skript. Musí sa vykonať iba vtedy, keď sa uskutoční merge request. Vyzerá to takto:
merge:
script:
only:
- merge_requestsPrejdime k samotnému skriptu. Narazil som na to, že virtuálny stroj nič nevie o origin/master. Preto jej trochu pomôžeme:
- git fetch originTeraz získame rozdiely medzi vetvami a uložíme výsledok do txt súboru:
- git diff --name-only origin/master $CI_COMMIT_SHA > pvs-fl.txtKde $CI_COMMIT_SHA – hash posledného commitu.
Ďalej spustíme analýzu zoznamu súborov s použitím prepínača -f. Poslednému .txt súboru preposielame už predtým získaný súbor. A podľa analógie s úplnou analýzou sledujeme návratové kódy:
- 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Úplný skript na kontrolu merge request bude vyzerať takto:
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_requestsOstáva už len pridať konverziu logu po tom, čo všetky skripty odpracovali. Použijeme značku after_script a utilitu plog-converter:
after_script:
- plog-converter -t html -o eLog ./PVS-Studio.jsonNástroj — je open source projekt, ktorý sa používa na konverziu reportov o chybách analyzátora do rôznych foriem, napríklad HTML. Podrobnejší popis nástroja nájdete v podsekcii "Nástroj Plog Converter" .
Mimochodom, ak chcete pohodlne pracovať s .json reportom lokálne z IDE, ponúkam náš pre IDE Rider. Podrobnejšie informácie o jeho používaní sú uvedené v .
Pre pohodlie tu je .gitlab-ci.yml vcelku:
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.jsonAkonáhle pridáte všetko do súboru, kliknite na Commit changes. Aby ste sa uistili, že je všetko správne, prejdite do CI/CD -> Pipelines -> Running. Otvorí sa okno virtuálneho stroja, na konci ktorého by malo byť toto:

Videli sme Job succeeded – úspech, všetko je v poriadku. Teraz môžeme otestovať, čo sme urobili.
Príklady práce
Pre príklad práce vytvoríme jednoduchý projekt (v master) s niekoľkými súbormi. Potom v inej vetve zmeníme iba jeden súbor a pokúsime sa urobiť merge request.
Zvážime dva prípady: keď sa zmenený súbor obsahuje chybu a keď nie. Najprv príklad s chybou.
Povedzme, že v master vetve je súbor Program.cs, ktorý neobsahuje chyby, a v inej vetve vývojár pridal chybový kód a chce urobiť merge request. Akú konkrétnu chybu urobil – to nie je také dôležité, dôležité je, že tam je. Napríklad zabudol na operátor throw (áno, ):
void MyAwesomeMethod(String name)
{
if (name == null)
new ArgumentNullException(....);
// urob niečo
....
}Pozrime sa na výsledok analýzy príkladu s chybou. Aby som sa tiež uistil, že bol analyzovaný iba jeden súbor, pridal som prepínač -r do príkazu pvs-studio-dotnet:

Vidíme, že analyzátor našiel chybu a nedovolil zlučovanie vetiev.
Skontrolujme príklad bez chyby. Opravený kód:
void MyAwesomeMethod(String name)
{
if (name == null)
throw new ArgumentNullException(....);
// urob niečo
....
}Výsledky analýzy merge request:

Ako vidíme, chyby neboli nájdené a vykonanie úlohy prebehlo úspešne, čo sme chceli overiť.
Záver
Filtrácia zlého kódu pred zlučovaním vetiev je veľmi praktická a pohodlná. Preto, ak používate CI/CD, vyskúšajte integrovať statický analyzátor na kontrolu. Obzvlášť, keď sa to robí dosť jednoducho.
Ďakujem za pozornosť.
Ak chcete zdieľať tento článok s anglicky hovoriacou komunitou, prosím, použite odkaz na preklad: Nikolay Mironov. .
Zdroj: habr.com
