I PVS-Studio-analysatoren til C- og C++-sprog på Linux og macOS, startende fra version 7.04, er der dukket en testmulighed op for at kontrollere listen over specificerede filer. Ved at bruge den nye tilstand kan du konfigurere analysatoren til at kontrollere commits og pull-anmodninger. Denne artikel viser dig, hvordan du opsætter et GitHub-projektfillistetjek i populære CI-systemer (Continuous Integration) såsom Travis CI, Buddy og AppVeyor.
Kontroltilstand for filliste
Versionen af PVS-Studio 7.04 til Linux og macOS har en tilstand til at kontrollere listen over kildefiler. Dette virker for projekter, hvis byggesystem giver dig mulighed for at generere en fil
Desuden kan tilstanden til at kontrollere listen over filer bruges sammen med trace-sporingen af compilerkørsler (pvs-studio-analyzer trace). For at gøre dette skal du først udføre en fuld build af projektet og spore det, så analysatoren indsamler fuldstændig information om kompileringsparametrene for alle de filer, der kontrolleres.
Denne mulighed har dog en betydelig ulempe - du skal enten udføre et fuldt byggespor af hele projektet ved hver lancering, hvilket i sig selv modsiger ideen om en hurtig forpligtelseskontrol. Eller, hvis du cacher selve sporingsresultatet, kan efterfølgende lanceringer af analysatoren vise sig at være ufuldstændig, hvis kildefilens afhængighedsstruktur ændres efter sporing (for eksempel tilføjes en ny #include til en af kildefilerne).
Derfor anbefaler vi ikke at bruge fillistekontroltilstanden med en sporingslog til at kontrollere commits eller pull-anmodninger. Hvis du kan lave en trinvis build, når du tjekker en commit, kan du overveje at bruge tilstanden
Listen over kildefiler til analyse gemmes i en tekstfil og sendes til analysatoren ved hjælp af parameteren -S:
pvs-studio-analyzer analyze ... -f build/compile_commands.json -S check-list.txt
Denne fil specificerer relative eller absolutte stier til filer, og hver ny fil skal være på en ny linje. Det er tilladt at angive ikke kun navnene på filer til analyse, men også forskellig tekst. Parseren vil se, at dette ikke er en fil og vil ignorere linjen. Dette kan være nyttigt til at kommentere, hvis filer er angivet manuelt. Imidlertid vil listen over filer ofte blive genereret under CI-parsing, for eksempel filer fra en commit eller en pull-anmodning.
Nu, ved at bruge denne tilstand, kan du hurtigt teste ny kode, før den kommer ind i hovedudviklingsgrenen. For at verifikationssystemet kan reagere på analysatoradvarsler, skal hjælpeprogrammet plog-konverter flag tilføjet --angiv-advarsler:
plog-converter ... --indicate-warnings ... -o /path/to/report.tasks ...
Med dette flag vil konverteren returnere en kode, der ikke er nul, hvis der er advarsler i analysatorrapporten. Ved at bruge returkoden kan du blokere en precommit-hook-, commit- eller pull-anmodning og vise den genererede analysatorrapport på skærmen, dele den eller sende den med posten.
Bemærk. Første gang du begynder at analysere listen over filer, vil hele projektet blive analyseret, fordi analysatoren skal generere en fil med afhængigheder af projektets kildefiler på header-filerne. Dette er en funktion ved at parse C- og C++-filer. I fremtiden kan afhængighedsfilen cachelagres, og den vil automatisk blive opdateret af analysatoren. Fordelen ved at kontrollere commits, når du bruger fillistekontroltilstand frem for at bruge inkrementel parsingtilstand, er, at kun den fil skal cachelagres, ikke objektfilerne.
Generelle principper for pull request-analyse
Analysen af hele projektet tager meget tid, så det giver mening kun at tjekke en del af det. Problemet er, at du skal adskille de nye filer fra resten af projektfilerne.
Overvej et eksempel på et commit-træ med to grene:
Lad os foregive, at begå A1 indeholder en ret stor mængde kode, som allerede er kontrolleret. Lidt tidligere lavede vi en gren fra commit A1 og ændrede nogle filer.
Det lagde du selvfølgelig mærke til bagefter A1 der var yderligere to commits, men det var også fusioner af andre filialer, fordi vi ikke commits i Master. Og nu er tiden kommet, hvornår hotfix parat. Derfor dukkede en pull-anmodning op om fusionen B3 и A3.
Selvfølgelig ville det være muligt at kontrollere hele resultatet af deres sammenfletning, men dette ville være for langt og uberettiget, da kun få filer blev ændret. Derfor er det mere effektivt kun at analysere de ændrede.
For at gøre dette får vi forskellen mellem grenene, idet vi er i HOVEDET af den gren, hvorfra vi ønsker at fusionere til master:
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
$MERGE_BASE vi vil overveje i detaljer senere. Faktum er, at ikke alle CI-tjenester giver den nødvendige information om grundlaget for fusionen, så hver gang skal du finde på nye måder at få disse data på. Dette vil blive beskrevet detaljeret nedenfor i hver af de beskrevne webtjenester.
Så vi fik forskellen mellem grenene, eller rettere, listen over filnavne, der er blevet ændret. Nu skal vi give filen .pvs-pr.list (vi omdirigerede outputtet ovenfor til det) til analysatoren:
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
-S .pvs-pr.list
Efter analyse skal vi konvertere logfilen (PVS-Studio.log) til et læsbart format:
plog-converter -t errorfile PVS-Studio.log --cerr -w
Denne kommando viser fejlene i
Kun her skal vi ikke kun vise fejl, men også informere vores service til montering og test om tilstedeværelsen af problemer. Til dette blev der tilføjet et flag til konverteren -W (--angiv-advarsler). Hvis der er mindst én analysatoradvarsel, returneringskoden for hjælpeprogrammet plog-konverter ændres til 2, hvilket igen vil meddele CI-tjenesten, at der er potentielle fejl i pull request-filerne.
Travis CI
Konfigurationen er lavet i form af en fil .travis.yml. For nemheds skyld råder jeg dig til at lægge alt i et separat bash-script med funktioner, der vil blive kaldt fra filen .travis.yml (bash scriptnavn.sh funktionsnavn).
Vi tilføjer den nødvendige kode til scriptet på bash, så vi får mere funktionalitet. I afsnittet installere lad os skrive følgende:
install:
- bash .travis.sh travis_install
Hvis du havde nogen instruktioner, kan du flytte dem til scriptet ved at fjerne bindestregerne.
Lad os åbne filen .travis.sh og tilføje analysatoropsætningen til funktionen travis_install():
travis_install() {
wget -q -O - https://files.viva64.com/etc/pubkey.txt
| sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
sudo apt-get update -qq
sudo apt-get install -qq pvs-studio
}
Lad os nu tilføje til afsnittet script Kør analyse:
script:
- bash .travis.sh travis_script
Og i bash script:
travis_script() {
pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
git diff --name-only origin/HEAD > .pvs-pr.list
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
-S .pvs-pr.list
--disableLicenseExpirationCheck
else
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
fi
plog-converter -t errorfile PVS-Studio.log --cerr -w
}
Denne kode skal køres efter projektet er bygget, for eksempel hvis du havde en CMake build:
travis_script() {
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
cmake $CMAKE_ARGS CMakeLists.txt
make -j8
}
Det bliver sådan her:
travis_script() {
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
cmake $CMAKE_ARGS CMakeLists.txt
make -j8
pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
git diff --name-only origin/HEAD > .pvs-pr.list
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
-S .pvs-pr.list
--disableLicenseExpirationCheck
else
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
fi
plog-converter -t errorfile PVS-Studio.log --cerr -w
}
Du har sikkert allerede bemærket de angivne miljøvariabler. $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Travis CI erklærer dem på egen hånd:
- $TRAVIS_PULL_REQUEST gemmer pull request-nummeret, eller falskhvis det er en normal gren;
- $TRAVIS_REPO_SLUG gemmer navnet på projektlageret.
Algoritmen for denne funktion:
Travis CI reagerer på returkoder, så tilstedeværelsen af advarsler vil bede tjenesten om at markere commit som buggy.
Lad os se nærmere på denne kodelinje:
git diff --name-only origin/HEAD > .pvs-pr.list
Faktum er, at Travis CI automatisk slår grene sammen under analysen af en pull-anmodning:
Derfor analyserer vi A4Og ikke B3->A3. På grund af denne funktion skal vi beregne forskellen fra A3, som bare er toppen af grenen fra oprindelse.
En vigtig detalje er tilbage - cachelægning af afhængighederne af header-filer på kompilerede oversættelsesenheder (*.c, *.cc, *.cpp osv.). Analysatoren beregner disse afhængigheder ved første start i tilstanden til at kontrollere listen over filer og gemmer dem derefter i biblioteket .PVS-Studio. Travis CI giver dig mulighed for at cache mapper, så vi gemmer mappedata .PVS-Studio/:
cache:
directories:
- .PVS-Studio/
Denne kode skal tilføjes til filen .travis.yml. Denne mappe gemmer forskellige data indsamlet efter analyse, hvilket vil fremskynde efterfølgende kørsler af fillisteanalyse eller trinvis analyse betydeligt. Hvis dette ikke gøres, vil analysatoren faktisk analysere alle filer hver gang.
Buddy
Ligesom Travis C.I.,
Først og fremmest skal vi tilføje en ny handling til byggelinjen:
Angiv den compiler, der blev brugt til at bygge projektet. Bemærk docker-containeren, der er installeret i denne aktivitet. For eksempel er der en speciel beholder til GCC:
Lad os nu installere PVS-Studio og de nødvendige hjælpeprogrammer:
Tilføj følgende linjer til editoren:
apt-get update && apt-get -y install wget gnupg jq
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
Lad os nu gå til fanen Kør (det første ikon) og tilføje følgende kode til det tilsvarende editorfelt:
pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY
if [ "$BUDDY_EXECUTION_PULL_REQUEST_NO" != '' ]; then
PULL_REQUEST_ID="pulls/$BUDDY_EXECUTION_PULL_REQUEST_NO"
MERGE_BASE=`wget -qO -
https://api.github.com/repos/${BUDDY_REPO_SLUG}/${PULL_REQUEST_ID}
| jq -r ".base.ref"`
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
-S .pvs-pr.list
else
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
fi
plog-converter -t errorfile PVS-Studio.log --cerr -w
Hvis du har læst afsnittet om Travs-CI, er denne kode allerede bekendt for dig, men nu er der et nyt trin:
Faktum er, at nu analyserer vi ikke resultatet af fusionen, men lederen af den gren, hvorfra pull-anmodningen er lavet:
Så vi er i en betinget forpligtelse B3 og vi skal have forskellen fra A3:
PULL_REQUEST_ID="pulls/$BUDDY_EXECUTION_PULL_REQUEST_NO"
MERGE_BASE=`wget -qO -
https://api.github.com/repos/${BUDDY_REPO_SLUG}/${PULL_REQUEST_ID}
| jq -r ".base.ref"`
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
At bestemme A3 Lad os bruge GitHub API:
https://api.github.com/repos/${USERNAME}/${REPO}/pulls/${PULL_REQUEST_ID}
Vi brugte følgende variabler leveret af Buddy:
- $BUDDY_EXECUTION_PULL_REQEUST_NO - pull anmodningsnummer;
- $BUDDY_REPO_SLUG - en kombination af brugernavn og repository (for eksempel max / test).
Lad os nu gemme ændringerne ved hjælp af knappen nedenfor og aktivere pull request-analyse:
I modsætning til Travis CI behøver vi ikke at specificere .pvs-studio til caching, da Buddy automatisk cacher alle filer til efterfølgende lanceringer. Derfor er det sidste tilbage at gemme login og adgangskode til PVS-Studio i Buddy. Efter at have gemt ændringerne, vender vi tilbage til Pipeline. Vi skal gå til indstilling af variabler og tilføje login og nøgle til PVS-Studio:
Derefter vil fremkomsten af en ny pull-anmodning eller commit udløse en check. Hvis en commit indeholder fejl, vil Buddy påpege det på pull request-siden.
AppVeyor
Opsætning af AppVeyor ligner Buddy, da alt sker i webgrænsefladen, og der ikke er behov for at tilføje en *.yml-fil til projektlageret.
Lad os gå til fanen Indstillinger i projektoversigten:
Lad os rulle ned på denne side og aktivere cachelagring for opbygning af pull-anmodninger:
Lad os nu gå til fanen Miljø, hvor vi specificerer det billede, der skal bygges, og de nødvendige miljøvariabler:
Hvis du har læst de foregående afsnit, er du meget fortrolig med disse to variable − PVS_KEY и PVS_USERNAME. Hvis ikke, så lad mig minde dig om, at de er nødvendige for at kontrollere licensen til PVS-Studio-analysatoren. I fremtiden vil vi møde dem igen i Bash-manuskripter.
Angiv mappen til caching på samme side nedenfor:
Hvis vi ikke gør dette, analyserer vi hele projektet i stedet for et par filer, men vi får output baseret på de angivne filer. Derfor er det vigtigt at indtaste det korrekte mappenavn.
Nu er det tid til at teste scriptet. Åbn fanen Tests og vælg Script:
Indsæt følgende kode i denne formular:
sudo apt-get update && sudo apt-get -y install jq
wget -q -O - https://files.viva64.com/etc/pubkey.txt
| sudo apt-key add -
sudo wget -O /etc/apt/sources.list.d/viva64.list
https://files.viva64.com/etc/viva64.list
sudo apt-get update && sudo apt-get -y install pvs-studio
pvs-studio-analyzer credentials $PVS_USERNAME $PVS_KEY
PWD=$(pwd -L)
if [ "$APPVEYOR_PULL_REQUEST_NUMBER" != '' ]; then
PULL_REQUEST_ID="pulls/$APPVEYOR_PULL_REQUEST_NUMBER"
MERGE_BASE=`wget -qO -
https://api.github.com/repos/${APPVEYOR_REPO_NAME}/${PULL_REQUEST_ID}
| jq -r ".base.ref"`
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
--dump-files --dump-log pvs-dump.log
-S .pvs-pr.list
else
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
fi
plog-converter -t errorfile PVS-Studio.log --cerr -w
Lad os tage et kig på følgende del af koden:
PWD=$(pwd -L)
if [ "$APPVEYOR_PULL_REQUEST_NUMBER" != '' ]; then
PULL_REQUEST_ID="pulls/$APPVEYOR_PULL_REQUEST_NUMBER"
MERGE_BASE=`wget -qO -
https://api.github.com/repos/${APPVEYOR_REPO_NAME}/${PULL_REQUEST_ID}
| jq -r ".base.ref"`
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
--dump-files --dump-log pvs-dump.log
-S .pvs-pr.list
else
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
--disableLicenseExpirationCheck
fi
Den ret specifikke tildeling af værdien af kommandoen pwd til en variabel, der skal gemme denne standardværdi, virker mærkelig ved første øjekast, men jeg vil forklare alt om et øjeblik.
Mens jeg satte analysatoren op i AppVeyor, stødte jeg på en ekstremt mærkelig opførsel af analysatoren. På den ene side fungerede alt korrekt, men analysen startede ikke. Jeg brugte meget tid på at bemærke, at vi er i mappen /home/appveyor/projects/testcalc/, og analysatoren er sikker på, at vi er i /opt/appveyor/build-agent/. Så indså jeg, at $PWD-variablen er lidt af en løgn. Af denne grund opdaterede jeg dens værdi manuelt, før jeg startede analysen.
Og så alt, som før:
Overvej nu følgende uddrag:
PULL_REQUEST_ID="pulls/$APPVEYOR_PULL_REQUEST_NUMBER"
MERGE_BASE=`wget -qO -
https://api.github.com/repos/${APPVEYOR_REPO_NAME}/${PULL_REQUEST_ID}
| jq -r ".base.ref"`
I den får vi forskellen mellem de grene, som pull-anmodningen er deklareret på. Til dette har vi brug for følgende miljøvariable:
- $APPVEYOR_PULL_REQUEST_NUMBER - pull-anmodningsnummer;
- $APPVEYOR_REPO_NAME - brugernavn og projektlager.
Konklusion
Selvfølgelig har vi ikke overvejet alle de mulige kontinuerlige integrationstjenester, men de har alle meget ens arbejdsspecifikationer. Med undtagelse af caching laver hver tjeneste sin egen "cykel", så alt er altid anderledes.
Et eller andet sted, som i Travis-CI, fungerer et par linjer kode og caching fejlfrit; et eller andet sted, som i AppVeyor, skal du blot angive mappen i indstillingerne; men et eller andet sted skal du oprette unikke nøgler og prøve at overbevise systemet om at give dig mulighed for at overskrive det cachelagrede fragment. Derfor, hvis du ønsker at opsætte pull request-analyse på en kontinuerlig integrationstjeneste, som ikke blev diskuteret ovenfor, så sørg først for, at du ikke får problemer med caching.
Tak for din opmærksomhed. Hvis noget ikke lykkes, så er du velkommen til at skrive til os på
Hvis du vil dele denne artikel med et engelsktalende publikum, så brug venligst oversættelseslinket: Maxim Zvyagintsev.
Kilde: www.habr.com