I PVS-Studio-analysatoren for C- og C++-språk på Linux og macOS, fra og med versjon 7.04, har det dukket opp et testalternativ for å sjekke listen over spesifiserte filer. Ved å bruke den nye modusen kan du konfigurere analysatoren til å sjekke forpliktelser og pull-forespørsler. Denne artikkelen vil fortelle deg hvordan du setter opp å sjekke listen over endrede filer til et GitHub-prosjekt i slike populære CI (Continuous Integration)-systemer som Travis CI, Buddy og AppVeyor.
Kontrollmodus for filliste
I versjon PVS-Studio 7.04 for Linux og macOS har det dukket opp en modus for å sjekke listen over kildefiler. Dette fungerer for prosjekter hvis byggesystem lar deg generere en fil
Fillistekontrollmodusen kan også brukes sammen med trace-sporingsloggen for kompilatorlanseringer (pvs-studio-analyzer trace). For å gjøre dette, må du først utføre en full build av prosjektet og spore det slik at analysatoren samler inn fullstendig informasjon om kompileringsparametrene til alle filene som kontrolleres.
Imidlertid har dette alternativet en betydelig ulempe - du må enten utføre et fullstendig byggespor av hele prosjektet hver gang du kjører det, noe som i seg selv motsier ideen om å raskt sjekke en forpliktelse. Eller, hvis du hurtigbuffer selve sporingsresultatet, kan påfølgende kjøringer av analysatoren være ufullstendige hvis avhengighetsstrukturen til kildefilene endres etter sporingen (for eksempel legges en ny #include til en av kildefilene).
Derfor anbefaler vi ikke å bruke fillistekontrollmodusen med sporingsloggen for å sjekke forpliktelser eller pull-forespørsler. Hvis du kan gjøre en inkrementell build når du sjekker en commit, bør du vurdere å bruke modusen
Listen over kildefiler for analyse lagres i en tekstfil og sendes til analysatoren ved hjelp av parameteren -S:
pvs-studio-analyzer analyze ... -f build/compile_commands.json -S check-list.txt
Denne filen spesifiserer relative eller absolutte stier til filer, og hver ny fil må være på en ny linje. Det er akseptabelt å spesifisere ikke bare filnavn for analyse, men også forskjellig tekst. Analysatoren vil se at dette ikke er en fil og vil ignorere linjen. Dette kan være nyttig for å kommentere hvis filer er spesifisert manuelt. Imidlertid vil ofte en liste over filer genereres under analyse i CI, for eksempel kan disse være filer fra en commit- eller pull-forespørsel.
Nå, ved å bruke denne modusen, kan du raskt sjekke ny kode før den kommer inn i hovedutviklingsgrenen. For å sikre at skannesystemet reagerer på analysatoradvarsler, må verktøyet plog-omformer flagg lagt til --indikerer-advarsler:
plog-converter ... --indicate-warnings ... -o /path/to/report.tasks ...
Med dette flagget vil omformeren returnere en ikke-nullkode hvis det er advarsler i analysatorrapporten. Ved å bruke returkoden kan du blokkere en precommit-krok-, commit- eller pull-forespørsel, og den genererte analysatorrapporten kan vises, deles eller sendes via e-post.
Merk. Når du først begynner å analysere en liste over filer, vil hele prosjektet bli analysert, fordi analysatoren må generere en fil med avhengigheter til prosjektkildefilene på overskriftsfilene. Dette er en funksjon for å analysere C- og C++-filer. I fremtiden kan avhengighetsfilen bufres og den vil bli oppdatert automatisk av analysatoren. Fordelen med å sjekke forpliktelser når du bruker fillistekontrollmodus fremfor bruk av inkrementell analysemodus, er at du bare trenger å cache den filen og ikke objektfilene.
Generelle prinsipper for pull request-analyse
Å analysere hele prosjektet tar mye tid, så det er fornuftig å sjekke bare en viss del av det. Problemet er at du må skille de nye filene fra resten av prosjektfilene.
La oss se på et eksempel på et commit-tre med to grener:
La oss forestille oss den forpliktelsen A1 inneholder en ganske stor mengde kode som allerede er testet. Litt tidligere har vi laget en gren fra commit A1 og endret noen filer.
Du la selvfølgelig merke til det etterpå A1 ytterligere to forpliktelser skjedde, men disse var også sammenslåinger av andre grener, fordi vi ikke forplikter oss til Master. Og nå er tiden kommet når hurtigreparasjon klar. Derfor dukket det opp en pull-forespørsel om sammenslåingen B3 и A3.
Selvfølgelig ville det være mulig å sjekke hele resultatet av deres sammenslåing, men dette ville være for tidkrevende og uberettiget, siden bare noen få filer ble endret. Derfor er det mer effektivt å analysere kun de endrede.
For å gjøre dette får vi forskjellen mellom grenene, som er i HODET til grenen som vi ønsker å slå sammen til master:
git diff --name-only HEAD origin/$MERGE_BASE > .pvs-pr.list
$MERGE_BASE vi vil se nærmere på det senere. Faktum er at ikke alle CI-tjenester gir den nødvendige informasjonen om databasen for sammenslåing, så hver gang må du finne nye måter å skaffe disse dataene på. Dette vil bli beskrevet i detalj nedenfor i hver av de beskrevne nettjenestene.
Så vi fikk forskjellen mellom grenene, eller rettere sagt, en liste over filnavn som ble endret. Nå må vi gi filen .pvs-pr.list (vi omdirigerte utdataene ovenfor til den) til analysatoren:
pvs-studio-analyzer analyze -j8
-o PVS-Studio.log
-S .pvs-pr.list
Etter analyse må vi konvertere loggfilen (PVS-Studio.log) til et lettlest format:
plog-converter -t errorfile PVS-Studio.log --cerr -w
Denne kommandoen vil liste opp feilene i
Først nå må vi ikke bare vise feil, men også informere vår tjeneste for montering og testing om tilstedeværelsen av problemer. For dette formålet ble et flagg lagt til omformeren -W (--indikerer-advarsler). Hvis det er minst én analysatoradvarsel, returnerer verktøyet koden plog-omformer endres til 2, som igjen vil informere CI-tjenesten om tilstedeværelsen av potensielle feil i pull request-filene.
Travis C.I.
Konfigurasjonen er laget som en fil .travis.yml. For enkelhets skyld anbefaler jeg deg å legge alt inn i et eget bash-skript med funksjoner som kalles opp fra filen .travis.yml (bash script_name.sh funksjonsnavn).
Vi vil legge til den nødvendige koden til skriptet på bash, på denne måten vil vi få mer funksjonalitet. I seksjon installere la oss skrive følgende:
install:
- bash .travis.sh travis_install
Hvis du hadde noen instruksjoner, kan du overføre dem til skriptet ved å fjerne bindestrekene.
La oss åpne filen .travis.sh og legg til analysatorinnstillingen til funksjonen 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
}
La oss nå legge til delen script kjør analyse:
script:
- bash .travis.sh travis_script
Og i bash-manuset:
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 koden må kjøres etter å ha bygget prosjektet, for eksempel hvis du hadde en build på CMake:
travis_script() {
CMAKE_ARGS="-DCMAKE_EXPORT_COMPILE_COMMANDS=On ${CMAKE_ARGS}"
cmake $CMAKE_ARGS CMakeLists.txt
make -j8
}
Det vil bli slik:
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 lagt merke til disse miljøvariablene $TRAVIS_PULL_REQUEST и $TRAVIS_BRANCH. Travis CI erklærer dem uavhengig:
- $TRAVIS_PULL_REQUEST lagrer pull request-nummeret eller falsk, hvis dette er en vanlig gren;
- $TRAVIS_REPO_SLUG lagrer navnet på prosjektlageret.
Algoritmen for denne funksjonen:
Travis CI reagerer på returkoder, så tilstedeværelsen av advarsler vil fortelle tjenesten om å markere forpliktelsen som inneholder feil.
La oss nå se nærmere på denne kodelinjen:
git diff --name-only origin/HEAD > .pvs-pr.list
Faktum er at Travis CI automatisk slår sammen grener mens han analyserer en pull-forespørsel:
Derfor analyserer vi A4Og ikke B3->A3. På grunn av denne funksjonen må vi beregne forskjellen med A3, som er nettopp toppen av grenen fra opprinnelse.
Det er én viktig detalj igjen - bufring av avhengighetene til overskriftsfiler på kompilerte oversettelsesenheter (*.c, *.cc, *.cpp, etc.). Analysatoren beregner disse avhengighetene når den først startes i modusen for å sjekke en liste over filer og lagrer dem deretter i .PVS-Studio-katalogen. Travis CI lar deg cache mapper, så vi lagrer katalogdataene .PVS-Studio/:
cache:
directories:
- .PVS-Studio/
Denne koden må legges til filen .travis.yml. Denne katalogen lagrer forskjellige data som er samlet inn etter analyse, noe som vil øke betydelig hastighet på påfølgende kjøringer av fillisteanalyse eller inkrementell analyse. Hvis dette ikke gjøres, vil analysatoren faktisk analysere alle filene hver gang.
Buddy
Som Travis CI,
Først av alt må vi legge til en ny handling på samlebåndet:
La oss angi kompilatoren som ble brukt til å bygge prosjektet. Legg merke til docker-beholderen som er installert i denne handlingen. For eksempel er det en spesiell beholder for GCC:
La oss nå installere PVS-Studio og de nødvendige verktøyene:
La oss legge til følgende linjer i 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
La oss nå gå til Kjør-fanen (første ikon) og legge til følgende kode i det tilsvarende redigeringsfeltet:
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 leser avsnittet om Travs-CI, er denne koden allerede kjent for deg, men nå er det et nytt stadium:
Faktum er at nå analyserer vi ikke resultatet av sammenslåingen, men HEAD for grenen som pull-forespørselen er gjort fra:
Så vi er i en betinget forpliktelse B3 og vi må få forskjellen 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
Å bestemme A3 La oss bruke GitHub API:
https://api.github.com/repos/${USERNAME}/${REPO}/pulls/${PULL_REQUEST_ID}
Vi brukte følgende variabler som Buddy gir:
- $BUDDY_EXECUTION_PULL_REQEUST_NO — pull request number;
- $BUDDY_REPO_SLUG — en kombinasjon av brukernavn og repository (for eksempel max/test).
La oss nå lagre endringene ved å bruke knappen nedenfor og aktivere analyse av pull-forespørselen:
I motsetning til Travis CI, trenger vi ikke spesifisere .pvs-studio for caching, siden Buddy automatisk cacher alle filer for påfølgende lanseringer. Derfor er det siste som gjenstår å lagre innlogging og passord for PVS-Studio i Buddy. Etter å ha lagret endringene, vil vi bli tatt tilbake til Pipeline. Vi må gå videre til å sette opp variabler og legge til en pålogging og nøkkel for PVS-Studio:
Etter dette vil utseendet til en ny pull-forespørsel eller commit utløse anmeldelsen. Hvis en commit inneholder feil, vil Buddy indikere dette på pull request-siden.
AppVeyor
Oppsett av AppVeyor ligner på Buddy, siden alt skjer i nettgrensesnittet og det er ikke nødvendig å legge til en *.yml-fil i prosjektlageret.
La oss gå til fanen Innstillinger i prosjektoversikten:
La oss bla nedover denne siden og aktivere hurtigbufferlagring for å samle inn pull-forespørsler:
La oss nå gå til fanen Miljø, der vi spesifiserer bildet for montering og de nødvendige miljøvariablene:
Hvis du har lest de foregående avsnittene, er du godt kjent med disse to variablene − PVS_KEY и PVS_USERNAME. Hvis ikke, la meg minne deg på at de er nødvendige for å bekrefte lisensen til PVS-Studio-analysatoren. Vi vil se dem igjen i Bash-manus i fremtiden.
På samme side nedenfor angir vi mappen for caching:
Hvis vi ikke gjør dette, vil vi analysere hele prosjektet i stedet for et par filer, men vi får utdata fra de angitte filene. Derfor er det viktig å angi riktig katalognavn.
Nå er det på tide at manuset skal testes. Åpne Tester-fanen og velg Script:
Du må lime inn følgende kode i dette skjemaet:
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
La oss ta hensyn til følgende del av 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 ganske spesifikke tilordningen av verdien til pwd-kommandoen til en variabel som skal lagre denne standardverdien virker rart ved første øyekast, men jeg skal forklare alt nå.
Mens jeg satte opp analysatoren i AppVeyor, møtte jeg ekstremt merkelig oppførsel til analysatoren. På den ene siden fungerte alt riktig, men analysen startet ikke. Jeg brukte mye tid på å legge merke til at vi er i /home/appveyor/projects/testcalc/-katalogen, og analysatoren er sikker på at vi er i /opt/appveyor/build-agent/. Så skjønte jeg at $PWD-variabelen løy litt. Av denne grunn oppdaterte jeg verdien manuelt før jeg startet analysen.
Og så er alt som før:
Tenk nå på følgende fragment:
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 forskjellen mellom grenene som pull-forespørselen er deklarert over. For å gjøre dette trenger vi følgende miljøvariabler:
- $APPVEYOR_PULL_REQUEST_NUMBER — pull request nummer;
- $APPVEYOR_REPO_NAME - brukernavn og prosjektlager.
Konklusjon
Selvfølgelig har vi ikke vurdert alle mulige kontinuerlige integreringstjenester, men de har alle ekstremt like driftsspesifikasjoner som hverandre. Med unntak av caching lager hver tjeneste sin egen "sykkel", så alt er alltid annerledes.
Et eller annet sted, som i Travis-CI, fungerer et par linjer med kode og caching feilfritt; et sted, som i AppVeyor, trenger du bare å spesifisere mappen i innstillingene; men et sted må du lage unike nøkler og prøve å overbevise systemet om å gi deg muligheten til å overskrive det bufrede fragmentet. Derfor, hvis du ønsker å sette opp analyse av pull-forespørsler på en kontinuerlig integrasjonstjeneste som ikke ble diskutert ovenfor, så sørg først for at du ikke får problemer med caching.
Takk for din oppmerksomhet. Hvis noe ikke fungerer, skriv gjerne til oss på
Hvis du vil dele denne artikkelen med et engelsktalende publikum, vennligst bruk oversettelseslenken: Maxim Zvyagintsev.
Kilde: www.habr.com